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