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