xref: /netbsd-src/external/bsd/libevent/dist/http.c (revision 7e68cdd7306a8b6c32d6a32c16ba01e5a2ddc083)
1 /*	$NetBSD: http.c,v 1.5 2021/04/07 03:36:48 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
5  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "event2/event-config.h"
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: http.c,v 1.5 2021/04/07 03:36:48 christos Exp $");
33 #include "evconfig-private.h"
34 
35 #ifdef EVENT__HAVE_SYS_PARAM_H
36 #include <sys/param.h>
37 #endif
38 #ifdef EVENT__HAVE_SYS_TYPES_H
39 #include <sys/types.h>
40 #endif
41 
42 #ifdef HAVE_SYS_IOCCOM_H
43 #include <sys/ioccom.h>
44 #endif
45 #ifdef EVENT__HAVE_SYS_RESOURCE_H
46 #include <sys/resource.h>
47 #endif
48 #ifdef EVENT__HAVE_SYS_TIME_H
49 #include <sys/time.h>
50 #endif
51 #ifdef EVENT__HAVE_SYS_WAIT_H
52 #include <sys/wait.h>
53 #endif
54 
55 #ifndef _WIN32
56 #include <sys/socket.h>
57 #include <sys/stat.h>
58 #else /* _WIN32 */
59 #include <winsock2.h>
60 #include <ws2tcpip.h>
61 #endif /* _WIN32 */
62 
63 #ifdef EVENT__HAVE_SYS_UN_H
64 #include <sys/un.h>
65 #endif
66 #ifdef EVENT__HAVE_AFUNIX_H
67 #include <afunix.h>
68 #endif
69 
70 #include <sys/queue.h>
71 
72 #ifdef EVENT__HAVE_NETINET_IN_H
73 #include <netinet/in.h>
74 #endif
75 #ifdef EVENT__HAVE_ARPA_INET_H
76 #include <arpa/inet.h>
77 #endif
78 #ifdef EVENT__HAVE_NETDB_H
79 #include <netdb.h>
80 #endif
81 
82 #ifdef _WIN32
83 #include <winsock2.h>
84 #endif
85 
86 #include <errno.h>
87 #include <stdio.h>
88 #include <stdlib.h>
89 #include <string.h>
90 #ifndef _WIN32
91 #include <syslog.h>
92 #endif /* !_WIN32 */
93 #include <signal.h>
94 #ifdef EVENT__HAVE_UNISTD_H
95 #include <unistd.h>
96 #endif
97 #ifdef EVENT__HAVE_FCNTL_H
98 #include <fcntl.h>
99 #endif
100 
101 #undef timeout_pending
102 #undef timeout_initialized
103 
104 #include "strlcpy-internal.h"
105 #include "event2/http.h"
106 #include "event2/event.h"
107 #include "event2/buffer.h"
108 #include "event2/bufferevent.h"
109 #include "event2/http_struct.h"
110 #include "event2/http_compat.h"
111 #include "event2/util.h"
112 #include "event2/listener.h"
113 #include "log-internal.h"
114 #include "util-internal.h"
115 #include "http-internal.h"
116 #include "mm-internal.h"
117 #include "bufferevent-internal.h"
118 
119 #ifndef EVENT__HAVE_GETNAMEINFO
120 #define NI_MAXSERV 32
121 #define NI_MAXHOST 1025
122 
123 #ifndef NI_NUMERICHOST
124 #define NI_NUMERICHOST 1
125 #endif
126 
127 #ifndef NI_NUMERICSERV
128 #define NI_NUMERICSERV 2
129 #endif
130 
131 static int
fake_getnameinfo(const struct sockaddr * sa,size_t salen,char * host,size_t hostlen,char * serv,size_t servlen,int flags)132 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
133 	size_t hostlen, char *serv, size_t servlen, int flags)
134 {
135 	struct sockaddr_in *sin = (struct sockaddr_in *)sa;
136 
137 	if (serv != NULL) {
138 		char tmpserv[16];
139 		evutil_snprintf(tmpserv, sizeof(tmpserv),
140 		    "%d", ntohs(sin->sin_port));
141 		if (strlcpy(serv, tmpserv, servlen) >= servlen)
142 			return (-1);
143 	}
144 
145 	if (host != NULL) {
146 		if (flags & NI_NUMERICHOST) {
147 			if (strlcpy(host, inet_ntoa(sin->sin_addr),
148 			    hostlen) >= hostlen)
149 				return (-1);
150 			else
151 				return (0);
152 		} else {
153 			struct hostent *hp;
154 			hp = gethostbyaddr((char *)&sin->sin_addr,
155 			    sizeof(struct in_addr), AF_INET);
156 			if (hp == NULL)
157 				return (-2);
158 
159 			if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
160 				return (-1);
161 			else
162 				return (0);
163 		}
164 	}
165 	return (0);
166 }
167 
168 #endif
169 
170 #define REQ_VERSION_BEFORE(req, major_v, minor_v)			\
171 	((req)->major < (major_v) ||					\
172 	    ((req)->major == (major_v) && (req)->minor < (minor_v)))
173 
174 #define REQ_VERSION_ATLEAST(req, major_v, minor_v)			\
175 	((req)->major > (major_v) ||					\
176 	    ((req)->major == (major_v) && (req)->minor >= (minor_v)))
177 
178 #ifndef MIN
179 #define MIN(a,b) (((a)<(b))?(a):(b))
180 #endif
181 
182 extern int debug;
183 
184 static evutil_socket_t create_bind_socket_nonblock(struct evutil_addrinfo *, int reuse);
185 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
186 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
187 static struct evhttp_uri *evhttp_uri_parse_authority(char *source_uri);
188 static int evhttp_associate_new_request_with_connection(
189 	struct evhttp_connection *evcon);
190 static void evhttp_connection_start_detectclose(
191 	struct evhttp_connection *evcon);
192 static void evhttp_connection_stop_detectclose(
193 	struct evhttp_connection *evcon);
194 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
195 static void evhttp_read_firstline(struct evhttp_connection *evcon,
196 				  struct evhttp_request *req);
197 static void evhttp_read_header(struct evhttp_connection *evcon,
198     struct evhttp_request *req);
199 static int evhttp_add_header_internal(struct evkeyvalq *headers,
200     const char *key, const char *value);
201 static const char *evhttp_response_phrase_internal(int code);
202 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t);
203 static void evhttp_write_buffer(struct evhttp_connection *,
204     void (*)(struct evhttp_connection *, void *), void *);
205 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
206 
207 /* callbacks for bufferevent */
208 static void evhttp_read_cb(struct bufferevent *, void *);
209 static void evhttp_write_cb(struct bufferevent *, void *);
210 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
211 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
212 		  const char *hostname);
213 
214 #ifndef EVENT__HAVE_STRSEP
215 /* strsep replacement for platforms that lack it.  Only works if
216  * del is one character long. */
217 static char *
strsep(char ** s,const char * del)218 strsep(char **s, const char *del)
219 {
220 	char *d, *tok;
221 	EVUTIL_ASSERT(strlen(del) == 1);
222 	if (!s || !*s)
223 		return NULL;
224 	tok = *s;
225 	d = strstr(tok, del);
226 	if (d) {
227 		*d = '\0';
228 		*s = d + 1;
229 	} else
230 		*s = NULL;
231 	return tok;
232 }
233 #endif
234 
235 static size_t
html_replace(const char ch,const char ** escaped)236 html_replace(const char ch, const char **escaped)
237 {
238 	switch (ch) {
239 	case '<':
240 		*escaped = "&lt;";
241 		return 4;
242 	case '>':
243 		*escaped = "&gt;";
244 		return 4;
245 	case '"':
246 		*escaped = "&quot;";
247 		return 6;
248 	case '\'':
249 		*escaped = "&#039;";
250 		return 6;
251 	case '&':
252 		*escaped = "&amp;";
253 		return 5;
254 	default:
255 		break;
256 	}
257 
258 	return 1;
259 }
260 
261 /*
262  * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
263  * &#039; and &amp; correspondingly.
264  *
265  * The returned string needs to be freed by the caller.
266  */
267 
268 char *
evhttp_htmlescape(const char * html)269 evhttp_htmlescape(const char *html)
270 {
271 	size_t i;
272 	size_t new_size = 0, old_size = 0;
273 	char *escaped_html, *p;
274 
275 	if (html == NULL)
276 		return (NULL);
277 
278 	old_size = strlen(html);
279 	for (i = 0; i < old_size; ++i) {
280 		const char *replaced = NULL;
281 		const size_t replace_size = html_replace(html[i], &replaced);
282 		if (replace_size > EV_SIZE_MAX - new_size) {
283 			event_warn("%s: html_replace overflow", __func__);
284 			return (NULL);
285 		}
286 		new_size += replace_size;
287 	}
288 
289 	if (new_size == EV_SIZE_MAX)
290 		return (NULL);
291 	p = escaped_html = mm_malloc(new_size + 1);
292 	if (escaped_html == NULL) {
293 		event_warn("%s: malloc(%lu)", __func__,
294 		           (unsigned long)(new_size + 1));
295 		return (NULL);
296 	}
297 	for (i = 0; i < old_size; ++i) {
298 		const char *replaced = &html[i];
299 		const size_t len = html_replace(html[i], &replaced);
300 		memcpy(p, replaced, len);
301 		p += len;
302 	}
303 
304 	*p = '\0';
305 
306 	return (escaped_html);
307 }
308 
309 /** Given an evhttp_cmd_type, returns a constant string containing the
310  * equivalent HTTP command, or NULL if the evhttp_command_type is
311  * unrecognized. */
312 static const char *
evhttp_method(enum evhttp_cmd_type type)313 evhttp_method(enum evhttp_cmd_type type)
314 {
315 	const char *method;
316 
317 	switch (type) {
318 	case EVHTTP_REQ_GET:
319 		method = "GET";
320 		break;
321 	case EVHTTP_REQ_POST:
322 		method = "POST";
323 		break;
324 	case EVHTTP_REQ_HEAD:
325 		method = "HEAD";
326 		break;
327 	case EVHTTP_REQ_PUT:
328 		method = "PUT";
329 		break;
330 	case EVHTTP_REQ_DELETE:
331 		method = "DELETE";
332 		break;
333 	case EVHTTP_REQ_OPTIONS:
334 		method = "OPTIONS";
335 		break;
336 	case EVHTTP_REQ_TRACE:
337 		method = "TRACE";
338 		break;
339 	case EVHTTP_REQ_CONNECT:
340 		method = "CONNECT";
341 		break;
342 	case EVHTTP_REQ_PATCH:
343 		method = "PATCH";
344 		break;
345 	default:
346 		method = NULL;
347 		break;
348 	}
349 
350 	return (method);
351 }
352 
353 /**
354  * Determines if a response should have a body.
355  * Follows the rules in RFC 2616 section 4.3.
356  * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
357  *     a body.
358  */
359 static int
evhttp_response_needs_body(struct evhttp_request * req)360 evhttp_response_needs_body(struct evhttp_request *req)
361 {
362 	return (req->response_code != HTTP_NOCONTENT &&
363 		req->response_code != HTTP_NOTMODIFIED &&
364 		(req->response_code < 100 || req->response_code >= 200) &&
365 		req->type != EVHTTP_REQ_CONNECT &&
366 		req->type != EVHTTP_REQ_HEAD);
367 }
368 
369 /** Helper: called after we've added some data to an evcon's bufferevent's
370  * output buffer.  Sets the evconn's writing-is-done callback, and puts
371  * the bufferevent into writing mode.
372  */
373 static void
evhttp_write_buffer(struct evhttp_connection * evcon,void (* cb)(struct evhttp_connection *,void *),void * arg)374 evhttp_write_buffer(struct evhttp_connection *evcon,
375     void (*cb)(struct evhttp_connection *, void *), void *arg)
376 {
377 	event_debug(("%s: preparing to write buffer\n", __func__));
378 
379 	/* Set call back */
380 	evcon->cb = cb;
381 	evcon->cb_arg = arg;
382 
383 	/* Disable the read callback: we don't actually care about data;
384 	 * we only care about close detection. (We don't disable reading --
385 	 * EV_READ, since we *do* want to learn about any close events.) */
386 	bufferevent_setcb(evcon->bufev,
387 	    NULL, /*read*/
388 	    evhttp_write_cb,
389 	    evhttp_error_cb,
390 	    evcon);
391 
392 	bufferevent_enable(evcon->bufev, EV_READ|EV_WRITE);
393 }
394 
395 static void
evhttp_send_continue_done(struct evhttp_connection * evcon,void * arg)396 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
397 {
398 	bufferevent_disable(evcon->bufev, EV_WRITE);
399 }
400 
401 static void
evhttp_send_continue(struct evhttp_connection * evcon,struct evhttp_request * req)402 evhttp_send_continue(struct evhttp_connection *evcon,
403 			struct evhttp_request *req)
404 {
405 	bufferevent_enable(evcon->bufev, EV_WRITE);
406 	evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
407 			"HTTP/%d.%d 100 Continue\r\n\r\n",
408 			req->major, req->minor);
409 	evcon->cb = evhttp_send_continue_done;
410 	evcon->cb_arg = NULL;
411 	bufferevent_setcb(evcon->bufev,
412 	    evhttp_read_cb,
413 	    evhttp_write_cb,
414 	    evhttp_error_cb,
415 	    evcon);
416 }
417 
418 /** Helper: returns true iff evconn is in any connected state. */
419 static int
evhttp_connected(struct evhttp_connection * evcon)420 evhttp_connected(struct evhttp_connection *evcon)
421 {
422 	switch (evcon->state) {
423 	case EVCON_DISCONNECTED:
424 	case EVCON_CONNECTING:
425 		return (0);
426 	case EVCON_IDLE:
427 	case EVCON_READING_FIRSTLINE:
428 	case EVCON_READING_HEADERS:
429 	case EVCON_READING_BODY:
430 	case EVCON_READING_TRAILER:
431 	case EVCON_WRITING:
432 	default:
433 		return (1);
434 	}
435 }
436 
437 /* Create the headers needed for an outgoing HTTP request, adds them to
438  * the request's header list, and writes the request line to the
439  * connection's output buffer.
440  */
441 static void
evhttp_make_header_request(struct evhttp_connection * evcon,struct evhttp_request * req)442 evhttp_make_header_request(struct evhttp_connection *evcon,
443     struct evhttp_request *req)
444 {
445 	const char *method;
446 
447 	evhttp_remove_header(req->output_headers, "Proxy-Connection");
448 
449 	/* Generate request line */
450 	if (!(method = evhttp_method(req->type))) {
451 		method = "NULL";
452 	}
453 
454 	evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
455 	    "%s %s HTTP/%d.%d\r\n",
456 	    method, req->uri, req->major, req->minor);
457 
458 	/* Add the content length on a post or put request if missing */
459 	if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
460 	    evhttp_find_header(req->output_headers, "Content-Length") == NULL){
461 		char size[22];
462 		evutil_snprintf(size, sizeof(size), EV_SIZE_FMT,
463 		    EV_SIZE_ARG(evbuffer_get_length(req->output_buffer)));
464 		evhttp_add_header(req->output_headers, "Content-Length", size);
465 	}
466 }
467 
468 /** Return true if the list of headers in 'headers', intepreted with respect
469  * to flags, means that we should send a "connection: close" when the request
470  * is done. */
471 static int
evhttp_is_connection_close(int flags,struct evkeyvalq * headers)472 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
473 {
474 	if (flags & EVHTTP_PROXY_REQUEST) {
475 		/* proxy connection */
476 		const char *connection = evhttp_find_header(headers, "Proxy-Connection");
477 		return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
478 	} else {
479 		const char *connection = evhttp_find_header(headers, "Connection");
480 		return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
481 	}
482 }
483 static int
evhttp_is_request_connection_close(struct evhttp_request * req)484 evhttp_is_request_connection_close(struct evhttp_request *req)
485 {
486 	if (req->type == EVHTTP_REQ_CONNECT)
487 		return 0;
488 
489 	return
490 		evhttp_is_connection_close(req->flags, req->input_headers) ||
491 		evhttp_is_connection_close(req->flags, req->output_headers);
492 }
493 
494 /* Return true iff 'headers' contains 'Connection: keep-alive' */
495 static int
evhttp_is_connection_keepalive(struct evkeyvalq * headers)496 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
497 {
498 	const char *connection = evhttp_find_header(headers, "Connection");
499 	return (connection != NULL
500 	    && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
501 }
502 
503 /* Add a correct "Date" header to headers, unless it already has one. */
504 static void
evhttp_maybe_add_date_header(struct evkeyvalq * headers)505 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
506 {
507 	if (evhttp_find_header(headers, "Date") == NULL) {
508 		char date[50];
509 		if (sizeof(date) - evutil_date_rfc1123(date, sizeof(date), NULL) > 0) {
510 			evhttp_add_header(headers, "Date", date);
511 		}
512 	}
513 }
514 
515 /* Add a "Content-Length" header with value 'content_length' to headers,
516  * unless it already has a content-length or transfer-encoding header. */
517 static void
evhttp_maybe_add_content_length_header(struct evkeyvalq * headers,size_t content_length)518 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
519     size_t content_length)
520 {
521 	if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
522 	    evhttp_find_header(headers,	"Content-Length") == NULL) {
523 		char len[22];
524 		evutil_snprintf(len, sizeof(len), EV_SIZE_FMT,
525 		    EV_SIZE_ARG(content_length));
526 		evhttp_add_header(headers, "Content-Length", len);
527 	}
528 }
529 
530 /*
531  * Create the headers needed for an HTTP reply in req->output_headers,
532  * and write the first HTTP response for req line to evcon.
533  */
534 static void
evhttp_make_header_response(struct evhttp_connection * evcon,struct evhttp_request * req)535 evhttp_make_header_response(struct evhttp_connection *evcon,
536     struct evhttp_request *req)
537 {
538 	int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
539 	evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
540 	    "HTTP/%d.%d %d %s\r\n",
541 	    req->major, req->minor, req->response_code,
542 	    req->response_code_line);
543 
544 	if (req->major == 1) {
545 		if (req->minor >= 1)
546 			evhttp_maybe_add_date_header(req->output_headers);
547 
548 		/*
549 		 * if the protocol is 1.0; and the connection was keep-alive
550 		 * we need to add a keep-alive header, too.
551 		 */
552 		if (req->minor == 0 && is_keepalive)
553 			evhttp_add_header(req->output_headers,
554 			    "Connection", "keep-alive");
555 
556 		if ((req->minor >= 1 || is_keepalive) &&
557 		    evhttp_response_needs_body(req)) {
558 			/*
559 			 * we need to add the content length if the
560 			 * user did not give it, this is required for
561 			 * persistent connections to work.
562 			 */
563 			evhttp_maybe_add_content_length_header(
564 				req->output_headers,
565 				evbuffer_get_length(req->output_buffer));
566 		}
567 	}
568 
569 	/* Potentially add headers for unidentified content. */
570 	if (evhttp_response_needs_body(req)) {
571 		if (evhttp_find_header(req->output_headers,
572 			"Content-Type") == NULL
573 		    && evcon->http_server->default_content_type) {
574 			evhttp_add_header(req->output_headers,
575 			    "Content-Type",
576 			    evcon->http_server->default_content_type);
577 		}
578 	}
579 
580 	/* if the request asked for a close, we send a close, too */
581 	if (evhttp_is_connection_close(req->flags, req->input_headers)) {
582 		evhttp_remove_header(req->output_headers, "Connection");
583 		if (!(req->flags & EVHTTP_PROXY_REQUEST))
584 		    evhttp_add_header(req->output_headers, "Connection", "close");
585 		evhttp_remove_header(req->output_headers, "Proxy-Connection");
586 	}
587 }
588 
589 enum expect { NO, CONTINUE, OTHER };
evhttp_have_expect(struct evhttp_request * req,int input)590 static enum expect evhttp_have_expect(struct evhttp_request *req, int input)
591 {
592 	const char *expect;
593 	struct evkeyvalq *h = input ? req->input_headers : req->output_headers;
594 
595 	if (!(req->kind == EVHTTP_REQUEST) || !REQ_VERSION_ATLEAST(req, 1, 1))
596 		return NO;
597 
598 	expect = evhttp_find_header(h, "Expect");
599 	if (!expect)
600 		return NO;
601 
602 	return !evutil_ascii_strcasecmp(expect, "100-continue") ? CONTINUE : OTHER;
603 }
604 
605 
606 /** Generate all headers appropriate for sending the http request in req (or
607  * the response, if we're sending a response), and write them to evcon's
608  * bufferevent. Also writes all data from req->output_buffer */
609 static void
evhttp_make_header(struct evhttp_connection * evcon,struct evhttp_request * req)610 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
611 {
612 	struct evkeyval *header;
613 	struct evbuffer *output = bufferevent_get_output(evcon->bufev);
614 
615 	/*
616 	 * Depending if this is a HTTP request or response, we might need to
617 	 * add some new headers or remove existing headers.
618 	 */
619 	if (req->kind == EVHTTP_REQUEST) {
620 		evhttp_make_header_request(evcon, req);
621 	} else {
622 		evhttp_make_header_response(evcon, req);
623 	}
624 
625 	TAILQ_FOREACH(header, req->output_headers, next) {
626 		evbuffer_add_printf(output, "%s: %s\r\n",
627 		    header->key, header->value);
628 	}
629 	evbuffer_add(output, "\r\n", 2);
630 
631 	if (evhttp_have_expect(req, 0) != CONTINUE &&
632 		evbuffer_get_length(req->output_buffer)) {
633 		/*
634 		 * For a request, we add the POST data, for a reply, this
635 		 * is the regular data.
636 		 */
637 		evbuffer_add_buffer(output, req->output_buffer);
638 	}
639 }
640 
641 void
evhttp_connection_set_max_headers_size(struct evhttp_connection * evcon,ev_ssize_t new_max_headers_size)642 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
643     ev_ssize_t new_max_headers_size)
644 {
645 	if (new_max_headers_size<0)
646 		evcon->max_headers_size = EV_SIZE_MAX;
647 	else
648 		evcon->max_headers_size = new_max_headers_size;
649 }
650 void
evhttp_connection_set_max_body_size(struct evhttp_connection * evcon,ev_ssize_t new_max_body_size)651 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
652     ev_ssize_t new_max_body_size)
653 {
654 	if (new_max_body_size<0)
655 		evcon->max_body_size = EV_UINT64_MAX;
656 	else
657 		evcon->max_body_size = new_max_body_size;
658 }
659 
660 static int
evhttp_connection_incoming_fail(struct evhttp_request * req,enum evhttp_request_error error)661 evhttp_connection_incoming_fail(struct evhttp_request *req,
662     enum evhttp_request_error error)
663 {
664 	switch (error) {
665 		case EVREQ_HTTP_DATA_TOO_LONG:
666 			req->response_code = HTTP_ENTITYTOOLARGE;
667 			break;
668 		default:
669 			req->response_code = HTTP_BADREQUEST;
670 	}
671 
672 	switch (error) {
673 	case EVREQ_HTTP_TIMEOUT:
674 	case EVREQ_HTTP_EOF:
675 		/*
676 		 * these are cases in which we probably should just
677 		 * close the connection and not send a reply.  this
678 		 * case may happen when a browser keeps a persistent
679 		 * connection open and we timeout on the read.  when
680 		 * the request is still being used for sending, we
681 		 * need to disassociated it from the connection here.
682 		 */
683 		if (!req->userdone) {
684 			/* remove it so that it will not be freed */
685 			TAILQ_REMOVE(&req->evcon->requests, req, next);
686 			/* indicate that this request no longer has a
687 			 * connection object
688 			 */
689 			req->evcon = NULL;
690 		}
691 		return (-1);
692 	case EVREQ_HTTP_INVALID_HEADER:
693 	case EVREQ_HTTP_BUFFER_ERROR:
694 	case EVREQ_HTTP_REQUEST_CANCEL:
695 	case EVREQ_HTTP_DATA_TOO_LONG:
696 	default:	/* xxx: probably should just error on default */
697 		/* the callback looks at the uri to determine errors */
698 		if (req->uri) {
699 			mm_free(req->uri);
700 			req->uri = NULL;
701 		}
702 		if (req->uri_elems) {
703 			evhttp_uri_free(req->uri_elems);
704 			req->uri_elems = NULL;
705 		}
706 
707 		/*
708 		 * the callback needs to send a reply, once the reply has
709 		 * been send, the connection should get freed.
710 		 */
711 		(*req->cb)(req, req->cb_arg);
712 	}
713 
714 	return (0);
715 }
716 
717 /* Free connection ownership of which can be acquired by user using
718  * evhttp_request_own(). */
719 static inline void
evhttp_request_free_auto(struct evhttp_request * req)720 evhttp_request_free_auto(struct evhttp_request *req)
721 {
722 	if (!(req->flags & EVHTTP_USER_OWNED))
723 		evhttp_request_free(req);
724 }
725 
726 static void
evhttp_request_free_(struct evhttp_connection * evcon,struct evhttp_request * req)727 evhttp_request_free_(struct evhttp_connection *evcon, struct evhttp_request *req)
728 {
729 	TAILQ_REMOVE(&evcon->requests, req, next);
730 	evhttp_request_free_auto(req);
731 }
732 
733 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
734  * given in error. If it's an outgoing connection, reset the connection,
735  * retry any pending requests, and inform the user.  If it's incoming,
736  * delegates to evhttp_connection_incoming_fail(). */
737 void
evhttp_connection_fail_(struct evhttp_connection * evcon,enum evhttp_request_error error)738 evhttp_connection_fail_(struct evhttp_connection *evcon,
739     enum evhttp_request_error error)
740 {
741 	const int errsave = EVUTIL_SOCKET_ERROR();
742 	struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
743 	void (*cb)(struct evhttp_request *, void *);
744 	void *cb_arg;
745 	void (*error_cb)(enum evhttp_request_error, void *);
746 	void *error_cb_arg;
747 	EVUTIL_ASSERT(req != NULL);
748 
749 	bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
750 
751 	if (evcon->flags & EVHTTP_CON_INCOMING) {
752 		/*
753 		 * for incoming requests, there are two different
754 		 * failure cases.  it's either a network level error
755 		 * or an http layer error. for problems on the network
756 		 * layer like timeouts we just drop the connections.
757 		 * For HTTP problems, we might have to send back a
758 		 * reply before the connection can be freed.
759 		 */
760 		if (evhttp_connection_incoming_fail(req, error) == -1)
761 			evhttp_connection_free(evcon);
762 		return;
763 	}
764 
765 	error_cb = req->error_cb;
766 	error_cb_arg = req->cb_arg;
767 	/* when the request was canceled, the callback is not executed */
768 	if (error != EVREQ_HTTP_REQUEST_CANCEL) {
769 		/* save the callback for later; the cb might free our object */
770 		cb = req->cb;
771 		cb_arg = req->cb_arg;
772 	} else {
773 		cb = NULL;
774 		cb_arg = NULL;
775 	}
776 
777 	/* do not fail all requests; the next request is going to get
778 	 * send over a new connection.   when a user cancels a request,
779 	 * all other pending requests should be processed as normal
780 	 */
781 	evhttp_request_free_(evcon, req);
782 
783 	/* reset the connection */
784 	evhttp_connection_reset_(evcon);
785 
786 	/* We are trying the next request that was queued on us */
787 	if (TAILQ_FIRST(&evcon->requests) != NULL)
788 		evhttp_connection_connect_(evcon);
789 	else
790 		if ((evcon->flags & EVHTTP_CON_OUTGOING) &&
791 		    (evcon->flags & EVHTTP_CON_AUTOFREE)) {
792 			evhttp_connection_free(evcon);
793 		}
794 
795 	/* The call to evhttp_connection_reset_ overwrote errno.
796 	 * Let's restore the original errno, so that the user's
797 	 * callback can have a better idea of what the error was.
798 	 */
799 	EVUTIL_SET_SOCKET_ERROR(errsave);
800 
801 	/* inform the user */
802 	if (error_cb != NULL)
803 		error_cb(error, error_cb_arg);
804 	if (cb != NULL)
805 		(*cb)(NULL, cb_arg);
806 }
807 
808 /* Bufferevent callback: invoked when any data has been written from an
809  * http connection's bufferevent */
810 static void
evhttp_write_cb(struct bufferevent * bufev,void * arg)811 evhttp_write_cb(struct bufferevent *bufev, void *arg)
812 {
813 	struct evhttp_connection *evcon = arg;
814 
815 	/* Activate our call back */
816 	if (evcon->cb != NULL)
817 		(*evcon->cb)(evcon, evcon->cb_arg);
818 }
819 
820 /**
821  * Advance the connection state.
822  * - If this is an outgoing connection, we've just processed the response;
823  *   idle or close the connection.
824  * - If this is an incoming connection, we've just processed the request;
825  *   respond.
826  */
827 static void
evhttp_connection_done(struct evhttp_connection * evcon)828 evhttp_connection_done(struct evhttp_connection *evcon)
829 {
830 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
831 	int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
832 	int free_evcon = 0;
833 
834 	if (con_outgoing) {
835 		/* idle or close the connection */
836 		int need_close = evhttp_is_request_connection_close(req);
837 		TAILQ_REMOVE(&evcon->requests, req, next);
838 		req->evcon = NULL;
839 
840 		evcon->state = EVCON_IDLE;
841 
842 		/* check if we got asked to close the connection */
843 		if (need_close)
844 			evhttp_connection_reset_(evcon);
845 
846 		if (TAILQ_FIRST(&evcon->requests) != NULL) {
847 			/*
848 			 * We have more requests; reset the connection
849 			 * and deal with the next request.
850 			 */
851 			if (!evhttp_connected(evcon))
852 				evhttp_connection_connect_(evcon);
853 			else
854 				evhttp_request_dispatch(evcon);
855 		} else if (!need_close) {
856 			/*
857 			 * The connection is going to be persistent, but we
858 			 * need to detect if the other side closes it.
859 			 */
860 			evhttp_connection_start_detectclose(evcon);
861 		} else if ((evcon->flags & EVHTTP_CON_AUTOFREE)) {
862 			/*
863 			 * If we have no more requests that need completion
864 			 * and we're not waiting for the connection to close
865 			 */
866 			 free_evcon = 1;
867 		}
868 	} else {
869 		/*
870 		 * incoming connection - we need to leave the request on the
871 		 * connection so that we can reply to it.
872 		 */
873 		evcon->state = EVCON_WRITING;
874 	}
875 
876 	/* notify the user of the request */
877 	(*req->cb)(req, req->cb_arg);
878 
879 	/* if this was an outgoing request, we own and it's done. so free it. */
880 	if (con_outgoing) {
881 		evhttp_request_free_auto(req);
882 	}
883 
884 	/* If this was the last request of an outgoing connection and we're
885 	 * not waiting to receive a connection close event and we want to
886 	 * automatically free the connection. We check to ensure our request
887 	 * list is empty one last time just in case our callback added a
888 	 * new request.
889 	 */
890 	if (free_evcon && TAILQ_FIRST(&evcon->requests) == NULL) {
891 		evhttp_connection_free(evcon);
892 	}
893 }
894 
895 /*
896  * Handles reading from a chunked request.
897  *   return ALL_DATA_READ:
898  *     all data has been read
899  *   return MORE_DATA_EXPECTED:
900  *     more data is expected
901  *   return DATA_CORRUPTED:
902  *     data is corrupted
903  *   return REQUEST_CANCELED:
904  *     request was canceled by the user calling evhttp_cancel_request
905  *   return DATA_TOO_LONG:
906  *     ran over the maximum limit
907  */
908 
909 static enum message_read_status
evhttp_handle_chunked_read(struct evhttp_request * req,struct evbuffer * buf)910 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
911 {
912 	if (req == NULL || buf == NULL) {
913 	    return DATA_CORRUPTED;
914 	}
915 
916 	while (1) {
917 		size_t buflen;
918 
919 		if ((buflen = evbuffer_get_length(buf)) == 0) {
920 			break;
921 		}
922 
923 		/* evbuffer_get_length returns size_t, but len variable is ssize_t,
924 		 * check for overflow conditions */
925 		if (buflen > EV_SSIZE_MAX) {
926 			return DATA_CORRUPTED;
927 		}
928 
929 		if (req->ntoread < 0) {
930 			/* Read chunk size */
931 			ev_int64_t ntoread;
932 			char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
933 			char *endp;
934 			int error;
935 			if (p == NULL)
936 				break;
937 			/* the last chunk is on a new line? */
938 			if (strlen(p) == 0) {
939 				mm_free(p);
940 				continue;
941 			}
942 			ntoread = evutil_strtoll(p, &endp, 16);
943 			error = (*p == '\0' ||
944 			    (*endp != '\0' && *endp != ' ') ||
945 			    ntoread < 0);
946 			mm_free(p);
947 			if (error) {
948 				/* could not get chunk size */
949 				return (DATA_CORRUPTED);
950 			}
951 
952 			/* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
953 			if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
954 			    return DATA_CORRUPTED;
955 			}
956 
957 			if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
958 				/* failed body length test */
959 				event_debug(("Request body is too long"));
960 				return (DATA_TOO_LONG);
961 			}
962 
963 			req->body_size += (size_t)ntoread;
964 			req->ntoread = ntoread;
965 			if (req->ntoread == 0) {
966 				/* Last chunk */
967 				return (ALL_DATA_READ);
968 			}
969 			continue;
970 		}
971 
972 		/* req->ntoread is signed int64, len is ssize_t, based on arch,
973 		 * ssize_t could only be 32b, check for these conditions */
974 		if (req->ntoread > EV_SSIZE_MAX) {
975 			return DATA_CORRUPTED;
976 		}
977 
978 		/* don't have enough to complete a chunk; wait for more */
979 		if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
980 			return (MORE_DATA_EXPECTED);
981 
982 		/* Completed chunk */
983 		evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
984 		req->ntoread = -1;
985 		if (req->chunk_cb != NULL) {
986 			req->flags |= EVHTTP_REQ_DEFER_FREE;
987 			(*req->chunk_cb)(req, req->cb_arg);
988 			evbuffer_drain(req->input_buffer,
989 			    evbuffer_get_length(req->input_buffer));
990 			req->flags &= ~EVHTTP_REQ_DEFER_FREE;
991 			if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
992 				return (REQUEST_CANCELED);
993 			}
994 		}
995 	}
996 
997 	return (MORE_DATA_EXPECTED);
998 }
999 
1000 static void
evhttp_read_trailer(struct evhttp_connection * evcon,struct evhttp_request * req)1001 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
1002 {
1003 	struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1004 
1005 	switch (evhttp_parse_headers_(req, buf)) {
1006 	case DATA_CORRUPTED:
1007 	case DATA_TOO_LONG:
1008 		evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1009 		break;
1010 	case ALL_DATA_READ:
1011 		bufferevent_disable(evcon->bufev, EV_READ);
1012 		evhttp_connection_done(evcon);
1013 		break;
1014 	case MORE_DATA_EXPECTED:
1015 	case REQUEST_CANCELED: /* ??? */
1016 	default:
1017 		break;
1018 	}
1019 }
1020 
1021 static void
evhttp_lingering_close(struct evhttp_connection * evcon,struct evhttp_request * req)1022 evhttp_lingering_close(struct evhttp_connection *evcon,
1023 	struct evhttp_request *req)
1024 {
1025 	struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1026 
1027 	size_t n = evbuffer_get_length(buf);
1028 	if (n > (size_t) req->ntoread)
1029 		n = (size_t) req->ntoread;
1030 	req->ntoread -= n;
1031 	req->body_size += n;
1032 
1033 	event_debug(("Request body is too long, left " EV_I64_FMT,
1034 		EV_I64_ARG(req->ntoread)));
1035 
1036 	evbuffer_drain(buf, n);
1037 	if (!req->ntoread)
1038 		evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1039 }
1040 static void
evhttp_lingering_fail(struct evhttp_connection * evcon,struct evhttp_request * req)1041 evhttp_lingering_fail(struct evhttp_connection *evcon,
1042 	struct evhttp_request *req)
1043 {
1044 	if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE)
1045 		evhttp_lingering_close(evcon, req);
1046 	else
1047 		evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1048 }
1049 
1050 static void
evhttp_read_body(struct evhttp_connection * evcon,struct evhttp_request * req)1051 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1052 {
1053 	struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1054 
1055 	if (req->chunked) {
1056 		switch (evhttp_handle_chunked_read(req, buf)) {
1057 		case ALL_DATA_READ:
1058 			/* finished last chunk */
1059 			evcon->state = EVCON_READING_TRAILER;
1060 			evhttp_read_trailer(evcon, req);
1061 			return;
1062 		case DATA_CORRUPTED:
1063 		case DATA_TOO_LONG:
1064 			/* corrupted data */
1065 			evhttp_connection_fail_(evcon,
1066 			    EVREQ_HTTP_DATA_TOO_LONG);
1067 			return;
1068 		case REQUEST_CANCELED:
1069 			/* request canceled */
1070 			evhttp_request_free_auto(req);
1071 			return;
1072 		case MORE_DATA_EXPECTED:
1073 		default:
1074 			break;
1075 		}
1076 	} else if (req->ntoread < 0) {
1077 		/* Read until connection close. */
1078 		if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
1079 			evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
1080 			return;
1081 		}
1082 
1083 		req->body_size += evbuffer_get_length(buf);
1084 		evbuffer_add_buffer(req->input_buffer, buf);
1085 	} else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
1086 		/* XXX: the above get_length comparison has to be fixed for overflow conditions! */
1087 		/* We've postponed moving the data until now, but we're
1088 		 * about to use it. */
1089 		size_t n = evbuffer_get_length(buf);
1090 
1091 		if (n > (size_t) req->ntoread)
1092 			n = (size_t) req->ntoread;
1093 		req->ntoread -= n;
1094 		req->body_size += n;
1095 		evbuffer_remove_buffer(buf, req->input_buffer, n);
1096 	}
1097 
1098 	if (req->body_size > req->evcon->max_body_size ||
1099 	    (!req->chunked && req->ntoread >= 0 &&
1100 		(size_t)req->ntoread > req->evcon->max_body_size)) {
1101 		/* XXX: The above casted comparison must checked for overflow */
1102 		/* failed body length test */
1103 
1104 		evhttp_lingering_fail(evcon, req);
1105 		return;
1106 	}
1107 
1108 	if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1109 		req->flags |= EVHTTP_REQ_DEFER_FREE;
1110 		(*req->chunk_cb)(req, req->cb_arg);
1111 		req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1112 		evbuffer_drain(req->input_buffer,
1113 		    evbuffer_get_length(req->input_buffer));
1114 		if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1115 			evhttp_request_free_auto(req);
1116 			return;
1117 		}
1118 	}
1119 
1120 	if (!req->ntoread) {
1121 		bufferevent_disable(evcon->bufev, EV_READ);
1122 		/* Completed content length */
1123 		evhttp_connection_done(evcon);
1124 		return;
1125 	}
1126 }
1127 
1128 #define get_deferred_queue(evcon)		\
1129 	((evcon)->base)
1130 
1131 /*
1132  * Gets called when more data becomes available
1133  */
1134 
1135 static void
evhttp_read_cb(struct bufferevent * bufev,void * arg)1136 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1137 {
1138 	struct evhttp_connection *evcon = arg;
1139 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1140 
1141 	/* Cancel if it's pending. */
1142 	event_deferred_cb_cancel_(get_deferred_queue(evcon),
1143 	    &evcon->read_more_deferred_cb);
1144 
1145 	switch (evcon->state) {
1146 	case EVCON_READING_FIRSTLINE:
1147 		evhttp_read_firstline(evcon, req);
1148 		/* note the request may have been freed in
1149 		 * evhttp_read_body */
1150 		break;
1151 	case EVCON_READING_HEADERS:
1152 		evhttp_read_header(evcon, req);
1153 		/* note the request may have been freed in
1154 		 * evhttp_read_body */
1155 		break;
1156 	case EVCON_READING_BODY:
1157 		evhttp_read_body(evcon, req);
1158 		/* note the request may have been freed in
1159 		 * evhttp_read_body */
1160 		break;
1161 	case EVCON_READING_TRAILER:
1162 		evhttp_read_trailer(evcon, req);
1163 		break;
1164 	case EVCON_IDLE:
1165 		{
1166 #ifdef USE_DEBUG
1167 			struct evbuffer *input;
1168 			size_t total_len;
1169 
1170 			input = bufferevent_get_input(evcon->bufev);
1171 			total_len = evbuffer_get_length(input);
1172 			event_debug(("%s: read "EV_SIZE_FMT
1173 				" bytes in EVCON_IDLE state,"
1174 				" resetting connection",
1175 				__func__, EV_SIZE_ARG(total_len)));
1176 #endif
1177 
1178 			evhttp_connection_reset_(evcon);
1179 		}
1180 		break;
1181 	case EVCON_DISCONNECTED:
1182 	case EVCON_CONNECTING:
1183 	case EVCON_WRITING:
1184 	default:
1185 		event_errx(1, "%s: illegal connection state %d",
1186 			   __func__, evcon->state);
1187 	}
1188 }
1189 
1190 static void
evhttp_deferred_read_cb(struct event_callback * cb,void * data)1191 evhttp_deferred_read_cb(struct event_callback *cb, void *data)
1192 {
1193 	struct evhttp_connection *evcon = data;
1194 	struct bufferevent *bev = evcon->bufev;
1195 	if (bev->readcb)
1196 		(bev->readcb)(evcon->bufev, evcon);
1197 }
1198 
1199 static void
evhttp_write_connectioncb(struct evhttp_connection * evcon,void * arg)1200 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1201 {
1202 	/* This is after writing the request to the server */
1203 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1204 	struct evbuffer *output = bufferevent_get_output(evcon->bufev);
1205 	EVUTIL_ASSERT(req != NULL);
1206 
1207 	EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1208 
1209 	/* We need to wait until we've written all of our output data before we can
1210 	 * continue */
1211 	if (evbuffer_get_length(output) > 0)
1212 		return;
1213 
1214 	/* We are done writing our header and are now expecting the response */
1215 	req->kind = EVHTTP_RESPONSE;
1216 
1217 	evhttp_start_read_(evcon);
1218 }
1219 
1220 /*
1221  * Clean up a connection object
1222  */
1223 
1224 void
evhttp_connection_free(struct evhttp_connection * evcon)1225 evhttp_connection_free(struct evhttp_connection *evcon)
1226 {
1227 	struct evhttp_request *req;
1228 	int need_close = 0;
1229 
1230 	/* notify interested parties that this connection is going down */
1231 	if (evcon->fd != -1) {
1232 		if (evhttp_connected(evcon) && evcon->closecb != NULL)
1233 			(*evcon->closecb)(evcon, evcon->closecb_arg);
1234 	}
1235 
1236 	/* remove all requests that might be queued on this
1237 	 * connection.  for server connections, this should be empty.
1238 	 * because it gets dequeued either in evhttp_connection_done or
1239 	 * evhttp_connection_fail_.
1240 	 */
1241 	while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1242 		evhttp_request_free_(evcon, req);
1243 	}
1244 
1245 	if (evcon->http_server != NULL) {
1246 		struct evhttp *http = evcon->http_server;
1247 		TAILQ_REMOVE(&http->connections, evcon, next);
1248 	}
1249 
1250 	if (event_initialized(&evcon->retry_ev)) {
1251 		event_del(&evcon->retry_ev);
1252 		event_debug_unassign(&evcon->retry_ev);
1253 	}
1254 
1255 	event_deferred_cb_cancel_(get_deferred_queue(evcon),
1256 	    &evcon->read_more_deferred_cb);
1257 
1258 	if (evcon->bufev != NULL) {
1259 		need_close =
1260 			!(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE);
1261 		if (evcon->fd == -1)
1262 			evcon->fd = bufferevent_getfd(evcon->bufev);
1263 
1264 		bufferevent_free(evcon->bufev);
1265 	}
1266 
1267 	if (evcon->fd != -1) {
1268 		shutdown(evcon->fd, EVUTIL_SHUT_WR);
1269 		if (need_close)
1270 			evutil_closesocket(evcon->fd);
1271 	}
1272 
1273 	if (evcon->bind_address != NULL)
1274 		mm_free(evcon->bind_address);
1275 
1276 	if (evcon->address != NULL)
1277 		mm_free(evcon->address);
1278 
1279 	mm_free(evcon);
1280 }
1281 
1282 void
evhttp_connection_free_on_completion(struct evhttp_connection * evcon)1283 evhttp_connection_free_on_completion(struct evhttp_connection *evcon) {
1284 	evcon->flags |= EVHTTP_CON_AUTOFREE;
1285 }
1286 
1287 void
evhttp_connection_set_local_address(struct evhttp_connection * evcon,const char * address)1288 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1289     const char *address)
1290 {
1291 	EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1292 	if (evcon->bind_address)
1293 		mm_free(evcon->bind_address);
1294 	if ((evcon->bind_address = mm_strdup(address)) == NULL)
1295 		event_warn("%s: strdup", __func__);
1296 }
1297 
1298 void
evhttp_connection_set_local_port(struct evhttp_connection * evcon,ev_uint16_t port)1299 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1300     ev_uint16_t port)
1301 {
1302 	EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1303 	evcon->bind_port = port;
1304 }
1305 
1306 static void
evhttp_request_dispatch(struct evhttp_connection * evcon)1307 evhttp_request_dispatch(struct evhttp_connection* evcon)
1308 {
1309 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1310 
1311 	/* this should not usually happy but it's possible */
1312 	if (req == NULL)
1313 		return;
1314 
1315 	EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST);
1316 
1317 	/* delete possible close detection events */
1318 	evhttp_connection_stop_detectclose(evcon);
1319 
1320 	/* we assume that the connection is connected already */
1321 	EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1322 
1323 	evcon->state = EVCON_WRITING;
1324 
1325 	/* Create the header from the store arguments */
1326 	evhttp_make_header(evcon, req);
1327 
1328 	evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1329 }
1330 
1331 /* Reset our connection state: disables reading/writing, closes our fd (if
1332 * any), clears out buffers, and puts us in state DISCONNECTED. */
1333 void
evhttp_connection_reset_(struct evhttp_connection * evcon)1334 evhttp_connection_reset_(struct evhttp_connection *evcon)
1335 {
1336 	struct evbuffer *tmp;
1337 	int err;
1338 
1339 	bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL);
1340 
1341 	/* XXXX This is not actually an optimal fix.  Instead we ought to have
1342 	   an API for "stop connecting", or use bufferevent_setfd to turn off
1343 	   connecting.  But for Libevent 2.0, this seems like a minimal change
1344 	   least likely to disrupt the rest of the bufferevent and http code.
1345 
1346 	   Why is this here?  If the fd is set in the bufferevent, and the
1347 	   bufferevent is connecting, then you can't actually stop the
1348 	   bufferevent from trying to connect with bufferevent_disable().  The
1349 	   connect will never trigger, since we close the fd, but the timeout
1350 	   might.  That caused an assertion failure in evhttp_connection_fail_.
1351 	*/
1352 	bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE);
1353 
1354 	if (evcon->fd == -1)
1355 		evcon->fd = bufferevent_getfd(evcon->bufev);
1356 
1357 	if (evcon->fd != -1) {
1358 		/* inform interested parties about connection close */
1359 		if (evhttp_connected(evcon) && evcon->closecb != NULL)
1360 			(*evcon->closecb)(evcon, evcon->closecb_arg);
1361 
1362 		shutdown(evcon->fd, EVUTIL_SHUT_WR);
1363 		evutil_closesocket(evcon->fd);
1364 		evcon->fd = -1;
1365 	}
1366 	err = bufferevent_setfd(evcon->bufev, -1);
1367 	EVUTIL_ASSERT(!err && "setfd");
1368 
1369 	/* we need to clean up any buffered data */
1370 	tmp = bufferevent_get_output(evcon->bufev);
1371 	err = evbuffer_drain(tmp, -1);
1372 	EVUTIL_ASSERT(!err && "drain output");
1373 	tmp = bufferevent_get_input(evcon->bufev);
1374 	err = evbuffer_drain(tmp, -1);
1375 	EVUTIL_ASSERT(!err && "drain input");
1376 
1377 	evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1378 
1379 	evcon->state = EVCON_DISCONNECTED;
1380 }
1381 
1382 static void
evhttp_connection_start_detectclose(struct evhttp_connection * evcon)1383 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1384 {
1385 	evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1386 	bufferevent_enable(evcon->bufev, EV_READ);
1387 }
1388 
1389 static void
evhttp_connection_stop_detectclose(struct evhttp_connection * evcon)1390 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1391 {
1392 	evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1393 	bufferevent_disable(evcon->bufev, EV_READ);
1394 }
1395 
1396 static void
evhttp_connection_retry(evutil_socket_t fd,short what,void * arg)1397 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1398 {
1399 	struct evhttp_connection *evcon = arg;
1400 
1401 	evcon->state = EVCON_DISCONNECTED;
1402 	evhttp_connection_connect_(evcon);
1403 }
1404 
1405 static void
evhttp_connection_cb_cleanup(struct evhttp_connection * evcon)1406 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1407 {
1408 	struct evcon_requestq requests;
1409 
1410 	evhttp_connection_reset_(evcon);
1411 	if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1412 		struct timeval tv_retry = evcon->initial_retry_timeout;
1413 		int i;
1414 		evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1415 		/* XXXX handle failure from evhttp_add_event */
1416 		for (i=0; i < evcon->retry_cnt; ++i) {
1417 			tv_retry.tv_usec *= 2;
1418 			if (tv_retry.tv_usec > 1000000) {
1419 				tv_retry.tv_usec -= 1000000;
1420 				tv_retry.tv_sec += 1;
1421 			}
1422 			tv_retry.tv_sec *= 2;
1423 			if (tv_retry.tv_sec > 3600) {
1424 				tv_retry.tv_sec = 3600;
1425 				tv_retry.tv_usec = 0;
1426 			}
1427 		}
1428 		event_add(&evcon->retry_ev, &tv_retry);
1429 		evcon->retry_cnt++;
1430 		return;
1431 	}
1432 
1433 	/*
1434 	 * User callback can do evhttp_make_request() on the same
1435 	 * evcon so new request will be added to evcon->requests.  To
1436 	 * avoid freeing it prematurely we iterate over the copy of
1437 	 * the queue.
1438 	 */
1439 	TAILQ_INIT(&requests);
1440 	while (TAILQ_FIRST(&evcon->requests) != NULL) {
1441 		struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1442 		TAILQ_REMOVE(&evcon->requests, request, next);
1443 		TAILQ_INSERT_TAIL(&requests, request, next);
1444 	}
1445 
1446 	/* for now, we just signal all requests by executing their callbacks */
1447 	while (TAILQ_FIRST(&requests) != NULL) {
1448 		struct evhttp_request *request = TAILQ_FIRST(&requests);
1449 		TAILQ_REMOVE(&requests, request, next);
1450 		request->evcon = NULL;
1451 
1452 		/* we might want to set an error here */
1453 		request->cb(request, request->cb_arg);
1454 		evhttp_request_free_auto(request);
1455 	}
1456 }
1457 
1458 static void
evhttp_connection_read_on_write_error(struct evhttp_connection * evcon,struct evhttp_request * req)1459 evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
1460     struct evhttp_request *req)
1461 {
1462 	struct evbuffer *buf;
1463 
1464 	/** Second time, we can't read anything */
1465 	if (evcon->flags & EVHTTP_CON_READING_ERROR) {
1466 		evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1467 		evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1468 		return;
1469 	}
1470 
1471 	req->kind = EVHTTP_RESPONSE;
1472 
1473 	buf = bufferevent_get_output(evcon->bufev);
1474 	evbuffer_unfreeze(buf, 1);
1475 	evbuffer_drain(buf, evbuffer_get_length(buf));
1476 	evbuffer_freeze(buf, 1);
1477 
1478 	evhttp_start_read_(evcon);
1479 	evcon->flags |= EVHTTP_CON_READING_ERROR;
1480 }
1481 
1482 static void
evhttp_error_cb(struct bufferevent * bufev,short what,void * arg)1483 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1484 {
1485 	struct evhttp_connection *evcon = arg;
1486 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1487 
1488 	if (evcon->fd == -1)
1489 		evcon->fd = bufferevent_getfd(bufev);
1490 
1491 	switch (evcon->state) {
1492 	case EVCON_CONNECTING:
1493 		if (what & BEV_EVENT_TIMEOUT) {
1494 			event_debug(("%s: connection timeout for \"%s:%d\" on "
1495 				EV_SOCK_FMT,
1496 				__func__, evcon->address, evcon->port,
1497 				EV_SOCK_ARG(evcon->fd)));
1498 			evhttp_connection_cb_cleanup(evcon);
1499 			return;
1500 		}
1501 		break;
1502 
1503 	case EVCON_READING_BODY:
1504 		if (!req->chunked && req->ntoread < 0
1505 		    && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1506 			/* EOF on read can be benign */
1507 			evhttp_connection_done(evcon);
1508 			return;
1509 		}
1510 		break;
1511 
1512 	case EVCON_DISCONNECTED:
1513 	case EVCON_IDLE:
1514 	case EVCON_READING_FIRSTLINE:
1515 	case EVCON_READING_HEADERS:
1516 	case EVCON_READING_TRAILER:
1517 	case EVCON_WRITING:
1518 	default:
1519 		break;
1520 	}
1521 
1522 	/* when we are in close detect mode, a read error means that
1523 	 * the other side closed their connection.
1524 	 */
1525 	if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1526 		evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1527 		EVUTIL_ASSERT(evcon->http_server == NULL);
1528 		/* For connections from the client, we just
1529 		 * reset the connection so that it becomes
1530 		 * disconnected.
1531 		 */
1532 		EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1533 		evhttp_connection_reset_(evcon);
1534 
1535 		/*
1536 		 * If we have no more requests that need completion
1537 		 * and we want to auto-free the connection when all
1538 		 * requests have been completed.
1539 		 */
1540 		if (TAILQ_FIRST(&evcon->requests) == NULL
1541 		  && (evcon->flags & EVHTTP_CON_OUTGOING)
1542 		  && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1543 			evhttp_connection_free(evcon);
1544 		}
1545 		return;
1546 	}
1547 
1548 	if (what & BEV_EVENT_TIMEOUT) {
1549 		evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
1550 	} else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1551 		if (what & BEV_EVENT_WRITING &&
1552 			evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR) {
1553 			evhttp_connection_read_on_write_error(evcon, req);
1554 			return;
1555 		}
1556 
1557 		if (what & BEV_EVENT_READING &&
1558 			evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR &&
1559 			evbuffer_get_length(bufferevent_get_input(bufev))) {
1560 			event_deferred_cb_schedule_(get_deferred_queue(evcon),
1561 			    &evcon->read_more_deferred_cb);
1562 			return;
1563 		}
1564 
1565 		evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1566 	} else if (what == BEV_EVENT_CONNECTED) {
1567 	} else {
1568 		evhttp_connection_fail_(evcon, EVREQ_HTTP_BUFFER_ERROR);
1569 	}
1570 }
1571 
1572 /*
1573  * Event callback for asynchronous connection attempt.
1574  */
1575 static void
evhttp_connection_cb(struct bufferevent * bufev,short what,void * arg)1576 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1577 {
1578 	struct evhttp_connection *evcon = arg;
1579 	int error;
1580 	ev_socklen_t errsz = sizeof(error);
1581 
1582 	if (evcon->fd == -1)
1583 		evcon->fd = bufferevent_getfd(bufev);
1584 
1585 	if (!(what & BEV_EVENT_CONNECTED)) {
1586 		/* some operating systems return ECONNREFUSED immediately
1587 		 * when connecting to a local address.  the cleanup is going
1588 		 * to reschedule this function call.
1589 		 */
1590 #ifndef _WIN32
1591 		if (errno == ECONNREFUSED)
1592 			goto cleanup;
1593 #endif
1594 		evhttp_error_cb(bufev, what, arg);
1595 		return;
1596 	}
1597 
1598 	if (evcon->fd == -1) {
1599 		event_debug(("%s: bufferevent_getfd returned -1",
1600 			__func__));
1601 		goto cleanup;
1602 	}
1603 
1604 	/* Check if the connection completed */
1605 	if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1606 		       &errsz) == -1) {
1607 		event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT,
1608 			__func__, evcon->address, evcon->port,
1609 			EV_SOCK_ARG(evcon->fd)));
1610 		goto cleanup;
1611 	}
1612 
1613 	if (error) {
1614 		event_debug(("%s: connect failed for \"%s:%d\" on "
1615 			EV_SOCK_FMT": %s",
1616 			__func__, evcon->address, evcon->port,
1617 			EV_SOCK_ARG(evcon->fd),
1618 			evutil_socket_error_to_string(error)));
1619 		goto cleanup;
1620 	}
1621 
1622 	/* We are connected to the server now */
1623 	event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1624 			__func__, evcon->address, evcon->port,
1625 			EV_SOCK_ARG(evcon->fd)));
1626 
1627 	/* Reset the retry count as we were successful in connecting */
1628 	evcon->retry_cnt = 0;
1629 	evcon->state = EVCON_IDLE;
1630 
1631 	/* reset the bufferevent cbs */
1632 	bufferevent_setcb(evcon->bufev,
1633 	    evhttp_read_cb,
1634 	    evhttp_write_cb,
1635 	    evhttp_error_cb,
1636 	    evcon);
1637 
1638 	if (!evutil_timerisset(&evcon->timeout)) {
1639 		const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 };
1640 		const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 };
1641 		bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv);
1642 	} else {
1643 		bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
1644 	}
1645 
1646 	/* try to start requests that have queued up on this connection */
1647 	evhttp_request_dispatch(evcon);
1648 	return;
1649 
1650  cleanup:
1651 	evhttp_connection_cb_cleanup(evcon);
1652 }
1653 
1654 /*
1655  * Check if we got a valid response code.
1656  */
1657 
1658 static int
evhttp_valid_response_code(int code)1659 evhttp_valid_response_code(int code)
1660 {
1661 	if (code == 0)
1662 		return (0);
1663 
1664 	return (1);
1665 }
1666 
1667 static int
evhttp_parse_http_version(const char * version,struct evhttp_request * req)1668 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1669 {
1670 	int major, minor;
1671 	char ch;
1672 	int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1673 	if (n != 2 || major > 1) {
1674 		event_debug(("%s: bad version %s on message %p from %s",
1675 			__func__, version, req, req->remote_host));
1676 		return (-1);
1677 	}
1678 	req->major = major;
1679 	req->minor = minor;
1680 	return (0);
1681 }
1682 
1683 /* Parses the status line of a web server */
1684 
1685 static int
evhttp_parse_response_line(struct evhttp_request * req,char * line)1686 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1687 {
1688 	char *protocol;
1689 	char *number;
1690 	const char *readable = "";
1691 
1692 	protocol = strsep(&line, " ");
1693 	if (line == NULL)
1694 		return (-1);
1695 	number = strsep(&line, " ");
1696 	if (line != NULL)
1697 		readable = line;
1698 
1699 	if (evhttp_parse_http_version(protocol, req) < 0)
1700 		return (-1);
1701 
1702 	req->response_code = atoi(number);
1703 	if (!evhttp_valid_response_code(req->response_code)) {
1704 		event_debug(("%s: bad response code \"%s\"",
1705 			__func__, number));
1706 		return (-1);
1707 	}
1708 
1709 	if (req->response_code_line != NULL)
1710 		mm_free(req->response_code_line);
1711 	if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1712 		event_warn("%s: strdup", __func__);
1713 		return (-1);
1714 	}
1715 
1716 	return (0);
1717 }
1718 
1719 /* Parse the first line of a HTTP request */
1720 
1721 static int
evhttp_parse_request_line(struct evhttp_request * req,char * line,size_t len)1722 evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len)
1723 {
1724 	char *eos = line + len;
1725 	char *method;
1726 	char *uri;
1727 	char *version;
1728 	const char *hostname;
1729 	const char *scheme;
1730 	size_t method_len;
1731 	enum evhttp_cmd_type type;
1732 
1733 	while (eos > line && *(eos-1) == ' ') {
1734 		*(eos-1) = '\0';
1735 		--eos;
1736 		--len;
1737 	}
1738 	if (len < strlen("GET / HTTP/1.0"))
1739 		return -1;
1740 
1741 	/* Parse the request line */
1742 	method = strsep(&line, " ");
1743 	if (!line)
1744 		return -1;
1745 	uri = line;
1746 	version = strrchr(uri, ' ');
1747 	if (!version || uri == version)
1748 		return -1;
1749 	*version = '\0';
1750 	version++;
1751 
1752 	method_len = (uri - method) - 1;
1753 	type       = EVHTTP_REQ_UNKNOWN_;
1754 
1755 	/* First line */
1756 	switch (method_len) {
1757 	    case 3:
1758 		/* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1759 
1760 		/* Since both GET and PUT share the same character 'T' at the end,
1761 		 * if the string doesn't have 'T', we can immediately determine this
1762 		 * is an invalid HTTP method */
1763 
1764 		if (method[2] != 'T') {
1765 		    break;
1766 		}
1767 
1768 		switch (*method) {
1769 		    case 'G':
1770 			/* This first byte is 'G', so make sure the next byte is
1771 			 * 'E', if it isn't then this isn't a valid method */
1772 
1773 			if (method[1] == 'E') {
1774 			    type = EVHTTP_REQ_GET;
1775 			}
1776 
1777 			break;
1778 		    case 'P':
1779 			/* First byte is P, check second byte for 'U', if not,
1780 			 * we know it's an invalid method */
1781 			if (method[1] == 'U') {
1782 			    type = EVHTTP_REQ_PUT;
1783 			}
1784 			break;
1785 		    default:
1786 			break;
1787 		}
1788 		break;
1789 	    case 4:
1790 		/* The method length is 4 bytes, leaving only the methods "POST" and "HEAD" */
1791 		switch (*method) {
1792 		    case 'P':
1793 			if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') {
1794 			    type = EVHTTP_REQ_POST;
1795 			}
1796 			break;
1797 		    case 'H':
1798 			if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') {
1799 			    type = EVHTTP_REQ_HEAD;
1800 			}
1801 			break;
1802 		    default:
1803 			break;
1804 		}
1805 		break;
1806 	    case 5:
1807 		/* Method length is 5 bytes, which can only encompass PATCH and TRACE */
1808 		switch (*method) {
1809 		    case 'P':
1810 			if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') {
1811 			    type = EVHTTP_REQ_PATCH;
1812 			}
1813 			break;
1814 		    case 'T':
1815 			if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') {
1816 			    type = EVHTTP_REQ_TRACE;
1817 			}
1818 
1819 			break;
1820 		    default:
1821 			break;
1822 		}
1823 		break;
1824 	    case 6:
1825 		/* Method length is 6, only valid method 6 bytes in length is DELEte */
1826 
1827 		/* If the first byte isn't 'D' then it's invalid */
1828 		if (*method != 'D') {
1829 		    break;
1830 		}
1831 
1832 		if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' && method[2] == 'L' && method[1] == 'E') {
1833 		    type = EVHTTP_REQ_DELETE;
1834 		}
1835 
1836 		break;
1837 	    case 7:
1838 		/* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1839 		switch (*method) {
1840 		    case 'O':
1841 			if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' &&
1842 				method[3] == 'I' && method[2] == 'T' && method[1] == 'P') {
1843 			    type = EVHTTP_REQ_OPTIONS;
1844 			}
1845 
1846 		       	break;
1847 		    case 'C':
1848 			if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' &&
1849 				method[3] == 'N' && method[2] == 'N' && method[1] == 'O') {
1850 			    type = EVHTTP_REQ_CONNECT;
1851 			}
1852 
1853 			break;
1854 		    default:
1855 			break;
1856 		}
1857 		break;
1858 	} /* switch */
1859 
1860 	if ((int)type == EVHTTP_REQ_UNKNOWN_) {
1861 	        event_debug(("%s: bad method %s on request %p from %s",
1862 			__func__, method, req, req->remote_host));
1863                 /* No error yet; we'll give a better error later when
1864                  * we see that req->type is unsupported. */
1865 	}
1866 
1867 	req->type = type;
1868 
1869 	if (evhttp_parse_http_version(version, req) < 0)
1870 		return -1;
1871 
1872 	if ((req->uri = mm_strdup(uri)) == NULL) {
1873 		event_debug(("%s: mm_strdup", __func__));
1874 		return -1;
1875 	}
1876 
1877 	if (type == EVHTTP_REQ_CONNECT) {
1878 		if ((req->uri_elems = evhttp_uri_parse_authority(req->uri)) == NULL) {
1879 			return -1;
1880 		}
1881 	} else {
1882 		if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
1883 			    EVHTTP_URI_NONCONFORMANT)) == NULL) {
1884 			return -1;
1885 		}
1886 	}
1887 
1888 	/* If we have an absolute-URI, check to see if it is an http request
1889 	   for a known vhost or server alias. If we don't know about this
1890 	   host, we consider it a proxy request. */
1891 	scheme = evhttp_uri_get_scheme(req->uri_elems);
1892 	hostname = evhttp_uri_get_host(req->uri_elems);
1893 	if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1894 		       !evutil_ascii_strcasecmp(scheme, "https")) &&
1895 	    hostname &&
1896 	    !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1897 		req->flags |= EVHTTP_PROXY_REQUEST;
1898 
1899 	return 0;
1900 }
1901 
1902 const char *
evhttp_find_header(const struct evkeyvalq * headers,const char * key)1903 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1904 {
1905 	struct evkeyval *header;
1906 
1907 	TAILQ_FOREACH(header, headers, next) {
1908 		if (evutil_ascii_strcasecmp(header->key, key) == 0)
1909 			return (header->value);
1910 	}
1911 
1912 	return (NULL);
1913 }
1914 
1915 void
evhttp_clear_headers(struct evkeyvalq * headers)1916 evhttp_clear_headers(struct evkeyvalq *headers)
1917 {
1918 	struct evkeyval *header;
1919 
1920 	for (header = TAILQ_FIRST(headers);
1921 	    header != NULL;
1922 	    header = TAILQ_FIRST(headers)) {
1923 		TAILQ_REMOVE(headers, header, next);
1924 		mm_free(header->key);
1925 		mm_free(header->value);
1926 		mm_free(header);
1927 	}
1928 }
1929 
1930 /*
1931  * Returns 0,  if the header was successfully removed.
1932  * Returns -1, if the header could not be found.
1933  */
1934 
1935 int
evhttp_remove_header(struct evkeyvalq * headers,const char * key)1936 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1937 {
1938 	struct evkeyval *header;
1939 
1940 	TAILQ_FOREACH(header, headers, next) {
1941 		if (evutil_ascii_strcasecmp(header->key, key) == 0)
1942 			break;
1943 	}
1944 
1945 	if (header == NULL)
1946 		return (-1);
1947 
1948 	/* Free and remove the header that we found */
1949 	TAILQ_REMOVE(headers, header, next);
1950 	mm_free(header->key);
1951 	mm_free(header->value);
1952 	mm_free(header);
1953 
1954 	return (0);
1955 }
1956 
1957 static int
evhttp_header_is_valid_value(const char * value)1958 evhttp_header_is_valid_value(const char *value)
1959 {
1960 	const char *p = value;
1961 
1962 	while ((p = strpbrk(p, "\r\n")) != NULL) {
1963 		/* we really expect only one new line */
1964 		p += strspn(p, "\r\n");
1965 		/* we expect a space or tab for continuation */
1966 		if (*p != ' ' && *p != '\t')
1967 			return (0);
1968 	}
1969 	return (1);
1970 }
1971 
1972 int
evhttp_add_header(struct evkeyvalq * headers,const char * key,const char * value)1973 evhttp_add_header(struct evkeyvalq *headers,
1974     const char *key, const char *value)
1975 {
1976 	event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1977 
1978 	if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1979 		/* drop illegal headers */
1980 		event_debug(("%s: dropping illegal header key\n", __func__));
1981 		return (-1);
1982 	}
1983 
1984 	if (!evhttp_header_is_valid_value(value)) {
1985 		event_debug(("%s: dropping illegal header value\n", __func__));
1986 		return (-1);
1987 	}
1988 
1989 	return (evhttp_add_header_internal(headers, key, value));
1990 }
1991 
1992 static int
evhttp_add_header_internal(struct evkeyvalq * headers,const char * key,const char * value)1993 evhttp_add_header_internal(struct evkeyvalq *headers,
1994     const char *key, const char *value)
1995 {
1996 	struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
1997 	if (header == NULL) {
1998 		event_warn("%s: calloc", __func__);
1999 		return (-1);
2000 	}
2001 	if ((header->key = mm_strdup(key)) == NULL) {
2002 		mm_free(header);
2003 		event_warn("%s: strdup", __func__);
2004 		return (-1);
2005 	}
2006 	if ((header->value = mm_strdup(value)) == NULL) {
2007 		mm_free(header->key);
2008 		mm_free(header);
2009 		event_warn("%s: strdup", __func__);
2010 		return (-1);
2011 	}
2012 
2013 	TAILQ_INSERT_TAIL(headers, header, next);
2014 
2015 	return (0);
2016 }
2017 
2018 /*
2019  * Parses header lines from a request or a response into the specified
2020  * request object given an event buffer.
2021  *
2022  * Returns
2023  *   DATA_CORRUPTED      on error
2024  *   MORE_DATA_EXPECTED  when we need to read more headers
2025  *   ALL_DATA_READ       when all headers have been read.
2026  */
2027 
2028 enum message_read_status
evhttp_parse_firstline_(struct evhttp_request * req,struct evbuffer * buffer)2029 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
2030 {
2031 	char *line;
2032 	enum message_read_status status = ALL_DATA_READ;
2033 
2034 	size_t len;
2035 	/* XXX try */
2036 	line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
2037 	if (line == NULL) {
2038 		if (req->evcon != NULL &&
2039 		    evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2040 			return (DATA_TOO_LONG);
2041 		else
2042 			return (MORE_DATA_EXPECTED);
2043 	}
2044 
2045 	if (req->evcon != NULL && len > req->evcon->max_headers_size) {
2046 		mm_free(line);
2047 		return (DATA_TOO_LONG);
2048 	}
2049 
2050 	req->headers_size = len;
2051 
2052 	switch (req->kind) {
2053 	case EVHTTP_REQUEST:
2054 		if (evhttp_parse_request_line(req, line, len) == -1)
2055 			status = DATA_CORRUPTED;
2056 		break;
2057 	case EVHTTP_RESPONSE:
2058 		if (evhttp_parse_response_line(req, line) == -1)
2059 			status = DATA_CORRUPTED;
2060 		break;
2061 	default:
2062 		status = DATA_CORRUPTED;
2063 	}
2064 
2065 	mm_free(line);
2066 	return (status);
2067 }
2068 
2069 static int
evhttp_append_to_last_header(struct evkeyvalq * headers,char * line)2070 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
2071 {
2072 	struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
2073 	char *newval;
2074 	size_t old_len, line_len;
2075 
2076 	if (header == NULL)
2077 		return (-1);
2078 
2079 	old_len = strlen(header->value);
2080 
2081 	/* Strip space from start and end of line. */
2082 	while (*line == ' ' || *line == '\t')
2083 		++line;
2084 	evutil_rtrim_lws_(line);
2085 
2086 	line_len = strlen(line);
2087 
2088 	newval = mm_realloc(header->value, old_len + line_len + 2);
2089 	if (newval == NULL)
2090 		return (-1);
2091 
2092 	newval[old_len] = ' ';
2093 	memcpy(newval + old_len + 1, line, line_len + 1);
2094 	header->value = newval;
2095 
2096 	return (0);
2097 }
2098 
2099 enum message_read_status
evhttp_parse_headers_(struct evhttp_request * req,struct evbuffer * buffer)2100 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
2101 {
2102 	enum message_read_status errcode = DATA_CORRUPTED;
2103 	char *line;
2104 	enum message_read_status status = MORE_DATA_EXPECTED;
2105 
2106 	struct evkeyvalq* headers = req->input_headers;
2107 	size_t len;
2108 	while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
2109 	       != NULL) {
2110 		char *skey, *svalue;
2111 
2112 		req->headers_size += len;
2113 
2114 		if (req->evcon != NULL &&
2115 		    req->headers_size > req->evcon->max_headers_size) {
2116 			errcode = DATA_TOO_LONG;
2117 			goto error;
2118 		}
2119 
2120 		if (*line == '\0') { /* Last header - Done */
2121 			status = ALL_DATA_READ;
2122 			mm_free(line);
2123 			break;
2124 		}
2125 
2126 		/* Check if this is a continuation line */
2127 		if (*line == ' ' || *line == '\t') {
2128 			if (evhttp_append_to_last_header(headers, line) == -1)
2129 				goto error;
2130 			mm_free(line);
2131 			continue;
2132 		}
2133 
2134 		/* Processing of header lines */
2135 		svalue = line;
2136 		skey = strsep(&svalue, ":");
2137 		if (svalue == NULL)
2138 			goto error;
2139 
2140 		svalue += strspn(svalue, " ");
2141 		evutil_rtrim_lws_(svalue);
2142 
2143 		if (evhttp_add_header(headers, skey, svalue) == -1)
2144 			goto error;
2145 
2146 		mm_free(line);
2147 	}
2148 
2149 	if (status == MORE_DATA_EXPECTED) {
2150 		if (req->evcon != NULL &&
2151 		req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2152 			return (DATA_TOO_LONG);
2153 	}
2154 
2155 	return (status);
2156 
2157  error:
2158 	mm_free(line);
2159 	return (errcode);
2160 }
2161 
2162 static int
evhttp_get_body_length(struct evhttp_request * req)2163 evhttp_get_body_length(struct evhttp_request *req)
2164 {
2165 	struct evkeyvalq *headers = req->input_headers;
2166 	const char *content_length;
2167 	const char *connection;
2168 
2169 	content_length = evhttp_find_header(headers, "Content-Length");
2170 	connection = evhttp_find_header(headers, "Connection");
2171 
2172 	if (content_length == NULL && connection == NULL)
2173 		req->ntoread = -1;
2174 	else if (content_length == NULL &&
2175 	    evutil_ascii_strcasecmp(connection, "Close") != 0) {
2176 		req->ntoread = 0;
2177 	} else if (content_length == NULL) {
2178 		req->ntoread = -1;
2179 	} else {
2180 		char *endp;
2181 		ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2182 		if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2183 			event_debug(("%s: illegal content length: %s",
2184 				__func__, content_length));
2185 			return (-1);
2186 		}
2187 		req->ntoread = ntoread;
2188 	}
2189 
2190 	event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2191 		__func__, EV_I64_ARG(req->ntoread),
2192 		EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2193 
2194 	return (0);
2195 }
2196 
2197 static int
evhttp_method_may_have_body(enum evhttp_cmd_type type)2198 evhttp_method_may_have_body(enum evhttp_cmd_type type)
2199 {
2200 	switch (type) {
2201 	case EVHTTP_REQ_POST:
2202 	case EVHTTP_REQ_PUT:
2203 	case EVHTTP_REQ_PATCH:
2204 
2205 	case EVHTTP_REQ_GET:
2206 	case EVHTTP_REQ_DELETE:
2207 	case EVHTTP_REQ_OPTIONS:
2208 	case EVHTTP_REQ_CONNECT:
2209 		return 1;
2210 
2211 	case EVHTTP_REQ_TRACE:
2212 	case EVHTTP_REQ_HEAD:
2213 	default:
2214 		return 0;
2215 	}
2216 }
2217 
2218 static void
evhttp_get_body(struct evhttp_connection * evcon,struct evhttp_request * req)2219 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2220 {
2221 	const char *xfer_enc;
2222 
2223 	/* If this is a request without a body, then we are done */
2224 	if (req->kind == EVHTTP_REQUEST &&
2225 	    !evhttp_method_may_have_body(req->type)) {
2226 		evhttp_connection_done(evcon);
2227 		return;
2228 	}
2229 	evcon->state = EVCON_READING_BODY;
2230 	xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
2231 	if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
2232 		req->chunked = 1;
2233 		req->ntoread = -1;
2234 	} else {
2235 		if (evhttp_get_body_length(req) == -1) {
2236 			evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2237 			return;
2238 		}
2239 		if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2240 			/* An incoming request with no content-length and no
2241 			 * transfer-encoding has no body. */
2242 			evhttp_connection_done(evcon);
2243 			return;
2244 		}
2245 	}
2246 
2247 	/* Should we send a 100 Continue status line? */
2248 	switch (evhttp_have_expect(req, 1)) {
2249 		case CONTINUE:
2250 				/* XXX It would be nice to do some sanity
2251 				   checking here. Does the resource exist?
2252 				   Should the resource accept post requests? If
2253 				   no, we should respond with an error. For
2254 				   now, just optimistically tell the client to
2255 				   send their message body. */
2256 				if (req->ntoread > 0) {
2257 					/* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2258 					if ((req->evcon->max_body_size <= EV_INT64_MAX) &&
2259 						(ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2260 						evhttp_lingering_fail(evcon, req);
2261 						return;
2262 					}
2263 				}
2264 				if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2265 					evhttp_send_continue(evcon, req);
2266 			break;
2267 		case OTHER:
2268 			evhttp_send_error(req, HTTP_EXPECTATIONFAILED, NULL);
2269 			return;
2270 		case NO: break;
2271 	}
2272 
2273 	evhttp_read_body(evcon, req);
2274 	/* note the request may have been freed in evhttp_read_body */
2275 }
2276 
2277 static void
evhttp_read_firstline(struct evhttp_connection * evcon,struct evhttp_request * req)2278 evhttp_read_firstline(struct evhttp_connection *evcon,
2279 		      struct evhttp_request *req)
2280 {
2281 	enum message_read_status res;
2282 
2283 	res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2284 	if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2285 		/* Error while reading, terminate */
2286 		event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2287 			__func__, EV_SOCK_ARG(evcon->fd)));
2288 		evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2289 		return;
2290 	} else if (res == MORE_DATA_EXPECTED) {
2291 		/* Need more header lines */
2292 		return;
2293 	}
2294 
2295 	evcon->state = EVCON_READING_HEADERS;
2296 	evhttp_read_header(evcon, req);
2297 }
2298 
2299 static void
evhttp_read_header(struct evhttp_connection * evcon,struct evhttp_request * req)2300 evhttp_read_header(struct evhttp_connection *evcon,
2301 		   struct evhttp_request *req)
2302 {
2303 	enum message_read_status res;
2304 	evutil_socket_t fd = evcon->fd;
2305 
2306 	res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2307 	if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2308 		/* Error while reading, terminate */
2309 		event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2310 			__func__, EV_SOCK_ARG(fd)));
2311 		evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2312 		return;
2313 	} else if (res == MORE_DATA_EXPECTED) {
2314 		/* Need more header lines */
2315 		return;
2316 	}
2317 
2318 	/* Callback can shut down connection with negative return value */
2319 	if (req->header_cb != NULL) {
2320 		if ((*req->header_cb)(req, req->cb_arg) < 0) {
2321 			evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2322 			return;
2323 		}
2324 	}
2325 
2326 	/* Done reading headers, do the real work */
2327 	switch (req->kind) {
2328 	case EVHTTP_REQUEST:
2329 		event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2330 			__func__, EV_SOCK_ARG(fd)));
2331 		evhttp_get_body(evcon, req);
2332 		/* note the request may have been freed in evhttp_get_body */
2333 		break;
2334 
2335 	case EVHTTP_RESPONSE:
2336 		/* Start over if we got a 100 Continue response. */
2337 		if (req->response_code == 100) {
2338 			struct evbuffer *output = bufferevent_get_output(evcon->bufev);
2339 			evbuffer_add_buffer(output, req->output_buffer);
2340 			evhttp_start_write_(evcon);
2341 			return;
2342 		}
2343 		if (!evhttp_response_needs_body(req)) {
2344 			event_debug(("%s: skipping body for code %d\n",
2345 					__func__, req->response_code));
2346 			evhttp_connection_done(evcon);
2347 		} else {
2348 			event_debug(("%s: start of read body for %s on "
2349 				EV_SOCK_FMT"\n",
2350 				__func__, req->remote_host, EV_SOCK_ARG(fd)));
2351 			evhttp_get_body(evcon, req);
2352 			/* note the request may have been freed in
2353 			 * evhttp_get_body */
2354 		}
2355 		break;
2356 
2357 	default:
2358 		event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2359 		    EV_SOCK_ARG(fd));
2360 		evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2361 		break;
2362 	}
2363 	/* request may have been freed above */
2364 }
2365 
2366 /*
2367  * Creates a TCP connection to the specified port and executes a callback
2368  * when finished.  Failure or success is indicate by the passed connection
2369  * object.
2370  *
2371  * Although this interface accepts a hostname, it is intended to take
2372  * only numeric hostnames so that non-blocking DNS resolution can
2373  * happen elsewhere.
2374  */
2375 
2376 struct evhttp_connection *
evhttp_connection_new(const char * address,ev_uint16_t port)2377 evhttp_connection_new(const char *address, ev_uint16_t port)
2378 {
2379 	return (evhttp_connection_base_new(NULL, NULL, address, port));
2380 }
2381 
2382 struct evhttp_connection *
evhttp_connection_base_bufferevent_new(struct event_base * base,struct evdns_base * dnsbase,struct bufferevent * bev,const char * address,ev_uint16_t port)2383 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2384     const char *address, ev_uint16_t port)
2385 {
2386 	struct evhttp_connection *evcon = NULL;
2387 
2388 	event_debug(("Attempting connection to %s:%d\n", address, port));
2389 
2390 	if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2391 		event_warn("%s: calloc failed", __func__);
2392 		goto error;
2393 	}
2394 
2395 	evcon->fd = -1;
2396 	evcon->port = port;
2397 
2398 	evcon->max_headers_size = EV_SIZE_MAX;
2399 	evcon->max_body_size = EV_SIZE_MAX;
2400 
2401 	evutil_timerclear(&evcon->timeout);
2402 	evcon->retry_cnt = evcon->retry_max = 0;
2403 
2404 	if ((evcon->address = mm_strdup(address)) == NULL) {
2405 		event_warn("%s: strdup failed", __func__);
2406 		goto error;
2407 	}
2408 
2409 	if (bev == NULL) {
2410 		if (!(bev = bufferevent_socket_new(base, -1, 0))) {
2411 			event_warn("%s: bufferevent_socket_new failed", __func__);
2412 			goto error;
2413 		}
2414 	}
2415 
2416 	bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2417 	evcon->bufev = bev;
2418 
2419 	evcon->state = EVCON_DISCONNECTED;
2420 	TAILQ_INIT(&evcon->requests);
2421 
2422 	evcon->initial_retry_timeout.tv_sec = 2;
2423 	evcon->initial_retry_timeout.tv_usec = 0;
2424 
2425 	if (base != NULL) {
2426 		evcon->base = base;
2427 		if (bufferevent_get_base(bev) != base)
2428 			bufferevent_base_set(base, evcon->bufev);
2429 	}
2430 
2431 	event_deferred_cb_init_(
2432 	    &evcon->read_more_deferred_cb,
2433 	    bufferevent_get_priority(bev),
2434 	    evhttp_deferred_read_cb, evcon);
2435 
2436 	evcon->dns_base = dnsbase;
2437 	evcon->ai_family = AF_UNSPEC;
2438 
2439 	return (evcon);
2440 
2441  error:
2442 	if (evcon != NULL)
2443 		evhttp_connection_free(evcon);
2444 	return (NULL);
2445 }
2446 
evhttp_connection_get_bufferevent(struct evhttp_connection * evcon)2447 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2448 {
2449 	return evcon->bufev;
2450 }
2451 
2452 struct evhttp *
evhttp_connection_get_server(struct evhttp_connection * evcon)2453 evhttp_connection_get_server(struct evhttp_connection *evcon)
2454 {
2455 	return evcon->http_server;
2456 }
2457 
2458 struct evhttp_connection *
evhttp_connection_base_new(struct event_base * base,struct evdns_base * dnsbase,const char * address,ev_uint16_t port)2459 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2460     const char *address, ev_uint16_t port)
2461 {
2462 	return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2463 }
2464 
evhttp_connection_set_family(struct evhttp_connection * evcon,int family)2465 void evhttp_connection_set_family(struct evhttp_connection *evcon,
2466 	int family)
2467 {
2468 	evcon->ai_family = family;
2469 }
2470 
evhttp_connection_set_flags(struct evhttp_connection * evcon,int flags)2471 int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2472 	int flags)
2473 {
2474 	int avail_flags = 0;
2475 	avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2476 	avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2477 
2478 	if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2479 		return 1;
2480 	evcon->flags &= ~avail_flags;
2481 
2482 	evcon->flags |= flags;
2483 
2484 	return 0;
2485 }
2486 
2487 void
evhttp_connection_set_base(struct evhttp_connection * evcon,struct event_base * base)2488 evhttp_connection_set_base(struct evhttp_connection *evcon,
2489     struct event_base *base)
2490 {
2491 	EVUTIL_ASSERT(evcon->base == NULL);
2492 	EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2493 	evcon->base = base;
2494 	bufferevent_base_set(base, evcon->bufev);
2495 }
2496 
2497 void
evhttp_connection_set_timeout(struct evhttp_connection * evcon,int timeout_in_secs)2498 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2499     int timeout_in_secs)
2500 {
2501 	if (timeout_in_secs == -1)
2502 		evhttp_connection_set_timeout_tv(evcon, NULL);
2503 	else {
2504 		struct timeval tv;
2505 		tv.tv_sec = timeout_in_secs;
2506 		tv.tv_usec = 0;
2507 		evhttp_connection_set_timeout_tv(evcon, &tv);
2508 	}
2509 }
2510 
2511 void
evhttp_connection_set_timeout_tv(struct evhttp_connection * evcon,const struct timeval * tv)2512 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2513     const struct timeval* tv)
2514 {
2515 	if (tv) {
2516 		evcon->timeout = *tv;
2517 		bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
2518 	} else {
2519 		const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 };
2520 		const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 };
2521 		evutil_timerclear(&evcon->timeout);
2522 		bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv);
2523 	}
2524 }
2525 
2526 void
evhttp_connection_set_initial_retry_tv(struct evhttp_connection * evcon,const struct timeval * tv)2527 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2528     const struct timeval *tv)
2529 {
2530 	if (tv) {
2531 		evcon->initial_retry_timeout = *tv;
2532 	} else {
2533 		evutil_timerclear(&evcon->initial_retry_timeout);
2534 		evcon->initial_retry_timeout.tv_sec = 2;
2535 	}
2536 }
2537 
2538 void
evhttp_connection_set_retries(struct evhttp_connection * evcon,int retry_max)2539 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2540     int retry_max)
2541 {
2542 	evcon->retry_max = retry_max;
2543 }
2544 
2545 void
evhttp_connection_set_closecb(struct evhttp_connection * evcon,void (* cb)(struct evhttp_connection *,void *),void * cbarg)2546 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2547     void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2548 {
2549 	evcon->closecb = cb;
2550 	evcon->closecb_arg = cbarg;
2551 }
2552 
2553 void
evhttp_connection_get_peer(struct evhttp_connection * evcon,char ** address,ev_uint16_t * port)2554 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2555     char **address, ev_uint16_t *port)
2556 {
2557 	*address = evcon->address;
2558 	*port = evcon->port;
2559 }
2560 
2561 const struct sockaddr*
evhttp_connection_get_addr(struct evhttp_connection * evcon)2562 evhttp_connection_get_addr(struct evhttp_connection *evcon)
2563 {
2564 	return bufferevent_socket_get_conn_address_(evcon->bufev);
2565 }
2566 
2567 int
evhttp_connection_connect_(struct evhttp_connection * evcon)2568 evhttp_connection_connect_(struct evhttp_connection *evcon)
2569 {
2570 	int old_state = evcon->state;
2571 	const char *address = evcon->address;
2572 	const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
2573 	int ret;
2574 
2575 	if (evcon->state == EVCON_CONNECTING)
2576 		return (0);
2577 
2578 	evhttp_connection_reset_(evcon);
2579 
2580 	EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2581 	evcon->flags |= EVHTTP_CON_OUTGOING;
2582 
2583 	if (evcon->bind_address || evcon->bind_port) {
2584 		evcon->fd = bind_socket(
2585 			evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2586 		if (evcon->fd == -1) {
2587 			event_debug(("%s: failed to bind to \"%s\"",
2588 				__func__, evcon->bind_address));
2589 			return (-1);
2590 		}
2591 
2592 		if (bufferevent_setfd(evcon->bufev, evcon->fd))
2593 			return (-1);
2594 	} else {
2595 		if (bufferevent_setfd(evcon->bufev, -1))
2596 			return (-1);
2597 	}
2598 
2599 	/* Set up a callback for successful connection setup */
2600 	bufferevent_setcb(evcon->bufev,
2601 	    NULL /* evhttp_read_cb */,
2602 	    NULL /* evhttp_write_cb */,
2603 	    evhttp_connection_cb,
2604 	    evcon);
2605 	if (!evutil_timerisset(&evcon->timeout)) {
2606 		const struct timeval conn_tv = { HTTP_CONNECT_TIMEOUT, 0 };
2607 		bufferevent_set_timeouts(evcon->bufev, &conn_tv, &conn_tv);
2608 	} else {
2609 		bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
2610 	}
2611 	/* make sure that we get a write callback */
2612 	if (bufferevent_enable(evcon->bufev, EV_WRITE))
2613 		return (-1);
2614 
2615 	evcon->state = EVCON_CONNECTING;
2616 
2617 	if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
2618 		sa &&
2619 		(sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
2620 		int socklen = sizeof(struct sockaddr_in);
2621 		if (sa->sa_family == AF_INET6) {
2622 			socklen = sizeof(struct sockaddr_in6);
2623 		}
2624 		ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
2625 	} else {
2626 		ret = bufferevent_socket_connect_hostname(evcon->bufev,
2627 				evcon->dns_base, evcon->ai_family, address, evcon->port);
2628 	}
2629 
2630 	if (ret < 0) {
2631 		evcon->state = old_state;
2632 		event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2633 		    __func__, evcon->address);
2634 		/* some operating systems return ECONNREFUSED immediately
2635 		 * when connecting to a local address.  the cleanup is going
2636 		 * to reschedule this function call.
2637 		 */
2638 		evhttp_connection_cb_cleanup(evcon);
2639 		return (0);
2640 	}
2641 
2642 	return (0);
2643 }
2644 
2645 /*
2646  * Starts an HTTP request on the provided evhttp_connection object.
2647  * If the connection object is not connected to the web server already,
2648  * this will start the connection.
2649  */
2650 
2651 int
evhttp_make_request(struct evhttp_connection * evcon,struct evhttp_request * req,enum evhttp_cmd_type type,const char * uri)2652 evhttp_make_request(struct evhttp_connection *evcon,
2653     struct evhttp_request *req,
2654     enum evhttp_cmd_type type, const char *uri)
2655 {
2656 	/* We are making a request */
2657 	req->kind = EVHTTP_REQUEST;
2658 	req->type = type;
2659 	if (req->uri != NULL)
2660 		mm_free(req->uri);
2661 	if ((req->uri = mm_strdup(uri)) == NULL) {
2662 		event_warn("%s: strdup", __func__);
2663 		evhttp_request_free_auto(req);
2664 		return (-1);
2665 	}
2666 
2667 	/* Set the protocol version if it is not supplied */
2668 	if (!req->major && !req->minor) {
2669 		req->major = 1;
2670 		req->minor = 1;
2671 	}
2672 
2673 	EVUTIL_ASSERT(req->evcon == NULL);
2674 	req->evcon = evcon;
2675 	EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2676 
2677 	TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2678 
2679 	/* We do not want to conflict with retry_ev */
2680 	if (evcon->retry_cnt)
2681 		return (0);
2682 
2683 	/* If the connection object is not connected; make it so */
2684 	if (!evhttp_connected(evcon)) {
2685 		int res = evhttp_connection_connect_(evcon);
2686 		/* evhttp_connection_fail_(), which is called through
2687 		 * evhttp_connection_connect_(), assumes that req lies in
2688 		 * evcon->requests.  Thus, enqueue the request in advance and
2689 		 * remove it in the error case. */
2690 		if (res != 0)
2691 			TAILQ_REMOVE(&evcon->requests, req, next);
2692 
2693 		return (res);
2694 	}
2695 
2696 	/*
2697 	 * If it's connected already and we are the first in the queue,
2698 	 * then we can dispatch this request immediately.  Otherwise, it
2699 	 * will be dispatched once the pending requests are completed.
2700 	 */
2701 	if (TAILQ_FIRST(&evcon->requests) == req)
2702 		evhttp_request_dispatch(evcon);
2703 
2704 	return (0);
2705 }
2706 
2707 void
evhttp_cancel_request(struct evhttp_request * req)2708 evhttp_cancel_request(struct evhttp_request *req)
2709 {
2710 	struct evhttp_connection *evcon = req->evcon;
2711 	if (evcon != NULL) {
2712 		/* We need to remove it from the connection */
2713 		if (TAILQ_FIRST(&evcon->requests) == req) {
2714 			/* it's currently being worked on, so reset
2715 			 * the connection.
2716 			 */
2717 			evhttp_connection_fail_(evcon,
2718 			    EVREQ_HTTP_REQUEST_CANCEL);
2719 
2720 			/* connection fail freed the request */
2721 			return;
2722 		} else {
2723 			/* otherwise, we can just remove it from the
2724 			 * queue
2725 			 */
2726 			TAILQ_REMOVE(&evcon->requests, req, next);
2727 		}
2728 	}
2729 
2730 	evhttp_request_free_auto(req);
2731 }
2732 
2733 /*
2734  * Reads data from file descriptor into request structure
2735  * Request structure needs to be set up correctly.
2736  */
2737 
2738 void
evhttp_start_read_(struct evhttp_connection * evcon)2739 evhttp_start_read_(struct evhttp_connection *evcon)
2740 {
2741 	bufferevent_disable(evcon->bufev, EV_WRITE);
2742 	bufferevent_enable(evcon->bufev, EV_READ);
2743 
2744 	evcon->state = EVCON_READING_FIRSTLINE;
2745 	/* Reset the bufferevent callbacks */
2746 	bufferevent_setcb(evcon->bufev,
2747 	    evhttp_read_cb,
2748 	    evhttp_write_cb,
2749 	    evhttp_error_cb,
2750 	    evcon);
2751 
2752 	/* If there's still data pending, process it next time through the
2753 	 * loop.  Don't do it now; that could get recusive. */
2754 	if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2755 		event_deferred_cb_schedule_(get_deferred_queue(evcon),
2756 		    &evcon->read_more_deferred_cb);
2757 	}
2758 }
2759 
2760 void
evhttp_start_write_(struct evhttp_connection * evcon)2761 evhttp_start_write_(struct evhttp_connection *evcon)
2762 {
2763 	bufferevent_disable(evcon->bufev, EV_WRITE);
2764 	bufferevent_enable(evcon->bufev, EV_READ);
2765 
2766 	evcon->state = EVCON_WRITING;
2767 	evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
2768 }
2769 
2770 static void
evhttp_send_done(struct evhttp_connection * evcon,void * arg)2771 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2772 {
2773 	int need_close;
2774 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2775 	TAILQ_REMOVE(&evcon->requests, req, next);
2776 
2777 	if (req->on_complete_cb != NULL) {
2778 		req->on_complete_cb(req, req->on_complete_cb_arg);
2779 	}
2780 
2781 	need_close =
2782 	    (REQ_VERSION_BEFORE(req, 1, 1) &&
2783 	    !evhttp_is_connection_keepalive(req->input_headers)) ||
2784 	    evhttp_is_request_connection_close(req);
2785 
2786 	EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2787 	evhttp_request_free(req);
2788 
2789 	if (need_close) {
2790 		evhttp_connection_free(evcon);
2791 		return;
2792 	}
2793 
2794 	/* we have a persistent connection; try to accept another request. */
2795 	if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2796 		evhttp_connection_free(evcon);
2797 	}
2798 }
2799 
2800 /*
2801  * Returns an error page.
2802  */
2803 
2804 void
evhttp_send_error(struct evhttp_request * req,int error,const char * reason)2805 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2806 {
2807 
2808 #define ERR_FORMAT "<HTML><HEAD>\n" \
2809 	    "<TITLE>%d %s</TITLE>\n" \
2810 	    "</HEAD><BODY>\n" \
2811 	    "<H1>%s</H1>\n" \
2812 	    "</BODY></HTML>\n"
2813 
2814 	struct evbuffer *buf = evbuffer_new();
2815 	if (buf == NULL) {
2816 		/* if we cannot allocate memory; we just drop the connection */
2817 		evhttp_connection_free(req->evcon);
2818 		return;
2819 	}
2820 	if (reason == NULL) {
2821 		reason = evhttp_response_phrase_internal(error);
2822 	}
2823 
2824 	evhttp_response_code_(req, error, reason);
2825 
2826 	evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2827 
2828 	evhttp_send_page_(req, buf);
2829 
2830 	evbuffer_free(buf);
2831 #undef ERR_FORMAT
2832 }
2833 
2834 /* Requires that headers and response code are already set up */
2835 
2836 static inline void
evhttp_send(struct evhttp_request * req,struct evbuffer * databuf)2837 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2838 {
2839 	struct evhttp_connection *evcon = req->evcon;
2840 
2841 	if (evcon == NULL) {
2842 		evhttp_request_free(req);
2843 		return;
2844 	}
2845 
2846 	EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2847 
2848 	/* we expect no more calls form the user on this request */
2849 	req->userdone = 1;
2850 
2851 	/* xxx: not sure if we really should expose the data buffer this way */
2852 	if (databuf != NULL)
2853 		evbuffer_add_buffer(req->output_buffer, databuf);
2854 
2855 	/* Adds headers to the response */
2856 	evhttp_make_header(evcon, req);
2857 
2858 	evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2859 }
2860 
2861 void
evhttp_send_reply(struct evhttp_request * req,int code,const char * reason,struct evbuffer * databuf)2862 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2863     struct evbuffer *databuf)
2864 {
2865 	evhttp_response_code_(req, code, reason);
2866 
2867 	evhttp_send(req, databuf);
2868 }
2869 
2870 void
evhttp_send_reply_start(struct evhttp_request * req,int code,const char * reason)2871 evhttp_send_reply_start(struct evhttp_request *req, int code,
2872     const char *reason)
2873 {
2874 	evhttp_response_code_(req, code, reason);
2875 
2876 	if (req->evcon == NULL)
2877 		return;
2878 
2879 	if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2880 	    REQ_VERSION_ATLEAST(req, 1, 1) &&
2881 	    evhttp_response_needs_body(req)) {
2882 		/*
2883 		 * prefer HTTP/1.1 chunked encoding to closing the connection;
2884 		 * note RFC 2616 section 4.4 forbids it with Content-Length:
2885 		 * and it's not necessary then anyway.
2886 		 */
2887 		evhttp_add_header(req->output_headers, "Transfer-Encoding",
2888 		    "chunked");
2889 		req->chunked = 1;
2890 	} else {
2891 		req->chunked = 0;
2892 	}
2893 	evhttp_make_header(req->evcon, req);
2894 	evhttp_write_buffer(req->evcon, NULL, NULL);
2895 }
2896 
2897 void
evhttp_send_reply_chunk_with_cb(struct evhttp_request * req,struct evbuffer * databuf,void (* cb)(struct evhttp_connection *,void *),void * arg)2898 evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
2899     void (*cb)(struct evhttp_connection *, void *), void *arg)
2900 {
2901 	struct evhttp_connection *evcon = req->evcon;
2902 	struct evbuffer *output;
2903 
2904 	if (evcon == NULL)
2905 		return;
2906 
2907 	output = bufferevent_get_output(evcon->bufev);
2908 
2909 	if (evbuffer_get_length(databuf) == 0)
2910 		return;
2911 	if (!evhttp_response_needs_body(req))
2912 		return;
2913 	if (req->chunked) {
2914 		evbuffer_add_printf(output, "%x\r\n",
2915 				    (unsigned)evbuffer_get_length(databuf));
2916 	}
2917 	evbuffer_add_buffer(output, databuf);
2918 	if (req->chunked) {
2919 		evbuffer_add(output, "\r\n", 2);
2920 	}
2921 	evhttp_write_buffer(evcon, cb, arg);
2922 }
2923 
2924 void
evhttp_send_reply_chunk(struct evhttp_request * req,struct evbuffer * databuf)2925 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
2926 {
2927 	evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
2928 }
2929 void
evhttp_send_reply_end(struct evhttp_request * req)2930 evhttp_send_reply_end(struct evhttp_request *req)
2931 {
2932 	struct evhttp_connection *evcon = req->evcon;
2933 	struct evbuffer *output;
2934 
2935 	if (evcon == NULL) {
2936 		evhttp_request_free(req);
2937 		return;
2938 	}
2939 
2940 	output = bufferevent_get_output(evcon->bufev);
2941 
2942 	/* we expect no more calls form the user on this request */
2943 	req->userdone = 1;
2944 
2945 	if (req->chunked) {
2946 		evbuffer_add(output, "0\r\n\r\n", 5);
2947 		evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2948 		req->chunked = 0;
2949 	} else if (evbuffer_get_length(output) == 0) {
2950 		/* let the connection know that we are done with the request */
2951 		evhttp_send_done(evcon, NULL);
2952 	} else {
2953 		/* make the callback execute after all data has been written */
2954 		evcon->cb = evhttp_send_done;
2955 		evcon->cb_arg = NULL;
2956 	}
2957 }
2958 
2959 static const char *informational_phrases[] = {
2960 	/* 100 */ "Continue",
2961 	/* 101 */ "Switching Protocols"
2962 };
2963 
2964 static const char *success_phrases[] = {
2965 	/* 200 */ "OK",
2966 	/* 201 */ "Created",
2967 	/* 202 */ "Accepted",
2968 	/* 203 */ "Non-Authoritative Information",
2969 	/* 204 */ "No Content",
2970 	/* 205 */ "Reset Content",
2971 	/* 206 */ "Partial Content"
2972 };
2973 
2974 static const char *redirection_phrases[] = {
2975 	/* 300 */ "Multiple Choices",
2976 	/* 301 */ "Moved Permanently",
2977 	/* 302 */ "Found",
2978 	/* 303 */ "See Other",
2979 	/* 304 */ "Not Modified",
2980 	/* 305 */ "Use Proxy",
2981 	/* 307 */ "Temporary Redirect"
2982 };
2983 
2984 static const char *client_error_phrases[] = {
2985 	/* 400 */ "Bad Request",
2986 	/* 401 */ "Unauthorized",
2987 	/* 402 */ "Payment Required",
2988 	/* 403 */ "Forbidden",
2989 	/* 404 */ "Not Found",
2990 	/* 405 */ "Method Not Allowed",
2991 	/* 406 */ "Not Acceptable",
2992 	/* 407 */ "Proxy Authentication Required",
2993 	/* 408 */ "Request Time-out",
2994 	/* 409 */ "Conflict",
2995 	/* 410 */ "Gone",
2996 	/* 411 */ "Length Required",
2997 	/* 412 */ "Precondition Failed",
2998 	/* 413 */ "Request Entity Too Large",
2999 	/* 414 */ "Request-URI Too Large",
3000 	/* 415 */ "Unsupported Media Type",
3001 	/* 416 */ "Requested range not satisfiable",
3002 	/* 417 */ "Expectation Failed"
3003 };
3004 
3005 static const char *server_error_phrases[] = {
3006 	/* 500 */ "Internal Server Error",
3007 	/* 501 */ "Not Implemented",
3008 	/* 502 */ "Bad Gateway",
3009 	/* 503 */ "Service Unavailable",
3010 	/* 504 */ "Gateway Time-out",
3011 	/* 505 */ "HTTP Version not supported"
3012 };
3013 
3014 struct response_class {
3015 	const char *name;
3016 	size_t num_responses;
3017 	const char **responses;
3018 };
3019 
3020 #ifndef MEMBERSOF
3021 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
3022 #endif
3023 
3024 static const struct response_class response_classes[] = {
3025 	/* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
3026 	/* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
3027 	/* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
3028 	/* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
3029 	/* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
3030 };
3031 
3032 static const char *
evhttp_response_phrase_internal(int code)3033 evhttp_response_phrase_internal(int code)
3034 {
3035 	int klass = code / 100 - 1;
3036 	int subcode = code % 100;
3037 
3038 	/* Unknown class - can't do any better here */
3039 	if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
3040 		return "Unknown Status Class";
3041 
3042 	/* Unknown sub-code, return class name at least */
3043 	if (subcode >= (int) response_classes[klass].num_responses)
3044 		return response_classes[klass].name;
3045 
3046 	return response_classes[klass].responses[subcode];
3047 }
3048 
3049 void
evhttp_response_code_(struct evhttp_request * req,int code,const char * reason)3050 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
3051 {
3052 	req->kind = EVHTTP_RESPONSE;
3053 	req->response_code = code;
3054 	if (req->response_code_line != NULL)
3055 		mm_free(req->response_code_line);
3056 	if (reason == NULL)
3057 		reason = evhttp_response_phrase_internal(code);
3058 	req->response_code_line = mm_strdup(reason);
3059 	if (req->response_code_line == NULL) {
3060 		event_warn("%s: strdup", __func__);
3061 		/* XXX what else can we do? */
3062 	}
3063 }
3064 
3065 void
evhttp_send_page_(struct evhttp_request * req,struct evbuffer * databuf)3066 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
3067 {
3068 	if (!req->major || !req->minor) {
3069 		req->major = 1;
3070 		req->minor = 1;
3071 	}
3072 
3073 	if (req->kind != EVHTTP_RESPONSE)
3074 		evhttp_response_code_(req, 200, "OK");
3075 
3076 	evhttp_clear_headers(req->output_headers);
3077 	evhttp_add_header(req->output_headers, "Content-Type", "text/html");
3078 	evhttp_add_header(req->output_headers, "Connection", "close");
3079 
3080 	evhttp_send(req, databuf);
3081 }
3082 
3083 static const char uri_chars[256] = {
3084 	/* 0 */
3085 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3086 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3087 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 1, 1, 0,
3088 	1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 0, 0, 0, 0, 0, 0,
3089 	/* 64 */
3090 	0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
3091 	1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 0, 1,
3092 	0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
3093 	1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 1, 0,
3094 	/* 128 */
3095 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3096 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3097 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3098 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3099 	/* 192 */
3100 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3101 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3102 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3103 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
3104 };
3105 
3106 #define CHAR_IS_UNRESERVED(c)			\
3107 	(uri_chars[(unsigned char)(c)])
3108 
3109 /*
3110  * Helper functions to encode/decode a string for inclusion in a URI.
3111  * The returned string must be freed by the caller.
3112  */
3113 char *
evhttp_uriencode(const char * uri,ev_ssize_t len,int space_as_plus)3114 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3115 {
3116 	struct evbuffer *buf = evbuffer_new();
3117 	const char *p, *end;
3118 	char *result = NULL;
3119 
3120 	if (!buf) {
3121 		goto out;
3122 	}
3123 
3124 	if (len >= 0) {
3125 		if (uri + len < uri) {
3126 			goto out;
3127 		}
3128 
3129 		end = uri + len;
3130 	} else {
3131 		size_t slen = strlen(uri);
3132 
3133 		if (slen >= EV_SSIZE_MAX) {
3134 			/* we don't want to mix signed and unsigned */
3135 			goto out;
3136 		}
3137 
3138 		if (uri + slen < uri) {
3139 			goto out;
3140 		}
3141 
3142 		end = uri + slen;
3143 	}
3144 
3145 	for (p = uri; p < end; p++) {
3146 		if (CHAR_IS_UNRESERVED(*p)) {
3147 			evbuffer_add(buf, p, 1);
3148 		} else if (*p == ' ' && space_as_plus) {
3149 			evbuffer_add(buf, "+", 1);
3150 		} else {
3151 			evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3152 		}
3153 	}
3154 
3155 	evbuffer_add(buf, "", 1); /* NUL-terminator. */
3156 	result = mm_malloc(evbuffer_get_length(buf));
3157 
3158 	if (result)
3159 		evbuffer_remove(buf, result, evbuffer_get_length(buf));
3160 
3161 out:
3162 	if (buf)
3163 		evbuffer_free(buf);
3164 	return result;
3165 }
3166 
3167 char *
evhttp_encode_uri(const char * str)3168 evhttp_encode_uri(const char *str)
3169 {
3170 	return evhttp_uriencode(str, -1, 0);
3171 }
3172 
3173 /*
3174  * @param decode_plus_ctl: if 1, we decode plus into space.  If 0, we don't.
3175  *     If -1, when true we transform plus to space only after we've seen
3176  *     a ?.  -1 is deprecated.
3177  * @return the number of bytes written to 'ret'.
3178  */
3179 int
evhttp_decode_uri_internal(const char * uri,size_t length,char * ret,int decode_plus_ctl)3180 evhttp_decode_uri_internal(
3181 	const char *uri, size_t length, char *ret, int decode_plus_ctl)
3182 {
3183 	char c;
3184 	int j;
3185 	int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3186 	unsigned i;
3187 
3188 	for (i = j = 0; i < length; i++) {
3189 		c = uri[i];
3190 		if (c == '?') {
3191 			if (decode_plus_ctl < 0)
3192 				decode_plus = 1;
3193 		} else if (c == '+' && decode_plus) {
3194 			c = ' ';
3195 		} else if ((i + 2) < length && c == '%' &&
3196 			EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3197 			char tmp[3];
3198 			tmp[0] = uri[i+1];
3199 			tmp[1] = uri[i+2];
3200 			tmp[2] = '\0';
3201 			c = (char)strtol(tmp, NULL, 16);
3202 			i += 2;
3203 		}
3204 		ret[j++] = c;
3205 	}
3206 	ret[j] = '\0';
3207 
3208 	return (j);
3209 }
3210 
3211 /* deprecated */
3212 char *
evhttp_decode_uri(const char * uri)3213 evhttp_decode_uri(const char *uri)
3214 {
3215 	char *ret;
3216 
3217 	if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3218 		event_warn("%s: malloc(%lu)", __func__,
3219 			  (unsigned long)(strlen(uri) + 1));
3220 		return (NULL);
3221 	}
3222 
3223 	evhttp_decode_uri_internal(uri, strlen(uri),
3224 	    ret, -1 /*always_decode_plus*/);
3225 
3226 	return (ret);
3227 }
3228 
3229 char *
evhttp_uridecode(const char * uri,int decode_plus,size_t * size_out)3230 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3231 {
3232 	char *ret;
3233 	int n;
3234 
3235 	if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3236 		event_warn("%s: malloc(%lu)", __func__,
3237 			  (unsigned long)(strlen(uri) + 1));
3238 		return (NULL);
3239 	}
3240 
3241 	n = evhttp_decode_uri_internal(uri, strlen(uri),
3242 	    ret, !!decode_plus/*always_decode_plus*/);
3243 
3244 	if (size_out) {
3245 		EVUTIL_ASSERT(n >= 0);
3246 		*size_out = (size_t)n;
3247 	}
3248 
3249 	return (ret);
3250 }
3251 
3252 /*
3253  * Helper function to parse out arguments in a query.
3254  * The arguments are separated by key and value.
3255  */
3256 
3257 static int
evhttp_parse_query_impl(const char * str,struct evkeyvalq * headers,int is_whole_uri)3258 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3259     int is_whole_uri)
3260 {
3261 	char *line=NULL;
3262 	char *argument;
3263 	char *p;
3264 	const char *query_part;
3265 	int result = -1;
3266 	struct evhttp_uri *uri=NULL;
3267 
3268 	TAILQ_INIT(headers);
3269 
3270 	if (is_whole_uri) {
3271 		uri = evhttp_uri_parse(str);
3272 		if (!uri)
3273 			goto error;
3274 		query_part = evhttp_uri_get_query(uri);
3275 	} else {
3276 		query_part = str;
3277 	}
3278 
3279 	/* No arguments - we are done */
3280 	if (!query_part || !strlen(query_part)) {
3281 		result = 0;
3282 		goto done;
3283 	}
3284 
3285 	if ((line = mm_strdup(query_part)) == NULL) {
3286 		event_warn("%s: strdup", __func__);
3287 		goto error;
3288 	}
3289 
3290 	p = argument = line;
3291 	while (p != NULL && *p != '\0') {
3292 		char *key, *value, *decoded_value;
3293 		int err;
3294 		argument = strsep(&p, "&");
3295 
3296 		value = argument;
3297 		key = strsep(&value, "=");
3298 		if (value == NULL || *key == '\0') {
3299 			goto error;
3300 		}
3301 
3302 		if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3303 			event_warn("%s: mm_malloc", __func__);
3304 			goto error;
3305 		}
3306 		evhttp_decode_uri_internal(value, strlen(value),
3307 		    decoded_value, 1 /*always_decode_plus*/);
3308 		event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3309 		err = evhttp_add_header_internal(headers, key, decoded_value);
3310 		mm_free(decoded_value);
3311 		if (err)
3312 			goto error;
3313 	}
3314 
3315 	result = 0;
3316 	goto done;
3317 error:
3318 	evhttp_clear_headers(headers);
3319 done:
3320 	if (line)
3321 		mm_free(line);
3322 	if (uri)
3323 		evhttp_uri_free(uri);
3324 	return result;
3325 }
3326 
3327 int
evhttp_parse_query(const char * uri,struct evkeyvalq * headers)3328 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3329 {
3330 	return evhttp_parse_query_impl(uri, headers, 1);
3331 }
3332 int
evhttp_parse_query_str(const char * uri,struct evkeyvalq * headers)3333 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3334 {
3335 	return evhttp_parse_query_impl(uri, headers, 0);
3336 }
3337 
3338 static struct evhttp_cb *
evhttp_dispatch_callback(struct httpcbq * callbacks,struct evhttp_request * req)3339 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3340 {
3341 	struct evhttp_cb *cb;
3342 	size_t offset = 0;
3343 	char *translated;
3344 	const char *path;
3345 
3346 	/* Test for different URLs */
3347 	path = evhttp_uri_get_path(req->uri_elems);
3348 	offset = strlen(path);
3349 	if ((translated = mm_malloc(offset + 1)) == NULL)
3350 		return (NULL);
3351 	evhttp_decode_uri_internal(path, offset, translated,
3352 	    0 /* decode_plus */);
3353 
3354 	TAILQ_FOREACH(cb, callbacks, next) {
3355 		if (!strcmp(cb->what, translated)) {
3356 			mm_free(translated);
3357 			return (cb);
3358 		}
3359 	}
3360 
3361 	mm_free(translated);
3362 	return (NULL);
3363 }
3364 
3365 
3366 static int
prefix_suffix_match(const char * pattern,const char * name,int ignorecase)3367 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3368 {
3369 	char c;
3370 
3371 	while (1) {
3372 		switch (c = *pattern++) {
3373 		case '\0':
3374 			return *name == '\0';
3375 
3376 		case '*':
3377 			while (*name != '\0') {
3378 				if (prefix_suffix_match(pattern, name,
3379 					ignorecase))
3380 					return (1);
3381 				++name;
3382 			}
3383 			return (0);
3384 		default:
3385 			if (c != *name) {
3386 				if (!ignorecase ||
3387 				    EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3388 					return (0);
3389 			}
3390 			++name;
3391 		}
3392 	}
3393 	/* NOTREACHED */
3394 }
3395 
3396 /*
3397    Search the vhost hierarchy beginning with http for a server alias
3398    matching hostname.  If a match is found, and outhttp is non-null,
3399    outhttp is set to the matching http object and 1 is returned.
3400 */
3401 
3402 static int
evhttp_find_alias(struct evhttp * http,struct evhttp ** outhttp,const char * hostname)3403 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3404 		  const char *hostname)
3405 {
3406 	struct evhttp_server_alias *alias;
3407 	struct evhttp *vhost;
3408 
3409 	TAILQ_FOREACH(alias, &http->aliases, next) {
3410 		/* XXX Do we need to handle IP addresses? */
3411 		if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3412 			if (outhttp)
3413 				*outhttp = http;
3414 			return 1;
3415 		}
3416 	}
3417 
3418 	/* XXX It might be good to avoid recursion here, but I don't
3419 	   see a way to do that w/o a list. */
3420 	TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3421 		if (evhttp_find_alias(vhost, outhttp, hostname))
3422 			return 1;
3423 	}
3424 
3425 	return 0;
3426 }
3427 
3428 /*
3429    Attempts to find the best http object to handle a request for a hostname.
3430    All aliases for the root http object and vhosts are searched for an exact
3431    match. Then, the vhost hierarchy is traversed again for a matching
3432    pattern.
3433 
3434    If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3435    is set with the best matching http object. If there are no matches, the
3436    root http object is stored in outhttp and 0 is returned.
3437 */
3438 
3439 static int
evhttp_find_vhost(struct evhttp * http,struct evhttp ** outhttp,const char * hostname)3440 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3441 		  const char *hostname)
3442 {
3443 	struct evhttp *vhost;
3444 	struct evhttp *oldhttp;
3445 	int match_found = 0;
3446 
3447 	if (evhttp_find_alias(http, outhttp, hostname))
3448 		return 1;
3449 
3450 	do {
3451 		oldhttp = http;
3452 		TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3453 			if (prefix_suffix_match(vhost->vhost_pattern,
3454 				hostname, 1 /* ignorecase */)) {
3455 				http = vhost;
3456 				match_found = 1;
3457 				break;
3458 			}
3459 		}
3460 	} while (oldhttp != http);
3461 
3462 	if (outhttp)
3463 		*outhttp = http;
3464 
3465 	return match_found;
3466 }
3467 
3468 static void
evhttp_handle_request(struct evhttp_request * req,void * arg)3469 evhttp_handle_request(struct evhttp_request *req, void *arg)
3470 {
3471 	struct evhttp *http = arg;
3472 	struct evhttp_cb *cb = NULL;
3473 	const char *hostname;
3474 
3475 	/* we have a new request on which the user needs to take action */
3476 	req->userdone = 0;
3477 
3478 	bufferevent_disable(req->evcon->bufev, EV_READ);
3479 
3480 	if (req->type == 0 || req->uri == NULL) {
3481 		evhttp_send_error(req, req->response_code, NULL);
3482 		return;
3483 	}
3484 
3485 	if ((http->allowed_methods & req->type) == 0) {
3486 		event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3487 			(unsigned)req->type, (unsigned)http->allowed_methods));
3488 		evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3489 		return;
3490 	}
3491 
3492 	/* handle potential virtual hosts */
3493 	hostname = evhttp_request_get_host(req);
3494 	if (hostname != NULL) {
3495 		evhttp_find_vhost(http, &http, hostname);
3496 	}
3497 
3498 	if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3499 		(*cb->cb)(req, cb->cbarg);
3500 		return;
3501 	}
3502 
3503 	/* Generic call back */
3504 	if (http->gencb) {
3505 		(*http->gencb)(req, http->gencbarg);
3506 		return;
3507 	} else {
3508 		/* We need to send a 404 here */
3509 #define ERR_FORMAT "<html><head>" \
3510 		    "<title>404 Not Found</title>" \
3511 		    "</head><body>" \
3512 		    "<h1>Not Found</h1>" \
3513 		    "<p>The requested URL %s was not found on this server.</p>"\
3514 		    "</body></html>\n"
3515 
3516 		char *escaped_html;
3517 		struct evbuffer *buf;
3518 
3519 		if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3520 			evhttp_connection_free(req->evcon);
3521 			return;
3522 		}
3523 
3524 		if ((buf = evbuffer_new()) == NULL) {
3525 			mm_free(escaped_html);
3526 			evhttp_connection_free(req->evcon);
3527 			return;
3528 		}
3529 
3530 		evhttp_response_code_(req, HTTP_NOTFOUND, "Not Found");
3531 
3532 		evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3533 
3534 		mm_free(escaped_html);
3535 
3536 		evhttp_send_page_(req, buf);
3537 
3538 		evbuffer_free(buf);
3539 #undef ERR_FORMAT
3540 	}
3541 }
3542 
3543 /* Listener callback when a connection arrives at a server. */
3544 static void
accept_socket_cb(struct evconnlistener * listener,evutil_socket_t nfd,struct sockaddr * peer_sa,int peer_socklen,void * arg)3545 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3546 {
3547 	struct evhttp *http = arg;
3548 
3549 	evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3550 }
3551 
3552 int
evhttp_bind_socket(struct evhttp * http,const char * address,ev_uint16_t port)3553 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3554 {
3555 	struct evhttp_bound_socket *bound =
3556 		evhttp_bind_socket_with_handle(http, address, port);
3557 	if (bound == NULL)
3558 		return (-1);
3559 	return (0);
3560 }
3561 
3562 struct evhttp_bound_socket *
evhttp_bind_socket_with_handle(struct evhttp * http,const char * address,ev_uint16_t port)3563 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3564 {
3565 	evutil_socket_t fd;
3566 	struct evhttp_bound_socket *bound;
3567 	int serrno;
3568 
3569 	if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3570 		return (NULL);
3571 
3572 	if (listen(fd, 128) == -1) {
3573 		serrno = EVUTIL_SOCKET_ERROR();
3574 		event_sock_warn(fd, "%s: listen", __func__);
3575 		evutil_closesocket(fd);
3576 		EVUTIL_SET_SOCKET_ERROR(serrno);
3577 		return (NULL);
3578 	}
3579 
3580 	bound = evhttp_accept_socket_with_handle(http, fd);
3581 
3582 	if (bound != NULL) {
3583 		event_debug(("Bound to port %d - Awaiting connections ... ",
3584 			port));
3585 		return (bound);
3586 	}
3587 
3588 	return (NULL);
3589 }
3590 
3591 int
evhttp_accept_socket(struct evhttp * http,evutil_socket_t fd)3592 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3593 {
3594 	struct evhttp_bound_socket *bound =
3595 		evhttp_accept_socket_with_handle(http, fd);
3596 	if (bound == NULL)
3597 		return (-1);
3598 	return (0);
3599 }
3600 
3601 void
evhttp_foreach_bound_socket(struct evhttp * http,evhttp_bound_socket_foreach_fn * function,void * argument)3602 evhttp_foreach_bound_socket(struct evhttp *http,
3603                             evhttp_bound_socket_foreach_fn *function,
3604                             void *argument)
3605 {
3606 	struct evhttp_bound_socket *bound;
3607 
3608 	TAILQ_FOREACH(bound, &http->sockets, next)
3609 		function(bound, argument);
3610 }
3611 
3612 struct evhttp_bound_socket *
evhttp_accept_socket_with_handle(struct evhttp * http,evutil_socket_t fd)3613 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3614 {
3615 	struct evhttp_bound_socket *bound;
3616 	struct evconnlistener *listener;
3617 	const int flags =
3618 	    LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3619 
3620 	listener = evconnlistener_new(http->base, NULL, NULL,
3621 	    flags,
3622 	    0, /* Backlog is '0' because we already said 'listen' */
3623 	    fd);
3624 	if (!listener)
3625 		return (NULL);
3626 
3627 	bound = evhttp_bind_listener(http, listener);
3628 	if (!bound) {
3629 		evconnlistener_free(listener);
3630 		return (NULL);
3631 	}
3632 	return (bound);
3633 }
3634 
3635 struct evhttp_bound_socket *
evhttp_bind_listener(struct evhttp * http,struct evconnlistener * listener)3636 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3637 {
3638 	struct evhttp_bound_socket *bound;
3639 
3640 	bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3641 	if (bound == NULL)
3642 		return (NULL);
3643 
3644 	bound->listener = listener;
3645 	TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3646 
3647 	evconnlistener_set_cb(listener, accept_socket_cb, http);
3648 	return bound;
3649 }
3650 
3651 evutil_socket_t
evhttp_bound_socket_get_fd(struct evhttp_bound_socket * bound)3652 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3653 {
3654 	return evconnlistener_get_fd(bound->listener);
3655 }
3656 
3657 struct evconnlistener *
evhttp_bound_socket_get_listener(struct evhttp_bound_socket * bound)3658 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3659 {
3660 	return bound->listener;
3661 }
3662 
3663 void
evhttp_del_accept_socket(struct evhttp * http,struct evhttp_bound_socket * bound)3664 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3665 {
3666 	TAILQ_REMOVE(&http->sockets, bound, next);
3667 	evconnlistener_free(bound->listener);
3668 	mm_free(bound);
3669 }
3670 
3671 static struct evhttp*
evhttp_new_object(void)3672 evhttp_new_object(void)
3673 {
3674 	struct evhttp *http = NULL;
3675 
3676 	if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3677 		event_warn("%s: calloc", __func__);
3678 		return (NULL);
3679 	}
3680 
3681 	evutil_timerclear(&http->timeout);
3682 	evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3683 	evhttp_set_max_body_size(http, EV_SIZE_MAX);
3684 	evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
3685 	evhttp_set_allowed_methods(http,
3686 	    EVHTTP_REQ_GET |
3687 	    EVHTTP_REQ_POST |
3688 	    EVHTTP_REQ_HEAD |
3689 	    EVHTTP_REQ_PUT |
3690 	    EVHTTP_REQ_DELETE);
3691 
3692 	TAILQ_INIT(&http->sockets);
3693 	TAILQ_INIT(&http->callbacks);
3694 	TAILQ_INIT(&http->connections);
3695 	TAILQ_INIT(&http->virtualhosts);
3696 	TAILQ_INIT(&http->aliases);
3697 
3698 	return (http);
3699 }
3700 
3701 struct evhttp *
evhttp_new(struct event_base * base)3702 evhttp_new(struct event_base *base)
3703 {
3704 	struct evhttp *http = NULL;
3705 
3706 	http = evhttp_new_object();
3707 	if (http == NULL)
3708 		return (NULL);
3709 	http->base = base;
3710 
3711 	return (http);
3712 }
3713 
3714 /*
3715  * Start a web server on the specified address and port.
3716  */
3717 
3718 struct evhttp *
evhttp_start(const char * address,ev_uint16_t port)3719 evhttp_start(const char *address, ev_uint16_t port)
3720 {
3721 	struct evhttp *http = NULL;
3722 
3723 	http = evhttp_new_object();
3724 	if (http == NULL)
3725 		return (NULL);
3726 	if (evhttp_bind_socket(http, address, port) == -1) {
3727 		mm_free(http);
3728 		return (NULL);
3729 	}
3730 
3731 	return (http);
3732 }
3733 
3734 void
evhttp_free(struct evhttp * http)3735 evhttp_free(struct evhttp* http)
3736 {
3737 	struct evhttp_cb *http_cb;
3738 	struct evhttp_connection *evcon;
3739 	struct evhttp_bound_socket *bound;
3740 	struct evhttp* vhost;
3741 	struct evhttp_server_alias *alias;
3742 
3743 	/* Remove the accepting part */
3744 	while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3745 		TAILQ_REMOVE(&http->sockets, bound, next);
3746 
3747 		evconnlistener_free(bound->listener);
3748 
3749 		mm_free(bound);
3750 	}
3751 
3752 	while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3753 		/* evhttp_connection_free removes the connection */
3754 		evhttp_connection_free(evcon);
3755 	}
3756 
3757 	while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3758 		TAILQ_REMOVE(&http->callbacks, http_cb, next);
3759 		mm_free(http_cb->what);
3760 		mm_free(http_cb);
3761 	}
3762 
3763 	while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3764 		TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3765 
3766 		evhttp_free(vhost);
3767 	}
3768 
3769 	if (http->vhost_pattern != NULL)
3770 		mm_free(http->vhost_pattern);
3771 
3772 	while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3773 		TAILQ_REMOVE(&http->aliases, alias, next);
3774 		mm_free(alias->alias);
3775 		mm_free(alias);
3776 	}
3777 
3778 	mm_free(http);
3779 }
3780 
3781 int
evhttp_add_virtual_host(struct evhttp * http,const char * pattern,struct evhttp * vhost)3782 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3783     struct evhttp* vhost)
3784 {
3785 	/* a vhost can only be a vhost once and should not have bound sockets */
3786 	if (vhost->vhost_pattern != NULL ||
3787 	    TAILQ_FIRST(&vhost->sockets) != NULL)
3788 		return (-1);
3789 
3790 	vhost->vhost_pattern = mm_strdup(pattern);
3791 	if (vhost->vhost_pattern == NULL)
3792 		return (-1);
3793 
3794 	TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3795 
3796 	return (0);
3797 }
3798 
3799 int
evhttp_remove_virtual_host(struct evhttp * http,struct evhttp * vhost)3800 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3801 {
3802 	if (vhost->vhost_pattern == NULL)
3803 		return (-1);
3804 
3805 	TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3806 
3807 	mm_free(vhost->vhost_pattern);
3808 	vhost->vhost_pattern = NULL;
3809 
3810 	return (0);
3811 }
3812 
3813 int
evhttp_add_server_alias(struct evhttp * http,const char * alias)3814 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3815 {
3816 	struct evhttp_server_alias *evalias;
3817 
3818 	evalias = mm_calloc(1, sizeof(*evalias));
3819 	if (!evalias)
3820 		return -1;
3821 
3822 	evalias->alias = mm_strdup(alias);
3823 	if (!evalias->alias) {
3824 		mm_free(evalias);
3825 		return -1;
3826 	}
3827 
3828 	TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3829 
3830 	return 0;
3831 }
3832 
3833 int
evhttp_remove_server_alias(struct evhttp * http,const char * alias)3834 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3835 {
3836 	struct evhttp_server_alias *evalias;
3837 
3838 	TAILQ_FOREACH(evalias, &http->aliases, next) {
3839 		if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3840 			TAILQ_REMOVE(&http->aliases, evalias, next);
3841 			mm_free(evalias->alias);
3842 			mm_free(evalias);
3843 			return 0;
3844 		}
3845 	}
3846 
3847 	return -1;
3848 }
3849 
3850 void
evhttp_set_timeout(struct evhttp * http,int timeout_in_secs)3851 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
3852 {
3853 	if (timeout_in_secs == -1) {
3854 		evhttp_set_timeout_tv(http, NULL);
3855 	} else {
3856 		struct timeval tv;
3857 		tv.tv_sec = timeout_in_secs;
3858 		tv.tv_usec = 0;
3859 		evhttp_set_timeout_tv(http, &tv);
3860 	}
3861 }
3862 
3863 void
evhttp_set_timeout_tv(struct evhttp * http,const struct timeval * tv)3864 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
3865 {
3866 	if (tv) {
3867 		http->timeout = *tv;
3868 	} else {
3869 		evutil_timerclear(&http->timeout);
3870 	}
3871 }
3872 
evhttp_set_flags(struct evhttp * http,int flags)3873 int evhttp_set_flags(struct evhttp *http, int flags)
3874 {
3875 	int avail_flags = 0;
3876 	avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
3877 
3878 	if (flags & ~avail_flags)
3879 		return 1;
3880 	http->flags &= ~avail_flags;
3881 
3882 	http->flags |= flags;
3883 
3884 	return 0;
3885 }
3886 
3887 void
evhttp_set_max_headers_size(struct evhttp * http,ev_ssize_t max_headers_size)3888 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
3889 {
3890 	if (max_headers_size < 0)
3891 		http->default_max_headers_size = EV_SIZE_MAX;
3892 	else
3893 		http->default_max_headers_size = max_headers_size;
3894 }
3895 
3896 void
evhttp_set_max_body_size(struct evhttp * http,ev_ssize_t max_body_size)3897 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
3898 {
3899 	if (max_body_size < 0)
3900 		http->default_max_body_size = EV_UINT64_MAX;
3901 	else
3902 		http->default_max_body_size = max_body_size;
3903 }
3904 
3905 void
evhttp_set_default_content_type(struct evhttp * http,const char * content_type)3906 evhttp_set_default_content_type(struct evhttp *http,
3907 	const char *content_type) {
3908 	http->default_content_type = content_type;
3909 }
3910 
3911 void
evhttp_set_allowed_methods(struct evhttp * http,ev_uint16_t methods)3912 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
3913 {
3914 	http->allowed_methods = methods;
3915 }
3916 
3917 int
evhttp_set_cb(struct evhttp * http,const char * uri,void (* cb)(struct evhttp_request *,void *),void * cbarg)3918 evhttp_set_cb(struct evhttp *http, const char *uri,
3919     void (*cb)(struct evhttp_request *, void *), void *cbarg)
3920 {
3921 	struct evhttp_cb *http_cb;
3922 
3923 	TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3924 		if (strcmp(http_cb->what, uri) == 0)
3925 			return (-1);
3926 	}
3927 
3928 	if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
3929 		event_warn("%s: calloc", __func__);
3930 		return (-2);
3931 	}
3932 
3933 	http_cb->what = mm_strdup(uri);
3934 	if (http_cb->what == NULL) {
3935 		event_warn("%s: strdup", __func__);
3936 		mm_free(http_cb);
3937 		return (-3);
3938 	}
3939 	http_cb->cb = cb;
3940 	http_cb->cbarg = cbarg;
3941 
3942 	TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
3943 
3944 	return (0);
3945 }
3946 
3947 int
evhttp_del_cb(struct evhttp * http,const char * uri)3948 evhttp_del_cb(struct evhttp *http, const char *uri)
3949 {
3950 	struct evhttp_cb *http_cb;
3951 
3952 	TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3953 		if (strcmp(http_cb->what, uri) == 0)
3954 			break;
3955 	}
3956 	if (http_cb == NULL)
3957 		return (-1);
3958 
3959 	TAILQ_REMOVE(&http->callbacks, http_cb, next);
3960 	mm_free(http_cb->what);
3961 	mm_free(http_cb);
3962 
3963 	return (0);
3964 }
3965 
3966 void
evhttp_set_gencb(struct evhttp * http,void (* cb)(struct evhttp_request *,void *),void * cbarg)3967 evhttp_set_gencb(struct evhttp *http,
3968     void (*cb)(struct evhttp_request *, void *), void *cbarg)
3969 {
3970 	http->gencb = cb;
3971 	http->gencbarg = cbarg;
3972 }
3973 
3974 void
evhttp_set_bevcb(struct evhttp * http,struct bufferevent * (* cb)(struct event_base *,void *),void * cbarg)3975 evhttp_set_bevcb(struct evhttp *http,
3976     struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
3977 {
3978 	http->bevcb = cb;
3979 	http->bevcbarg = cbarg;
3980 }
3981 
3982 /*
3983  * Request related functions
3984  */
3985 
3986 struct evhttp_request *
evhttp_request_new(void (* cb)(struct evhttp_request *,void *),void * arg)3987 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
3988 {
3989 	struct evhttp_request *req = NULL;
3990 
3991 	/* Allocate request structure */
3992 	if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
3993 		event_warn("%s: calloc", __func__);
3994 		goto error;
3995 	}
3996 
3997 	req->headers_size = 0;
3998 	req->body_size = 0;
3999 
4000 	req->kind = EVHTTP_RESPONSE;
4001 	req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4002 	if (req->input_headers == NULL) {
4003 		event_warn("%s: calloc", __func__);
4004 		goto error;
4005 	}
4006 	TAILQ_INIT(req->input_headers);
4007 
4008 	req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4009 	if (req->output_headers == NULL) {
4010 		event_warn("%s: calloc", __func__);
4011 		goto error;
4012 	}
4013 	TAILQ_INIT(req->output_headers);
4014 
4015 	if ((req->input_buffer = evbuffer_new()) == NULL) {
4016 		event_warn("%s: evbuffer_new", __func__);
4017 		goto error;
4018 	}
4019 
4020 	if ((req->output_buffer = evbuffer_new()) == NULL) {
4021 		event_warn("%s: evbuffer_new", __func__);
4022 		goto error;
4023 	}
4024 
4025 	req->cb = cb;
4026 	req->cb_arg = arg;
4027 
4028 	return (req);
4029 
4030  error:
4031 	if (req != NULL)
4032 		evhttp_request_free(req);
4033 	return (NULL);
4034 }
4035 
4036 void
evhttp_request_free(struct evhttp_request * req)4037 evhttp_request_free(struct evhttp_request *req)
4038 {
4039 	if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
4040 		req->flags |= EVHTTP_REQ_NEEDS_FREE;
4041 		return;
4042 	}
4043 
4044 	if (req->remote_host != NULL)
4045 		mm_free(req->remote_host);
4046 	if (req->uri != NULL)
4047 		mm_free(req->uri);
4048 	if (req->uri_elems != NULL)
4049 		evhttp_uri_free(req->uri_elems);
4050 	if (req->response_code_line != NULL)
4051 		mm_free(req->response_code_line);
4052 	if (req->host_cache != NULL)
4053 		mm_free(req->host_cache);
4054 
4055 	evhttp_clear_headers(req->input_headers);
4056 	mm_free(req->input_headers);
4057 
4058 	evhttp_clear_headers(req->output_headers);
4059 	mm_free(req->output_headers);
4060 
4061 	if (req->input_buffer != NULL)
4062 		evbuffer_free(req->input_buffer);
4063 
4064 	if (req->output_buffer != NULL)
4065 		evbuffer_free(req->output_buffer);
4066 
4067 	mm_free(req);
4068 }
4069 
4070 void
evhttp_request_own(struct evhttp_request * req)4071 evhttp_request_own(struct evhttp_request *req)
4072 {
4073 	req->flags |= EVHTTP_USER_OWNED;
4074 }
4075 
4076 int
evhttp_request_is_owned(struct evhttp_request * req)4077 evhttp_request_is_owned(struct evhttp_request *req)
4078 {
4079 	return (req->flags & EVHTTP_USER_OWNED) != 0;
4080 }
4081 
4082 struct evhttp_connection *
evhttp_request_get_connection(struct evhttp_request * req)4083 evhttp_request_get_connection(struct evhttp_request *req)
4084 {
4085 	return req->evcon;
4086 }
4087 
4088 struct event_base *
evhttp_connection_get_base(struct evhttp_connection * conn)4089 evhttp_connection_get_base(struct evhttp_connection *conn)
4090 {
4091 	return conn->base;
4092 }
4093 
4094 void
evhttp_request_set_chunked_cb(struct evhttp_request * req,void (* cb)(struct evhttp_request *,void *))4095 evhttp_request_set_chunked_cb(struct evhttp_request *req,
4096     void (*cb)(struct evhttp_request *, void *))
4097 {
4098 	req->chunk_cb = cb;
4099 }
4100 
4101 void
evhttp_request_set_header_cb(struct evhttp_request * req,int (* cb)(struct evhttp_request *,void *))4102 evhttp_request_set_header_cb(struct evhttp_request *req,
4103     int (*cb)(struct evhttp_request *, void *))
4104 {
4105 	req->header_cb = cb;
4106 }
4107 
4108 void
evhttp_request_set_error_cb(struct evhttp_request * req,void (* cb)(enum evhttp_request_error,void *))4109 evhttp_request_set_error_cb(struct evhttp_request *req,
4110     void (*cb)(enum evhttp_request_error, void *))
4111 {
4112 	req->error_cb = cb;
4113 }
4114 
4115 void
evhttp_request_set_on_complete_cb(struct evhttp_request * req,void (* cb)(struct evhttp_request *,void *),void * cb_arg)4116 evhttp_request_set_on_complete_cb(struct evhttp_request *req,
4117     void (*cb)(struct evhttp_request *, void *), void *cb_arg)
4118 {
4119 	req->on_complete_cb = cb;
4120 	req->on_complete_cb_arg = cb_arg;
4121 }
4122 
4123 /*
4124  * Allows for inspection of the request URI
4125  */
4126 
4127 const char *
evhttp_request_get_uri(const struct evhttp_request * req)4128 evhttp_request_get_uri(const struct evhttp_request *req) {
4129 	if (req->uri == NULL)
4130 		event_debug(("%s: request %p has no uri\n", __func__, req));
4131 	return (req->uri);
4132 }
4133 
4134 const struct evhttp_uri *
evhttp_request_get_evhttp_uri(const struct evhttp_request * req)4135 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4136 	if (req->uri_elems == NULL)
4137 		event_debug(("%s: request %p has no uri elems\n",
4138 			    __func__, req));
4139 	return (req->uri_elems);
4140 }
4141 
4142 const char *
evhttp_request_get_host(struct evhttp_request * req)4143 evhttp_request_get_host(struct evhttp_request *req)
4144 {
4145 	const char *host = NULL;
4146 
4147 	if (req->host_cache)
4148 		return req->host_cache;
4149 
4150 	if (req->uri_elems)
4151 		host = evhttp_uri_get_host(req->uri_elems);
4152 	if (!host && req->input_headers) {
4153 		const char *p;
4154 		size_t len;
4155 
4156 		host = evhttp_find_header(req->input_headers, "Host");
4157 		/* The Host: header may include a port. Remove it here
4158 		   to be consistent with uri_elems case above. */
4159 		if (host) {
4160 			p = host + strlen(host) - 1;
4161 			while (p > host && EVUTIL_ISDIGIT_(*p))
4162 				--p;
4163 			if (p > host && *p == ':') {
4164 				len = p - host;
4165 				req->host_cache = mm_malloc(len + 1);
4166 				if (!req->host_cache) {
4167 					event_warn("%s: malloc", __func__);
4168 					return NULL;
4169 				}
4170 				memcpy(req->host_cache, host, len);
4171 				req->host_cache[len] = '\0';
4172 				host = req->host_cache;
4173 			}
4174 		}
4175 	}
4176 
4177 	return host;
4178 }
4179 
4180 enum evhttp_cmd_type
evhttp_request_get_command(const struct evhttp_request * req)4181 evhttp_request_get_command(const struct evhttp_request *req) {
4182 	return (req->type);
4183 }
4184 
4185 int
evhttp_request_get_response_code(const struct evhttp_request * req)4186 evhttp_request_get_response_code(const struct evhttp_request *req)
4187 {
4188 	return req->response_code;
4189 }
4190 
4191 const char *
evhttp_request_get_response_code_line(const struct evhttp_request * req)4192 evhttp_request_get_response_code_line(const struct evhttp_request *req)
4193 {
4194 	return req->response_code_line;
4195 }
4196 
4197 /** Returns the input headers */
evhttp_request_get_input_headers(struct evhttp_request * req)4198 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4199 {
4200 	return (req->input_headers);
4201 }
4202 
4203 /** Returns the output headers */
evhttp_request_get_output_headers(struct evhttp_request * req)4204 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4205 {
4206 	return (req->output_headers);
4207 }
4208 
4209 /** Returns the input buffer */
evhttp_request_get_input_buffer(struct evhttp_request * req)4210 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4211 {
4212 	return (req->input_buffer);
4213 }
4214 
4215 /** Returns the output buffer */
evhttp_request_get_output_buffer(struct evhttp_request * req)4216 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4217 {
4218 	return (req->output_buffer);
4219 }
4220 
4221 
4222 /*
4223  * Takes a file descriptor to read a request from.
4224  * The callback is executed once the whole request has been read.
4225  */
4226 
4227 static struct evhttp_connection*
evhttp_get_request_connection(struct evhttp * http,evutil_socket_t fd,struct sockaddr * sa,ev_socklen_t salen)4228 evhttp_get_request_connection(
4229 	struct evhttp* http,
4230 	evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
4231 {
4232 	struct evhttp_connection *evcon;
4233 	char *hostname = NULL, *portname = NULL;
4234 	struct bufferevent* bev = NULL;
4235 
4236 #ifdef EVENT__HAVE_STRUCT_SOCKADDR_UN
4237 	if (sa->sa_family == AF_UNIX) {
4238 		struct sockaddr_un *sa_un = (struct sockaddr_un *)sa;
4239 		sa_un->sun_path[0] = '\0';
4240 	}
4241 #endif
4242 
4243 	name_from_addr(sa, salen, &hostname, &portname);
4244 	if (hostname == NULL || portname == NULL) {
4245 		if (hostname) mm_free(hostname);
4246 		if (portname) mm_free(portname);
4247 		return (NULL);
4248 	}
4249 
4250 	event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4251 		__func__, hostname, portname, EV_SOCK_ARG(fd)));
4252 
4253 	/* we need a connection object to put the http request on */
4254 	if (http->bevcb != NULL) {
4255 		bev = (*http->bevcb)(http->base, http->bevcbarg);
4256 	}
4257 	evcon = evhttp_connection_base_bufferevent_new(
4258 		http->base, NULL, bev, hostname, atoi(portname));
4259 	mm_free(hostname);
4260 	mm_free(portname);
4261 	if (evcon == NULL)
4262 		return (NULL);
4263 
4264 	evcon->max_headers_size = http->default_max_headers_size;
4265 	evcon->max_body_size = http->default_max_body_size;
4266 	if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4267 		evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4268 
4269 	evcon->flags |= EVHTTP_CON_INCOMING;
4270 	evcon->state = EVCON_READING_FIRSTLINE;
4271 
4272 	evcon->fd = fd;
4273 
4274 	if (bufferevent_setfd(evcon->bufev, fd))
4275 		goto err;
4276 	if (bufferevent_enable(evcon->bufev, EV_READ))
4277 		goto err;
4278 	if (bufferevent_disable(evcon->bufev, EV_WRITE))
4279 		goto err;
4280 	bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
4281 
4282 	return (evcon);
4283 
4284 err:
4285 	evhttp_connection_free(evcon);
4286 	return (NULL);
4287 }
4288 
4289 static int
evhttp_associate_new_request_with_connection(struct evhttp_connection * evcon)4290 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4291 {
4292 	struct evhttp *http = evcon->http_server;
4293 	struct evhttp_request *req;
4294 	if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4295 		return (-1);
4296 
4297 	if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4298 		event_warn("%s: strdup", __func__);
4299 		evhttp_request_free(req);
4300 		return (-1);
4301 	}
4302 	req->remote_port = evcon->port;
4303 
4304 	req->evcon = evcon;	/* the request ends up owning the connection */
4305 	req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4306 
4307 	/* We did not present the request to the user user yet, so treat it as
4308 	 * if the user was done with the request.  This allows us to free the
4309 	 * request on a persistent connection if the client drops it without
4310 	 * sending a request.
4311 	 */
4312 	req->userdone = 1;
4313 
4314 	TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4315 
4316 	req->kind = EVHTTP_REQUEST;
4317 
4318 
4319 	evhttp_start_read_(evcon);
4320 
4321 	return (0);
4322 }
4323 
4324 static void
evhttp_get_request(struct evhttp * http,evutil_socket_t fd,struct sockaddr * sa,ev_socklen_t salen)4325 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4326     struct sockaddr *sa, ev_socklen_t salen)
4327 {
4328 	struct evhttp_connection *evcon;
4329 
4330 	evcon = evhttp_get_request_connection(http, fd, sa, salen);
4331 	if (evcon == NULL) {
4332 		event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4333 		    __func__, EV_SOCK_ARG(fd));
4334 		evutil_closesocket(fd);
4335 		return;
4336 	}
4337 
4338 	/* the timeout can be used by the server to close idle connections */
4339 	if (evutil_timerisset(&http->timeout))
4340 		evhttp_connection_set_timeout_tv(evcon, &http->timeout);
4341 
4342 	/*
4343 	 * if we want to accept more than one request on a connection,
4344 	 * we need to know which http server it belongs to.
4345 	 */
4346 	evcon->http_server = http;
4347 	TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4348 
4349 	if (evhttp_associate_new_request_with_connection(evcon) == -1)
4350 		evhttp_connection_free(evcon);
4351 }
4352 
4353 
4354 /*
4355  * Network helper functions that we do not want to export to the rest of
4356  * the world.
4357  */
4358 
4359 static void
name_from_addr(struct sockaddr * sa,ev_socklen_t salen,char ** phost,char ** pport)4360 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4361     char **phost, char **pport)
4362 {
4363 	char ntop[NI_MAXHOST];
4364 	char strport[NI_MAXSERV];
4365 	int ni_result;
4366 
4367 #ifdef EVENT__HAVE_GETNAMEINFO
4368 	ni_result = getnameinfo(sa, salen,
4369 		ntop, sizeof(ntop), strport, sizeof(strport),
4370 		NI_NUMERICHOST|NI_NUMERICSERV);
4371 
4372 	if (ni_result != 0) {
4373 #ifdef EAI_SYSTEM
4374 		/* Windows doesn't have an EAI_SYSTEM. */
4375 		if (ni_result == EAI_SYSTEM)
4376 			event_err(1, "getnameinfo failed");
4377 		else
4378 #endif
4379 			event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4380 		return;
4381 	}
4382 #else
4383 	ni_result = fake_getnameinfo(sa, salen,
4384 		ntop, sizeof(ntop), strport, sizeof(strport),
4385 		NI_NUMERICHOST|NI_NUMERICSERV);
4386 	if (ni_result != 0)
4387 			return;
4388 #endif
4389 
4390 	*phost = mm_strdup(ntop);
4391 	*pport = mm_strdup(strport);
4392 }
4393 
4394 /* Create a non-blocking socket and bind it */
4395 static evutil_socket_t
create_bind_socket_nonblock(struct evutil_addrinfo * ai,int reuse)4396 create_bind_socket_nonblock(struct evutil_addrinfo *ai, int reuse)
4397 {
4398 	evutil_socket_t fd;
4399 
4400 	int on = 1, r;
4401 	int serrno;
4402 
4403 	/* Create listen socket */
4404 	fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
4405 	    SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
4406 	if (fd == -1) {
4407 			event_sock_warn(-1, "socket");
4408 			return (-1);
4409 	}
4410 
4411 	if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
4412 		goto out;
4413 	if (reuse) {
4414 		if (evutil_make_listen_socket_reuseable(fd) < 0)
4415 			goto out;
4416 	}
4417 
4418 	if (ai != NULL) {
4419 		r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
4420 		if (r == -1)
4421 			goto out;
4422 	}
4423 
4424 	return (fd);
4425 
4426  out:
4427 	serrno = EVUTIL_SOCKET_ERROR();
4428 	evutil_closesocket(fd);
4429 	EVUTIL_SET_SOCKET_ERROR(serrno);
4430 	return (-1);
4431 }
4432 
4433 static struct evutil_addrinfo *
make_addrinfo(const char * address,ev_uint16_t port)4434 make_addrinfo(const char *address, ev_uint16_t port)
4435 {
4436 	struct evutil_addrinfo *ai = NULL;
4437 
4438 	struct evutil_addrinfo hints;
4439 	char strport[NI_MAXSERV];
4440 	int ai_result;
4441 
4442 	memset(&hints, 0, sizeof(hints));
4443 	hints.ai_family = AF_UNSPEC;
4444 	hints.ai_socktype = SOCK_STREAM;
4445 	/* turn NULL hostname into INADDR_ANY, and skip looking up any address
4446 	 * types we don't have an interface to connect to. */
4447 	hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
4448 	evutil_snprintf(strport, sizeof(strport), "%d", port);
4449 	if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
4450 	    != 0) {
4451 		if (ai_result == EVUTIL_EAI_SYSTEM)
4452 			event_warn("getaddrinfo");
4453 		else
4454 			event_warnx("getaddrinfo: %s",
4455 			    evutil_gai_strerror(ai_result));
4456 		return (NULL);
4457 	}
4458 
4459 	return (ai);
4460 }
4461 
4462 static evutil_socket_t
bind_socket(const char * address,ev_uint16_t port,int reuse)4463 bind_socket(const char *address, ev_uint16_t port, int reuse)
4464 {
4465 	evutil_socket_t fd;
4466 	struct evutil_addrinfo *aitop = NULL;
4467 
4468 	/* just create an unbound socket */
4469 	if (address == NULL && port == 0)
4470 		return create_bind_socket_nonblock(NULL, 0);
4471 
4472 	aitop = make_addrinfo(address, port);
4473 
4474 	if (aitop == NULL)
4475 		return (-1);
4476 
4477 	fd = create_bind_socket_nonblock(aitop, reuse);
4478 
4479 	evutil_freeaddrinfo(aitop);
4480 
4481 	return (fd);
4482 }
4483 
4484 struct evhttp_uri {
4485 	unsigned flags;
4486 	char *scheme; /* scheme; e.g http, ftp etc */
4487 	char *userinfo; /* userinfo (typically username:pass), or NULL */
4488 	char *host; /* hostname, IP address, or NULL */
4489 	int port; /* port, or zero */
4490 	char *path; /* path, or "". */
4491 	char *query; /* query, or NULL */
4492 	char *fragment; /* fragment or NULL */
4493 };
4494 
4495 struct evhttp_uri *
evhttp_uri_new(void)4496 evhttp_uri_new(void)
4497 {
4498 	struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
4499 	if (uri)
4500 		uri->port = -1;
4501 	return uri;
4502 }
4503 
4504 void
evhttp_uri_set_flags(struct evhttp_uri * uri,unsigned flags)4505 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
4506 {
4507 	uri->flags = flags;
4508 }
4509 
4510 /* Return true if the string starting at s and ending immediately before eos
4511  * is a valid URI scheme according to RFC3986
4512  */
4513 static int
scheme_ok(const char * s,const char * eos)4514 scheme_ok(const char *s, const char *eos)
4515 {
4516 	/* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4517 	EVUTIL_ASSERT(eos >= s);
4518 	if (s == eos)
4519 		return 0;
4520 	if (!EVUTIL_ISALPHA_(*s))
4521 		return 0;
4522 	while (++s < eos) {
4523 		if (! EVUTIL_ISALNUM_(*s) &&
4524 		    *s != '+' && *s != '-' && *s != '.')
4525 			return 0;
4526 	}
4527 	return 1;
4528 }
4529 
4530 #define SUBDELIMS "!$&'()*+,;="
4531 
4532 /* Return true iff [s..eos) is a valid userinfo */
4533 static int
userinfo_ok(const char * s,const char * eos)4534 userinfo_ok(const char *s, const char *eos)
4535 {
4536 	while (s < eos) {
4537 		if (CHAR_IS_UNRESERVED(*s) ||
4538 		    strchr(SUBDELIMS, *s) ||
4539 		    *s == ':')
4540 			++s;
4541 		else if (*s == '%' && s+2 < eos &&
4542 		    EVUTIL_ISXDIGIT_(s[1]) &&
4543 		    EVUTIL_ISXDIGIT_(s[2]))
4544 			s += 3;
4545 		else
4546 			return 0;
4547 	}
4548 	return 1;
4549 }
4550 
4551 static int
regname_ok(const char * s,const char * eos)4552 regname_ok(const char *s, const char *eos)
4553 {
4554 	while (s && s<eos) {
4555 		if (CHAR_IS_UNRESERVED(*s) ||
4556 		    strchr(SUBDELIMS, *s))
4557 			++s;
4558 		else if (*s == '%' &&
4559 		    EVUTIL_ISXDIGIT_(s[1]) &&
4560 		    EVUTIL_ISXDIGIT_(s[2]))
4561 			s += 3;
4562 		else
4563 			return 0;
4564 	}
4565 	return 1;
4566 }
4567 
4568 static int
parse_port(const char * s,const char * eos)4569 parse_port(const char *s, const char *eos)
4570 {
4571 	int portnum = 0;
4572 	while (s < eos) {
4573 		if (! EVUTIL_ISDIGIT_(*s))
4574 			return -1;
4575 		portnum = (portnum * 10) + (*s - '0');
4576 		if (portnum < 0)
4577 			return -1;
4578 		if (portnum > 65535)
4579 			return -1;
4580 		++s;
4581 	}
4582 	return portnum;
4583 }
4584 
4585 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4586 static int
bracket_addr_ok(const char * s,const char * eos)4587 bracket_addr_ok(const char *s, const char *eos)
4588 {
4589 	if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4590 		return 0;
4591 	if (s[1] == 'v') {
4592 		/* IPvFuture, or junk.
4593 		   "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4594 		 */
4595 		s += 2; /* skip [v */
4596 		--eos;
4597 		if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
4598 			return 0;
4599 		while (s < eos && *s != '.') {
4600 			if (EVUTIL_ISXDIGIT_(*s))
4601 				++s;
4602 			else
4603 				return 0;
4604 		}
4605 		if (*s != '.')
4606 			return 0;
4607 		++s;
4608 		while (s < eos) {
4609 			if (CHAR_IS_UNRESERVED(*s) ||
4610 			    strchr(SUBDELIMS, *s) ||
4611 			    *s == ':')
4612 				++s;
4613 			else
4614 				return 0;
4615 		}
4616 		return 2;
4617 	} else {
4618 		/* IPv6, or junk */
4619 		char buf[64];
4620 		ev_ssize_t n_chars = eos-s-2;
4621 		struct in6_addr in6;
4622 		if (n_chars >= 64) /* way too long */
4623 			return 0;
4624 		memcpy(buf, s+1, n_chars);
4625 		buf[n_chars]='\0';
4626 		return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4627 	}
4628 }
4629 
4630 static int
parse_authority(struct evhttp_uri * uri,char * s,char * eos)4631 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4632 {
4633 	char *cp, *port;
4634 	EVUTIL_ASSERT(eos);
4635 	if (eos == s) {
4636 		uri->host = mm_strdup("");
4637 		if (uri->host == NULL) {
4638 			event_warn("%s: strdup", __func__);
4639 			return -1;
4640 		}
4641 		return 0;
4642 	}
4643 
4644 	/* Optionally, we start with "userinfo@" */
4645 
4646 	cp = strchr(s, '@');
4647 	if (cp && cp < eos) {
4648 		if (! userinfo_ok(s,cp))
4649 			return -1;
4650 		*cp++ = '\0';
4651 		uri->userinfo = mm_strdup(s);
4652 		if (uri->userinfo == NULL) {
4653 			event_warn("%s: strdup", __func__);
4654 			return -1;
4655 		}
4656 	} else {
4657 		cp = s;
4658 	}
4659 	/* Optionally, we end with ":port" */
4660 	for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
4661 		;
4662 	if (port >= cp && *port == ':') {
4663 		if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4664 				    * nil port */
4665 			uri->port = -1;
4666 		else if ((uri->port = parse_port(port+1, eos))<0)
4667 			return -1;
4668 		eos = port;
4669 	}
4670 	/* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4671 	 * an IP-Literal, or a reg-name */
4672 	EVUTIL_ASSERT(eos >= cp);
4673 	if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4674 		/* IPv6address, IP-Literal, or junk. */
4675 		if (! bracket_addr_ok(cp, eos))
4676 			return -1;
4677 	} else {
4678 		/* Make sure the host part is ok. */
4679 		if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4680 			return -1;
4681 	}
4682 	uri->host = mm_malloc(eos-cp+1);
4683 	if (uri->host == NULL) {
4684 		event_warn("%s: malloc", __func__);
4685 		return -1;
4686 	}
4687 	memcpy(uri->host, cp, eos-cp);
4688 	uri->host[eos-cp] = '\0';
4689 	return 0;
4690 
4691 }
4692 
4693 static char *
end_of_authority(char * cp)4694 end_of_authority(char *cp)
4695 {
4696 	while (*cp) {
4697 		if (*cp == '?' || *cp == '#' || *cp == '/')
4698 			return cp;
4699 		++cp;
4700 	}
4701 	return cp;
4702 }
4703 
4704 enum uri_part {
4705 	PART_PATH,
4706 	PART_QUERY,
4707 	PART_FRAGMENT
4708 };
4709 
4710 /* Return the character after the longest prefix of 'cp' that matches...
4711  *   *pchar / "/" if allow_qchars is false, or
4712  *   *(pchar / "/" / "?") if allow_qchars is true.
4713  */
4714 static char *
end_of_path(const char * cp,enum uri_part part,unsigned flags)4715 end_of_path(const char *cp, enum uri_part part, unsigned flags)
4716 {
4717 	if (flags & EVHTTP_URI_NONCONFORMANT) {
4718 		/* If NONCONFORMANT:
4719 		 *   Path is everything up to a # or ? or nul.
4720 		 *   Query is everything up a # or nul
4721 		 *   Fragment is everything up to a nul.
4722 		 */
4723 		switch (part) {
4724 		case PART_PATH:
4725 			while (*cp && *cp != '#' && *cp != '?')
4726 				++cp;
4727 			break;
4728 		case PART_QUERY:
4729 			while (*cp && *cp != '#')
4730 				++cp;
4731 			break;
4732 		case PART_FRAGMENT:
4733 			cp += strlen(cp);
4734 			break;
4735 		};
4736 		return __UNCONST(cp);
4737 	}
4738 
4739 	while (*cp) {
4740 		if (CHAR_IS_UNRESERVED(*cp) ||
4741 		    strchr(SUBDELIMS, *cp) ||
4742 		    *cp == ':' || *cp == '@' || *cp == '/')
4743 			++cp;
4744 		else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
4745 		    EVUTIL_ISXDIGIT_(cp[2]))
4746 			cp += 3;
4747 		else if (*cp == '?' && part != PART_PATH)
4748 			++cp;
4749 		else
4750 			return __UNCONST(cp);
4751 	}
4752 	return __UNCONST(cp);
4753 }
4754 
4755 static int
path_matches_noscheme(const char * cp)4756 path_matches_noscheme(const char *cp)
4757 {
4758 	while (*cp) {
4759 		if (*cp == ':')
4760 			return 0;
4761 		else if (*cp == '/')
4762 			return 1;
4763 		++cp;
4764 	}
4765 	return 1;
4766 }
4767 
4768 struct evhttp_uri *
evhttp_uri_parse(const char * source_uri)4769 evhttp_uri_parse(const char *source_uri)
4770 {
4771 	return evhttp_uri_parse_with_flags(source_uri, 0);
4772 }
4773 
4774 struct evhttp_uri *
evhttp_uri_parse_with_flags(const char * source_uri,unsigned flags)4775 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4776 {
4777 	char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4778 	char *path = NULL, *fragment = NULL;
4779 	int got_authority = 0;
4780 
4781 	struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4782 	if (uri == NULL) {
4783 		event_warn("%s: calloc", __func__);
4784 		goto err;
4785 	}
4786 	uri->port = -1;
4787 	uri->flags = flags;
4788 
4789 	readbuf = mm_strdup(source_uri);
4790 	if (readbuf == NULL) {
4791 		event_warn("%s: strdup", __func__);
4792 		goto err;
4793 	}
4794 
4795 	readp = readbuf;
4796 	token = NULL;
4797 
4798 	/* We try to follow RFC3986 here as much as we can, and match
4799 	   the productions
4800 
4801 	      URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4802 
4803 	      relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
4804 	 */
4805 
4806 	/* 1. scheme: */
4807 	token = strchr(readp, ':');
4808 	if (token && scheme_ok(readp,token)) {
4809 		*token = '\0';
4810 		uri->scheme = mm_strdup(readp);
4811 		if (uri->scheme == NULL) {
4812 			event_warn("%s: strdup", __func__);
4813 			goto err;
4814 		}
4815 		readp = token+1; /* eat : */
4816 	}
4817 
4818 	/* 2. Optionally, "//" then an 'authority' part. */
4819 	if (readp[0]=='/' && readp[1] == '/') {
4820 		char *authority;
4821 		readp += 2;
4822 		authority = readp;
4823 		path = end_of_authority(readp);
4824 		if (parse_authority(uri, authority, path) < 0)
4825 			goto err;
4826 		readp = path;
4827 		got_authority = 1;
4828 	}
4829 
4830 	/* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4831 	 */
4832 	path = readp;
4833 	readp = end_of_path(path, PART_PATH, flags);
4834 
4835 	/* Query */
4836 	if (*readp == '?') {
4837 		*readp = '\0';
4838 		++readp;
4839 		query = readp;
4840 		readp = end_of_path(readp, PART_QUERY, flags);
4841 	}
4842 	/* fragment */
4843 	if (*readp == '#') {
4844 		*readp = '\0';
4845 		++readp;
4846 		fragment = readp;
4847 		readp = end_of_path(readp, PART_FRAGMENT, flags);
4848 	}
4849 	if (*readp != '\0') {
4850 		goto err;
4851 	}
4852 
4853 	/* These next two cases may be unreachable; I'm leaving them
4854 	 * in to be defensive. */
4855 	/* If you didn't get an authority, the path can't begin with "//" */
4856 	if (!got_authority && path[0]=='/' && path[1]=='/')
4857 		goto err;
4858 	/* If you did get an authority, the path must begin with "/" or be
4859 	 * empty. */
4860 	if (got_authority && path[0] != '/' && path[0] != '\0')
4861 		goto err;
4862 	/* (End of maybe-unreachable cases) */
4863 
4864 	/* If there was no scheme, the first part of the path (if any) must
4865 	 * have no colon in it. */
4866 	if (! uri->scheme && !path_matches_noscheme(path))
4867 		goto err;
4868 
4869 	EVUTIL_ASSERT(path);
4870 	uri->path = mm_strdup(path);
4871 	if (uri->path == NULL) {
4872 		event_warn("%s: strdup", __func__);
4873 		goto err;
4874 	}
4875 
4876 	if (query) {
4877 		uri->query = mm_strdup(query);
4878 		if (uri->query == NULL) {
4879 			event_warn("%s: strdup", __func__);
4880 			goto err;
4881 		}
4882 	}
4883 	if (fragment) {
4884 		uri->fragment = mm_strdup(fragment);
4885 		if (uri->fragment == NULL) {
4886 			event_warn("%s: strdup", __func__);
4887 			goto err;
4888 		}
4889 	}
4890 
4891 	mm_free(readbuf);
4892 
4893 	return uri;
4894 err:
4895 	if (uri)
4896 		evhttp_uri_free(uri);
4897 	if (readbuf)
4898 		mm_free(readbuf);
4899 	return NULL;
4900 }
4901 
4902 static struct evhttp_uri *
evhttp_uri_parse_authority(char * source_uri)4903 evhttp_uri_parse_authority(char *source_uri)
4904 {
4905 	struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4906 	char *end;
4907 
4908 	if (uri == NULL) {
4909 		event_warn("%s: calloc", __func__);
4910 		goto err;
4911 	}
4912 	uri->port = -1;
4913 	uri->flags = 0;
4914 
4915 	end = end_of_authority(source_uri);
4916 	if (parse_authority(uri, source_uri, end) < 0)
4917 		goto err;
4918 
4919 	uri->path = mm_strdup("");
4920 	if (uri->path == NULL) {
4921 		event_warn("%s: strdup", __func__);
4922 		goto err;
4923 	}
4924 
4925 	return uri;
4926 err:
4927 	if (uri)
4928 		evhttp_uri_free(uri);
4929 	return NULL;
4930 }
4931 
4932 void
evhttp_uri_free(struct evhttp_uri * uri)4933 evhttp_uri_free(struct evhttp_uri *uri)
4934 {
4935 #define URI_FREE_STR_(f)		\
4936 	if (uri->f) {			\
4937 		mm_free(uri->f);		\
4938 	}
4939 
4940 	URI_FREE_STR_(scheme);
4941 	URI_FREE_STR_(userinfo);
4942 	URI_FREE_STR_(host);
4943 	URI_FREE_STR_(path);
4944 	URI_FREE_STR_(query);
4945 	URI_FREE_STR_(fragment);
4946 
4947 	mm_free(uri);
4948 #undef URI_FREE_STR_
4949 }
4950 
4951 char *
evhttp_uri_join(struct evhttp_uri * uri,char * buf,size_t limit)4952 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
4953 {
4954 	struct evbuffer *tmp = 0;
4955 	size_t joined_size = 0;
4956 	char *output = NULL;
4957 
4958 #define URI_ADD_(f)	evbuffer_add(tmp, uri->f, strlen(uri->f))
4959 
4960 	if (!uri || !buf || !limit)
4961 		return NULL;
4962 
4963 	tmp = evbuffer_new();
4964 	if (!tmp)
4965 		return NULL;
4966 
4967 	if (uri->scheme) {
4968 		URI_ADD_(scheme);
4969 		evbuffer_add(tmp, ":", 1);
4970 	}
4971 	if (uri->host) {
4972 		evbuffer_add(tmp, "//", 2);
4973 		if (uri->userinfo)
4974 			evbuffer_add_printf(tmp,"%s@", uri->userinfo);
4975 		URI_ADD_(host);
4976 		if (uri->port >= 0)
4977 			evbuffer_add_printf(tmp,":%d", uri->port);
4978 
4979 		if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
4980 			goto err;
4981 	}
4982 
4983 	if (uri->path)
4984 		URI_ADD_(path);
4985 
4986 	if (uri->query) {
4987 		evbuffer_add(tmp, "?", 1);
4988 		URI_ADD_(query);
4989 	}
4990 
4991 	if (uri->fragment) {
4992 		evbuffer_add(tmp, "#", 1);
4993 		URI_ADD_(fragment);
4994 	}
4995 
4996 	evbuffer_add(tmp, "\0", 1); /* NUL */
4997 
4998 	joined_size = evbuffer_get_length(tmp);
4999 
5000 	if (joined_size > limit) {
5001 		/* It doesn't fit. */
5002 		evbuffer_free(tmp);
5003 		return NULL;
5004 	}
5005        	evbuffer_remove(tmp, buf, joined_size);
5006 
5007 	output = buf;
5008 err:
5009 	evbuffer_free(tmp);
5010 
5011 	return output;
5012 #undef URI_ADD_
5013 }
5014 
5015 const char *
evhttp_uri_get_scheme(const struct evhttp_uri * uri)5016 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
5017 {
5018 	return uri->scheme;
5019 }
5020 const char *
evhttp_uri_get_userinfo(const struct evhttp_uri * uri)5021 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
5022 {
5023 	return uri->userinfo;
5024 }
5025 const char *
evhttp_uri_get_host(const struct evhttp_uri * uri)5026 evhttp_uri_get_host(const struct evhttp_uri *uri)
5027 {
5028 	return uri->host;
5029 }
5030 int
evhttp_uri_get_port(const struct evhttp_uri * uri)5031 evhttp_uri_get_port(const struct evhttp_uri *uri)
5032 {
5033 	return uri->port;
5034 }
5035 const char *
evhttp_uri_get_path(const struct evhttp_uri * uri)5036 evhttp_uri_get_path(const struct evhttp_uri *uri)
5037 {
5038 	return uri->path;
5039 }
5040 const char *
evhttp_uri_get_query(const struct evhttp_uri * uri)5041 evhttp_uri_get_query(const struct evhttp_uri *uri)
5042 {
5043 	return uri->query;
5044 }
5045 const char *
evhttp_uri_get_fragment(const struct evhttp_uri * uri)5046 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
5047 {
5048 	return uri->fragment;
5049 }
5050 
5051 #define URI_SET_STR_(f) do {					\
5052 	if (uri->f)						\
5053 		mm_free(uri->f);				\
5054 	if (f) {						\
5055 		if ((uri->f = mm_strdup(f)) == NULL) {		\
5056 			event_warn("%s: strdup()", __func__);	\
5057 			return -1;				\
5058 		}						\
5059 	} else {						\
5060 		uri->f = NULL;					\
5061 	}							\
5062 	} while(0)
5063 
5064 int
evhttp_uri_set_scheme(struct evhttp_uri * uri,const char * scheme)5065 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
5066 {
5067 	if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
5068 		return -1;
5069 
5070 	URI_SET_STR_(scheme);
5071 	return 0;
5072 }
5073 int
evhttp_uri_set_userinfo(struct evhttp_uri * uri,const char * userinfo)5074 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
5075 {
5076 	if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
5077 		return -1;
5078 	URI_SET_STR_(userinfo);
5079 	return 0;
5080 }
5081 int
evhttp_uri_set_host(struct evhttp_uri * uri,const char * host)5082 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
5083 {
5084 	if (host) {
5085 		if (host[0] == '[') {
5086 			if (! bracket_addr_ok(host, host+strlen(host)))
5087 				return -1;
5088 		} else {
5089 			if (! regname_ok(host, host+strlen(host)))
5090 				return -1;
5091 		}
5092 	}
5093 
5094 	URI_SET_STR_(host);
5095 	return 0;
5096 }
5097 int
evhttp_uri_set_port(struct evhttp_uri * uri,int port)5098 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
5099 {
5100 	if (port < -1)
5101 		return -1;
5102 	uri->port = port;
5103 	return 0;
5104 }
5105 #define end_of_cpath(cp,p,f) \
5106 	((const char*)(end_of_path(((const char*)(cp)), (p), (f))))
5107 
5108 int
evhttp_uri_set_path(struct evhttp_uri * uri,const char * path)5109 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
5110 {
5111 	if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
5112 		return -1;
5113 
5114 	URI_SET_STR_(path);
5115 	return 0;
5116 }
5117 int
evhttp_uri_set_query(struct evhttp_uri * uri,const char * query)5118 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
5119 {
5120 	if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
5121 		return -1;
5122 	URI_SET_STR_(query);
5123 	return 0;
5124 }
5125 int
evhttp_uri_set_fragment(struct evhttp_uri * uri,const char * fragment)5126 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
5127 {
5128 	if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
5129 		return -1;
5130 	URI_SET_STR_(fragment);
5131 	return 0;
5132 }
5133