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