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