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