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