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