ipc/chromium/src/third_party/libevent/http.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2  * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
     3  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
     4  *
     5  * Redistribution and use in source and binary forms, with or without
     6  * modification, are permitted provided that the following conditions
     7  * are met:
     8  * 1. Redistributions of source code must retain the above copyright
     9  *    notice, this list of conditions and the following disclaimer.
    10  * 2. Redistributions in binary form must reproduce the above copyright
    11  *    notice, this list of conditions and the following disclaimer in the
    12  *    documentation and/or other materials provided with the distribution.
    13  * 3. The name of the author may not be used to endorse or promote products
    14  *    derived from this software without specific prior written permission.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    26  */
    28 #include "event2/event-config.h"
    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
    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
    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
    54 #include <sys/queue.h>
    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
    66 #ifdef WIN32
    67 #include <winsock2.h>
    68 #endif
    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
    86 #undef timeout_pending
    87 #undef timeout_initialized
    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"
   105 #ifndef _EVENT_HAVE_GETNAMEINFO
   106 #define NI_MAXSERV 32
   107 #define NI_MAXHOST 1025
   109 #ifndef NI_NUMERICHOST
   110 #define NI_NUMERICHOST 1
   111 #endif
   113 #ifndef NI_NUMERICSERV
   114 #define NI_NUMERICSERV 2
   115 #endif
   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;
   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 	}
   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);
   145 			if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
   146 				return (-1);
   147 			else
   148 				return (0);
   149 		}
   150 	}
   151 	return (0);
   152 }
   154 #endif
   156 #define REQ_VERSION_BEFORE(req, major_v, minor_v)			\
   157 	((req)->major < (major_v) ||					\
   158 	    ((req)->major == (major_v) && (req)->minor < (minor_v)))
   160 #define REQ_VERSION_ATLEAST(req, major_v, minor_v)			\
   161 	((req)->major > (major_v) ||					\
   162 	    ((req)->major == (major_v) && (req)->minor >= (minor_v)))
   164 #ifndef MIN
   165 #define MIN(a,b) (((a)<(b))?(a):(b))
   166 #endif
   168 extern int debug;
   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 *);
   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);
   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
   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 	}
   245 	return 1;
   246 }
   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  */
   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;
   262 	if (html == NULL)
   263 		return (NULL);
   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 	}
   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 	}
   291 	*p = '\0';
   293 	return (escaped_html);
   294 }
   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;
   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 	}
   337 	return (method);
   338 }
   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 }
   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;
   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 }
   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__));
   382 	/* Set call back */
   383 	evcon->cb = cb;
   384 	evcon->cb_arg = arg;
   386 	bufferevent_enable(evcon->bufev, EV_WRITE);
   388 	/* Disable the read callback: we don't actually care about data;
   389 	 * we only care about close detection.  (We don't disable reading,
   390 	 * since we *do* want to learn about any close events.) */
   391 	bufferevent_setcb(evcon->bufev,
   392 	    NULL, /*read*/
   393 	    evhttp_write_cb,
   394 	    evhttp_error_cb,
   395 	    evcon);
   396 }
   398 static void
   399 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
   400 {
   401 	bufferevent_disable(evcon->bufev, EV_WRITE);
   402 }
   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 }
   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 }
   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;
   450 	evhttp_remove_header(req->output_headers, "Proxy-Connection");
   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);
   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 }
   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 }
   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 }
   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 }
   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 }
   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);
   546 	if (req->major == 1) {
   547 		if (req->minor >= 1)
   548 			evhttp_maybe_add_date_header(req->output_headers);
   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");
   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 	}
   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 	}
   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 }
   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);
   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 	}
   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);
   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 }
   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 }
   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 		}
   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 	}
   690 	return (0);
   691 }
   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);
   706 	bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
   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 	}
   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 	}
   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);
   739 	/* reset the connection */
   740 	evhttp_connection_reset(evcon);
   742 	/* We are trying the next request that was queued on us */
   743 	if (TAILQ_FIRST(&evcon->requests) != NULL)
   744 		evhttp_connection_connect(evcon);
   746 	/* inform the user */
   747 	if (cb != NULL)
   748 		(*cb)(NULL, cb_arg);
   749 }
   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;
   758 	/* Activate our call back */
   759 	if (evcon->cb != NULL)
   760 		(*evcon->cb)(evcon, evcon->cb_arg);
   761 }
   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;
   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;
   782 		evcon->state = EVCON_IDLE;
   784 		need_close =
   785 		    evhttp_is_connection_close(req->flags, req->input_headers)||
   786 		    evhttp_is_connection_close(req->flags, req->output_headers);
   788 		/* check if we got asked to close the connection */
   789 		if (need_close)
   790 			evhttp_connection_reset(evcon);
   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 	}
   816 	/* notify the user of the request */
   817 	(*req->cb)(req, req->cb_arg);
   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 }
   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  */
   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 	}
   848 	while (1) {
   849 		size_t buflen;
   851 		if ((buflen = evbuffer_get_length(buf)) == 0) {
   852 			break;
   853 		}
   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 		}
   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 			}
   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 			}
   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 			}
   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 		}
   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 		}
   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);
   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 	}
   929 	return (MORE_DATA_EXPECTED);
   930 }
   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);
   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 }
   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);
   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 		}
   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);
   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);
  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;
  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;
  1025 	if (req->ntoread == 0) {
  1026 		bufferevent_disable(evcon->bufev, EV_READ);
  1027 		/* Completed content length */
  1028 		evhttp_connection_done(evcon);
  1029 		return;
  1032 	/* Read more! */
  1033 	bufferevent_enable(evcon->bufev, EV_READ);
  1036 #define get_deferred_queue(evcon)		\
  1037 	(event_base_get_deferred_cb_queue((evcon)->base))
  1039 /*
  1040  * Gets called when more data becomes available
  1041  */
  1043 static void
  1044 evhttp_read_cb(struct bufferevent *bufev, void *arg)
  1046 	struct evhttp_connection *evcon = arg;
  1047 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
  1049 	/* Cancel if it's pending. */
  1050 	event_deferred_cb_cancel(get_deferred_queue(evcon),
  1051 	    &evcon->read_more_deferred_cb);
  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:
  1074 #ifdef USE_DEBUG
  1075 			struct evbuffer *input;
  1076 			size_t total_len;
  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
  1086 			evhttp_connection_reset(evcon);
  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);
  1098 static void
  1099 evhttp_deferred_read_cb(struct deferred_cb *cb, void *data)
  1101 	struct evhttp_connection *evcon = data;
  1102 	evhttp_read_cb(evcon->bufev, evcon);
  1105 static void
  1106 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
  1108 	/* This is after writing the request to the server */
  1109 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
  1110 	EVUTIL_ASSERT(req != NULL);
  1112 	EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
  1114 	/* We are done writing our header and are now expecting the response */
  1115 	req->kind = EVHTTP_RESPONSE;
  1117 	evhttp_start_read(evcon);
  1120 /*
  1121  * Clean up a connection object
  1122  */
  1124 void
  1125 evhttp_connection_free(struct evhttp_connection *evcon)
  1127 	struct evhttp_request *req;
  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);
  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);
  1145 	if (evcon->http_server != NULL) {
  1146 		struct evhttp *http = evcon->http_server;
  1147 		TAILQ_REMOVE(&http->connections, evcon, next);
  1150 	if (event_initialized(&evcon->retry_ev)) {
  1151 		event_del(&evcon->retry_ev);
  1152 		event_debug_unassign(&evcon->retry_ev);
  1155 	if (evcon->bufev != NULL)
  1156 		bufferevent_free(evcon->bufev);
  1158 	event_deferred_cb_cancel(get_deferred_queue(evcon),
  1159 	    &evcon->read_more_deferred_cb);
  1161 	if (evcon->fd != -1) {
  1162 		shutdown(evcon->fd, EVUTIL_SHUT_WR);
  1163 		evutil_closesocket(evcon->fd);
  1166 	if (evcon->bind_address != NULL)
  1167 		mm_free(evcon->bind_address);
  1169 	if (evcon->address != NULL)
  1170 		mm_free(evcon->address);
  1172 	mm_free(evcon);
  1175 void
  1176 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
  1177     const char *address)
  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__);
  1186 void
  1187 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
  1188     ev_uint16_t port)
  1190 	EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
  1191 	evcon->bind_port = port;
  1194 static void
  1195 evhttp_request_dispatch(struct evhttp_connection* evcon)
  1197 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
  1199 	/* this should not usually happy but it's possible */
  1200 	if (req == NULL)
  1201 		return;
  1203 	/* delete possible close detection events */
  1204 	evhttp_connection_stop_detectclose(evcon);
  1206 	/* we assume that the connection is connected already */
  1207 	EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
  1209 	evcon->state = EVCON_WRITING;
  1211 	/* Create the header from the store arguments */
  1212 	evhttp_make_header(evcon, req);
  1214 	evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
  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)
  1222 	struct evbuffer *tmp;
  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.
  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);
  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);
  1242 		shutdown(evcon->fd, EVUTIL_SHUT_WR);
  1243 		evutil_closesocket(evcon->fd);
  1244 		evcon->fd = -1;
  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));
  1253 	evcon->state = EVCON_DISCONNECTED;
  1256 static void
  1257 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
  1259 	evcon->flags |= EVHTTP_CON_CLOSEDETECT;
  1261 	bufferevent_enable(evcon->bufev, EV_READ);
  1264 static void
  1265 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
  1267 	evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
  1269 	bufferevent_disable(evcon->bufev, EV_READ);
  1272 static void
  1273 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
  1275 	struct evhttp_connection *evcon = arg;
  1277 	evcon->state = EVCON_DISCONNECTED;
  1278 	evhttp_connection_connect(evcon);
  1281 static void
  1282 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
  1284 	struct evcon_requestq requests;
  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;
  1295 	evhttp_connection_reset(evcon);
  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);
  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;
  1316 		/* we might want to set an error here */
  1317 		request->cb(request, request->cb_arg);
  1318 		evhttp_request_free(request);
  1322 static void
  1323 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
  1325 	struct evhttp_connection *evcon = arg;
  1326 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
  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;
  1338 		break;
  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;
  1347 		break;
  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;
  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;
  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);
  1383 /*
  1384  * Event callback for asynchronous connection attempt.
  1385  */
  1386 static void
  1387 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
  1389 	struct evhttp_connection *evcon = arg;
  1390 	int error;
  1391 	ev_socklen_t errsz = sizeof(error);
  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;
  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;
  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;
  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)));
  1429 	/* Reset the retry count as we were successful in connecting */
  1430 	evcon->retry_cnt = 0;
  1431 	evcon->state = EVCON_IDLE;
  1433 	/* reset the bufferevent cbs */
  1434 	bufferevent_setcb(evcon->bufev,
  1435 	    evhttp_read_cb,
  1436 	    evhttp_write_cb,
  1437 	    evhttp_error_cb,
  1438 	    evcon);
  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);
  1450 	/* try to start requests that have queued up on this connection */
  1451 	evhttp_request_dispatch(evcon);
  1452 	return;
  1454  cleanup:
  1455 	evhttp_connection_cb_cleanup(evcon);
  1458 /*
  1459  * Check if we got a valid response code.
  1460  */
  1462 static int
  1463 evhttp_valid_response_code(int code)
  1465 	if (code == 0)
  1466 		return (0);
  1468 	return (1);
  1471 static int
  1472 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
  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);
  1482 	req->major = major;
  1483 	req->minor = minor;
  1484 	return (0);
  1487 /* Parses the status line of a web server */
  1489 static int
  1490 evhttp_parse_response_line(struct evhttp_request *req, char *line)
  1492 	char *protocol;
  1493 	char *number;
  1494 	const char *readable = "";
  1496 	protocol = strsep(&line, " ");
  1497 	if (line == NULL)
  1498 		return (-1);
  1499 	number = strsep(&line, " ");
  1500 	if (line != NULL)
  1501 		readable = line;
  1503 	if (evhttp_parse_http_version(protocol, req) < 0)
  1504 		return (-1);
  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);
  1513 	if ((req->response_code_line = mm_strdup(readable)) == NULL) {
  1514 		event_warn("%s: strdup", __func__);
  1515 		return (-1);
  1518 	return (0);
  1521 /* Parse the first line of a HTTP request */
  1523 static int
  1524 evhttp_parse_request_line(struct evhttp_request *req, char *line)
  1526 	char *method;
  1527 	char *uri;
  1528 	char *version;
  1529 	const char *hostname;
  1530 	const char *scheme;
  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);
  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. */
  1568 	if (evhttp_parse_http_version(version, req) < 0)
  1569 		return (-1);
  1571 	if ((req->uri = mm_strdup(uri)) == NULL) {
  1572 		event_debug(("%s: mm_strdup", __func__));
  1573 		return (-1);
  1576 	if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
  1577 		    EVHTTP_URI_NONCONFORMANT)) == NULL) {
  1578 		return -1;
  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;
  1592 	return (0);
  1595 const char *
  1596 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
  1598 	struct evkeyval *header;
  1600 	TAILQ_FOREACH(header, headers, next) {
  1601 		if (evutil_ascii_strcasecmp(header->key, key) == 0)
  1602 			return (header->value);
  1605 	return (NULL);
  1608 void
  1609 evhttp_clear_headers(struct evkeyvalq *headers)
  1611 	struct evkeyval *header;
  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);
  1623 /*
  1624  * Returns 0,  if the header was successfully removed.
  1625  * Returns -1, if the header could not be found.
  1626  */
  1628 int
  1629 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
  1631 	struct evkeyval *header;
  1633 	TAILQ_FOREACH(header, headers, next) {
  1634 		if (evutil_ascii_strcasecmp(header->key, key) == 0)
  1635 			break;
  1638 	if (header == NULL)
  1639 		return (-1);
  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);
  1647 	return (0);
  1650 static int
  1651 evhttp_header_is_valid_value(const char *value)
  1653 	const char *p = value;
  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);
  1662 	return (1);
  1665 int
  1666 evhttp_add_header(struct evkeyvalq *headers,
  1667     const char *key, const char *value)
  1669 	event_debug(("%s: key: %s val: %s\n", __func__, key, value));
  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);
  1677 	if (!evhttp_header_is_valid_value(value)) {
  1678 		event_debug(("%s: dropping illegal header value\n", __func__));
  1679 		return (-1);
  1682 	return (evhttp_add_header_internal(headers, key, value));
  1685 static int
  1686 evhttp_add_header_internal(struct evkeyvalq *headers,
  1687     const char *key, const char *value)
  1689 	struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
  1690 	if (header == NULL) {
  1691 		event_warn("%s: calloc", __func__);
  1692 		return (-1);
  1694 	if ((header->key = mm_strdup(key)) == NULL) {
  1695 		mm_free(header);
  1696 		event_warn("%s: strdup", __func__);
  1697 		return (-1);
  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);
  1706 	TAILQ_INSERT_TAIL(headers, header, next);
  1708 	return (0);
  1711 /*
  1712  * Parses header lines from a request or a response into the specified
  1713  * request object given an event buffer.
  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  */
  1721 enum message_read_status
  1722 evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
  1724 	char *line;
  1725 	enum message_read_status status = ALL_DATA_READ;
  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);
  1738 	if (req->evcon != NULL &&
  1739 	    line_length > req->evcon->max_headers_size) {
  1740 		mm_free(line);
  1741 		return (DATA_TOO_LONG);
  1744 	req->headers_size = line_length;
  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;
  1759 	mm_free(line);
  1760 	return (status);
  1763 static int
  1764 evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
  1766 	struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
  1767 	char *newval;
  1768 	size_t old_len, line_len;
  1770 	if (header == NULL)
  1771 		return (-1);
  1773 	old_len = strlen(header->value);
  1774 	line_len = strlen(line);
  1776 	newval = mm_realloc(header->value, old_len + line_len + 1);
  1777 	if (newval == NULL)
  1778 		return (-1);
  1780 	memcpy(newval + old_len, line, line_len + 1);
  1781 	header->value = newval;
  1783 	return (0);
  1786 enum message_read_status
  1787 evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
  1789 	enum message_read_status errcode = DATA_CORRUPTED;
  1790 	char *line;
  1791 	enum message_read_status status = MORE_DATA_EXPECTED;
  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;
  1799 		req->headers_size += line_length;
  1801 		if (req->evcon != NULL &&
  1802 		    req->headers_size > req->evcon->max_headers_size) {
  1803 			errcode = DATA_TOO_LONG;
  1804 			goto error;
  1807 		if (*line == '\0') { /* Last header - Done */
  1808 			status = ALL_DATA_READ;
  1809 			mm_free(line);
  1810 			break;
  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;
  1821 		/* Processing of header lines */
  1822 		svalue = line;
  1823 		skey = strsep(&svalue, ":");
  1824 		if (svalue == NULL)
  1825 			goto error;
  1827 		svalue += strspn(svalue, " ");
  1829 		if (evhttp_add_header(headers, skey, svalue) == -1)
  1830 			goto error;
  1832 		mm_free(line);
  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);
  1841 	return (status);
  1843  error:
  1844 	mm_free(line);
  1845 	return (errcode);
  1848 static int
  1849 evhttp_get_body_length(struct evhttp_request *req)
  1851 	struct evkeyvalq *headers = req->input_headers;
  1852 	const char *content_length;
  1853 	const char *connection;
  1855 	content_length = evhttp_find_header(headers, "Content-Length");
  1856 	connection = evhttp_find_header(headers, "Connection");
  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);
  1877 		req->ntoread = ntoread;
  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)))));
  1884 	return (0);
  1887 static int
  1888 evhttp_method_may_have_body(enum evhttp_cmd_type type)
  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;
  1909 static void
  1910 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
  1912 	const char *xfer_enc;
  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;
  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;
  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;
  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;
  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;
  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;
  1969 	evhttp_read_body(evcon, req);
  1970 	/* note the request may have been freed in evhttp_read_body */
  1973 static void
  1974 evhttp_read_firstline(struct evhttp_connection *evcon,
  1975 		      struct evhttp_request *req)
  1977 	enum message_read_status res;
  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;
  1991 	evcon->state = EVCON_READING_HEADERS;
  1992 	evhttp_read_header(evcon, req);
  1995 static void
  1996 evhttp_read_header(struct evhttp_connection *evcon,
  1997 		   struct evhttp_request *req)
  1999 	enum message_read_status res;
  2000 	evutil_socket_t fd = evcon->fd;
  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;
  2014 	/* Disable reading for now */
  2015 	bufferevent_disable(evcon->bufev, EV_READ);
  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;
  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;
  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 */
  2044 		break;
  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;
  2052 	/* request may have been freed above */
  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.
  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  */
  2065 struct evhttp_connection *
  2066 evhttp_connection_new(const char *address, unsigned short port)
  2068 	return (evhttp_connection_base_new(NULL, NULL, address, port));
  2071 struct evhttp_connection *
  2072 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
  2073     const char *address, unsigned short port)
  2075 	struct evhttp_connection *evcon = NULL;
  2077 	event_debug(("Attempting connection to %s:%d\n", address, port));
  2079 	if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
  2080 		event_warn("%s: calloc failed", __func__);
  2081 		goto error;
  2084 	evcon->fd = -1;
  2085 	evcon->port = port;
  2087 	evcon->max_headers_size = EV_SIZE_MAX;
  2088 	evcon->max_body_size = EV_SIZE_MAX;
  2090 	evcon->timeout = -1;
  2091 	evcon->retry_cnt = evcon->retry_max = 0;
  2093 	if ((evcon->address = mm_strdup(address)) == NULL) {
  2094 		event_warn("%s: strdup failed", __func__);
  2095 		goto error;
  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;
  2106 	evcon->state = EVCON_DISCONNECTED;
  2107 	TAILQ_INIT(&evcon->requests);
  2109 	if (base != NULL) {
  2110 		evcon->base = base;
  2111 		bufferevent_base_set(base, evcon->bufev);
  2115 	event_deferred_cb_init(&evcon->read_more_deferred_cb,
  2116 	    evhttp_deferred_read_cb, evcon);
  2118 	evcon->dns_base = dnsbase;
  2120 	return (evcon);
  2122  error:
  2123 	if (evcon != NULL)
  2124 		evhttp_connection_free(evcon);
  2125 	return (NULL);
  2128 struct bufferevent *
  2129 evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
  2131 	return evcon->bufev;
  2134 void
  2135 evhttp_connection_set_base(struct evhttp_connection *evcon,
  2136     struct event_base *base)
  2138 	EVUTIL_ASSERT(evcon->base == NULL);
  2139 	EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
  2140 	evcon->base = base;
  2141 	bufferevent_base_set(base, evcon->bufev);
  2144 void
  2145 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
  2146     int timeout_in_secs)
  2148 	evcon->timeout = timeout_in_secs;
  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);
  2158 void
  2159 evhttp_connection_set_retries(struct evhttp_connection *evcon,
  2160     int retry_max)
  2162 	evcon->retry_max = retry_max;
  2165 void
  2166 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
  2167     void (*cb)(struct evhttp_connection *, void *), void *cbarg)
  2169 	evcon->closecb = cb;
  2170 	evcon->closecb_arg = cbarg;
  2173 void
  2174 evhttp_connection_get_peer(struct evhttp_connection *evcon,
  2175     char **address, ev_uint16_t *port)
  2177 	*address = evcon->address;
  2178 	*port = evcon->port;
  2181 int
  2182 evhttp_connection_connect(struct evhttp_connection *evcon)
  2184 	if (evcon->state == EVCON_CONNECTING)
  2185 		return (0);
  2187 	evhttp_connection_reset(evcon);
  2189 	EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
  2190 	evcon->flags |= EVHTTP_CON_OUTGOING;
  2192 	evcon->fd = bind_socket(
  2193 		evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
  2194 	if (evcon->fd == -1) {
  2195 		event_debug(("%s: failed to bind to \"%s\"",
  2196 			__func__, evcon->bind_address));
  2197 		return (-1);
  2200 	/* Set up a callback for successful connection setup */
  2201 	bufferevent_setfd(evcon->bufev, evcon->fd);
  2202 	bufferevent_setcb(evcon->bufev,
  2203 	    NULL /* evhttp_read_cb */,
  2204 	    NULL /* evhttp_write_cb */,
  2205 	    evhttp_connection_cb,
  2206 	    evcon);
  2207 	bufferevent_settimeout(evcon->bufev, 0,
  2208 	    evcon->timeout != -1 ? evcon->timeout : HTTP_CONNECT_TIMEOUT);
  2209 	/* make sure that we get a write callback */
  2210 	bufferevent_enable(evcon->bufev, EV_WRITE);
  2212 	if (bufferevent_socket_connect_hostname(evcon->bufev, evcon->dns_base,
  2213 		AF_UNSPEC, evcon->address, evcon->port) < 0) {
  2214 		event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
  2215 		    __func__, evcon->address);
  2216 		/* some operating systems return ECONNREFUSED immediately
  2217 		 * when connecting to a local address.  the cleanup is going
  2218 		 * to reschedule this function call.
  2219 		 */
  2220 		evhttp_connection_cb_cleanup(evcon);
  2221 		return (0);
  2224 	evcon->state = EVCON_CONNECTING;
  2226 	return (0);
  2229 /*
  2230  * Starts an HTTP request on the provided evhttp_connection object.
  2231  * If the connection object is not connected to the web server already,
  2232  * this will start the connection.
  2233  */
  2235 int
  2236 evhttp_make_request(struct evhttp_connection *evcon,
  2237     struct evhttp_request *req,
  2238     enum evhttp_cmd_type type, const char *uri)
  2240 	/* We are making a request */
  2241 	req->kind = EVHTTP_REQUEST;
  2242 	req->type = type;
  2243 	if (req->uri != NULL)
  2244 		mm_free(req->uri);
  2245 	if ((req->uri = mm_strdup(uri)) == NULL) {
  2246 		event_warn("%s: strdup", __func__);
  2247 		evhttp_request_free(req);
  2248 		return (-1);
  2251 	/* Set the protocol version if it is not supplied */
  2252 	if (!req->major && !req->minor) {
  2253 		req->major = 1;
  2254 		req->minor = 1;
  2257 	EVUTIL_ASSERT(req->evcon == NULL);
  2258 	req->evcon = evcon;
  2259 	EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
  2261        TAILQ_INSERT_TAIL(&evcon->requests, req, next);
  2263 	/* If the connection object is not connected; make it so */
  2264 	if (!evhttp_connected(evcon)) {
  2265 		int res = evhttp_connection_connect(evcon);
  2266 	       /* evhttp_connection_fail(), which is called through
  2267 		* evhttp_connection_connect(), assumes that req lies in
  2268 		* evcon->requests.  Thus, enqueue the request in advance and r
  2269 		* it in the error case. */
  2270 	       if (res != 0)
  2271 		       TAILQ_REMOVE(&evcon->requests, req, next);
  2273 		return res;
  2276 	/*
  2277 	 * If it's connected already and we are the first in the queue,
  2278 	 * then we can dispatch this request immediately.  Otherwise, it
  2279 	 * will be dispatched once the pending requests are completed.
  2280 	 */
  2281 	if (TAILQ_FIRST(&evcon->requests) == req)
  2282 		evhttp_request_dispatch(evcon);
  2284 	return (0);
  2287 void
  2288 evhttp_cancel_request(struct evhttp_request *req)
  2290 	struct evhttp_connection *evcon = req->evcon;
  2291 	if (evcon != NULL) {
  2292 		/* We need to remove it from the connection */
  2293 		if (TAILQ_FIRST(&evcon->requests) == req) {
  2294 			/* it's currently being worked on, so reset
  2295 			 * the connection.
  2296 			 */
  2297 			evhttp_connection_fail(evcon,
  2298 			    EVCON_HTTP_REQUEST_CANCEL);
  2300 			/* connection fail freed the request */
  2301 			return;
  2302 		} else {
  2303 			/* otherwise, we can just remove it from the
  2304 			 * queue
  2305 			 */
  2306 			TAILQ_REMOVE(&evcon->requests, req, next);
  2310 	evhttp_request_free(req);
  2313 /*
  2314  * Reads data from file descriptor into request structure
  2315  * Request structure needs to be set up correctly.
  2316  */
  2318 void
  2319 evhttp_start_read(struct evhttp_connection *evcon)
  2321 	/* Set up an event to read the headers */
  2322 	bufferevent_disable(evcon->bufev, EV_WRITE);
  2323 	bufferevent_enable(evcon->bufev, EV_READ);
  2324 	evcon->state = EVCON_READING_FIRSTLINE;
  2325 	/* Reset the bufferevent callbacks */
  2326 	bufferevent_setcb(evcon->bufev,
  2327 	    evhttp_read_cb,
  2328 	    evhttp_write_cb,
  2329 	    evhttp_error_cb,
  2330 	    evcon);
  2332 	/* If there's still data pending, process it next time through the
  2333 	 * loop.  Don't do it now; that could get recusive. */
  2334 	if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
  2335 		event_deferred_cb_schedule(get_deferred_queue(evcon),
  2336 		    &evcon->read_more_deferred_cb);
  2340 static void
  2341 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
  2343 	int need_close;
  2344 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
  2345 	TAILQ_REMOVE(&evcon->requests, req, next);
  2347 	need_close =
  2348 	    (REQ_VERSION_BEFORE(req, 1, 1) &&
  2349 		!evhttp_is_connection_keepalive(req->input_headers))||
  2350 	    evhttp_is_connection_close(req->flags, req->input_headers) ||
  2351 	    evhttp_is_connection_close(req->flags, req->output_headers);
  2353 	EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
  2354 	evhttp_request_free(req);
  2356 	if (need_close) {
  2357 		evhttp_connection_free(evcon);
  2358 		return;
  2361 	/* we have a persistent connection; try to accept another request. */
  2362 	if (evhttp_associate_new_request_with_connection(evcon) == -1) {
  2363 		evhttp_connection_free(evcon);
  2367 /*
  2368  * Returns an error page.
  2369  */
  2371 void
  2372 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
  2375 #define ERR_FORMAT "<HTML><HEAD>\n" \
  2376 	    "<TITLE>%d %s</TITLE>\n" \
  2377 	    "</HEAD><BODY>\n" \
  2378 	    "<H1>%s</H1>\n" \
  2379 	    "</BODY></HTML>\n"
  2381 	struct evbuffer *buf = evbuffer_new();
  2382 	if (buf == NULL) {
  2383 		/* if we cannot allocate memory; we just drop the connection */
  2384 		evhttp_connection_free(req->evcon);
  2385 		return;
  2387 	if (reason == NULL) {
  2388 		reason = evhttp_response_phrase_internal(error);
  2391 	evhttp_response_code(req, error, reason);
  2393 	evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
  2395 	evhttp_send_page(req, buf);
  2397 	evbuffer_free(buf);
  2398 #undef ERR_FORMAT
  2401 /* Requires that headers and response code are already set up */
  2403 static inline void
  2404 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
  2406 	struct evhttp_connection *evcon = req->evcon;
  2408 	if (evcon == NULL) {
  2409 		evhttp_request_free(req);
  2410 		return;
  2413 	EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
  2415 	/* we expect no more calls form the user on this request */
  2416 	req->userdone = 1;
  2418 	/* xxx: not sure if we really should expose the data buffer this way */
  2419 	if (databuf != NULL)
  2420 		evbuffer_add_buffer(req->output_buffer, databuf);
  2422 	/* Adds headers to the response */
  2423 	evhttp_make_header(evcon, req);
  2425 	evhttp_write_buffer(evcon, evhttp_send_done, NULL);
  2428 void
  2429 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
  2430     struct evbuffer *databuf)
  2432 	evhttp_response_code(req, code, reason);
  2434 	evhttp_send(req, databuf);
  2437 void
  2438 evhttp_send_reply_start(struct evhttp_request *req, int code,
  2439     const char *reason)
  2441 	evhttp_response_code(req, code, reason);
  2442 	if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
  2443 	    REQ_VERSION_ATLEAST(req, 1, 1) &&
  2444 	    evhttp_response_needs_body(req)) {
  2445 		/*
  2446 		 * prefer HTTP/1.1 chunked encoding to closing the connection;
  2447 		 * note RFC 2616 section 4.4 forbids it with Content-Length:
  2448 		 * and it's not necessary then anyway.
  2449 		 */
  2450 		evhttp_add_header(req->output_headers, "Transfer-Encoding",
  2451 		    "chunked");
  2452 		req->chunked = 1;
  2453 	} else {
  2454 		req->chunked = 0;
  2456 	evhttp_make_header(req->evcon, req);
  2457 	evhttp_write_buffer(req->evcon, NULL, NULL);
  2460 void
  2461 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
  2463 	struct evhttp_connection *evcon = req->evcon;
  2464 	struct evbuffer *output;
  2466 	if (evcon == NULL)
  2467 		return;
  2469 	output = bufferevent_get_output(evcon->bufev);
  2471 	if (evbuffer_get_length(databuf) == 0)
  2472 		return;
  2473 	if (!evhttp_response_needs_body(req))
  2474 		return;
  2475 	if (req->chunked) {
  2476 		evbuffer_add_printf(output, "%x\r\n",
  2477 				    (unsigned)evbuffer_get_length(databuf));
  2479 	evbuffer_add_buffer(output, databuf);
  2480 	if (req->chunked) {
  2481 		evbuffer_add(output, "\r\n", 2);
  2483 	evhttp_write_buffer(evcon, NULL, NULL);
  2486 void
  2487 evhttp_send_reply_end(struct evhttp_request *req)
  2489 	struct evhttp_connection *evcon = req->evcon;
  2490 	struct evbuffer *output;
  2492 	if (evcon == NULL) {
  2493 		evhttp_request_free(req);
  2494 		return;
  2497 	output = bufferevent_get_output(evcon->bufev);
  2499 	/* we expect no more calls form the user on this request */
  2500 	req->userdone = 1;
  2502 	if (req->chunked) {
  2503 		evbuffer_add(output, "0\r\n\r\n", 5);
  2504 		evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
  2505 		req->chunked = 0;
  2506 	} else if (evbuffer_get_length(output) == 0) {
  2507 		/* let the connection know that we are done with the request */
  2508 		evhttp_send_done(evcon, NULL);
  2509 	} else {
  2510 		/* make the callback execute after all data has been written */
  2511 		evcon->cb = evhttp_send_done;
  2512 		evcon->cb_arg = NULL;
  2516 static const char *informational_phrases[] = {
  2517 	/* 100 */ "Continue",
  2518 	/* 101 */ "Switching Protocols"
  2519 };
  2521 static const char *success_phrases[] = {
  2522 	/* 200 */ "OK",
  2523 	/* 201 */ "Created",
  2524 	/* 202 */ "Accepted",
  2525 	/* 203 */ "Non-Authoritative Information",
  2526 	/* 204 */ "No Content",
  2527 	/* 205 */ "Reset Content",
  2528 	/* 206 */ "Partial Content"
  2529 };
  2531 static const char *redirection_phrases[] = {
  2532 	/* 300 */ "Multiple Choices",
  2533 	/* 301 */ "Moved Permanently",
  2534 	/* 302 */ "Found",
  2535 	/* 303 */ "See Other",
  2536 	/* 304 */ "Not Modified",
  2537 	/* 305 */ "Use Proxy",
  2538 	/* 307 */ "Temporary Redirect"
  2539 };
  2541 static const char *client_error_phrases[] = {
  2542 	/* 400 */ "Bad Request",
  2543 	/* 401 */ "Unauthorized",
  2544 	/* 402 */ "Payment Required",
  2545 	/* 403 */ "Forbidden",
  2546 	/* 404 */ "Not Found",
  2547 	/* 405 */ "Method Not Allowed",
  2548 	/* 406 */ "Not Acceptable",
  2549 	/* 407 */ "Proxy Authentication Required",
  2550 	/* 408 */ "Request Time-out",
  2551 	/* 409 */ "Conflict",
  2552 	/* 410 */ "Gone",
  2553 	/* 411 */ "Length Required",
  2554 	/* 412 */ "Precondition Failed",
  2555 	/* 413 */ "Request Entity Too Large",
  2556 	/* 414 */ "Request-URI Too Large",
  2557 	/* 415 */ "Unsupported Media Type",
  2558 	/* 416 */ "Requested range not satisfiable",
  2559 	/* 417 */ "Expectation Failed"
  2560 };
  2562 static const char *server_error_phrases[] = {
  2563 	/* 500 */ "Internal Server Error",
  2564 	/* 501 */ "Not Implemented",
  2565 	/* 502 */ "Bad Gateway",
  2566 	/* 503 */ "Service Unavailable",
  2567 	/* 504 */ "Gateway Time-out",
  2568 	/* 505 */ "HTTP Version not supported"
  2569 };
  2571 struct response_class {
  2572 	const char *name;
  2573 	size_t num_responses;
  2574 	const char **responses;
  2575 };
  2577 #ifndef MEMBERSOF
  2578 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
  2579 #endif
  2581 static const struct response_class response_classes[] = {
  2582 	/* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
  2583 	/* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
  2584 	/* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
  2585 	/* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
  2586 	/* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
  2587 };
  2589 static const char *
  2590 evhttp_response_phrase_internal(int code)
  2592 	int klass = code / 100 - 1;
  2593 	int subcode = code % 100;
  2595 	/* Unknown class - can't do any better here */
  2596 	if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
  2597 		return "Unknown Status Class";
  2599 	/* Unknown sub-code, return class name at least */
  2600 	if (subcode >= (int) response_classes[klass].num_responses)
  2601 		return response_classes[klass].name;
  2603 	return response_classes[klass].responses[subcode];
  2606 void
  2607 evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
  2609 	req->kind = EVHTTP_RESPONSE;
  2610 	req->response_code = code;
  2611 	if (req->response_code_line != NULL)
  2612 		mm_free(req->response_code_line);
  2613 	if (reason == NULL)
  2614 		reason = evhttp_response_phrase_internal(code);
  2615 	req->response_code_line = mm_strdup(reason);
  2616 	if (req->response_code_line == NULL) {
  2617 		event_warn("%s: strdup", __func__);
  2618 		/* XXX what else can we do? */
  2622 void
  2623 evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
  2625 	if (!req->major || !req->minor) {
  2626 		req->major = 1;
  2627 		req->minor = 1;
  2630 	if (req->kind != EVHTTP_RESPONSE)
  2631 		evhttp_response_code(req, 200, "OK");
  2633 	evhttp_clear_headers(req->output_headers);
  2634 	evhttp_add_header(req->output_headers, "Content-Type", "text/html");
  2635 	evhttp_add_header(req->output_headers, "Connection", "close");
  2637 	evhttp_send(req, databuf);
  2640 static const char uri_chars[256] = {
  2641 	/* 0 */
  2642 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
  2643 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
  2644 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 1, 1, 0,
  2645 	1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 0, 0, 0, 0, 0, 0,
  2646 	/* 64 */
  2647 	0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
  2648 	1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 0, 1,
  2649 	0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
  2650 	1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 1, 0,
  2651 	/* 128 */
  2652 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
  2653 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
  2654 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
  2655 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
  2656 	/* 192 */
  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 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
  2660 	0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
  2661 };
  2663 #define CHAR_IS_UNRESERVED(c)			\
  2664 	(uri_chars[(unsigned char)(c)])
  2666 /*
  2667  * Helper functions to encode/decode a string for inclusion in a URI.
  2668  * The returned string must be freed by the caller.
  2669  */
  2670 char *
  2671 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
  2673 	struct evbuffer *buf = evbuffer_new();
  2674 	const char *p, *end;
  2675 	char *result;
  2677 	if (buf == NULL)
  2678 		return (NULL);
  2680 	if (len >= 0)
  2681 		end = uri+len;
  2682 	else
  2683 		end = uri+strlen(uri);
  2685 	for (p = uri; p < end; p++) {
  2686 		if (CHAR_IS_UNRESERVED(*p)) {
  2687 			evbuffer_add(buf, p, 1);
  2688 		} else if (*p == ' ' && space_as_plus) {
  2689 			evbuffer_add(buf, "+", 1);
  2690 		} else {
  2691 			evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
  2694 	evbuffer_add(buf, "", 1); /* NUL-terminator. */
  2695 	result = mm_malloc(evbuffer_get_length(buf));
  2696 	if (result)
  2697 		evbuffer_remove(buf, result, evbuffer_get_length(buf));
  2698 	evbuffer_free(buf);
  2700 	return (result);
  2703 char *
  2704 evhttp_encode_uri(const char *str)
  2706 	return evhttp_uriencode(str, -1, 0);
  2709 /*
  2710  * @param decode_plus_ctl: if 1, we decode plus into space.  If 0, we don't.
  2711  *     If -1, when true we transform plus to space only after we've seen
  2712  *     a ?.  -1 is deprecated.
  2713  * @return the number of bytes written to 'ret'.
  2714  */
  2715 static int
  2716 evhttp_decode_uri_internal(
  2717 	const char *uri, size_t length, char *ret, int decode_plus_ctl)
  2719 	char c;
  2720 	int j;
  2721 	int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
  2722 	unsigned i;
  2724 	for (i = j = 0; i < length; i++) {
  2725 		c = uri[i];
  2726 		if (c == '?') {
  2727 			if (decode_plus_ctl < 0)
  2728 				decode_plus = 1;
  2729 		} else if (c == '+' && decode_plus) {
  2730 			c = ' ';
  2731 		} else if (c == '%' && EVUTIL_ISXDIGIT(uri[i+1]) &&
  2732 		    EVUTIL_ISXDIGIT(uri[i+2])) {
  2733 			char tmp[3];
  2734 			tmp[0] = uri[i+1];
  2735 			tmp[1] = uri[i+2];
  2736 			tmp[2] = '\0';
  2737 			c = (char)strtol(tmp, NULL, 16);
  2738 			i += 2;
  2740 		ret[j++] = c;
  2742 	ret[j] = '\0';
  2744 	return (j);
  2747 /* deprecated */
  2748 char *
  2749 evhttp_decode_uri(const char *uri)
  2751 	char *ret;
  2753 	if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
  2754 		event_warn("%s: malloc(%lu)", __func__,
  2755 			  (unsigned long)(strlen(uri) + 1));
  2756 		return (NULL);
  2759 	evhttp_decode_uri_internal(uri, strlen(uri),
  2760 	    ret, -1 /*always_decode_plus*/);
  2762 	return (ret);
  2765 char *
  2766 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
  2768 	char *ret;
  2769 	int n;
  2771 	if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
  2772 		event_warn("%s: malloc(%lu)", __func__,
  2773 			  (unsigned long)(strlen(uri) + 1));
  2774 		return (NULL);
  2777 	n = evhttp_decode_uri_internal(uri, strlen(uri),
  2778 	    ret, !!decode_plus/*always_decode_plus*/);
  2780 	if (size_out) {
  2781 		EVUTIL_ASSERT(n >= 0);
  2782 		*size_out = (size_t)n;
  2785 	return (ret);
  2788 /*
  2789  * Helper function to parse out arguments in a query.
  2790  * The arguments are separated by key and value.
  2791  */
  2793 static int
  2794 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
  2795     int is_whole_uri)
  2797 	char *line=NULL;
  2798 	char *argument;
  2799 	char *p;
  2800 	const char *query_part;
  2801 	int result = -1;
  2802 	struct evhttp_uri *uri=NULL;
  2804 	TAILQ_INIT(headers);
  2806 	if (is_whole_uri) {
  2807 		uri = evhttp_uri_parse(str);
  2808 		if (!uri)
  2809 			goto error;
  2810 		query_part = evhttp_uri_get_query(uri);
  2811 	} else {
  2812 		query_part = str;
  2815 	/* No arguments - we are done */
  2816 	if (!query_part || !strlen(query_part)) {
  2817 		result = 0;
  2818 		goto done;
  2821 	if ((line = mm_strdup(query_part)) == NULL) {
  2822 		event_warn("%s: strdup", __func__);
  2823 		goto error;
  2826 	p = argument = line;
  2827 	while (p != NULL && *p != '\0') {
  2828 		char *key, *value, *decoded_value;
  2829 		argument = strsep(&p, "&");
  2831 		value = argument;
  2832 		key = strsep(&value, "=");
  2833 		if (value == NULL || *key == '\0') {
  2834 			goto error;
  2837 		if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
  2838 			event_warn("%s: mm_malloc", __func__);
  2839 			goto error;
  2841 		evhttp_decode_uri_internal(value, strlen(value),
  2842 		    decoded_value, 1 /*always_decode_plus*/);
  2843 		event_debug(("Query Param: %s -> %s\n", key, decoded_value));
  2844 		evhttp_add_header_internal(headers, key, decoded_value);
  2845 		mm_free(decoded_value);
  2848 	result = 0;
  2849 	goto done;
  2850 error:
  2851 	evhttp_clear_headers(headers);
  2852 done:
  2853 	if (line)
  2854 		mm_free(line);
  2855 	if (uri)
  2856 		evhttp_uri_free(uri);
  2857 	return result;
  2860 int
  2861 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
  2863 	return evhttp_parse_query_impl(uri, headers, 1);
  2865 int
  2866 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
  2868 	return evhttp_parse_query_impl(uri, headers, 0);
  2871 static struct evhttp_cb *
  2872 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
  2874 	struct evhttp_cb *cb;
  2875 	size_t offset = 0;
  2876 	char *translated;
  2877 	const char *path;
  2879 	/* Test for different URLs */
  2880 	path = evhttp_uri_get_path(req->uri_elems);
  2881 	offset = strlen(path);
  2882 	if ((translated = mm_malloc(offset + 1)) == NULL)
  2883 		return (NULL);
  2884 	evhttp_decode_uri_internal(path, offset, translated,
  2885 	    0 /* decode_plus */);
  2887 	TAILQ_FOREACH(cb, callbacks, next) {
  2888 		if (!strcmp(cb->what, translated)) {
  2889 			mm_free(translated);
  2890 			return (cb);
  2894 	mm_free(translated);
  2895 	return (NULL);
  2899 static int
  2900 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
  2902 	char c;
  2904 	while (1) {
  2905 		switch (c = *pattern++) {
  2906 		case '\0':
  2907 			return *name == '\0';
  2909 		case '*':
  2910 			while (*name != '\0') {
  2911 				if (prefix_suffix_match(pattern, name,
  2912 					ignorecase))
  2913 					return (1);
  2914 				++name;
  2916 			return (0);
  2917 		default:
  2918 			if (c != *name) {
  2919 				if (!ignorecase ||
  2920 				    EVUTIL_TOLOWER(c) != EVUTIL_TOLOWER(*name))
  2921 					return (0);
  2923 			++name;
  2926 	/* NOTREACHED */
  2929 /*
  2930    Search the vhost hierarchy beginning with http for a server alias
  2931    matching hostname.  If a match is found, and outhttp is non-null,
  2932    outhttp is set to the matching http object and 1 is returned.
  2933 */
  2935 static int
  2936 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
  2937 		  const char *hostname)
  2939 	struct evhttp_server_alias *alias;
  2940 	struct evhttp *vhost;
  2942 	TAILQ_FOREACH(alias, &http->aliases, next) {
  2943 		/* XXX Do we need to handle IP addresses? */
  2944 		if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
  2945 			if (outhttp)
  2946 				*outhttp = http;
  2947 			return 1;
  2951 	/* XXX It might be good to avoid recursion here, but I don't
  2952 	   see a way to do that w/o a list. */
  2953 	TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
  2954 		if (evhttp_find_alias(vhost, outhttp, hostname))
  2955 			return 1;
  2958 	return 0;
  2961 /*
  2962    Attempts to find the best http object to handle a request for a hostname.
  2963    All aliases for the root http object and vhosts are searched for an exact
  2964    match. Then, the vhost hierarchy is traversed again for a matching
  2965    pattern.
  2967    If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
  2968    is set with the best matching http object. If there are no matches, the
  2969    root http object is stored in outhttp and 0 is returned.
  2970 */
  2972 static int
  2973 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
  2974 		  const char *hostname)
  2976 	struct evhttp *vhost;
  2977 	struct evhttp *oldhttp;
  2978 	int match_found = 0;
  2980 	if (evhttp_find_alias(http, outhttp, hostname))
  2981 		return 1;
  2983 	do {
  2984 		oldhttp = http;
  2985 		TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
  2986 			if (prefix_suffix_match(vhost->vhost_pattern,
  2987 				hostname, 1 /* ignorecase */)) {
  2988 				http = vhost;
  2989 				match_found = 1;
  2990 				break;
  2993 	} while (oldhttp != http);
  2995 	if (outhttp)
  2996 		*outhttp = http;
  2998 	return match_found;
  3001 static void
  3002 evhttp_handle_request(struct evhttp_request *req, void *arg)
  3004 	struct evhttp *http = arg;
  3005 	struct evhttp_cb *cb = NULL;
  3006 	const char *hostname;
  3008 	/* we have a new request on which the user needs to take action */
  3009 	req->userdone = 0;
  3011 	if (req->type == 0 || req->uri == NULL) {
  3012 		evhttp_send_error(req, HTTP_BADREQUEST, NULL);
  3013 		return;
  3016 	if ((http->allowed_methods & req->type) == 0) {
  3017 		event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
  3018 			(unsigned)req->type, (unsigned)http->allowed_methods));
  3019 		evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
  3020 		return;
  3023 	/* handle potential virtual hosts */
  3024 	hostname = evhttp_request_get_host(req);
  3025 	if (hostname != NULL) {
  3026 		evhttp_find_vhost(http, &http, hostname);
  3029 	if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
  3030 		(*cb->cb)(req, cb->cbarg);
  3031 		return;
  3034 	/* Generic call back */
  3035 	if (http->gencb) {
  3036 		(*http->gencb)(req, http->gencbarg);
  3037 		return;
  3038 	} else {
  3039 		/* We need to send a 404 here */
  3040 #define ERR_FORMAT "<html><head>" \
  3041 		    "<title>404 Not Found</title>" \
  3042 		    "</head><body>" \
  3043 		    "<h1>Not Found</h1>" \
  3044 		    "<p>The requested URL %s was not found on this server.</p>"\
  3045 		    "</body></html>\n"
  3047 		char *escaped_html;
  3048 		struct evbuffer *buf;
  3050 		if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
  3051 			evhttp_connection_free(req->evcon);
  3052 			return;
  3055 		if ((buf = evbuffer_new()) == NULL) {
  3056 			mm_free(escaped_html);
  3057 			evhttp_connection_free(req->evcon);
  3058 			return;
  3061 		evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
  3063 		evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
  3065 		mm_free(escaped_html);
  3067 		evhttp_send_page(req, buf);
  3069 		evbuffer_free(buf);
  3070 #undef ERR_FORMAT
  3074 /* Listener callback when a connection arrives at a server. */
  3075 static void
  3076 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
  3078 	struct evhttp *http = arg;
  3080 	evhttp_get_request(http, nfd, peer_sa, peer_socklen);
  3083 int
  3084 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
  3086 	struct evhttp_bound_socket *bound =
  3087 		evhttp_bind_socket_with_handle(http, address, port);
  3088 	if (bound == NULL)
  3089 		return (-1);
  3090 	return (0);
  3093 struct evhttp_bound_socket *
  3094 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
  3096 	evutil_socket_t fd;
  3097 	struct evhttp_bound_socket *bound;
  3099 	if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
  3100 		return (NULL);
  3102 	if (listen(fd, 128) == -1) {
  3103 		event_sock_warn(fd, "%s: listen", __func__);
  3104 		evutil_closesocket(fd);
  3105 		return (NULL);
  3108 	bound = evhttp_accept_socket_with_handle(http, fd);
  3110 	if (bound != NULL) {
  3111 		event_debug(("Bound to port %d - Awaiting connections ... ",
  3112 			port));
  3113 		return (bound);
  3116 	return (NULL);
  3119 int
  3120 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
  3122 	struct evhttp_bound_socket *bound =
  3123 		evhttp_accept_socket_with_handle(http, fd);
  3124 	if (bound == NULL)
  3125 		return (-1);
  3126 	return (0);
  3130 struct evhttp_bound_socket *
  3131 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
  3133 	struct evhttp_bound_socket *bound;
  3134 	struct evconnlistener *listener;
  3135 	const int flags =
  3136 	    LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
  3138 	listener = evconnlistener_new(http->base, NULL, NULL,
  3139 	    flags,
  3140 	    0, /* Backlog is '0' because we already said 'listen' */
  3141 	    fd);
  3142 	if (!listener)
  3143 		return (NULL);
  3145 	bound = evhttp_bind_listener(http, listener);
  3146 	if (!bound) {
  3147 		evconnlistener_free(listener);
  3148 		return (NULL);
  3150 	return (bound);
  3153 struct evhttp_bound_socket *
  3154 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
  3156 	struct evhttp_bound_socket *bound;
  3158 	bound = mm_malloc(sizeof(struct evhttp_bound_socket));
  3159 	if (bound == NULL)
  3160 		return (NULL);
  3162 	bound->listener = listener;
  3163 	TAILQ_INSERT_TAIL(&http->sockets, bound, next);
  3165 	evconnlistener_set_cb(listener, accept_socket_cb, http);
  3166 	return bound;
  3169 evutil_socket_t
  3170 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
  3172 	return evconnlistener_get_fd(bound->listener);
  3175 struct evconnlistener *
  3176 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
  3178 	return bound->listener;
  3181 void
  3182 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
  3184 	TAILQ_REMOVE(&http->sockets, bound, next);
  3185 	evconnlistener_free(bound->listener);
  3186 	mm_free(bound);
  3189 static struct evhttp*
  3190 evhttp_new_object(void)
  3192 	struct evhttp *http = NULL;
  3194 	if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
  3195 		event_warn("%s: calloc", __func__);
  3196 		return (NULL);
  3199 	http->timeout = -1;
  3200 	evhttp_set_max_headers_size(http, EV_SIZE_MAX);
  3201 	evhttp_set_max_body_size(http, EV_SIZE_MAX);
  3202 	evhttp_set_allowed_methods(http,
  3203 	    EVHTTP_REQ_GET |
  3204 	    EVHTTP_REQ_POST |
  3205 	    EVHTTP_REQ_HEAD |
  3206 	    EVHTTP_REQ_PUT |
  3207 	    EVHTTP_REQ_DELETE);
  3209 	TAILQ_INIT(&http->sockets);
  3210 	TAILQ_INIT(&http->callbacks);
  3211 	TAILQ_INIT(&http->connections);
  3212 	TAILQ_INIT(&http->virtualhosts);
  3213 	TAILQ_INIT(&http->aliases);
  3215 	return (http);
  3218 struct evhttp *
  3219 evhttp_new(struct event_base *base)
  3221 	struct evhttp *http = NULL;
  3223 	http = evhttp_new_object();
  3224 	if (http == NULL)
  3225 		return (NULL);
  3226 	http->base = base;
  3228 	return (http);
  3231 /*
  3232  * Start a web server on the specified address and port.
  3233  */
  3235 struct evhttp *
  3236 evhttp_start(const char *address, unsigned short port)
  3238 	struct evhttp *http = NULL;
  3240 	http = evhttp_new_object();
  3241 	if (http == NULL)
  3242 		return (NULL);
  3243 	if (evhttp_bind_socket(http, address, port) == -1) {
  3244 		mm_free(http);
  3245 		return (NULL);
  3248 	return (http);
  3251 void
  3252 evhttp_free(struct evhttp* http)
  3254 	struct evhttp_cb *http_cb;
  3255 	struct evhttp_connection *evcon;
  3256 	struct evhttp_bound_socket *bound;
  3257 	struct evhttp* vhost;
  3258 	struct evhttp_server_alias *alias;
  3260 	/* Remove the accepting part */
  3261 	while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
  3262 		TAILQ_REMOVE(&http->sockets, bound, next);
  3264 		evconnlistener_free(bound->listener);
  3266 		mm_free(bound);
  3269 	while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
  3270 		/* evhttp_connection_free removes the connection */
  3271 		evhttp_connection_free(evcon);
  3274 	while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
  3275 		TAILQ_REMOVE(&http->callbacks, http_cb, next);
  3276 		mm_free(http_cb->what);
  3277 		mm_free(http_cb);
  3280 	while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
  3281 		TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
  3283 		evhttp_free(vhost);
  3286 	if (http->vhost_pattern != NULL)
  3287 		mm_free(http->vhost_pattern);
  3289 	while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
  3290 		TAILQ_REMOVE(&http->aliases, alias, next);
  3291 		mm_free(alias->alias);
  3292 		mm_free(alias);
  3295 	mm_free(http);
  3298 int
  3299 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
  3300     struct evhttp* vhost)
  3302 	/* a vhost can only be a vhost once and should not have bound sockets */
  3303 	if (vhost->vhost_pattern != NULL ||
  3304 	    TAILQ_FIRST(&vhost->sockets) != NULL)
  3305 		return (-1);
  3307 	vhost->vhost_pattern = mm_strdup(pattern);
  3308 	if (vhost->vhost_pattern == NULL)
  3309 		return (-1);
  3311 	TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
  3313 	return (0);
  3316 int
  3317 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
  3319 	if (vhost->vhost_pattern == NULL)
  3320 		return (-1);
  3322 	TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
  3324 	mm_free(vhost->vhost_pattern);
  3325 	vhost->vhost_pattern = NULL;
  3327 	return (0);
  3330 int
  3331 evhttp_add_server_alias(struct evhttp *http, const char *alias)
  3333 	struct evhttp_server_alias *evalias;
  3335 	evalias = mm_calloc(1, sizeof(*evalias));
  3336 	if (!evalias)
  3337 		return -1;
  3339 	evalias->alias = mm_strdup(alias);
  3340 	if (!evalias->alias) {
  3341 		mm_free(evalias);
  3342 		return -1;
  3345 	TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
  3347 	return 0;
  3350 int
  3351 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
  3353 	struct evhttp_server_alias *evalias;
  3355 	TAILQ_FOREACH(evalias, &http->aliases, next) {
  3356 		if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
  3357 			TAILQ_REMOVE(&http->aliases, evalias, next);
  3358 			mm_free(evalias->alias);
  3359 			mm_free(evalias);
  3360 			return 0;
  3364 	return -1;
  3367 void
  3368 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
  3370 	http->timeout = timeout_in_secs;
  3373 void
  3374 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
  3376 	if (max_headers_size < 0)
  3377 		http->default_max_headers_size = EV_SIZE_MAX;
  3378 	else
  3379 		http->default_max_headers_size = max_headers_size;
  3382 void
  3383 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
  3385 	if (max_body_size < 0)
  3386 		http->default_max_body_size = EV_UINT64_MAX;
  3387 	else
  3388 		http->default_max_body_size = max_body_size;
  3391 void
  3392 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
  3394 	http->allowed_methods = methods;
  3397 int
  3398 evhttp_set_cb(struct evhttp *http, const char *uri,
  3399     void (*cb)(struct evhttp_request *, void *), void *cbarg)
  3401 	struct evhttp_cb *http_cb;
  3403 	TAILQ_FOREACH(http_cb, &http->callbacks, next) {
  3404 		if (strcmp(http_cb->what, uri) == 0)
  3405 			return (-1);
  3408 	if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
  3409 		event_warn("%s: calloc", __func__);
  3410 		return (-2);
  3413 	http_cb->what = mm_strdup(uri);
  3414 	if (http_cb->what == NULL) {
  3415 		event_warn("%s: strdup", __func__);
  3416 		mm_free(http_cb);
  3417 		return (-3);
  3419 	http_cb->cb = cb;
  3420 	http_cb->cbarg = cbarg;
  3422 	TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
  3424 	return (0);
  3427 int
  3428 evhttp_del_cb(struct evhttp *http, const char *uri)
  3430 	struct evhttp_cb *http_cb;
  3432 	TAILQ_FOREACH(http_cb, &http->callbacks, next) {
  3433 		if (strcmp(http_cb->what, uri) == 0)
  3434 			break;
  3436 	if (http_cb == NULL)
  3437 		return (-1);
  3439 	TAILQ_REMOVE(&http->callbacks, http_cb, next);
  3440 	mm_free(http_cb->what);
  3441 	mm_free(http_cb);
  3443 	return (0);
  3446 void
  3447 evhttp_set_gencb(struct evhttp *http,
  3448     void (*cb)(struct evhttp_request *, void *), void *cbarg)
  3450 	http->gencb = cb;
  3451 	http->gencbarg = cbarg;
  3454 /*
  3455  * Request related functions
  3456  */
  3458 struct evhttp_request *
  3459 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
  3461 	struct evhttp_request *req = NULL;
  3463 	/* Allocate request structure */
  3464 	if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
  3465 		event_warn("%s: calloc", __func__);
  3466 		goto error;
  3469 	req->headers_size = 0;
  3470 	req->body_size = 0;
  3472 	req->kind = EVHTTP_RESPONSE;
  3473 	req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
  3474 	if (req->input_headers == NULL) {
  3475 		event_warn("%s: calloc", __func__);
  3476 		goto error;
  3478 	TAILQ_INIT(req->input_headers);
  3480 	req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
  3481 	if (req->output_headers == NULL) {
  3482 		event_warn("%s: calloc", __func__);
  3483 		goto error;
  3485 	TAILQ_INIT(req->output_headers);
  3487 	if ((req->input_buffer = evbuffer_new()) == NULL) {
  3488 		event_warn("%s: evbuffer_new", __func__);
  3489 		goto error;
  3492 	if ((req->output_buffer = evbuffer_new()) == NULL) {
  3493 		event_warn("%s: evbuffer_new", __func__);
  3494 		goto error;
  3497 	req->cb = cb;
  3498 	req->cb_arg = arg;
  3500 	return (req);
  3502  error:
  3503 	if (req != NULL)
  3504 		evhttp_request_free(req);
  3505 	return (NULL);
  3508 void
  3509 evhttp_request_free(struct evhttp_request *req)
  3511 	if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
  3512 		req->flags |= EVHTTP_REQ_NEEDS_FREE;
  3513 		return;
  3516 	if (req->remote_host != NULL)
  3517 		mm_free(req->remote_host);
  3518 	if (req->uri != NULL)
  3519 		mm_free(req->uri);
  3520 	if (req->uri_elems != NULL)
  3521 		evhttp_uri_free(req->uri_elems);
  3522 	if (req->response_code_line != NULL)
  3523 		mm_free(req->response_code_line);
  3524 	if (req->host_cache != NULL)
  3525 		mm_free(req->host_cache);
  3527 	evhttp_clear_headers(req->input_headers);
  3528 	mm_free(req->input_headers);
  3530 	evhttp_clear_headers(req->output_headers);
  3531 	mm_free(req->output_headers);
  3533 	if (req->input_buffer != NULL)
  3534 		evbuffer_free(req->input_buffer);
  3536 	if (req->output_buffer != NULL)
  3537 		evbuffer_free(req->output_buffer);
  3539 	mm_free(req);
  3542 void
  3543 evhttp_request_own(struct evhttp_request *req)
  3545 	req->flags |= EVHTTP_USER_OWNED;
  3548 int
  3549 evhttp_request_is_owned(struct evhttp_request *req)
  3551 	return (req->flags & EVHTTP_USER_OWNED) != 0;
  3554 struct evhttp_connection *
  3555 evhttp_request_get_connection(struct evhttp_request *req)
  3557 	return req->evcon;
  3560 struct event_base *
  3561 evhttp_connection_get_base(struct evhttp_connection *conn)
  3563 	return conn->base;
  3566 void
  3567 evhttp_request_set_chunked_cb(struct evhttp_request *req,
  3568     void (*cb)(struct evhttp_request *, void *))
  3570 	req->chunk_cb = cb;
  3573 /*
  3574  * Allows for inspection of the request URI
  3575  */
  3577 const char *
  3578 evhttp_request_get_uri(const struct evhttp_request *req) {
  3579 	if (req->uri == NULL)
  3580 		event_debug(("%s: request %p has no uri\n", __func__, req));
  3581 	return (req->uri);
  3584 const struct evhttp_uri *
  3585 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
  3586 	if (req->uri_elems == NULL)
  3587 		event_debug(("%s: request %p has no uri elems\n",
  3588 			    __func__, req));
  3589 	return (req->uri_elems);
  3592 const char *
  3593 evhttp_request_get_host(struct evhttp_request *req)
  3595 	const char *host = NULL;
  3597 	if (req->host_cache)
  3598 		return req->host_cache;
  3600 	if (req->uri_elems)
  3601 		host = evhttp_uri_get_host(req->uri_elems);
  3602 	if (!host && req->input_headers) {
  3603 		const char *p;
  3604 		size_t len;
  3606 		host = evhttp_find_header(req->input_headers, "Host");
  3607 		/* The Host: header may include a port. Remove it here
  3608 		   to be consistent with uri_elems case above. */
  3609 		if (host) {
  3610 			p = host + strlen(host) - 1;
  3611 			while (p > host && EVUTIL_ISDIGIT(*p))
  3612 				--p;
  3613 			if (p > host && *p == ':') {
  3614 				len = p - host;
  3615 				req->host_cache = mm_malloc(len + 1);
  3616 				if (!req->host_cache) {
  3617 					event_warn("%s: malloc", __func__);
  3618 					return NULL;
  3620 				memcpy(req->host_cache, host, len);
  3621 				req->host_cache[len] = '\0';
  3622 				host = req->host_cache;
  3627 	return host;
  3630 enum evhttp_cmd_type
  3631 evhttp_request_get_command(const struct evhttp_request *req) {
  3632 	return (req->type);
  3635 int
  3636 evhttp_request_get_response_code(const struct evhttp_request *req)
  3638 	return req->response_code;
  3641 /** Returns the input headers */
  3642 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
  3644 	return (req->input_headers);
  3647 /** Returns the output headers */
  3648 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
  3650 	return (req->output_headers);
  3653 /** Returns the input buffer */
  3654 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
  3656 	return (req->input_buffer);
  3659 /** Returns the output buffer */
  3660 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
  3662 	return (req->output_buffer);
  3666 /*
  3667  * Takes a file descriptor to read a request from.
  3668  * The callback is executed once the whole request has been read.
  3669  */
  3671 static struct evhttp_connection*
  3672 evhttp_get_request_connection(
  3673 	struct evhttp* http,
  3674 	evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
  3676 	struct evhttp_connection *evcon;
  3677 	char *hostname = NULL, *portname = NULL;
  3679 	name_from_addr(sa, salen, &hostname, &portname);
  3680 	if (hostname == NULL || portname == NULL) {
  3681 		if (hostname) mm_free(hostname);
  3682 		if (portname) mm_free(portname);
  3683 		return (NULL);
  3686 	event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
  3687 		__func__, hostname, portname, EV_SOCK_ARG(fd)));
  3689 	/* we need a connection object to put the http request on */
  3690 	evcon = evhttp_connection_base_new(
  3691 		http->base, NULL, hostname, atoi(portname));
  3692 	mm_free(hostname);
  3693 	mm_free(portname);
  3694 	if (evcon == NULL)
  3695 		return (NULL);
  3697 	evcon->max_headers_size = http->default_max_headers_size;
  3698 	evcon->max_body_size = http->default_max_body_size;
  3700 	evcon->flags |= EVHTTP_CON_INCOMING;
  3701 	evcon->state = EVCON_READING_FIRSTLINE;
  3703 	evcon->fd = fd;
  3705 	bufferevent_setfd(evcon->bufev, fd);
  3707 	return (evcon);
  3710 static int
  3711 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
  3713 	struct evhttp *http = evcon->http_server;
  3714 	struct evhttp_request *req;
  3715 	if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
  3716 		return (-1);
  3718 	if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
  3719 		event_warn("%s: strdup", __func__);
  3720 		evhttp_request_free(req);
  3721 		return (-1);
  3723 	req->remote_port = evcon->port;
  3725 	req->evcon = evcon;	/* the request ends up owning the connection */
  3726 	req->flags |= EVHTTP_REQ_OWN_CONNECTION;
  3728 	/* We did not present the request to the user user yet, so treat it as
  3729 	 * if the user was done with the request.  This allows us to free the
  3730 	 * request on a persistent connection if the client drops it without
  3731 	 * sending a request.
  3732 	 */
  3733 	req->userdone = 1;
  3735 	TAILQ_INSERT_TAIL(&evcon->requests, req, next);
  3737 	req->kind = EVHTTP_REQUEST;
  3740 	evhttp_start_read(evcon);
  3742 	return (0);
  3745 static void
  3746 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
  3747     struct sockaddr *sa, ev_socklen_t salen)
  3749 	struct evhttp_connection *evcon;
  3751 	evcon = evhttp_get_request_connection(http, fd, sa, salen);
  3752 	if (evcon == NULL) {
  3753 		event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
  3754 		    __func__, EV_SOCK_ARG(fd));
  3755 		evutil_closesocket(fd);
  3756 		return;
  3759 	/* the timeout can be used by the server to close idle connections */
  3760 	if (http->timeout != -1)
  3761 		evhttp_connection_set_timeout(evcon, http->timeout);
  3763 	/*
  3764 	 * if we want to accept more than one request on a connection,
  3765 	 * we need to know which http server it belongs to.
  3766 	 */
  3767 	evcon->http_server = http;
  3768 	TAILQ_INSERT_TAIL(&http->connections, evcon, next);
  3770 	if (evhttp_associate_new_request_with_connection(evcon) == -1)
  3771 		evhttp_connection_free(evcon);
  3775 /*
  3776  * Network helper functions that we do not want to export to the rest of
  3777  * the world.
  3778  */
  3780 static void
  3781 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
  3782     char **phost, char **pport)
  3784 	char ntop[NI_MAXHOST];
  3785 	char strport[NI_MAXSERV];
  3786 	int ni_result;
  3788 #ifdef _EVENT_HAVE_GETNAMEINFO
  3789 	ni_result = getnameinfo(sa, salen,
  3790 		ntop, sizeof(ntop), strport, sizeof(strport),
  3791 		NI_NUMERICHOST|NI_NUMERICSERV);
  3793 	if (ni_result != 0) {
  3794 #ifdef EAI_SYSTEM
  3795 		/* Windows doesn't have an EAI_SYSTEM. */
  3796 		if (ni_result == EAI_SYSTEM)
  3797 			event_err(1, "getnameinfo failed");
  3798 		else
  3799 #endif
  3800 			event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
  3801 		return;
  3803 #else
  3804 	ni_result = fake_getnameinfo(sa, salen,
  3805 		ntop, sizeof(ntop), strport, sizeof(strport),
  3806 		NI_NUMERICHOST|NI_NUMERICSERV);
  3807 	if (ni_result != 0)
  3808 			return;
  3809 #endif
  3811 	*phost = mm_strdup(ntop);
  3812 	*pport = mm_strdup(strport);
  3815 /* Create a non-blocking socket and bind it */
  3816 /* todo: rename this function */
  3817 static evutil_socket_t
  3818 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
  3820 	evutil_socket_t fd;
  3822 	int on = 1, r;
  3823 	int serrno;
  3825 	/* Create listen socket */
  3826 	fd = socket(ai ? ai->ai_family : AF_INET, SOCK_STREAM, 0);
  3827 	if (fd == -1) {
  3828 			event_sock_warn(-1, "socket");
  3829 			return (-1);
  3832 	if (evutil_make_socket_nonblocking(fd) < 0)
  3833 		goto out;
  3834 	if (evutil_make_socket_closeonexec(fd) < 0)
  3835 		goto out;
  3837 	if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
  3838 		goto out;
  3839 	if (reuse) {
  3840 		if (evutil_make_listen_socket_reuseable(fd) < 0)
  3841 			goto out;
  3844 	if (ai != NULL) {
  3845 		r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
  3846 		if (r == -1)
  3847 			goto out;
  3850 	return (fd);
  3852  out:
  3853 	serrno = EVUTIL_SOCKET_ERROR();
  3854 	evutil_closesocket(fd);
  3855 	EVUTIL_SET_SOCKET_ERROR(serrno);
  3856 	return (-1);
  3859 static struct evutil_addrinfo *
  3860 make_addrinfo(const char *address, ev_uint16_t port)
  3862 	struct evutil_addrinfo *ai = NULL;
  3864 	struct evutil_addrinfo hints;
  3865 	char strport[NI_MAXSERV];
  3866 	int ai_result;
  3868 	memset(&hints, 0, sizeof(hints));
  3869 	hints.ai_family = AF_UNSPEC;
  3870 	hints.ai_socktype = SOCK_STREAM;
  3871 	/* turn NULL hostname into INADDR_ANY, and skip looking up any address
  3872 	 * types we don't have an interface to connect to. */
  3873 	hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
  3874 	evutil_snprintf(strport, sizeof(strport), "%d", port);
  3875 	if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
  3876 	    != 0) {
  3877 		if (ai_result == EVUTIL_EAI_SYSTEM)
  3878 			event_warn("getaddrinfo");
  3879 		else
  3880 			event_warnx("getaddrinfo: %s",
  3881 			    evutil_gai_strerror(ai_result));
  3882 		return (NULL);
  3885 	return (ai);
  3888 static evutil_socket_t
  3889 bind_socket(const char *address, ev_uint16_t port, int reuse)
  3891 	evutil_socket_t fd;
  3892 	struct evutil_addrinfo *aitop = NULL;
  3894 	/* just create an unbound socket */
  3895 	if (address == NULL && port == 0)
  3896 		return bind_socket_ai(NULL, 0);
  3898 	aitop = make_addrinfo(address, port);
  3900 	if (aitop == NULL)
  3901 		return (-1);
  3903 	fd = bind_socket_ai(aitop, reuse);
  3905 	evutil_freeaddrinfo(aitop);
  3907 	return (fd);
  3910 struct evhttp_uri {
  3911 	unsigned flags;
  3912 	char *scheme; /* scheme; e.g http, ftp etc */
  3913 	char *userinfo; /* userinfo (typically username:pass), or NULL */
  3914 	char *host; /* hostname, IP address, or NULL */
  3915 	int port; /* port, or zero */
  3916 	char *path; /* path, or "". */
  3917 	char *query; /* query, or NULL */
  3918 	char *fragment; /* fragment or NULL */
  3919 };
  3921 struct evhttp_uri *
  3922 evhttp_uri_new(void)
  3924 	struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
  3925 	if (uri)
  3926 		uri->port = -1;
  3927 	return uri;
  3930 void
  3931 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
  3933 	uri->flags = flags;
  3936 /* Return true if the string starting at s and ending immediately before eos
  3937  * is a valid URI scheme according to RFC3986
  3938  */
  3939 static int
  3940 scheme_ok(const char *s, const char *eos)
  3942 	/* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
  3943 	EVUTIL_ASSERT(eos >= s);
  3944 	if (s == eos)
  3945 		return 0;
  3946 	if (!EVUTIL_ISALPHA(*s))
  3947 		return 0;
  3948 	while (++s < eos) {
  3949 		if (! EVUTIL_ISALNUM(*s) &&
  3950 		    *s != '+' && *s != '-' && *s != '.')
  3951 			return 0;
  3953 	return 1;
  3956 #define SUBDELIMS "!$&'()*+,;="
  3958 /* Return true iff [s..eos) is a valid userinfo */
  3959 static int
  3960 userinfo_ok(const char *s, const char *eos)
  3962 	while (s < eos) {
  3963 		if (CHAR_IS_UNRESERVED(*s) ||
  3964 		    strchr(SUBDELIMS, *s) ||
  3965 		    *s == ':')
  3966 			++s;
  3967 		else if (*s == '%' && s+2 < eos &&
  3968 		    EVUTIL_ISXDIGIT(s[1]) &&
  3969 		    EVUTIL_ISXDIGIT(s[2]))
  3970 			s += 3;
  3971 		else
  3972 			return 0;
  3974 	return 1;
  3977 static int
  3978 regname_ok(const char *s, const char *eos)
  3980 	while (s && s<eos) {
  3981 		if (CHAR_IS_UNRESERVED(*s) ||
  3982 		    strchr(SUBDELIMS, *s))
  3983 			++s;
  3984 		else if (*s == '%' &&
  3985 		    EVUTIL_ISXDIGIT(s[1]) &&
  3986 		    EVUTIL_ISXDIGIT(s[2]))
  3987 			s += 3;
  3988 		else
  3989 			return 0;
  3991 	return 1;
  3994 static int
  3995 parse_port(const char *s, const char *eos)
  3997 	int portnum = 0;
  3998 	while (s < eos) {
  3999 		if (! EVUTIL_ISDIGIT(*s))
  4000 			return -1;
  4001 		portnum = (portnum * 10) + (*s - '0');
  4002 		if (portnum < 0)
  4003 			return -1;
  4004 		++s;
  4006 	return portnum;
  4009 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
  4010 static int
  4011 bracket_addr_ok(const char *s, const char *eos)
  4013 	if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
  4014 		return 0;
  4015 	if (s[1] == 'v') {
  4016 		/* IPvFuture, or junk.
  4017 		   "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
  4018 		 */
  4019 		s += 2; /* skip [v */
  4020 		--eos;
  4021 		if (!EVUTIL_ISXDIGIT(*s)) /*require at least one*/
  4022 			return 0;
  4023 		while (s < eos && *s != '.') {
  4024 			if (EVUTIL_ISXDIGIT(*s))
  4025 				++s;
  4026 			else
  4027 				return 0;
  4029 		if (*s != '.')
  4030 			return 0;
  4031 		++s;
  4032 		while (s < eos) {
  4033 			if (CHAR_IS_UNRESERVED(*s) ||
  4034 			    strchr(SUBDELIMS, *s) ||
  4035 			    *s == ':')
  4036 				++s;
  4037 			else
  4038 				return 0;
  4040 		return 2;
  4041 	} else {
  4042 		/* IPv6, or junk */
  4043 		char buf[64];
  4044 		ev_ssize_t n_chars = eos-s-2;
  4045 		struct in6_addr in6;
  4046 		if (n_chars >= 64) /* way too long */
  4047 			return 0;
  4048 		memcpy(buf, s+1, n_chars);
  4049 		buf[n_chars]='\0';
  4050 		return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
  4054 static int
  4055 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
  4057 	char *cp, *port;
  4058 	EVUTIL_ASSERT(eos);
  4059 	if (eos == s) {
  4060 		uri->host = mm_strdup("");
  4061 		if (uri->host == NULL) {
  4062 			event_warn("%s: strdup", __func__);
  4063 			return -1;
  4065 		return 0;
  4068 	/* Optionally, we start with "userinfo@" */
  4070 	cp = strchr(s, '@');
  4071 	if (cp && cp < eos) {
  4072 		if (! userinfo_ok(s,cp))
  4073 			return -1;
  4074 		*cp++ = '\0';
  4075 		uri->userinfo = mm_strdup(s);
  4076 		if (uri->userinfo == NULL) {
  4077 			event_warn("%s: strdup", __func__);
  4078 			return -1;
  4080 	} else {
  4081 		cp = s;
  4083 	/* Optionally, we end with ":port" */
  4084 	for (port=eos-1; port >= cp && EVUTIL_ISDIGIT(*port); --port)
  4086 	if (port >= cp && *port == ':') {
  4087 		if (port+1 == eos) /* Leave port unspecified; the RFC allows a
  4088 				    * nil port */
  4089 			uri->port = -1;
  4090 		else if ((uri->port = parse_port(port+1, eos))<0)
  4091 			return -1;
  4092 		eos = port;
  4094 	/* Now, cp..eos holds the "host" port, which can be an IPv4Address,
  4095 	 * an IP-Literal, or a reg-name */
  4096 	EVUTIL_ASSERT(eos >= cp);
  4097 	if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
  4098 		/* IPv6address, IP-Literal, or junk. */
  4099 		if (! bracket_addr_ok(cp, eos))
  4100 			return -1;
  4101 	} else {
  4102 		/* Make sure the host part is ok. */
  4103 		if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
  4104 			return -1;
  4106 	uri->host = mm_malloc(eos-cp+1);
  4107 	if (uri->host == NULL) {
  4108 		event_warn("%s: malloc", __func__);
  4109 		return -1;
  4111 	memcpy(uri->host, cp, eos-cp);
  4112 	uri->host[eos-cp] = '\0';
  4113 	return 0;
  4117 static char *
  4118 end_of_authority(char *cp)
  4120 	while (*cp) {
  4121 		if (*cp == '?' || *cp == '#' || *cp == '/')
  4122 			return cp;
  4123 		++cp;
  4125 	return cp;
  4128 enum uri_part {
  4129 	PART_PATH,
  4130 	PART_QUERY,
  4131 	PART_FRAGMENT
  4132 };
  4134 /* Return the character after the longest prefix of 'cp' that matches...
  4135  *   *pchar / "/" if allow_qchars is false, or
  4136  *   *(pchar / "/" / "?") if allow_qchars is true.
  4137  */
  4138 static char *
  4139 end_of_path(char *cp, enum uri_part part, unsigned flags)
  4141 	if (flags & EVHTTP_URI_NONCONFORMANT) {
  4142 		/* If NONCONFORMANT:
  4143 		 *   Path is everything up to a # or ? or nul.
  4144 		 *   Query is everything up a # or nul
  4145 		 *   Fragment is everything up to a nul.
  4146 		 */
  4147 		switch (part) {
  4148 		case PART_PATH:
  4149 			while (*cp && *cp != '#' && *cp != '?')
  4150 				++cp;
  4151 			break;
  4152 		case PART_QUERY:
  4153 			while (*cp && *cp != '#')
  4154 				++cp;
  4155 			break;
  4156 		case PART_FRAGMENT:
  4157 			cp += strlen(cp);
  4158 			break;
  4159 		};
  4160 		return cp;
  4163 	while (*cp) {
  4164 		if (CHAR_IS_UNRESERVED(*cp) ||
  4165 		    strchr(SUBDELIMS, *cp) ||
  4166 		    *cp == ':' || *cp == '@' || *cp == '/')
  4167 			++cp;
  4168 		else if (*cp == '%' && EVUTIL_ISXDIGIT(cp[1]) &&
  4169 		    EVUTIL_ISXDIGIT(cp[2]))
  4170 			cp += 3;
  4171 		else if (*cp == '?' && part != PART_PATH)
  4172 			++cp;
  4173 		else
  4174 			return cp;
  4176 	return cp;
  4179 static int
  4180 path_matches_noscheme(const char *cp)
  4182 	while (*cp) {
  4183 		if (*cp == ':')
  4184 			return 0;
  4185 		else if (*cp == '/')
  4186 			return 1;
  4187 		++cp;
  4189 	return 1;
  4192 struct evhttp_uri *
  4193 evhttp_uri_parse(const char *source_uri)
  4195 	return evhttp_uri_parse_with_flags(source_uri, 0);
  4198 struct evhttp_uri *
  4199 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
  4201 	char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
  4202 	char *path = NULL, *fragment = NULL;
  4203 	int got_authority = 0;
  4205 	struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
  4206 	if (uri == NULL) {
  4207 		event_warn("%s: calloc", __func__);
  4208 		goto err;
  4210 	uri->port = -1;
  4211 	uri->flags = flags;
  4213 	readbuf = mm_strdup(source_uri);
  4214 	if (readbuf == NULL) {
  4215 		event_warn("%s: strdup", __func__);
  4216 		goto err;
  4219 	readp = readbuf;
  4220 	token = NULL;
  4222 	/* We try to follow RFC3986 here as much as we can, and match
  4223 	   the productions
  4225 	      URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
  4227 	      relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
  4228 	 */
  4230 	/* 1. scheme: */
  4231 	token = strchr(readp, ':');
  4232 	if (token && scheme_ok(readp,token)) {
  4233 		*token = '\0';
  4234 		uri->scheme = mm_strdup(readp);
  4235 		if (uri->scheme == NULL) {
  4236 			event_warn("%s: strdup", __func__);
  4237 			goto err;
  4239 		readp = token+1; /* eat : */
  4242 	/* 2. Optionally, "//" then an 'authority' part. */
  4243 	if (readp[0]=='/' && readp[1] == '/') {
  4244 		char *authority;
  4245 		readp += 2;
  4246 		authority = readp;
  4247 		path = end_of_authority(readp);
  4248 		if (parse_authority(uri, authority, path) < 0)
  4249 			goto err;
  4250 		readp = path;
  4251 		got_authority = 1;
  4254 	/* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
  4255 	 */
  4256 	path = readp;
  4257 	readp = end_of_path(path, PART_PATH, flags);
  4259 	/* Query */
  4260 	if (*readp == '?') {
  4261 		*readp = '\0';
  4262 		++readp;
  4263 		query = readp;
  4264 		readp = end_of_path(readp, PART_QUERY, flags);
  4266 	/* fragment */
  4267 	if (*readp == '#') {
  4268 		*readp = '\0';
  4269 		++readp;
  4270 		fragment = readp;
  4271 		readp = end_of_path(readp, PART_FRAGMENT, flags);
  4273 	if (*readp != '\0') {
  4274 		goto err;
  4277 	/* These next two cases may be unreachable; I'm leaving them
  4278 	 * in to be defensive. */
  4279 	/* If you didn't get an authority, the path can't begin with "//" */
  4280 	if (!got_authority && path[0]=='/' && path[1]=='/')
  4281 		goto err;
  4282 	/* If you did get an authority, the path must begin with "/" or be
  4283 	 * empty. */
  4284 	if (got_authority && path[0] != '/' && path[0] != '\0')
  4285 		goto err;
  4286 	/* (End of maybe-unreachable cases) */
  4288 	/* If there was no scheme, the first part of the path (if any) must
  4289 	 * have no colon in it. */
  4290 	if (! uri->scheme && !path_matches_noscheme(path))
  4291 		goto err;
  4293 	EVUTIL_ASSERT(path);
  4294 	uri->path = mm_strdup(path);
  4295 	if (uri->path == NULL) {
  4296 		event_warn("%s: strdup", __func__);
  4297 		goto err;
  4300 	if (query) {
  4301 		uri->query = mm_strdup(query);
  4302 		if (uri->query == NULL) {
  4303 			event_warn("%s: strdup", __func__);
  4304 			goto err;
  4307 	if (fragment) {
  4308 		uri->fragment = mm_strdup(fragment);
  4309 		if (uri->fragment == NULL) {
  4310 			event_warn("%s: strdup", __func__);
  4311 			goto err;
  4315 	mm_free(readbuf);
  4317 	return uri;
  4318 err:
  4319 	if (uri)
  4320 		evhttp_uri_free(uri);
  4321 	if (readbuf)
  4322 		mm_free(readbuf);
  4323 	return NULL;
  4326 void
  4327 evhttp_uri_free(struct evhttp_uri *uri)
  4329 #define _URI_FREE_STR(f)		\
  4330 	if (uri->f) {			\
  4331 		mm_free(uri->f);		\
  4334 	_URI_FREE_STR(scheme);
  4335 	_URI_FREE_STR(userinfo);
  4336 	_URI_FREE_STR(host);
  4337 	_URI_FREE_STR(path);
  4338 	_URI_FREE_STR(query);
  4339 	_URI_FREE_STR(fragment);
  4341 	mm_free(uri);
  4342 #undef _URI_FREE_STR
  4345 char *
  4346 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
  4348 	struct evbuffer *tmp = 0;
  4349 	size_t joined_size = 0;
  4350 	char *output = NULL;
  4352 #define _URI_ADD(f)	evbuffer_add(tmp, uri->f, strlen(uri->f))
  4354 	if (!uri || !buf || !limit)
  4355 		return NULL;
  4357 	tmp = evbuffer_new();
  4358 	if (!tmp)
  4359 		return NULL;
  4361 	if (uri->scheme) {
  4362 		_URI_ADD(scheme);
  4363 		evbuffer_add(tmp, ":", 1);
  4365 	if (uri->host) {
  4366 		evbuffer_add(tmp, "//", 2);
  4367 		if (uri->userinfo)
  4368 			evbuffer_add_printf(tmp,"%s@", uri->userinfo);
  4369 		_URI_ADD(host);
  4370 		if (uri->port >= 0)
  4371 			evbuffer_add_printf(tmp,":%d", uri->port);
  4373 		if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
  4374 			goto err;
  4377 	if (uri->path)
  4378 		_URI_ADD(path);
  4380 	if (uri->query) {
  4381 		evbuffer_add(tmp, "?", 1);
  4382 		_URI_ADD(query);
  4385 	if (uri->fragment) {
  4386 		evbuffer_add(tmp, "#", 1);
  4387 		_URI_ADD(fragment);
  4390 	evbuffer_add(tmp, "\0", 1); /* NUL */
  4392 	joined_size = evbuffer_get_length(tmp);
  4394 	if (joined_size > limit) {
  4395 		/* It doesn't fit. */
  4396 		evbuffer_free(tmp);
  4397 		return NULL;
  4399        	evbuffer_remove(tmp, buf, joined_size);
  4401 	output = buf;
  4402 err:
  4403 	evbuffer_free(tmp);
  4405 	return output;
  4406 #undef _URI_ADD
  4409 const char *
  4410 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
  4412 	return uri->scheme;
  4414 const char *
  4415 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
  4417 	return uri->userinfo;
  4419 const char *
  4420 evhttp_uri_get_host(const struct evhttp_uri *uri)
  4422 	return uri->host;
  4424 int
  4425 evhttp_uri_get_port(const struct evhttp_uri *uri)
  4427 	return uri->port;
  4429 const char *
  4430 evhttp_uri_get_path(const struct evhttp_uri *uri)
  4432 	return uri->path;
  4434 const char *
  4435 evhttp_uri_get_query(const struct evhttp_uri *uri)
  4437 	return uri->query;
  4439 const char *
  4440 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
  4442 	return uri->fragment;
  4445 #define _URI_SET_STR(f) do {					\
  4446 	if (uri->f)						\
  4447 		mm_free(uri->f);				\
  4448 	if (f) {						\
  4449 		if ((uri->f = mm_strdup(f)) == NULL) {		\
  4450 			event_warn("%s: strdup()", __func__);	\
  4451 			return -1;				\
  4452 		}						\
  4453 	} else {						\
  4454 		uri->f = NULL;					\
  4455 	}							\
  4456 	} while(0)
  4458 int
  4459 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
  4461 	if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
  4462 		return -1;
  4464 	_URI_SET_STR(scheme);
  4465 	return 0;
  4467 int
  4468 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
  4470 	if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
  4471 		return -1;
  4472 	_URI_SET_STR(userinfo);
  4473 	return 0;
  4475 int
  4476 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
  4478 	if (host) {
  4479 		if (host[0] == '[') {
  4480 			if (! bracket_addr_ok(host, host+strlen(host)))
  4481 				return -1;
  4482 		} else {
  4483 			if (! regname_ok(host, host+strlen(host)))
  4484 				return -1;
  4488 	_URI_SET_STR(host);
  4489 	return 0;
  4491 int
  4492 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
  4494 	if (port < -1)
  4495 		return -1;
  4496 	uri->port = port;
  4497 	return 0;
  4499 #define end_of_cpath(cp,p,f) \
  4500 	((const char*)(end_of_path(((char*)(cp)), (p), (f))))
  4502 int
  4503 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
  4505 	if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
  4506 		return -1;
  4508 	_URI_SET_STR(path);
  4509 	return 0;
  4511 int
  4512 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
  4514 	if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
  4515 		return -1;
  4516 	_URI_SET_STR(query);
  4517 	return 0;
  4519 int
  4520 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
  4522 	if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
  4523 		return -1;
  4524 	_URI_SET_STR(fragment);
  4525 	return 0;

mercurial