dnscrypt: updated to 1.6.1
[tomato.git] / release / src / router / dnscrypt / src / libevent-modified / http.c
blobea70de508a2edda808264bcb630bdc292355caef
1 /*
2 * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
3 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
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.
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.
28 #include "event2/event-config.h"
30 #ifdef _EVENT_HAVE_SYS_PARAM_H
31 #include <sys/param.h>
32 #endif
33 #ifdef _EVENT_HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
37 #ifdef _EVENT_HAVE_SYS_TIME_H
38 #include <sys/time.h>
39 #endif
40 #ifdef HAVE_SYS_IOCCOM_H
41 #include <sys/ioccom.h>
42 #endif
44 #ifndef WIN32
45 #include <sys/resource.h>
46 #include <sys/socket.h>
47 #include <sys/stat.h>
48 #include <sys/wait.h>
49 #else
50 #include <winsock2.h>
51 #include <ws2tcpip.h>
52 #endif
54 #include <sys/queue.h>
56 #ifdef _EVENT_HAVE_NETINET_IN_H
57 #include <netinet/in.h>
58 #endif
59 #ifdef _EVENT_HAVE_ARPA_INET_H
60 #include <arpa/inet.h>
61 #endif
62 #ifdef _EVENT_HAVE_NETDB_H
63 #include <netdb.h>
64 #endif
66 #ifdef WIN32
67 #include <winsock2.h>
68 #endif
70 #include <errno.h>
71 #include <stdio.h>
72 #include <stdlib.h>
73 #include <string.h>
74 #ifndef WIN32
75 #include <syslog.h>
76 #endif
77 #include <signal.h>
78 #include <time.h>
79 #ifdef _EVENT_HAVE_UNISTD_H
80 #include <unistd.h>
81 #endif
82 #ifdef _EVENT_HAVE_FCNTL_H
83 #include <fcntl.h>
84 #endif
86 #undef timeout_pending
87 #undef timeout_initialized
89 #include "strlcpy-internal.h"
90 #include "event2/http.h"
91 #include "event2/event.h"
92 #include "event2/buffer.h"
93 #include "event2/bufferevent.h"
94 #include "event2/bufferevent_compat.h"
95 #include "event2/http_struct.h"
96 #include "event2/http_compat.h"
97 #include "event2/util.h"
98 #include "event2/listener.h"
99 #include "log-internal.h"
100 #include "util-internal.h"
101 #include "http-internal.h"
102 #include "mm-internal.h"
103 #include "bufferevent-internal.h"
105 #ifndef _EVENT_HAVE_GETNAMEINFO
106 #define NI_MAXSERV 32
107 #define NI_MAXHOST 1025
109 #ifndef NI_NUMERICHOST
110 #define NI_NUMERICHOST 1
111 #endif
113 #ifndef NI_NUMERICSERV
114 #define NI_NUMERICSERV 2
115 #endif
117 static int
118 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
119 size_t hostlen, char *serv, size_t servlen, int flags)
121 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
123 if (serv != NULL) {
124 char tmpserv[16];
125 evutil_snprintf(tmpserv, sizeof(tmpserv),
126 "%d", ntohs(sin->sin_port));
127 if (strlcpy(serv, tmpserv, servlen) >= servlen)
128 return (-1);
131 if (host != NULL) {
132 if (flags & NI_NUMERICHOST) {
133 if (strlcpy(host, inet_ntoa(sin->sin_addr),
134 hostlen) >= hostlen)
135 return (-1);
136 else
137 return (0);
138 } else {
139 struct hostent *hp;
140 hp = gethostbyaddr((char *)&sin->sin_addr,
141 sizeof(struct in_addr), AF_INET);
142 if (hp == NULL)
143 return (-2);
145 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
146 return (-1);
147 else
148 return (0);
151 return (0);
154 #endif
156 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \
157 ((req)->major < (major_v) || \
158 ((req)->major == (major_v) && (req)->minor < (minor_v)))
160 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \
161 ((req)->major > (major_v) || \
162 ((req)->major == (major_v) && (req)->minor >= (minor_v)))
164 #ifndef MIN
165 #define MIN(a,b) (((a)<(b))?(a):(b))
166 #endif
168 extern int debug;
170 static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse);
171 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
172 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
173 static int evhttp_associate_new_request_with_connection(
174 struct evhttp_connection *evcon);
175 static void evhttp_connection_start_detectclose(
176 struct evhttp_connection *evcon);
177 static void evhttp_connection_stop_detectclose(
178 struct evhttp_connection *evcon);
179 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
180 static void evhttp_read_firstline(struct evhttp_connection *evcon,
181 struct evhttp_request *req);
182 static void evhttp_read_header(struct evhttp_connection *evcon,
183 struct evhttp_request *req);
184 static int evhttp_add_header_internal(struct evkeyvalq *headers,
185 const char *key, const char *value);
186 static const char *evhttp_response_phrase_internal(int code);
187 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t);
188 static void evhttp_write_buffer(struct evhttp_connection *,
189 void (*)(struct evhttp_connection *, void *), void *);
190 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
192 /* callbacks for bufferevent */
193 static void evhttp_read_cb(struct bufferevent *, void *);
194 static void evhttp_write_cb(struct bufferevent *, void *);
195 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
196 static int evhttp_decode_uri_internal(const char *uri, size_t length,
197 char *ret, int decode_plus);
198 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
199 const char *hostname);
201 #ifndef _EVENT_HAVE_STRSEP
202 /* strsep replacement for platforms that lack it. Only works if
203 * del is one character long. */
204 static char *
205 strsep(char **s, const char *del)
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;
220 #endif
222 static size_t
223 html_replace(const char ch, const char **escaped)
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;
245 return 1;
249 * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
250 * &#039; and &amp; correspondingly.
252 * The returned string needs to be freed by the caller.
255 char *
256 evhttp_htmlescape(const char *html)
258 size_t i;
259 size_t new_size = 0, old_size = 0;
260 char *escaped_html, *p;
262 if (html == NULL)
263 return (NULL);
265 old_size = strlen(html);
266 for (i = 0; i < old_size; ++i) {
267 const char *replaced = NULL;
268 const size_t replace_size = html_replace(html[i], &replaced);
269 if (replace_size > EV_SIZE_MAX - new_size) {
270 event_warn("%s: html_replace overflow", __func__);
271 return (NULL);
273 new_size += replace_size;
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);
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;
291 *p = '\0';
293 return (escaped_html);
296 /** Given an evhttp_cmd_type, returns a constant string containing the
297 * equivalent HTTP command, or NULL if the evhttp_command_type is
298 * unrecognized. */
299 static const char *
300 evhttp_method(enum evhttp_cmd_type type)
302 const char *method;
304 switch (type) {
305 case EVHTTP_REQ_GET:
306 method = "GET";
307 break;
308 case EVHTTP_REQ_POST:
309 method = "POST";
310 break;
311 case EVHTTP_REQ_HEAD:
312 method = "HEAD";
313 break;
314 case EVHTTP_REQ_PUT:
315 method = "PUT";
316 break;
317 case EVHTTP_REQ_DELETE:
318 method = "DELETE";
319 break;
320 case EVHTTP_REQ_OPTIONS:
321 method = "OPTIONS";
322 break;
323 case EVHTTP_REQ_TRACE:
324 method = "TRACE";
325 break;
326 case EVHTTP_REQ_CONNECT:
327 method = "CONNECT";
328 break;
329 case EVHTTP_REQ_PATCH:
330 method = "PATCH";
331 break;
332 default:
333 method = NULL;
334 break;
337 return (method);
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.
346 static int
347 evhttp_response_needs_body(struct evhttp_request *req)
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);
355 /** Helper: adds the event 'ev' with the timeout 'timeout', or with
356 * default_timeout if timeout is -1.
358 static int
359 evhttp_add_event(struct event *ev, int timeout, int default_timeout)
361 if (timeout != 0) {
362 struct timeval tv;
364 evutil_timerclear(&tv);
365 tv.tv_sec = timeout != -1 ? timeout : default_timeout;
366 return event_add(ev, &tv);
367 } else {
368 return event_add(ev, NULL);
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.
376 static void
377 evhttp_write_buffer(struct evhttp_connection *evcon,
378 void (*cb)(struct evhttp_connection *, void *), void *arg)
380 event_debug(("%s: preparing to write buffer\n", __func__));
382 /* Set call back */
383 evcon->cb = cb;
384 evcon->cb_arg = arg;
386 /* Disable the read callback: we don't actually care about data;
387 * we only care about close detection. (We don't disable reading,
388 * since we *do* want to learn about any close events.) */
389 bufferevent_setcb(evcon->bufev,
390 NULL, /*read*/
391 evhttp_write_cb,
392 evhttp_error_cb,
393 evcon);
395 bufferevent_enable(evcon->bufev, EV_WRITE);
398 static void
399 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
401 bufferevent_disable(evcon->bufev, EV_WRITE);
404 static void
405 evhttp_send_continue(struct evhttp_connection *evcon,
406 struct evhttp_request *req)
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);
421 /** Helper: returns true iff evconn is in any connected state. */
422 static int
423 evhttp_connected(struct evhttp_connection *evcon)
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);
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.
444 static void
445 evhttp_make_header_request(struct evhttp_connection *evcon,
446 struct evhttp_request *req)
448 const char *method;
450 evhttp_remove_header(req->output_headers, "Proxy-Connection");
452 /* Generate request line */
453 method = evhttp_method(req->type);
454 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
455 "%s %s HTTP/%d.%d\r\n",
456 method, req->uri, req->major, req->minor);
458 /* Add the content length on a post or put request if missing */
459 if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
460 evhttp_find_header(req->output_headers, "Content-Length") == NULL){
461 char size[22];
462 evutil_snprintf(size, sizeof(size), EV_SIZE_FMT,
463 EV_SIZE_ARG(evbuffer_get_length(req->output_buffer)));
464 evhttp_add_header(req->output_headers, "Content-Length", size);
468 /** Return true if the list of headers in 'headers', intepreted with respect
469 * to flags, means that we should send a "connection: close" when the request
470 * is done. */
471 static int
472 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
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);
484 /* Return true iff 'headers' contains 'Connection: keep-alive' */
485 static int
486 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
488 const char *connection = evhttp_find_header(headers, "Connection");
489 return (connection != NULL
490 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
493 /* Add a correct "Date" header to headers, unless it already has one. */
494 static void
495 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
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);
517 /* Add a "Content-Length" header with value 'content_length' to headers,
518 * unless it already has a content-length or transfer-encoding header. */
519 static void
520 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
521 size_t content_length)
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);
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.
536 static void
537 evhttp_make_header_response(struct evhttp_connection *evcon,
538 struct evhttp_request *req)
540 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
541 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
542 "HTTP/%d.%d %d %s\r\n",
543 req->major, req->minor, req->response_code,
544 req->response_code_line);
546 if (req->major == 1) {
547 if (req->minor >= 1)
548 evhttp_maybe_add_date_header(req->output_headers);
551 * if the protocol is 1.0; and the connection was keep-alive
552 * we need to add a keep-alive header, too.
554 if (req->minor == 0 && is_keepalive)
555 evhttp_add_header(req->output_headers,
556 "Connection", "keep-alive");
558 if ((req->minor >= 1 || is_keepalive) &&
559 evhttp_response_needs_body(req)) {
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.
565 evhttp_maybe_add_content_length_header(
566 req->output_headers,
567 evbuffer_get_length(req->output_buffer));
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");
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");
589 /** Generate all headers appropriate for sending the http request in req (or
590 * the response, if we're sending a response), and write them to evcon's
591 * bufferevent. Also writes all data from req->output_buffer */
592 static void
593 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
595 struct evkeyval *header;
596 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
599 * Depending if this is a HTTP request or response, we might need to
600 * add some new headers or remove existing headers.
602 if (req->kind == EVHTTP_REQUEST) {
603 evhttp_make_header_request(evcon, req);
604 } else {
605 evhttp_make_header_response(evcon, req);
608 TAILQ_FOREACH(header, req->output_headers, next) {
609 evbuffer_add_printf(output, "%s: %s\r\n",
610 header->key, header->value);
612 evbuffer_add(output, "\r\n", 2);
614 if (evbuffer_get_length(req->output_buffer) > 0) {
616 * For a request, we add the POST data, for a reply, this
617 * is the regular data.
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);
626 void
627 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
628 ev_ssize_t new_max_headers_size)
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;
635 void
636 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
637 ev_ssize_t new_max_body_size)
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;
645 static int
646 evhttp_connection_incoming_fail(struct evhttp_request *req,
647 enum evhttp_connection_error error)
649 switch (error) {
650 case EVCON_HTTP_TIMEOUT:
651 case EVCON_HTTP_EOF:
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.
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
666 req->evcon = NULL;
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;
678 if (req->uri_elems) {
679 evhttp_uri_free(req->uri_elems);
680 req->uri_elems = NULL;
684 * the callback needs to send a reply, once the reply has
685 * been send, the connection should get freed.
687 (*req->cb)(req, req->cb_arg);
690 return (0);
693 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
694 * given in error. If it's an outgoing connection, reset the connection,
695 * retry any pending requests, and inform the user. If it's incoming,
696 * delegates to evhttp_connection_incoming_fail(). */
697 void
698 evhttp_connection_fail(struct evhttp_connection *evcon,
699 enum evhttp_connection_error error)
701 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
702 void (*cb)(struct evhttp_request *, void *);
703 void *cb_arg;
704 EVUTIL_ASSERT(req != NULL);
706 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
708 if (evcon->flags & EVHTTP_CON_INCOMING) {
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.
717 if (evhttp_connection_incoming_fail(req, error) == -1)
718 evhttp_connection_free(evcon);
719 return;
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;
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
736 TAILQ_REMOVE(&evcon->requests, req, next);
737 evhttp_request_free(req);
739 /* reset the connection */
740 evhttp_connection_reset(evcon);
742 /* We are trying the next request that was queued on us */
743 if (TAILQ_FIRST(&evcon->requests) != NULL)
744 evhttp_connection_connect(evcon);
746 /* inform the user */
747 if (cb != NULL)
748 (*cb)(NULL, cb_arg);
751 /* Bufferevent callback: invoked when any data has been written from an
752 * http connection's bufferevent */
753 static void
754 evhttp_write_cb(struct bufferevent *bufev, void *arg)
756 struct evhttp_connection *evcon = arg;
758 /* Activate our call back */
759 if (evcon->cb != NULL)
760 (*evcon->cb)(evcon, evcon->cb_arg);
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.
770 static void
771 evhttp_connection_done(struct evhttp_connection *evcon)
773 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
774 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
776 if (con_outgoing) {
777 /* idle or close the connection */
778 int need_close;
779 TAILQ_REMOVE(&evcon->requests, req, next);
780 req->evcon = NULL;
782 evcon->state = EVCON_IDLE;
784 need_close =
785 evhttp_is_connection_close(req->flags, req->input_headers)||
786 evhttp_is_connection_close(req->flags, req->output_headers);
788 /* check if we got asked to close the connection */
789 if (need_close)
790 evhttp_connection_reset(evcon);
792 if (TAILQ_FIRST(&evcon->requests) != NULL) {
794 * We have more requests; reset the connection
795 * and deal with the next request.
797 if (!evhttp_connected(evcon))
798 evhttp_connection_connect(evcon);
799 else
800 evhttp_request_dispatch(evcon);
801 } else if (!need_close) {
803 * The connection is going to be persistent, but we
804 * need to detect if the other side closes it.
806 evhttp_connection_start_detectclose(evcon);
808 } else {
810 * incoming connection - we need to leave the request on the
811 * connection so that we can reply to it.
813 evcon->state = EVCON_WRITING;
816 /* notify the user of the request */
817 (*req->cb)(req, req->cb_arg);
819 /* if this was an outgoing request, we own and it's done. so free it.
820 * unless the callback specifically requested to own the request.
822 if (con_outgoing && ((req->flags & EVHTTP_USER_OWNED) == 0)) {
823 evhttp_request_free(req);
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
841 static enum message_read_status
842 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
844 if (req == NULL || buf == NULL) {
845 return DATA_CORRUPTED;
848 while (1) {
849 size_t buflen;
851 if ((buflen = evbuffer_get_length(buf)) == 0) {
852 break;
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;
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;
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);
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;
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);
895 req->body_size += (size_t)ntoread;
896 req->ntoread = ntoread;
897 if (req->ntoread == 0) {
898 /* Last chunk */
899 return (ALL_DATA_READ);
901 continue;
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;
910 /* don't have enough to complete a chunk; wait for more */
911 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
912 return (MORE_DATA_EXPECTED);
914 /* Completed chunk */
915 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
916 req->ntoread = -1;
917 if (req->chunk_cb != NULL) {
918 req->flags |= EVHTTP_REQ_DEFER_FREE;
919 (*req->chunk_cb)(req, req->cb_arg);
920 evbuffer_drain(req->input_buffer,
921 evbuffer_get_length(req->input_buffer));
922 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
923 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
924 return (REQUEST_CANCELED);
929 return (MORE_DATA_EXPECTED);
932 static void
933 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
935 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
937 switch (evhttp_parse_headers(req, buf)) {
938 case DATA_CORRUPTED:
939 case DATA_TOO_LONG:
940 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
941 break;
942 case ALL_DATA_READ:
943 bufferevent_disable(evcon->bufev, EV_READ);
944 evhttp_connection_done(evcon);
945 break;
946 case MORE_DATA_EXPECTED:
947 case REQUEST_CANCELED: /* ??? */
948 default:
949 bufferevent_enable(evcon->bufev, EV_READ);
950 break;
954 static void
955 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
957 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
959 if (req->chunked) {
960 switch (evhttp_handle_chunked_read(req, buf)) {
961 case ALL_DATA_READ:
962 /* finished last chunk */
963 evcon->state = EVCON_READING_TRAILER;
964 evhttp_read_trailer(evcon, req);
965 return;
966 case DATA_CORRUPTED:
967 case DATA_TOO_LONG:/*separate error for this? XXX */
968 /* corrupted data */
969 evhttp_connection_fail(evcon,
970 EVCON_HTTP_INVALID_HEADER);
971 return;
972 case REQUEST_CANCELED:
973 /* request canceled */
974 evhttp_request_free(req);
975 return;
976 case MORE_DATA_EXPECTED:
977 default:
978 break;
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;
987 req->body_size += evbuffer_get_length(buf);
988 evbuffer_add_buffer(req->input_buffer, buf);
989 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
990 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
991 /* We've postponed moving the data until now, but we're
992 * about to use it. */
993 size_t n = evbuffer_get_length(buf);
995 if (n > (size_t) req->ntoread)
996 n = (size_t) req->ntoread;
997 req->ntoread -= n;
998 req->body_size += n;
999 evbuffer_remove_buffer(buf, req->input_buffer, n);
1002 if (req->body_size > req->evcon->max_body_size ||
1003 (!req->chunked && req->ntoread >= 0 &&
1004 (size_t)req->ntoread > req->evcon->max_body_size)) {
1005 /* XXX: The above casted comparison must checked for overflow */
1006 /* failed body length test */
1007 event_debug(("Request body is too long"));
1008 evhttp_connection_fail(evcon,
1009 EVCON_HTTP_INVALID_HEADER);
1010 return;
1013 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1014 req->flags |= EVHTTP_REQ_DEFER_FREE;
1015 (*req->chunk_cb)(req, req->cb_arg);
1016 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1017 evbuffer_drain(req->input_buffer,
1018 evbuffer_get_length(req->input_buffer));
1019 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1020 evhttp_request_free(req);
1021 return;
1025 if (req->ntoread == 0) {
1026 bufferevent_disable(evcon->bufev, EV_READ);
1027 /* Completed content length */
1028 evhttp_connection_done(evcon);
1029 return;
1032 /* Read more! */
1033 bufferevent_enable(evcon->bufev, EV_READ);
1036 #define get_deferred_queue(evcon) \
1037 (event_base_get_deferred_cb_queue((evcon)->base))
1040 * Gets called when more data becomes available
1043 static void
1044 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1046 struct evhttp_connection *evcon = arg;
1047 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1049 /* Cancel if it's pending. */
1050 event_deferred_cb_cancel(get_deferred_queue(evcon),
1051 &evcon->read_more_deferred_cb);
1053 switch (evcon->state) {
1054 case EVCON_READING_FIRSTLINE:
1055 evhttp_read_firstline(evcon, req);
1056 /* note the request may have been freed in
1057 * evhttp_read_body */
1058 break;
1059 case EVCON_READING_HEADERS:
1060 evhttp_read_header(evcon, req);
1061 /* note the request may have been freed in
1062 * evhttp_read_body */
1063 break;
1064 case EVCON_READING_BODY:
1065 evhttp_read_body(evcon, req);
1066 /* note the request may have been freed in
1067 * evhttp_read_body */
1068 break;
1069 case EVCON_READING_TRAILER:
1070 evhttp_read_trailer(evcon, req);
1071 break;
1072 case EVCON_IDLE:
1074 #ifdef USE_DEBUG
1075 struct evbuffer *input;
1076 size_t total_len;
1078 input = bufferevent_get_input(evcon->bufev);
1079 total_len = evbuffer_get_length(input);
1080 event_debug(("%s: read "EV_SIZE_FMT
1081 " bytes in EVCON_IDLE state,"
1082 " resetting connection",
1083 __func__, EV_SIZE_ARG(total_len)));
1084 #endif
1086 evhttp_connection_reset(evcon);
1088 break;
1089 case EVCON_DISCONNECTED:
1090 case EVCON_CONNECTING:
1091 case EVCON_WRITING:
1092 default:
1093 event_errx(1, "%s: illegal connection state %d",
1094 __func__, evcon->state);
1098 static void
1099 evhttp_deferred_read_cb(struct deferred_cb *cb, void *data)
1101 struct evhttp_connection *evcon = data;
1102 evhttp_read_cb(evcon->bufev, evcon);
1105 static void
1106 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1108 /* This is after writing the request to the server */
1109 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1110 EVUTIL_ASSERT(req != NULL);
1112 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1114 /* We are done writing our header and are now expecting the response */
1115 req->kind = EVHTTP_RESPONSE;
1117 evhttp_start_read(evcon);
1121 * Clean up a connection object
1124 void
1125 evhttp_connection_free(struct evhttp_connection *evcon)
1127 struct evhttp_request *req;
1129 /* notify interested parties that this connection is going down */
1130 if (evcon->fd != -1) {
1131 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1132 (*evcon->closecb)(evcon, evcon->closecb_arg);
1135 /* remove all requests that might be queued on this
1136 * connection. for server connections, this should be empty.
1137 * because it gets dequeued either in evhttp_connection_done or
1138 * evhttp_connection_fail.
1140 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1141 TAILQ_REMOVE(&evcon->requests, req, next);
1142 evhttp_request_free(req);
1145 if (evcon->http_server != NULL) {
1146 struct evhttp *http = evcon->http_server;
1147 TAILQ_REMOVE(&http->connections, evcon, next);
1150 if (event_initialized(&evcon->retry_ev)) {
1151 event_del(&evcon->retry_ev);
1152 event_debug_unassign(&evcon->retry_ev);
1155 if (evcon->bufev != NULL)
1156 bufferevent_free(evcon->bufev);
1158 event_deferred_cb_cancel(get_deferred_queue(evcon),
1159 &evcon->read_more_deferred_cb);
1161 if (evcon->fd != -1) {
1162 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1163 evutil_closesocket(evcon->fd);
1166 if (evcon->bind_address != NULL)
1167 mm_free(evcon->bind_address);
1169 if (evcon->address != NULL)
1170 mm_free(evcon->address);
1172 mm_free(evcon);
1175 void
1176 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1177 const char *address)
1179 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1180 if (evcon->bind_address)
1181 mm_free(evcon->bind_address);
1182 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1183 event_warn("%s: strdup", __func__);
1186 void
1187 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1188 ev_uint16_t port)
1190 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1191 evcon->bind_port = port;
1194 static void
1195 evhttp_request_dispatch(struct evhttp_connection* evcon)
1197 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1199 /* this should not usually happy but it's possible */
1200 if (req == NULL)
1201 return;
1203 /* delete possible close detection events */
1204 evhttp_connection_stop_detectclose(evcon);
1206 /* we assume that the connection is connected already */
1207 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1209 evcon->state = EVCON_WRITING;
1211 /* Create the header from the store arguments */
1212 evhttp_make_header(evcon, req);
1214 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1217 /* Reset our connection state: disables reading/writing, closes our fd (if
1218 * any), clears out buffers, and puts us in state DISCONNECTED. */
1219 void
1220 evhttp_connection_reset(struct evhttp_connection *evcon)
1222 struct evbuffer *tmp;
1224 /* XXXX This is not actually an optimal fix. Instead we ought to have
1225 an API for "stop connecting", or use bufferevent_setfd to turn off
1226 connecting. But for Libevent 2.0, this seems like a minimal change
1227 least likely to disrupt the rest of the bufferevent and http code.
1229 Why is this here? If the fd is set in the bufferevent, and the
1230 bufferevent is connecting, then you can't actually stop the
1231 bufferevent from trying to connect with bufferevent_disable(). The
1232 connect will never trigger, since we close the fd, but the timeout
1233 might. That caused an assertion failure in evhttp_connection_fail.
1235 bufferevent_disable_hard(evcon->bufev, EV_READ|EV_WRITE);
1237 if (evcon->fd != -1) {
1238 /* inform interested parties about connection close */
1239 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1240 (*evcon->closecb)(evcon, evcon->closecb_arg);
1242 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1243 evutil_closesocket(evcon->fd);
1244 evcon->fd = -1;
1247 /* we need to clean up any buffered data */
1248 tmp = bufferevent_get_output(evcon->bufev);
1249 evbuffer_drain(tmp, evbuffer_get_length(tmp));
1250 tmp = bufferevent_get_input(evcon->bufev);
1251 evbuffer_drain(tmp, evbuffer_get_length(tmp));
1253 evcon->state = EVCON_DISCONNECTED;
1256 static void
1257 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1259 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1261 bufferevent_enable(evcon->bufev, EV_READ);
1264 static void
1265 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1267 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1269 bufferevent_disable(evcon->bufev, EV_READ);
1272 static void
1273 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1275 struct evhttp_connection *evcon = arg;
1277 evcon->state = EVCON_DISCONNECTED;
1278 evhttp_connection_connect(evcon);
1281 static void
1282 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1284 struct evcon_requestq requests;
1286 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1287 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1288 /* XXXX handle failure from evhttp_add_event */
1289 evhttp_add_event(&evcon->retry_ev,
1290 MIN(3600, 2 << evcon->retry_cnt),
1291 HTTP_CONNECT_TIMEOUT);
1292 evcon->retry_cnt++;
1293 return;
1295 evhttp_connection_reset(evcon);
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.
1303 TAILQ_INIT(&requests);
1304 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1305 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1306 TAILQ_REMOVE(&evcon->requests, request, next);
1307 TAILQ_INSERT_TAIL(&requests, request, next);
1310 /* for now, we just signal all requests by executing their callbacks */
1311 while (TAILQ_FIRST(&requests) != NULL) {
1312 struct evhttp_request *request = TAILQ_FIRST(&requests);
1313 TAILQ_REMOVE(&requests, request, next);
1314 request->evcon = NULL;
1316 /* we might want to set an error here */
1317 request->cb(request, request->cb_arg);
1318 evhttp_request_free(request);
1322 static void
1323 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1325 struct evhttp_connection *evcon = arg;
1326 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1328 if (evcon->fd == -1)
1329 evcon->fd = bufferevent_getfd(bufev);
1331 switch (evcon->state) {
1332 case EVCON_CONNECTING:
1333 if (what & BEV_EVENT_TIMEOUT) {
1334 event_debug(("%s: connection timeout for \"%s:%d\" on "
1335 EV_SOCK_FMT,
1336 __func__, evcon->address, evcon->port,
1337 EV_SOCK_ARG(evcon->fd)));
1338 evhttp_connection_cb_cleanup(evcon);
1339 return;
1341 break;
1343 case EVCON_READING_BODY:
1344 if (!req->chunked && req->ntoread < 0
1345 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1346 /* EOF on read can be benign */
1347 evhttp_connection_done(evcon);
1348 return;
1350 break;
1352 case EVCON_DISCONNECTED:
1353 case EVCON_IDLE:
1354 case EVCON_READING_FIRSTLINE:
1355 case EVCON_READING_HEADERS:
1356 case EVCON_READING_TRAILER:
1357 case EVCON_WRITING:
1358 default:
1359 break;
1362 /* when we are in close detect mode, a read error means that
1363 * the other side closed their connection.
1365 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1366 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1367 EVUTIL_ASSERT(evcon->http_server == NULL);
1368 /* For connections from the client, we just
1369 * reset the connection so that it becomes
1370 * disconnected.
1372 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1373 evhttp_connection_reset(evcon);
1374 return;
1377 if (what & BEV_EVENT_TIMEOUT) {
1378 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
1379 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1380 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
1381 } else {
1382 evhttp_connection_fail(evcon, EVCON_HTTP_BUFFER_ERROR);
1387 * Event callback for asynchronous connection attempt.
1389 static void
1390 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1392 struct evhttp_connection *evcon = arg;
1393 int error;
1394 ev_socklen_t errsz = sizeof(error);
1396 if (evcon->fd == -1)
1397 evcon->fd = bufferevent_getfd(bufev);
1399 if (!(what & BEV_EVENT_CONNECTED)) {
1400 /* some operating systems return ECONNREFUSED immediately
1401 * when connecting to a local address. the cleanup is going
1402 * to reschedule this function call.
1404 #ifndef WIN32
1405 if (errno == ECONNREFUSED)
1406 goto cleanup;
1407 #endif
1408 evhttp_error_cb(bufev, what, arg);
1409 return;
1412 /* Check if the connection completed */
1413 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1414 &errsz) == -1) {
1415 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT,
1416 __func__, evcon->address, evcon->port,
1417 EV_SOCK_ARG(evcon->fd)));
1418 goto cleanup;
1421 if (error) {
1422 event_debug(("%s: connect failed for \"%s:%d\" on "
1423 EV_SOCK_FMT": %s",
1424 __func__, evcon->address, evcon->port,
1425 EV_SOCK_ARG(evcon->fd),
1426 evutil_socket_error_to_string(error)));
1427 goto cleanup;
1430 /* We are connected to the server now */
1431 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1432 __func__, evcon->address, evcon->port,
1433 EV_SOCK_ARG(evcon->fd)));
1435 /* Reset the retry count as we were successful in connecting */
1436 evcon->retry_cnt = 0;
1437 evcon->state = EVCON_IDLE;
1439 /* reset the bufferevent cbs */
1440 bufferevent_setcb(evcon->bufev,
1441 evhttp_read_cb,
1442 evhttp_write_cb,
1443 evhttp_error_cb,
1444 evcon);
1446 if (evcon->timeout == -1)
1447 bufferevent_settimeout(evcon->bufev,
1448 HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
1449 else {
1450 struct timeval tv;
1451 tv.tv_sec = evcon->timeout;
1452 tv.tv_usec = 0;
1453 bufferevent_set_timeouts(evcon->bufev, &tv, &tv);
1456 /* try to start requests that have queued up on this connection */
1457 evhttp_request_dispatch(evcon);
1458 return;
1460 cleanup:
1461 evhttp_connection_cb_cleanup(evcon);
1465 * Check if we got a valid response code.
1468 static int
1469 evhttp_valid_response_code(int code)
1471 if (code == 0)
1472 return (0);
1474 return (1);
1477 static int
1478 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1480 int major, minor;
1481 char ch;
1482 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1483 if (n != 2 || major > 1) {
1484 event_debug(("%s: bad version %s on message %p from %s",
1485 __func__, version, req, req->remote_host));
1486 return (-1);
1488 req->major = major;
1489 req->minor = minor;
1490 return (0);
1493 /* Parses the status line of a web server */
1495 static int
1496 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1498 char *protocol;
1499 char *number;
1500 const char *readable = "";
1502 protocol = strsep(&line, " ");
1503 if (line == NULL)
1504 return (-1);
1505 number = strsep(&line, " ");
1506 if (line != NULL)
1507 readable = line;
1509 if (evhttp_parse_http_version(protocol, req) < 0)
1510 return (-1);
1512 req->response_code = atoi(number);
1513 if (!evhttp_valid_response_code(req->response_code)) {
1514 event_debug(("%s: bad response code \"%s\"",
1515 __func__, number));
1516 return (-1);
1519 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1520 event_warn("%s: strdup", __func__);
1521 return (-1);
1524 return (0);
1527 /* Parse the first line of a HTTP request */
1529 static int
1530 evhttp_parse_request_line(struct evhttp_request *req, char *line)
1532 char *method;
1533 char *uri;
1534 char *version;
1535 const char *hostname;
1536 const char *scheme;
1538 /* Parse the request line */
1539 method = strsep(&line, " ");
1540 if (line == NULL)
1541 return (-1);
1542 uri = strsep(&line, " ");
1543 if (line == NULL)
1544 return (-1);
1545 version = strsep(&line, " ");
1546 if (line != NULL)
1547 return (-1);
1549 /* First line */
1550 if (strcmp(method, "GET") == 0) {
1551 req->type = EVHTTP_REQ_GET;
1552 } else if (strcmp(method, "POST") == 0) {
1553 req->type = EVHTTP_REQ_POST;
1554 } else if (strcmp(method, "HEAD") == 0) {
1555 req->type = EVHTTP_REQ_HEAD;
1556 } else if (strcmp(method, "PUT") == 0) {
1557 req->type = EVHTTP_REQ_PUT;
1558 } else if (strcmp(method, "DELETE") == 0) {
1559 req->type = EVHTTP_REQ_DELETE;
1560 } else if (strcmp(method, "OPTIONS") == 0) {
1561 req->type = EVHTTP_REQ_OPTIONS;
1562 } else if (strcmp(method, "TRACE") == 0) {
1563 req->type = EVHTTP_REQ_TRACE;
1564 } else if (strcmp(method, "PATCH") == 0) {
1565 req->type = EVHTTP_REQ_PATCH;
1566 } else {
1567 req->type = _EVHTTP_REQ_UNKNOWN;
1568 event_debug(("%s: bad method %s on request %p from %s",
1569 __func__, method, req, req->remote_host));
1570 /* No error yet; we'll give a better error later when
1571 * we see that req->type is unsupported. */
1574 if (evhttp_parse_http_version(version, req) < 0)
1575 return (-1);
1577 if ((req->uri = mm_strdup(uri)) == NULL) {
1578 event_debug(("%s: mm_strdup", __func__));
1579 return (-1);
1582 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
1583 EVHTTP_URI_NONCONFORMANT)) == NULL) {
1584 return -1;
1587 /* If we have an absolute-URI, check to see if it is an http request
1588 for a known vhost or server alias. If we don't know about this
1589 host, we consider it a proxy request. */
1590 scheme = evhttp_uri_get_scheme(req->uri_elems);
1591 hostname = evhttp_uri_get_host(req->uri_elems);
1592 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1593 !evutil_ascii_strcasecmp(scheme, "https")) &&
1594 hostname &&
1595 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1596 req->flags |= EVHTTP_PROXY_REQUEST;
1598 return (0);
1601 const char *
1602 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1604 struct evkeyval *header;
1606 TAILQ_FOREACH(header, headers, next) {
1607 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1608 return (header->value);
1611 return (NULL);
1614 void
1615 evhttp_clear_headers(struct evkeyvalq *headers)
1617 struct evkeyval *header;
1619 for (header = TAILQ_FIRST(headers);
1620 header != NULL;
1621 header = TAILQ_FIRST(headers)) {
1622 TAILQ_REMOVE(headers, header, next);
1623 mm_free(header->key);
1624 mm_free(header->value);
1625 mm_free(header);
1630 * Returns 0, if the header was successfully removed.
1631 * Returns -1, if the header could not be found.
1635 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1637 struct evkeyval *header;
1639 TAILQ_FOREACH(header, headers, next) {
1640 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1641 break;
1644 if (header == NULL)
1645 return (-1);
1647 /* Free and remove the header that we found */
1648 TAILQ_REMOVE(headers, header, next);
1649 mm_free(header->key);
1650 mm_free(header->value);
1651 mm_free(header);
1653 return (0);
1656 static int
1657 evhttp_header_is_valid_value(const char *value)
1659 const char *p = value;
1661 while ((p = strpbrk(p, "\r\n")) != NULL) {
1662 /* we really expect only one new line */
1663 p += strspn(p, "\r\n");
1664 /* we expect a space or tab for continuation */
1665 if (*p != ' ' && *p != '\t')
1666 return (0);
1668 return (1);
1672 evhttp_add_header(struct evkeyvalq *headers,
1673 const char *key, const char *value)
1675 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1677 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1678 /* drop illegal headers */
1679 event_debug(("%s: dropping illegal header key\n", __func__));
1680 return (-1);
1683 if (!evhttp_header_is_valid_value(value)) {
1684 event_debug(("%s: dropping illegal header value\n", __func__));
1685 return (-1);
1688 return (evhttp_add_header_internal(headers, key, value));
1691 static int
1692 evhttp_add_header_internal(struct evkeyvalq *headers,
1693 const char *key, const char *value)
1695 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
1696 if (header == NULL) {
1697 event_warn("%s: calloc", __func__);
1698 return (-1);
1700 if ((header->key = mm_strdup(key)) == NULL) {
1701 mm_free(header);
1702 event_warn("%s: strdup", __func__);
1703 return (-1);
1705 if ((header->value = mm_strdup(value)) == NULL) {
1706 mm_free(header->key);
1707 mm_free(header);
1708 event_warn("%s: strdup", __func__);
1709 return (-1);
1712 TAILQ_INSERT_TAIL(headers, header, next);
1714 return (0);
1718 * Parses header lines from a request or a response into the specified
1719 * request object given an event buffer.
1721 * Returns
1722 * DATA_CORRUPTED on error
1723 * MORE_DATA_EXPECTED when we need to read more headers
1724 * ALL_DATA_READ when all headers have been read.
1727 enum message_read_status
1728 evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
1730 char *line;
1731 enum message_read_status status = ALL_DATA_READ;
1733 size_t line_length;
1734 /* XXX try */
1735 line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF);
1736 if (line == NULL) {
1737 if (req->evcon != NULL &&
1738 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1739 return (DATA_TOO_LONG);
1740 else
1741 return (MORE_DATA_EXPECTED);
1744 if (req->evcon != NULL &&
1745 line_length > req->evcon->max_headers_size) {
1746 mm_free(line);
1747 return (DATA_TOO_LONG);
1750 req->headers_size = line_length;
1752 switch (req->kind) {
1753 case EVHTTP_REQUEST:
1754 if (evhttp_parse_request_line(req, line) == -1)
1755 status = DATA_CORRUPTED;
1756 break;
1757 case EVHTTP_RESPONSE:
1758 if (evhttp_parse_response_line(req, line) == -1)
1759 status = DATA_CORRUPTED;
1760 break;
1761 default:
1762 status = DATA_CORRUPTED;
1765 mm_free(line);
1766 return (status);
1769 static int
1770 evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
1772 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
1773 char *newval;
1774 size_t old_len, line_len;
1776 if (header == NULL)
1777 return (-1);
1779 old_len = strlen(header->value);
1780 line_len = strlen(line);
1782 newval = mm_realloc(header->value, old_len + line_len + 1);
1783 if (newval == NULL)
1784 return (-1);
1786 memcpy(newval + old_len, line, line_len + 1);
1787 header->value = newval;
1789 return (0);
1792 enum message_read_status
1793 evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
1795 enum message_read_status errcode = DATA_CORRUPTED;
1796 char *line;
1797 enum message_read_status status = MORE_DATA_EXPECTED;
1799 struct evkeyvalq* headers = req->input_headers;
1800 size_t line_length;
1801 while ((line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF))
1802 != NULL) {
1803 char *skey, *svalue;
1805 req->headers_size += line_length;
1807 if (req->evcon != NULL &&
1808 req->headers_size > req->evcon->max_headers_size) {
1809 errcode = DATA_TOO_LONG;
1810 goto error;
1813 if (*line == '\0') { /* Last header - Done */
1814 status = ALL_DATA_READ;
1815 mm_free(line);
1816 break;
1819 /* Check if this is a continuation line */
1820 if (*line == ' ' || *line == '\t') {
1821 if (evhttp_append_to_last_header(headers, line) == -1)
1822 goto error;
1823 mm_free(line);
1824 continue;
1827 /* Processing of header lines */
1828 svalue = line;
1829 skey = strsep(&svalue, ":");
1830 if (svalue == NULL)
1831 goto error;
1833 svalue += strspn(svalue, " ");
1835 if (evhttp_add_header(headers, skey, svalue) == -1)
1836 goto error;
1838 mm_free(line);
1841 if (status == MORE_DATA_EXPECTED) {
1842 if (req->evcon != NULL &&
1843 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1844 return (DATA_TOO_LONG);
1847 return (status);
1849 error:
1850 mm_free(line);
1851 return (errcode);
1854 static int
1855 evhttp_get_body_length(struct evhttp_request *req)
1857 struct evkeyvalq *headers = req->input_headers;
1858 const char *content_length;
1859 const char *connection;
1861 content_length = evhttp_find_header(headers, "Content-Length");
1862 connection = evhttp_find_header(headers, "Connection");
1864 if (content_length == NULL && connection == NULL)
1865 req->ntoread = -1;
1866 else if (content_length == NULL &&
1867 evutil_ascii_strcasecmp(connection, "Close") != 0) {
1868 /* Bad combination, we don't know when it will end */
1869 event_warnx("%s: we got no content length, but the "
1870 "server wants to keep the connection open: %s.",
1871 __func__, connection);
1872 return (-1);
1873 } else if (content_length == NULL) {
1874 req->ntoread = -1;
1875 } else {
1876 char *endp;
1877 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
1878 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
1879 event_debug(("%s: illegal content length: %s",
1880 __func__, content_length));
1881 return (-1);
1883 req->ntoread = ntoread;
1886 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
1887 __func__, EV_I64_ARG(req->ntoread),
1888 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
1890 return (0);
1893 static int
1894 evhttp_method_may_have_body(enum evhttp_cmd_type type)
1896 switch (type) {
1897 case EVHTTP_REQ_POST:
1898 case EVHTTP_REQ_PUT:
1899 case EVHTTP_REQ_PATCH:
1900 return 1;
1901 case EVHTTP_REQ_TRACE:
1902 return 0;
1903 /* XXX May any of the below methods have a body? */
1904 case EVHTTP_REQ_GET:
1905 case EVHTTP_REQ_HEAD:
1906 case EVHTTP_REQ_DELETE:
1907 case EVHTTP_REQ_OPTIONS:
1908 case EVHTTP_REQ_CONNECT:
1909 return 0;
1910 default:
1911 return 0;
1915 static void
1916 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1918 const char *xfer_enc;
1920 /* If this is a request without a body, then we are done */
1921 if (req->kind == EVHTTP_REQUEST &&
1922 !evhttp_method_may_have_body(req->type)) {
1923 evhttp_connection_done(evcon);
1924 return;
1926 evcon->state = EVCON_READING_BODY;
1927 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
1928 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
1929 req->chunked = 1;
1930 req->ntoread = -1;
1931 } else {
1932 if (evhttp_get_body_length(req) == -1) {
1933 evhttp_connection_fail(evcon,
1934 EVCON_HTTP_INVALID_HEADER);
1935 return;
1937 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
1938 /* An incoming request with no content-length and no
1939 * transfer-encoding has no body. */
1940 evhttp_connection_done(evcon);
1941 return;
1945 /* Should we send a 100 Continue status line? */
1946 if (req->kind == EVHTTP_REQUEST && REQ_VERSION_ATLEAST(req, 1, 1)) {
1947 const char *expect;
1949 expect = evhttp_find_header(req->input_headers, "Expect");
1950 if (expect) {
1951 if (!evutil_ascii_strcasecmp(expect, "100-continue")) {
1952 /* XXX It would be nice to do some sanity
1953 checking here. Does the resource exist?
1954 Should the resource accept post requests? If
1955 no, we should respond with an error. For
1956 now, just optimistically tell the client to
1957 send their message body. */
1958 if (req->ntoread > 0) {
1959 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
1960 if ((req->evcon->max_body_size <= EV_INT64_MAX) && (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
1961 evhttp_send_error(req, HTTP_ENTITYTOOLARGE, NULL);
1962 return;
1965 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
1966 evhttp_send_continue(evcon, req);
1967 } else {
1968 evhttp_send_error(req, HTTP_EXPECTATIONFAILED,
1969 NULL);
1970 return;
1975 evhttp_read_body(evcon, req);
1976 /* note the request may have been freed in evhttp_read_body */
1979 static void
1980 evhttp_read_firstline(struct evhttp_connection *evcon,
1981 struct evhttp_request *req)
1983 enum message_read_status res;
1985 res = evhttp_parse_firstline(req, bufferevent_get_input(evcon->bufev));
1986 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
1987 /* Error while reading, terminate */
1988 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
1989 __func__, EV_SOCK_ARG(evcon->fd)));
1990 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1991 return;
1992 } else if (res == MORE_DATA_EXPECTED) {
1993 /* Need more header lines */
1994 return;
1997 evcon->state = EVCON_READING_HEADERS;
1998 evhttp_read_header(evcon, req);
2001 static void
2002 evhttp_read_header(struct evhttp_connection *evcon,
2003 struct evhttp_request *req)
2005 enum message_read_status res;
2006 evutil_socket_t fd = evcon->fd;
2008 res = evhttp_parse_headers(req, bufferevent_get_input(evcon->bufev));
2009 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2010 /* Error while reading, terminate */
2011 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2012 __func__, EV_SOCK_ARG(fd)));
2013 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
2014 return;
2015 } else if (res == MORE_DATA_EXPECTED) {
2016 /* Need more header lines */
2017 return;
2020 /* Disable reading for now */
2021 bufferevent_disable(evcon->bufev, EV_READ);
2023 /* Done reading headers, do the real work */
2024 switch (req->kind) {
2025 case EVHTTP_REQUEST:
2026 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2027 __func__, EV_SOCK_ARG(fd)));
2028 evhttp_get_body(evcon, req);
2029 /* note the request may have been freed in evhttp_get_body */
2030 break;
2032 case EVHTTP_RESPONSE:
2033 /* Start over if we got a 100 Continue response. */
2034 if (req->response_code == 100) {
2035 evhttp_start_read(evcon);
2036 return;
2038 if (!evhttp_response_needs_body(req)) {
2039 event_debug(("%s: skipping body for code %d\n",
2040 __func__, req->response_code));
2041 evhttp_connection_done(evcon);
2042 } else {
2043 event_debug(("%s: start of read body for %s on "
2044 EV_SOCK_FMT"\n",
2045 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2046 evhttp_get_body(evcon, req);
2047 /* note the request may have been freed in
2048 * evhttp_get_body */
2050 break;
2052 default:
2053 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2054 EV_SOCK_ARG(fd));
2055 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
2056 break;
2058 /* request may have been freed above */
2062 * Creates a TCP connection to the specified port and executes a callback
2063 * when finished. Failure or success is indicate by the passed connection
2064 * object.
2066 * Although this interface accepts a hostname, it is intended to take
2067 * only numeric hostnames so that non-blocking DNS resolution can
2068 * happen elsewhere.
2071 struct evhttp_connection *
2072 evhttp_connection_new(const char *address, unsigned short port)
2074 return (evhttp_connection_base_new(NULL, NULL, address, port));
2077 struct evhttp_connection *
2078 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2079 const char *address, unsigned short port)
2081 struct evhttp_connection *evcon = NULL;
2083 event_debug(("Attempting connection to %s:%d\n", address, port));
2085 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2086 event_warn("%s: calloc failed", __func__);
2087 goto error;
2090 evcon->fd = -1;
2091 evcon->port = port;
2093 evcon->max_headers_size = EV_SIZE_MAX;
2094 evcon->max_body_size = EV_SIZE_MAX;
2096 evcon->timeout = -1;
2097 evcon->retry_cnt = evcon->retry_max = 0;
2099 if ((evcon->address = mm_strdup(address)) == NULL) {
2100 event_warn("%s: strdup failed", __func__);
2101 goto error;
2104 if ((evcon->bufev = bufferevent_new(-1,
2105 evhttp_read_cb,
2106 evhttp_write_cb,
2107 evhttp_error_cb, evcon)) == NULL) {
2108 event_warn("%s: bufferevent_new failed", __func__);
2109 goto error;
2112 evcon->state = EVCON_DISCONNECTED;
2113 TAILQ_INIT(&evcon->requests);
2115 if (base != NULL) {
2116 evcon->base = base;
2117 bufferevent_base_set(base, evcon->bufev);
2121 event_deferred_cb_init(&evcon->read_more_deferred_cb,
2122 evhttp_deferred_read_cb, evcon);
2124 evcon->dns_base = dnsbase;
2126 return (evcon);
2128 error:
2129 if (evcon != NULL)
2130 evhttp_connection_free(evcon);
2131 return (NULL);
2134 struct bufferevent *
2135 evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2137 return evcon->bufev;
2140 void
2141 evhttp_connection_set_base(struct evhttp_connection *evcon,
2142 struct event_base *base)
2144 EVUTIL_ASSERT(evcon->base == NULL);
2145 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2146 evcon->base = base;
2147 bufferevent_base_set(base, evcon->bufev);
2150 void
2151 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2152 int timeout_in_secs)
2154 evcon->timeout = timeout_in_secs;
2156 if (evcon->timeout == -1)
2157 bufferevent_settimeout(evcon->bufev,
2158 HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
2159 else
2160 bufferevent_settimeout(evcon->bufev,
2161 evcon->timeout, evcon->timeout);
2164 void
2165 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2166 int retry_max)
2168 evcon->retry_max = retry_max;
2171 void
2172 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2173 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2175 evcon->closecb = cb;
2176 evcon->closecb_arg = cbarg;
2179 void
2180 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2181 char **address, ev_uint16_t *port)
2183 *address = evcon->address;
2184 *port = evcon->port;
2188 evhttp_connection_connect(struct evhttp_connection *evcon)
2190 int old_state = evcon->state;
2192 if (evcon->state == EVCON_CONNECTING)
2193 return (0);
2195 evhttp_connection_reset(evcon);
2197 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2198 evcon->flags |= EVHTTP_CON_OUTGOING;
2200 if (evcon->bind_address || evcon->bind_port) {
2201 evcon->fd = bind_socket(
2202 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2203 if (evcon->fd == -1) {
2204 event_debug(("%s: failed to bind to \"%s\"",
2205 __func__, evcon->bind_address));
2206 return (-1);
2209 bufferevent_setfd(evcon->bufev, evcon->fd);
2210 } else {
2211 bufferevent_setfd(evcon->bufev, -1);
2214 /* Set up a callback for successful connection setup */
2215 bufferevent_setcb(evcon->bufev,
2216 NULL /* evhttp_read_cb */,
2217 NULL /* evhttp_write_cb */,
2218 evhttp_connection_cb,
2219 evcon);
2220 bufferevent_settimeout(evcon->bufev, 0,
2221 evcon->timeout != -1 ? evcon->timeout : HTTP_CONNECT_TIMEOUT);
2222 /* make sure that we get a write callback */
2223 bufferevent_enable(evcon->bufev, EV_WRITE);
2225 evcon->state = EVCON_CONNECTING;
2227 if (bufferevent_socket_connect_hostname(evcon->bufev, evcon->dns_base,
2228 AF_UNSPEC, evcon->address, evcon->port) < 0) {
2229 evcon->state = old_state;
2230 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2231 __func__, evcon->address);
2232 /* some operating systems return ECONNREFUSED immediately
2233 * when connecting to a local address. the cleanup is going
2234 * to reschedule this function call.
2236 evhttp_connection_cb_cleanup(evcon);
2237 return (0);
2240 return (0);
2244 * Starts an HTTP request on the provided evhttp_connection object.
2245 * If the connection object is not connected to the web server already,
2246 * this will start the connection.
2250 evhttp_make_request(struct evhttp_connection *evcon,
2251 struct evhttp_request *req,
2252 enum evhttp_cmd_type type, const char *uri)
2254 /* We are making a request */
2255 req->kind = EVHTTP_REQUEST;
2256 req->type = type;
2257 if (req->uri != NULL)
2258 mm_free(req->uri);
2259 if ((req->uri = mm_strdup(uri)) == NULL) {
2260 event_warn("%s: strdup", __func__);
2261 evhttp_request_free(req);
2262 return (-1);
2265 /* Set the protocol version if it is not supplied */
2266 if (!req->major && !req->minor) {
2267 req->major = 1;
2268 req->minor = 1;
2271 EVUTIL_ASSERT(req->evcon == NULL);
2272 req->evcon = evcon;
2273 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2275 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2277 /* If the connection object is not connected; make it so */
2278 if (!evhttp_connected(evcon)) {
2279 int res = evhttp_connection_connect(evcon);
2280 /* evhttp_connection_fail(), which is called through
2281 * evhttp_connection_connect(), assumes that req lies in
2282 * evcon->requests. Thus, enqueue the request in advance and r
2283 * it in the error case. */
2284 if (res != 0)
2285 TAILQ_REMOVE(&evcon->requests, req, next);
2287 return res;
2291 * If it's connected already and we are the first in the queue,
2292 * then we can dispatch this request immediately. Otherwise, it
2293 * will be dispatched once the pending requests are completed.
2295 if (TAILQ_FIRST(&evcon->requests) == req)
2296 evhttp_request_dispatch(evcon);
2298 return (0);
2301 void
2302 evhttp_cancel_request(struct evhttp_request *req)
2304 struct evhttp_connection *evcon = req->evcon;
2305 if (evcon != NULL) {
2306 /* We need to remove it from the connection */
2307 if (TAILQ_FIRST(&evcon->requests) == req) {
2308 /* it's currently being worked on, so reset
2309 * the connection.
2311 evhttp_connection_fail(evcon,
2312 EVCON_HTTP_REQUEST_CANCEL);
2314 /* connection fail freed the request */
2315 return;
2316 } else {
2317 /* otherwise, we can just remove it from the
2318 * queue
2320 TAILQ_REMOVE(&evcon->requests, req, next);
2324 evhttp_request_free(req);
2328 * Reads data from file descriptor into request structure
2329 * Request structure needs to be set up correctly.
2332 void
2333 evhttp_start_read(struct evhttp_connection *evcon)
2335 /* Set up an event to read the headers */
2336 bufferevent_disable(evcon->bufev, EV_WRITE);
2337 bufferevent_enable(evcon->bufev, EV_READ);
2338 evcon->state = EVCON_READING_FIRSTLINE;
2339 /* Reset the bufferevent callbacks */
2340 bufferevent_setcb(evcon->bufev,
2341 evhttp_read_cb,
2342 evhttp_write_cb,
2343 evhttp_error_cb,
2344 evcon);
2346 /* If there's still data pending, process it next time through the
2347 * loop. Don't do it now; that could get recusive. */
2348 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2349 event_deferred_cb_schedule(get_deferred_queue(evcon),
2350 &evcon->read_more_deferred_cb);
2354 static void
2355 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2357 int need_close;
2358 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2359 TAILQ_REMOVE(&evcon->requests, req, next);
2361 need_close =
2362 (REQ_VERSION_BEFORE(req, 1, 1) &&
2363 !evhttp_is_connection_keepalive(req->input_headers))||
2364 evhttp_is_connection_close(req->flags, req->input_headers) ||
2365 evhttp_is_connection_close(req->flags, req->output_headers);
2367 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2368 evhttp_request_free(req);
2370 if (need_close) {
2371 evhttp_connection_free(evcon);
2372 return;
2375 /* we have a persistent connection; try to accept another request. */
2376 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2377 evhttp_connection_free(evcon);
2382 * Returns an error page.
2385 void
2386 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2389 #define ERR_FORMAT "<HTML><HEAD>\n" \
2390 "<TITLE>%d %s</TITLE>\n" \
2391 "</HEAD><BODY>\n" \
2392 "<H1>%s</H1>\n" \
2393 "</BODY></HTML>\n"
2395 struct evbuffer *buf = evbuffer_new();
2396 if (buf == NULL) {
2397 /* if we cannot allocate memory; we just drop the connection */
2398 evhttp_connection_free(req->evcon);
2399 return;
2401 if (reason == NULL) {
2402 reason = evhttp_response_phrase_internal(error);
2405 evhttp_response_code(req, error, reason);
2407 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2409 evhttp_send_page(req, buf);
2411 evbuffer_free(buf);
2412 #undef ERR_FORMAT
2415 /* Requires that headers and response code are already set up */
2417 static inline void
2418 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2420 struct evhttp_connection *evcon = req->evcon;
2422 if (evcon == NULL) {
2423 evhttp_request_free(req);
2424 return;
2427 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2429 /* we expect no more calls form the user on this request */
2430 req->userdone = 1;
2432 /* xxx: not sure if we really should expose the data buffer this way */
2433 if (databuf != NULL)
2434 evbuffer_add_buffer(req->output_buffer, databuf);
2436 /* Adds headers to the response */
2437 evhttp_make_header(evcon, req);
2439 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2442 void
2443 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2444 struct evbuffer *databuf)
2446 evhttp_response_code(req, code, reason);
2448 evhttp_send(req, databuf);
2451 void
2452 evhttp_send_reply_start(struct evhttp_request *req, int code,
2453 const char *reason)
2455 evhttp_response_code(req, code, reason);
2456 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2457 REQ_VERSION_ATLEAST(req, 1, 1) &&
2458 evhttp_response_needs_body(req)) {
2460 * prefer HTTP/1.1 chunked encoding to closing the connection;
2461 * note RFC 2616 section 4.4 forbids it with Content-Length:
2462 * and it's not necessary then anyway.
2464 evhttp_add_header(req->output_headers, "Transfer-Encoding",
2465 "chunked");
2466 req->chunked = 1;
2467 } else {
2468 req->chunked = 0;
2470 evhttp_make_header(req->evcon, req);
2471 evhttp_write_buffer(req->evcon, NULL, NULL);
2474 void
2475 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
2477 struct evhttp_connection *evcon = req->evcon;
2478 struct evbuffer *output;
2480 if (evcon == NULL)
2481 return;
2483 output = bufferevent_get_output(evcon->bufev);
2485 if (evbuffer_get_length(databuf) == 0)
2486 return;
2487 if (!evhttp_response_needs_body(req))
2488 return;
2489 if (req->chunked) {
2490 evbuffer_add_printf(output, "%x\r\n",
2491 (unsigned)evbuffer_get_length(databuf));
2493 evbuffer_add_buffer(output, databuf);
2494 if (req->chunked) {
2495 evbuffer_add(output, "\r\n", 2);
2497 evhttp_write_buffer(evcon, NULL, NULL);
2500 void
2501 evhttp_send_reply_end(struct evhttp_request *req)
2503 struct evhttp_connection *evcon = req->evcon;
2504 struct evbuffer *output;
2506 if (evcon == NULL) {
2507 evhttp_request_free(req);
2508 return;
2511 output = bufferevent_get_output(evcon->bufev);
2513 /* we expect no more calls form the user on this request */
2514 req->userdone = 1;
2516 if (req->chunked) {
2517 evbuffer_add(output, "0\r\n\r\n", 5);
2518 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2519 req->chunked = 0;
2520 } else if (evbuffer_get_length(output) == 0) {
2521 /* let the connection know that we are done with the request */
2522 evhttp_send_done(evcon, NULL);
2523 } else {
2524 /* make the callback execute after all data has been written */
2525 evcon->cb = evhttp_send_done;
2526 evcon->cb_arg = NULL;
2530 static const char *informational_phrases[] = {
2531 /* 100 */ "Continue",
2532 /* 101 */ "Switching Protocols"
2535 static const char *success_phrases[] = {
2536 /* 200 */ "OK",
2537 /* 201 */ "Created",
2538 /* 202 */ "Accepted",
2539 /* 203 */ "Non-Authoritative Information",
2540 /* 204 */ "No Content",
2541 /* 205 */ "Reset Content",
2542 /* 206 */ "Partial Content"
2545 static const char *redirection_phrases[] = {
2546 /* 300 */ "Multiple Choices",
2547 /* 301 */ "Moved Permanently",
2548 /* 302 */ "Found",
2549 /* 303 */ "See Other",
2550 /* 304 */ "Not Modified",
2551 /* 305 */ "Use Proxy",
2552 /* 307 */ "Temporary Redirect"
2555 static const char *client_error_phrases[] = {
2556 /* 400 */ "Bad Request",
2557 /* 401 */ "Unauthorized",
2558 /* 402 */ "Payment Required",
2559 /* 403 */ "Forbidden",
2560 /* 404 */ "Not Found",
2561 /* 405 */ "Method Not Allowed",
2562 /* 406 */ "Not Acceptable",
2563 /* 407 */ "Proxy Authentication Required",
2564 /* 408 */ "Request Time-out",
2565 /* 409 */ "Conflict",
2566 /* 410 */ "Gone",
2567 /* 411 */ "Length Required",
2568 /* 412 */ "Precondition Failed",
2569 /* 413 */ "Request Entity Too Large",
2570 /* 414 */ "Request-URI Too Large",
2571 /* 415 */ "Unsupported Media Type",
2572 /* 416 */ "Requested range not satisfiable",
2573 /* 417 */ "Expectation Failed"
2576 static const char *server_error_phrases[] = {
2577 /* 500 */ "Internal Server Error",
2578 /* 501 */ "Not Implemented",
2579 /* 502 */ "Bad Gateway",
2580 /* 503 */ "Service Unavailable",
2581 /* 504 */ "Gateway Time-out",
2582 /* 505 */ "HTTP Version not supported"
2585 struct response_class {
2586 const char *name;
2587 size_t num_responses;
2588 const char **responses;
2591 #ifndef MEMBERSOF
2592 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
2593 #endif
2595 static const struct response_class response_classes[] = {
2596 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
2597 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
2598 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
2599 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
2600 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
2603 static const char *
2604 evhttp_response_phrase_internal(int code)
2606 int klass = code / 100 - 1;
2607 int subcode = code % 100;
2609 /* Unknown class - can't do any better here */
2610 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
2611 return "Unknown Status Class";
2613 /* Unknown sub-code, return class name at least */
2614 if (subcode >= (int) response_classes[klass].num_responses)
2615 return response_classes[klass].name;
2617 return response_classes[klass].responses[subcode];
2620 void
2621 evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
2623 req->kind = EVHTTP_RESPONSE;
2624 req->response_code = code;
2625 if (req->response_code_line != NULL)
2626 mm_free(req->response_code_line);
2627 if (reason == NULL)
2628 reason = evhttp_response_phrase_internal(code);
2629 req->response_code_line = mm_strdup(reason);
2630 if (req->response_code_line == NULL) {
2631 event_warn("%s: strdup", __func__);
2632 /* XXX what else can we do? */
2636 void
2637 evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
2639 if (!req->major || !req->minor) {
2640 req->major = 1;
2641 req->minor = 1;
2644 if (req->kind != EVHTTP_RESPONSE)
2645 evhttp_response_code(req, 200, "OK");
2647 evhttp_clear_headers(req->output_headers);
2648 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
2649 evhttp_add_header(req->output_headers, "Connection", "close");
2651 evhttp_send(req, databuf);
2654 static const char uri_chars[256] = {
2655 /* 0 */
2656 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2657 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2658 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
2659 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
2660 /* 64 */
2661 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2662 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
2663 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2664 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
2665 /* 128 */
2666 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2667 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2668 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2669 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2670 /* 192 */
2671 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2672 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2673 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2674 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2677 #define CHAR_IS_UNRESERVED(c) \
2678 (uri_chars[(unsigned char)(c)])
2681 * Helper functions to encode/decode a string for inclusion in a URI.
2682 * The returned string must be freed by the caller.
2684 char *
2685 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
2687 struct evbuffer *buf = evbuffer_new();
2688 const char *p, *end;
2689 char *result;
2691 if (buf == NULL)
2692 return (NULL);
2694 if (len >= 0)
2695 end = uri+len;
2696 else
2697 end = uri+strlen(uri);
2699 for (p = uri; p < end; p++) {
2700 if (CHAR_IS_UNRESERVED(*p)) {
2701 evbuffer_add(buf, p, 1);
2702 } else if (*p == ' ' && space_as_plus) {
2703 evbuffer_add(buf, "+", 1);
2704 } else {
2705 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
2708 evbuffer_add(buf, "", 1); /* NUL-terminator. */
2709 result = mm_malloc(evbuffer_get_length(buf));
2710 if (result)
2711 evbuffer_remove(buf, result, evbuffer_get_length(buf));
2712 evbuffer_free(buf);
2714 return (result);
2717 char *
2718 evhttp_encode_uri(const char *str)
2720 return evhttp_uriencode(str, -1, 0);
2724 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
2725 * If -1, when true we transform plus to space only after we've seen
2726 * a ?. -1 is deprecated.
2727 * @return the number of bytes written to 'ret'.
2729 static int
2730 evhttp_decode_uri_internal(
2731 const char *uri, size_t length, char *ret, int decode_plus_ctl)
2733 char c;
2734 int j;
2735 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
2736 unsigned i;
2738 for (i = j = 0; i < length; i++) {
2739 c = uri[i];
2740 if (c == '?') {
2741 if (decode_plus_ctl < 0)
2742 decode_plus = 1;
2743 } else if (c == '+' && decode_plus) {
2744 c = ' ';
2745 } else if (c == '%' && EVUTIL_ISXDIGIT(uri[i+1]) &&
2746 EVUTIL_ISXDIGIT(uri[i+2])) {
2747 char tmp[3];
2748 tmp[0] = uri[i+1];
2749 tmp[1] = uri[i+2];
2750 tmp[2] = '\0';
2751 c = (char)strtol(tmp, NULL, 16);
2752 i += 2;
2754 ret[j++] = c;
2756 ret[j] = '\0';
2758 return (j);
2761 /* deprecated */
2762 char *
2763 evhttp_decode_uri(const char *uri)
2765 char *ret;
2767 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2768 event_warn("%s: malloc(%lu)", __func__,
2769 (unsigned long)(strlen(uri) + 1));
2770 return (NULL);
2773 evhttp_decode_uri_internal(uri, strlen(uri),
2774 ret, -1 /*always_decode_plus*/);
2776 return (ret);
2779 char *
2780 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
2782 char *ret;
2783 int n;
2785 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2786 event_warn("%s: malloc(%lu)", __func__,
2787 (unsigned long)(strlen(uri) + 1));
2788 return (NULL);
2791 n = evhttp_decode_uri_internal(uri, strlen(uri),
2792 ret, !!decode_plus/*always_decode_plus*/);
2794 if (size_out) {
2795 EVUTIL_ASSERT(n >= 0);
2796 *size_out = (size_t)n;
2799 return (ret);
2803 * Helper function to parse out arguments in a query.
2804 * The arguments are separated by key and value.
2807 static int
2808 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
2809 int is_whole_uri)
2811 char *line=NULL;
2812 char *argument;
2813 char *p;
2814 const char *query_part;
2815 int result = -1;
2816 struct evhttp_uri *uri=NULL;
2818 TAILQ_INIT(headers);
2820 if (is_whole_uri) {
2821 uri = evhttp_uri_parse(str);
2822 if (!uri)
2823 goto error;
2824 query_part = evhttp_uri_get_query(uri);
2825 } else {
2826 query_part = str;
2829 /* No arguments - we are done */
2830 if (!query_part || !strlen(query_part)) {
2831 result = 0;
2832 goto done;
2835 if ((line = mm_strdup(query_part)) == NULL) {
2836 event_warn("%s: strdup", __func__);
2837 goto error;
2840 p = argument = line;
2841 while (p != NULL && *p != '\0') {
2842 char *key, *value, *decoded_value;
2843 argument = strsep(&p, "&");
2845 value = argument;
2846 key = strsep(&value, "=");
2847 if (value == NULL || *key == '\0') {
2848 goto error;
2851 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
2852 event_warn("%s: mm_malloc", __func__);
2853 goto error;
2855 evhttp_decode_uri_internal(value, strlen(value),
2856 decoded_value, 1 /*always_decode_plus*/);
2857 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
2858 evhttp_add_header_internal(headers, key, decoded_value);
2859 mm_free(decoded_value);
2862 result = 0;
2863 goto done;
2864 error:
2865 evhttp_clear_headers(headers);
2866 done:
2867 if (line)
2868 mm_free(line);
2869 if (uri)
2870 evhttp_uri_free(uri);
2871 return result;
2875 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
2877 return evhttp_parse_query_impl(uri, headers, 1);
2880 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
2882 return evhttp_parse_query_impl(uri, headers, 0);
2885 static struct evhttp_cb *
2886 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
2888 struct evhttp_cb *cb;
2889 size_t offset = 0;
2890 char *translated;
2891 const char *path;
2893 /* Test for different URLs */
2894 path = evhttp_uri_get_path(req->uri_elems);
2895 offset = strlen(path);
2896 if ((translated = mm_malloc(offset + 1)) == NULL)
2897 return (NULL);
2898 evhttp_decode_uri_internal(path, offset, translated,
2899 0 /* decode_plus */);
2901 TAILQ_FOREACH(cb, callbacks, next) {
2902 if (!strcmp(cb->what, translated)) {
2903 mm_free(translated);
2904 return (cb);
2908 mm_free(translated);
2909 return (NULL);
2913 static int
2914 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
2916 char c;
2918 while (1) {
2919 switch (c = *pattern++) {
2920 case '\0':
2921 return *name == '\0';
2923 case '*':
2924 while (*name != '\0') {
2925 if (prefix_suffix_match(pattern, name,
2926 ignorecase))
2927 return (1);
2928 ++name;
2930 return (0);
2931 default:
2932 if (c != *name) {
2933 if (!ignorecase ||
2934 EVUTIL_TOLOWER(c) != EVUTIL_TOLOWER(*name))
2935 return (0);
2937 ++name;
2940 /* NOTREACHED */
2944 Search the vhost hierarchy beginning with http for a server alias
2945 matching hostname. If a match is found, and outhttp is non-null,
2946 outhttp is set to the matching http object and 1 is returned.
2949 static int
2950 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
2951 const char *hostname)
2953 struct evhttp_server_alias *alias;
2954 struct evhttp *vhost;
2956 TAILQ_FOREACH(alias, &http->aliases, next) {
2957 /* XXX Do we need to handle IP addresses? */
2958 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
2959 if (outhttp)
2960 *outhttp = http;
2961 return 1;
2965 /* XXX It might be good to avoid recursion here, but I don't
2966 see a way to do that w/o a list. */
2967 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
2968 if (evhttp_find_alias(vhost, outhttp, hostname))
2969 return 1;
2972 return 0;
2976 Attempts to find the best http object to handle a request for a hostname.
2977 All aliases for the root http object and vhosts are searched for an exact
2978 match. Then, the vhost hierarchy is traversed again for a matching
2979 pattern.
2981 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
2982 is set with the best matching http object. If there are no matches, the
2983 root http object is stored in outhttp and 0 is returned.
2986 static int
2987 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
2988 const char *hostname)
2990 struct evhttp *vhost;
2991 struct evhttp *oldhttp;
2992 int match_found = 0;
2994 if (evhttp_find_alias(http, outhttp, hostname))
2995 return 1;
2997 do {
2998 oldhttp = http;
2999 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3000 if (prefix_suffix_match(vhost->vhost_pattern,
3001 hostname, 1 /* ignorecase */)) {
3002 http = vhost;
3003 match_found = 1;
3004 break;
3007 } while (oldhttp != http);
3009 if (outhttp)
3010 *outhttp = http;
3012 return match_found;
3015 static void
3016 evhttp_handle_request(struct evhttp_request *req, void *arg)
3018 struct evhttp *http = arg;
3019 struct evhttp_cb *cb = NULL;
3020 const char *hostname;
3022 /* we have a new request on which the user needs to take action */
3023 req->userdone = 0;
3025 if (req->type == 0 || req->uri == NULL) {
3026 evhttp_send_error(req, HTTP_BADREQUEST, NULL);
3027 return;
3030 if ((http->allowed_methods & req->type) == 0) {
3031 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3032 (unsigned)req->type, (unsigned)http->allowed_methods));
3033 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3034 return;
3037 /* handle potential virtual hosts */
3038 hostname = evhttp_request_get_host(req);
3039 if (hostname != NULL) {
3040 evhttp_find_vhost(http, &http, hostname);
3043 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3044 (*cb->cb)(req, cb->cbarg);
3045 return;
3048 /* Generic call back */
3049 if (http->gencb) {
3050 (*http->gencb)(req, http->gencbarg);
3051 return;
3052 } else {
3053 /* We need to send a 404 here */
3054 #define ERR_FORMAT "<html><head>" \
3055 "<title>404 Not Found</title>" \
3056 "</head><body>" \
3057 "<h1>Not Found</h1>" \
3058 "<p>The requested URL %s was not found on this server.</p>"\
3059 "</body></html>\n"
3061 char *escaped_html;
3062 struct evbuffer *buf;
3064 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3065 evhttp_connection_free(req->evcon);
3066 return;
3069 if ((buf = evbuffer_new()) == NULL) {
3070 mm_free(escaped_html);
3071 evhttp_connection_free(req->evcon);
3072 return;
3075 evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
3077 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3079 mm_free(escaped_html);
3081 evhttp_send_page(req, buf);
3083 evbuffer_free(buf);
3084 #undef ERR_FORMAT
3088 /* Listener callback when a connection arrives at a server. */
3089 static void
3090 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3092 struct evhttp *http = arg;
3094 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3098 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3100 struct evhttp_bound_socket *bound =
3101 evhttp_bind_socket_with_handle(http, address, port);
3102 if (bound == NULL)
3103 return (-1);
3104 return (0);
3107 struct evhttp_bound_socket *
3108 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3110 evutil_socket_t fd;
3111 struct evhttp_bound_socket *bound;
3113 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3114 return (NULL);
3116 if (listen(fd, 128) == -1) {
3117 event_sock_warn(fd, "%s: listen", __func__);
3118 evutil_closesocket(fd);
3119 return (NULL);
3122 bound = evhttp_accept_socket_with_handle(http, fd);
3124 if (bound != NULL) {
3125 event_debug(("Bound to port %d - Awaiting connections ... ",
3126 port));
3127 return (bound);
3130 return (NULL);
3134 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3136 struct evhttp_bound_socket *bound =
3137 evhttp_accept_socket_with_handle(http, fd);
3138 if (bound == NULL)
3139 return (-1);
3140 return (0);
3144 struct evhttp_bound_socket *
3145 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3147 struct evhttp_bound_socket *bound;
3148 struct evconnlistener *listener;
3149 const int flags =
3150 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3152 listener = evconnlistener_new(http->base, NULL, NULL,
3153 flags,
3154 0, /* Backlog is '0' because we already said 'listen' */
3155 fd);
3156 if (!listener)
3157 return (NULL);
3159 bound = evhttp_bind_listener(http, listener);
3160 if (!bound) {
3161 evconnlistener_free(listener);
3162 return (NULL);
3164 return (bound);
3167 struct evhttp_bound_socket *
3168 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3170 struct evhttp_bound_socket *bound;
3172 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3173 if (bound == NULL)
3174 return (NULL);
3176 bound->listener = listener;
3177 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3179 evconnlistener_set_cb(listener, accept_socket_cb, http);
3180 return bound;
3183 evutil_socket_t
3184 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3186 return evconnlistener_get_fd(bound->listener);
3189 struct evconnlistener *
3190 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3192 return bound->listener;
3195 void
3196 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3198 TAILQ_REMOVE(&http->sockets, bound, next);
3199 evconnlistener_free(bound->listener);
3200 mm_free(bound);
3203 static struct evhttp*
3204 evhttp_new_object(void)
3206 struct evhttp *http = NULL;
3208 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3209 event_warn("%s: calloc", __func__);
3210 return (NULL);
3213 http->timeout = -1;
3214 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3215 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3216 evhttp_set_allowed_methods(http,
3217 EVHTTP_REQ_GET |
3218 EVHTTP_REQ_POST |
3219 EVHTTP_REQ_HEAD |
3220 EVHTTP_REQ_PUT |
3221 EVHTTP_REQ_DELETE);
3223 TAILQ_INIT(&http->sockets);
3224 TAILQ_INIT(&http->callbacks);
3225 TAILQ_INIT(&http->connections);
3226 TAILQ_INIT(&http->virtualhosts);
3227 TAILQ_INIT(&http->aliases);
3229 return (http);
3232 struct evhttp *
3233 evhttp_new(struct event_base *base)
3235 struct evhttp *http = NULL;
3237 http = evhttp_new_object();
3238 if (http == NULL)
3239 return (NULL);
3240 http->base = base;
3242 return (http);
3246 * Start a web server on the specified address and port.
3249 struct evhttp *
3250 evhttp_start(const char *address, unsigned short port)
3252 struct evhttp *http = NULL;
3254 http = evhttp_new_object();
3255 if (http == NULL)
3256 return (NULL);
3257 if (evhttp_bind_socket(http, address, port) == -1) {
3258 mm_free(http);
3259 return (NULL);
3262 return (http);
3265 void
3266 evhttp_free(struct evhttp* http)
3268 struct evhttp_cb *http_cb;
3269 struct evhttp_connection *evcon;
3270 struct evhttp_bound_socket *bound;
3271 struct evhttp* vhost;
3272 struct evhttp_server_alias *alias;
3274 /* Remove the accepting part */
3275 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3276 TAILQ_REMOVE(&http->sockets, bound, next);
3278 evconnlistener_free(bound->listener);
3280 mm_free(bound);
3283 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3284 /* evhttp_connection_free removes the connection */
3285 evhttp_connection_free(evcon);
3288 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3289 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3290 mm_free(http_cb->what);
3291 mm_free(http_cb);
3294 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3295 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3297 evhttp_free(vhost);
3300 if (http->vhost_pattern != NULL)
3301 mm_free(http->vhost_pattern);
3303 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3304 TAILQ_REMOVE(&http->aliases, alias, next);
3305 mm_free(alias->alias);
3306 mm_free(alias);
3309 mm_free(http);
3313 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3314 struct evhttp* vhost)
3316 /* a vhost can only be a vhost once and should not have bound sockets */
3317 if (vhost->vhost_pattern != NULL ||
3318 TAILQ_FIRST(&vhost->sockets) != NULL)
3319 return (-1);
3321 vhost->vhost_pattern = mm_strdup(pattern);
3322 if (vhost->vhost_pattern == NULL)
3323 return (-1);
3325 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3327 return (0);
3331 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3333 if (vhost->vhost_pattern == NULL)
3334 return (-1);
3336 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3338 mm_free(vhost->vhost_pattern);
3339 vhost->vhost_pattern = NULL;
3341 return (0);
3345 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3347 struct evhttp_server_alias *evalias;
3349 evalias = mm_calloc(1, sizeof(*evalias));
3350 if (!evalias)
3351 return -1;
3353 evalias->alias = mm_strdup(alias);
3354 if (!evalias->alias) {
3355 mm_free(evalias);
3356 return -1;
3359 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3361 return 0;
3365 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3367 struct evhttp_server_alias *evalias;
3369 TAILQ_FOREACH(evalias, &http->aliases, next) {
3370 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3371 TAILQ_REMOVE(&http->aliases, evalias, next);
3372 mm_free(evalias->alias);
3373 mm_free(evalias);
3374 return 0;
3378 return -1;
3381 void
3382 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
3384 http->timeout = timeout_in_secs;
3387 void
3388 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
3390 if (max_headers_size < 0)
3391 http->default_max_headers_size = EV_SIZE_MAX;
3392 else
3393 http->default_max_headers_size = max_headers_size;
3396 void
3397 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
3399 if (max_body_size < 0)
3400 http->default_max_body_size = EV_UINT64_MAX;
3401 else
3402 http->default_max_body_size = max_body_size;
3405 void
3406 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
3408 http->allowed_methods = methods;
3412 evhttp_set_cb(struct evhttp *http, const char *uri,
3413 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3415 struct evhttp_cb *http_cb;
3417 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3418 if (strcmp(http_cb->what, uri) == 0)
3419 return (-1);
3422 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
3423 event_warn("%s: calloc", __func__);
3424 return (-2);
3427 http_cb->what = mm_strdup(uri);
3428 if (http_cb->what == NULL) {
3429 event_warn("%s: strdup", __func__);
3430 mm_free(http_cb);
3431 return (-3);
3433 http_cb->cb = cb;
3434 http_cb->cbarg = cbarg;
3436 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
3438 return (0);
3442 evhttp_del_cb(struct evhttp *http, const char *uri)
3444 struct evhttp_cb *http_cb;
3446 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3447 if (strcmp(http_cb->what, uri) == 0)
3448 break;
3450 if (http_cb == NULL)
3451 return (-1);
3453 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3454 mm_free(http_cb->what);
3455 mm_free(http_cb);
3457 return (0);
3460 void
3461 evhttp_set_gencb(struct evhttp *http,
3462 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3464 http->gencb = cb;
3465 http->gencbarg = cbarg;
3469 * Request related functions
3472 struct evhttp_request *
3473 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
3475 struct evhttp_request *req = NULL;
3477 /* Allocate request structure */
3478 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
3479 event_warn("%s: calloc", __func__);
3480 goto error;
3483 req->headers_size = 0;
3484 req->body_size = 0;
3486 req->kind = EVHTTP_RESPONSE;
3487 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3488 if (req->input_headers == NULL) {
3489 event_warn("%s: calloc", __func__);
3490 goto error;
3492 TAILQ_INIT(req->input_headers);
3494 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3495 if (req->output_headers == NULL) {
3496 event_warn("%s: calloc", __func__);
3497 goto error;
3499 TAILQ_INIT(req->output_headers);
3501 if ((req->input_buffer = evbuffer_new()) == NULL) {
3502 event_warn("%s: evbuffer_new", __func__);
3503 goto error;
3506 if ((req->output_buffer = evbuffer_new()) == NULL) {
3507 event_warn("%s: evbuffer_new", __func__);
3508 goto error;
3511 req->cb = cb;
3512 req->cb_arg = arg;
3514 return (req);
3516 error:
3517 if (req != NULL)
3518 evhttp_request_free(req);
3519 return (NULL);
3522 void
3523 evhttp_request_free(struct evhttp_request *req)
3525 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
3526 req->flags |= EVHTTP_REQ_NEEDS_FREE;
3527 return;
3530 if (req->remote_host != NULL)
3531 mm_free(req->remote_host);
3532 if (req->uri != NULL)
3533 mm_free(req->uri);
3534 if (req->uri_elems != NULL)
3535 evhttp_uri_free(req->uri_elems);
3536 if (req->response_code_line != NULL)
3537 mm_free(req->response_code_line);
3538 if (req->host_cache != NULL)
3539 mm_free(req->host_cache);
3541 evhttp_clear_headers(req->input_headers);
3542 mm_free(req->input_headers);
3544 evhttp_clear_headers(req->output_headers);
3545 mm_free(req->output_headers);
3547 if (req->input_buffer != NULL)
3548 evbuffer_free(req->input_buffer);
3550 if (req->output_buffer != NULL)
3551 evbuffer_free(req->output_buffer);
3553 mm_free(req);
3556 void
3557 evhttp_request_own(struct evhttp_request *req)
3559 req->flags |= EVHTTP_USER_OWNED;
3563 evhttp_request_is_owned(struct evhttp_request *req)
3565 return (req->flags & EVHTTP_USER_OWNED) != 0;
3568 struct evhttp_connection *
3569 evhttp_request_get_connection(struct evhttp_request *req)
3571 return req->evcon;
3574 struct event_base *
3575 evhttp_connection_get_base(struct evhttp_connection *conn)
3577 return conn->base;
3580 void
3581 evhttp_request_set_chunked_cb(struct evhttp_request *req,
3582 void (*cb)(struct evhttp_request *, void *))
3584 req->chunk_cb = cb;
3588 * Allows for inspection of the request URI
3591 const char *
3592 evhttp_request_get_uri(const struct evhttp_request *req) {
3593 if (req->uri == NULL)
3594 event_debug(("%s: request %p has no uri\n", __func__, req));
3595 return (req->uri);
3598 const struct evhttp_uri *
3599 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
3600 if (req->uri_elems == NULL)
3601 event_debug(("%s: request %p has no uri elems\n",
3602 __func__, req));
3603 return (req->uri_elems);
3606 const char *
3607 evhttp_request_get_host(struct evhttp_request *req)
3609 const char *host = NULL;
3611 if (req->host_cache)
3612 return req->host_cache;
3614 if (req->uri_elems)
3615 host = evhttp_uri_get_host(req->uri_elems);
3616 if (!host && req->input_headers) {
3617 const char *p;
3618 size_t len;
3620 host = evhttp_find_header(req->input_headers, "Host");
3621 /* The Host: header may include a port. Remove it here
3622 to be consistent with uri_elems case above. */
3623 if (host) {
3624 p = host + strlen(host) - 1;
3625 while (p > host && EVUTIL_ISDIGIT(*p))
3626 --p;
3627 if (p > host && *p == ':') {
3628 len = p - host;
3629 req->host_cache = mm_malloc(len + 1);
3630 if (!req->host_cache) {
3631 event_warn("%s: malloc", __func__);
3632 return NULL;
3634 memcpy(req->host_cache, host, len);
3635 req->host_cache[len] = '\0';
3636 host = req->host_cache;
3641 return host;
3644 enum evhttp_cmd_type
3645 evhttp_request_get_command(const struct evhttp_request *req) {
3646 return (req->type);
3650 evhttp_request_get_response_code(const struct evhttp_request *req)
3652 return req->response_code;
3655 /** Returns the input headers */
3656 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
3658 return (req->input_headers);
3661 /** Returns the output headers */
3662 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
3664 return (req->output_headers);
3667 /** Returns the input buffer */
3668 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
3670 return (req->input_buffer);
3673 /** Returns the output buffer */
3674 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
3676 return (req->output_buffer);
3681 * Takes a file descriptor to read a request from.
3682 * The callback is executed once the whole request has been read.
3685 static struct evhttp_connection*
3686 evhttp_get_request_connection(
3687 struct evhttp* http,
3688 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
3690 struct evhttp_connection *evcon;
3691 char *hostname = NULL, *portname = NULL;
3693 name_from_addr(sa, salen, &hostname, &portname);
3694 if (hostname == NULL || portname == NULL) {
3695 if (hostname) mm_free(hostname);
3696 if (portname) mm_free(portname);
3697 return (NULL);
3700 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
3701 __func__, hostname, portname, EV_SOCK_ARG(fd)));
3703 /* we need a connection object to put the http request on */
3704 evcon = evhttp_connection_base_new(
3705 http->base, NULL, hostname, atoi(portname));
3706 mm_free(hostname);
3707 mm_free(portname);
3708 if (evcon == NULL)
3709 return (NULL);
3711 evcon->max_headers_size = http->default_max_headers_size;
3712 evcon->max_body_size = http->default_max_body_size;
3714 evcon->flags |= EVHTTP_CON_INCOMING;
3715 evcon->state = EVCON_READING_FIRSTLINE;
3717 evcon->fd = fd;
3719 bufferevent_setfd(evcon->bufev, fd);
3721 return (evcon);
3724 static int
3725 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
3727 struct evhttp *http = evcon->http_server;
3728 struct evhttp_request *req;
3729 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
3730 return (-1);
3732 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
3733 event_warn("%s: strdup", __func__);
3734 evhttp_request_free(req);
3735 return (-1);
3737 req->remote_port = evcon->port;
3739 req->evcon = evcon; /* the request ends up owning the connection */
3740 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
3742 /* We did not present the request to the user user yet, so treat it as
3743 * if the user was done with the request. This allows us to free the
3744 * request on a persistent connection if the client drops it without
3745 * sending a request.
3747 req->userdone = 1;
3749 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
3751 req->kind = EVHTTP_REQUEST;
3754 evhttp_start_read(evcon);
3756 return (0);
3759 static void
3760 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
3761 struct sockaddr *sa, ev_socklen_t salen)
3763 struct evhttp_connection *evcon;
3765 evcon = evhttp_get_request_connection(http, fd, sa, salen);
3766 if (evcon == NULL) {
3767 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
3768 __func__, EV_SOCK_ARG(fd));
3769 evutil_closesocket(fd);
3770 return;
3773 /* the timeout can be used by the server to close idle connections */
3774 if (http->timeout != -1)
3775 evhttp_connection_set_timeout(evcon, http->timeout);
3778 * if we want to accept more than one request on a connection,
3779 * we need to know which http server it belongs to.
3781 evcon->http_server = http;
3782 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
3784 if (evhttp_associate_new_request_with_connection(evcon) == -1)
3785 evhttp_connection_free(evcon);
3790 * Network helper functions that we do not want to export to the rest of
3791 * the world.
3794 static void
3795 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
3796 char **phost, char **pport)
3798 char ntop[NI_MAXHOST];
3799 char strport[NI_MAXSERV];
3800 int ni_result;
3802 #ifdef _EVENT_HAVE_GETNAMEINFO
3803 ni_result = getnameinfo(sa, salen,
3804 ntop, sizeof(ntop), strport, sizeof(strport),
3805 NI_NUMERICHOST|NI_NUMERICSERV);
3807 if (ni_result != 0) {
3808 #ifdef EAI_SYSTEM
3809 /* Windows doesn't have an EAI_SYSTEM. */
3810 if (ni_result == EAI_SYSTEM)
3811 event_err(1, "getnameinfo failed");
3812 else
3813 #endif
3814 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
3815 return;
3817 #else
3818 ni_result = fake_getnameinfo(sa, salen,
3819 ntop, sizeof(ntop), strport, sizeof(strport),
3820 NI_NUMERICHOST|NI_NUMERICSERV);
3821 if (ni_result != 0)
3822 return;
3823 #endif
3825 *phost = mm_strdup(ntop);
3826 *pport = mm_strdup(strport);
3829 /* Create a non-blocking socket and bind it */
3830 /* todo: rename this function */
3831 static evutil_socket_t
3832 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
3834 evutil_socket_t fd;
3836 int on = 1, r;
3837 int serrno;
3839 /* Create listen socket */
3840 fd = socket(ai ? ai->ai_family : AF_INET, SOCK_STREAM, 0);
3841 if (fd == -1) {
3842 event_sock_warn(-1, "socket");
3843 return (-1);
3846 if (evutil_make_socket_nonblocking(fd) < 0)
3847 goto out;
3848 if (evutil_make_socket_closeonexec(fd) < 0)
3849 goto out;
3851 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
3852 goto out;
3853 if (reuse) {
3854 if (evutil_make_listen_socket_reuseable(fd) < 0)
3855 goto out;
3858 if (ai != NULL) {
3859 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
3860 if (r == -1)
3861 goto out;
3864 return (fd);
3866 out:
3867 serrno = EVUTIL_SOCKET_ERROR();
3868 evutil_closesocket(fd);
3869 EVUTIL_SET_SOCKET_ERROR(serrno);
3870 return (-1);
3873 static struct evutil_addrinfo *
3874 make_addrinfo(const char *address, ev_uint16_t port)
3876 struct evutil_addrinfo *ai = NULL;
3878 struct evutil_addrinfo hints;
3879 char strport[NI_MAXSERV];
3880 int ai_result;
3882 memset(&hints, 0, sizeof(hints));
3883 hints.ai_family = AF_UNSPEC;
3884 hints.ai_socktype = SOCK_STREAM;
3885 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
3886 * types we don't have an interface to connect to. */
3887 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
3888 evutil_snprintf(strport, sizeof(strport), "%d", port);
3889 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
3890 != 0) {
3891 if (ai_result == EVUTIL_EAI_SYSTEM)
3892 event_warn("getaddrinfo");
3893 else
3894 event_warnx("getaddrinfo: %s",
3895 evutil_gai_strerror(ai_result));
3896 return (NULL);
3899 return (ai);
3902 static evutil_socket_t
3903 bind_socket(const char *address, ev_uint16_t port, int reuse)
3905 evutil_socket_t fd;
3906 struct evutil_addrinfo *aitop = NULL;
3908 /* just create an unbound socket */
3909 if (address == NULL && port == 0)
3910 return bind_socket_ai(NULL, 0);
3912 aitop = make_addrinfo(address, port);
3914 if (aitop == NULL)
3915 return (-1);
3917 fd = bind_socket_ai(aitop, reuse);
3919 evutil_freeaddrinfo(aitop);
3921 return (fd);
3924 struct evhttp_uri {
3925 unsigned flags;
3926 char *scheme; /* scheme; e.g http, ftp etc */
3927 char *userinfo; /* userinfo (typically username:pass), or NULL */
3928 char *host; /* hostname, IP address, or NULL */
3929 int port; /* port, or zero */
3930 char *path; /* path, or "". */
3931 char *query; /* query, or NULL */
3932 char *fragment; /* fragment or NULL */
3935 struct evhttp_uri *
3936 evhttp_uri_new(void)
3938 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
3939 if (uri)
3940 uri->port = -1;
3941 return uri;
3944 void
3945 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
3947 uri->flags = flags;
3950 /* Return true if the string starting at s and ending immediately before eos
3951 * is a valid URI scheme according to RFC3986
3953 static int
3954 scheme_ok(const char *s, const char *eos)
3956 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
3957 EVUTIL_ASSERT(eos >= s);
3958 if (s == eos)
3959 return 0;
3960 if (!EVUTIL_ISALPHA(*s))
3961 return 0;
3962 while (++s < eos) {
3963 if (! EVUTIL_ISALNUM(*s) &&
3964 *s != '+' && *s != '-' && *s != '.')
3965 return 0;
3967 return 1;
3970 #define SUBDELIMS "!$&'()*+,;="
3972 /* Return true iff [s..eos) is a valid userinfo */
3973 static int
3974 userinfo_ok(const char *s, const char *eos)
3976 while (s < eos) {
3977 if (CHAR_IS_UNRESERVED(*s) ||
3978 strchr(SUBDELIMS, *s) ||
3979 *s == ':')
3980 ++s;
3981 else if (*s == '%' && s+2 < eos &&
3982 EVUTIL_ISXDIGIT(s[1]) &&
3983 EVUTIL_ISXDIGIT(s[2]))
3984 s += 3;
3985 else
3986 return 0;
3988 return 1;
3991 static int
3992 regname_ok(const char *s, const char *eos)
3994 while (s && s<eos) {
3995 if (CHAR_IS_UNRESERVED(*s) ||
3996 strchr(SUBDELIMS, *s))
3997 ++s;
3998 else if (*s == '%' &&
3999 EVUTIL_ISXDIGIT(s[1]) &&
4000 EVUTIL_ISXDIGIT(s[2]))
4001 s += 3;
4002 else
4003 return 0;
4005 return 1;
4008 static int
4009 parse_port(const char *s, const char *eos)
4011 int portnum = 0;
4012 while (s < eos) {
4013 if (! EVUTIL_ISDIGIT(*s))
4014 return -1;
4015 portnum = (portnum * 10) + (*s - '0');
4016 if (portnum < 0)
4017 return -1;
4018 ++s;
4020 return portnum;
4023 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4024 static int
4025 bracket_addr_ok(const char *s, const char *eos)
4027 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4028 return 0;
4029 if (s[1] == 'v') {
4030 /* IPvFuture, or junk.
4031 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4033 s += 2; /* skip [v */
4034 --eos;
4035 if (!EVUTIL_ISXDIGIT(*s)) /*require at least one*/
4036 return 0;
4037 while (s < eos && *s != '.') {
4038 if (EVUTIL_ISXDIGIT(*s))
4039 ++s;
4040 else
4041 return 0;
4043 if (*s != '.')
4044 return 0;
4045 ++s;
4046 while (s < eos) {
4047 if (CHAR_IS_UNRESERVED(*s) ||
4048 strchr(SUBDELIMS, *s) ||
4049 *s == ':')
4050 ++s;
4051 else
4052 return 0;
4054 return 2;
4055 } else {
4056 /* IPv6, or junk */
4057 char buf[64];
4058 ev_ssize_t n_chars = eos-s-2;
4059 struct in6_addr in6;
4060 if (n_chars >= 64) /* way too long */
4061 return 0;
4062 memcpy(buf, s+1, n_chars);
4063 buf[n_chars]='\0';
4064 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4068 static int
4069 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4071 char *cp, *port;
4072 EVUTIL_ASSERT(eos);
4073 if (eos == s) {
4074 uri->host = mm_strdup("");
4075 if (uri->host == NULL) {
4076 event_warn("%s: strdup", __func__);
4077 return -1;
4079 return 0;
4082 /* Optionally, we start with "userinfo@" */
4084 cp = strchr(s, '@');
4085 if (cp && cp < eos) {
4086 if (! userinfo_ok(s,cp))
4087 return -1;
4088 *cp++ = '\0';
4089 uri->userinfo = mm_strdup(s);
4090 if (uri->userinfo == NULL) {
4091 event_warn("%s: strdup", __func__);
4092 return -1;
4094 } else {
4095 cp = s;
4097 /* Optionally, we end with ":port" */
4098 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT(*port); --port)
4100 if (port >= cp && *port == ':') {
4101 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4102 * nil port */
4103 uri->port = -1;
4104 else if ((uri->port = parse_port(port+1, eos))<0)
4105 return -1;
4106 eos = port;
4108 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4109 * an IP-Literal, or a reg-name */
4110 EVUTIL_ASSERT(eos >= cp);
4111 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4112 /* IPv6address, IP-Literal, or junk. */
4113 if (! bracket_addr_ok(cp, eos))
4114 return -1;
4115 } else {
4116 /* Make sure the host part is ok. */
4117 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4118 return -1;
4120 uri->host = mm_malloc(eos-cp+1);
4121 if (uri->host == NULL) {
4122 event_warn("%s: malloc", __func__);
4123 return -1;
4125 memcpy(uri->host, cp, eos-cp);
4126 uri->host[eos-cp] = '\0';
4127 return 0;
4131 static char *
4132 end_of_authority(char *cp)
4134 while (*cp) {
4135 if (*cp == '?' || *cp == '#' || *cp == '/')
4136 return cp;
4137 ++cp;
4139 return cp;
4142 enum uri_part {
4143 PART_PATH,
4144 PART_QUERY,
4145 PART_FRAGMENT
4148 /* Return the character after the longest prefix of 'cp' that matches...
4149 * *pchar / "/" if allow_qchars is false, or
4150 * *(pchar / "/" / "?") if allow_qchars is true.
4152 static char *
4153 end_of_path(char *cp, enum uri_part part, unsigned flags)
4155 if (flags & EVHTTP_URI_NONCONFORMANT) {
4156 /* If NONCONFORMANT:
4157 * Path is everything up to a # or ? or nul.
4158 * Query is everything up a # or nul
4159 * Fragment is everything up to a nul.
4161 switch (part) {
4162 case PART_PATH:
4163 while (*cp && *cp != '#' && *cp != '?')
4164 ++cp;
4165 break;
4166 case PART_QUERY:
4167 while (*cp && *cp != '#')
4168 ++cp;
4169 break;
4170 case PART_FRAGMENT:
4171 cp += strlen(cp);
4172 break;
4174 return cp;
4177 while (*cp) {
4178 if (CHAR_IS_UNRESERVED(*cp) ||
4179 strchr(SUBDELIMS, *cp) ||
4180 *cp == ':' || *cp == '@' || *cp == '/')
4181 ++cp;
4182 else if (*cp == '%' && EVUTIL_ISXDIGIT(cp[1]) &&
4183 EVUTIL_ISXDIGIT(cp[2]))
4184 cp += 3;
4185 else if (*cp == '?' && part != PART_PATH)
4186 ++cp;
4187 else
4188 return cp;
4190 return cp;
4193 static int
4194 path_matches_noscheme(const char *cp)
4196 while (*cp) {
4197 if (*cp == ':')
4198 return 0;
4199 else if (*cp == '/')
4200 return 1;
4201 ++cp;
4203 return 1;
4206 struct evhttp_uri *
4207 evhttp_uri_parse(const char *source_uri)
4209 return evhttp_uri_parse_with_flags(source_uri, 0);
4212 struct evhttp_uri *
4213 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4215 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4216 char *path = NULL, *fragment = NULL;
4217 int got_authority = 0;
4219 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4220 if (uri == NULL) {
4221 event_warn("%s: calloc", __func__);
4222 goto err;
4224 uri->port = -1;
4225 uri->flags = flags;
4227 readbuf = mm_strdup(source_uri);
4228 if (readbuf == NULL) {
4229 event_warn("%s: strdup", __func__);
4230 goto err;
4233 readp = readbuf;
4234 token = NULL;
4236 /* We try to follow RFC3986 here as much as we can, and match
4237 the productions
4239 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4241 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
4244 /* 1. scheme: */
4245 token = strchr(readp, ':');
4246 if (token && scheme_ok(readp,token)) {
4247 *token = '\0';
4248 uri->scheme = mm_strdup(readp);
4249 if (uri->scheme == NULL) {
4250 event_warn("%s: strdup", __func__);
4251 goto err;
4253 readp = token+1; /* eat : */
4256 /* 2. Optionally, "//" then an 'authority' part. */
4257 if (readp[0]=='/' && readp[1] == '/') {
4258 char *authority;
4259 readp += 2;
4260 authority = readp;
4261 path = end_of_authority(readp);
4262 if (parse_authority(uri, authority, path) < 0)
4263 goto err;
4264 readp = path;
4265 got_authority = 1;
4268 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4270 path = readp;
4271 readp = end_of_path(path, PART_PATH, flags);
4273 /* Query */
4274 if (*readp == '?') {
4275 *readp = '\0';
4276 ++readp;
4277 query = readp;
4278 readp = end_of_path(readp, PART_QUERY, flags);
4280 /* fragment */
4281 if (*readp == '#') {
4282 *readp = '\0';
4283 ++readp;
4284 fragment = readp;
4285 readp = end_of_path(readp, PART_FRAGMENT, flags);
4287 if (*readp != '\0') {
4288 goto err;
4291 /* These next two cases may be unreachable; I'm leaving them
4292 * in to be defensive. */
4293 /* If you didn't get an authority, the path can't begin with "//" */
4294 if (!got_authority && path[0]=='/' && path[1]=='/')
4295 goto err;
4296 /* If you did get an authority, the path must begin with "/" or be
4297 * empty. */
4298 if (got_authority && path[0] != '/' && path[0] != '\0')
4299 goto err;
4300 /* (End of maybe-unreachable cases) */
4302 /* If there was no scheme, the first part of the path (if any) must
4303 * have no colon in it. */
4304 if (! uri->scheme && !path_matches_noscheme(path))
4305 goto err;
4307 EVUTIL_ASSERT(path);
4308 uri->path = mm_strdup(path);
4309 if (uri->path == NULL) {
4310 event_warn("%s: strdup", __func__);
4311 goto err;
4314 if (query) {
4315 uri->query = mm_strdup(query);
4316 if (uri->query == NULL) {
4317 event_warn("%s: strdup", __func__);
4318 goto err;
4321 if (fragment) {
4322 uri->fragment = mm_strdup(fragment);
4323 if (uri->fragment == NULL) {
4324 event_warn("%s: strdup", __func__);
4325 goto err;
4329 mm_free(readbuf);
4331 return uri;
4332 err:
4333 if (uri)
4334 evhttp_uri_free(uri);
4335 if (readbuf)
4336 mm_free(readbuf);
4337 return NULL;
4340 void
4341 evhttp_uri_free(struct evhttp_uri *uri)
4343 #define _URI_FREE_STR(f) \
4344 if (uri->f) { \
4345 mm_free(uri->f); \
4348 _URI_FREE_STR(scheme);
4349 _URI_FREE_STR(userinfo);
4350 _URI_FREE_STR(host);
4351 _URI_FREE_STR(path);
4352 _URI_FREE_STR(query);
4353 _URI_FREE_STR(fragment);
4355 mm_free(uri);
4356 #undef _URI_FREE_STR
4359 char *
4360 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
4362 struct evbuffer *tmp = 0;
4363 size_t joined_size = 0;
4364 char *output = NULL;
4366 #define _URI_ADD(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
4368 if (!uri || !buf || !limit)
4369 return NULL;
4371 tmp = evbuffer_new();
4372 if (!tmp)
4373 return NULL;
4375 if (uri->scheme) {
4376 _URI_ADD(scheme);
4377 evbuffer_add(tmp, ":", 1);
4379 if (uri->host) {
4380 evbuffer_add(tmp, "//", 2);
4381 if (uri->userinfo)
4382 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
4383 _URI_ADD(host);
4384 if (uri->port >= 0)
4385 evbuffer_add_printf(tmp,":%d", uri->port);
4387 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
4388 goto err;
4391 if (uri->path)
4392 _URI_ADD(path);
4394 if (uri->query) {
4395 evbuffer_add(tmp, "?", 1);
4396 _URI_ADD(query);
4399 if (uri->fragment) {
4400 evbuffer_add(tmp, "#", 1);
4401 _URI_ADD(fragment);
4404 evbuffer_add(tmp, "\0", 1); /* NUL */
4406 joined_size = evbuffer_get_length(tmp);
4408 if (joined_size > limit) {
4409 /* It doesn't fit. */
4410 evbuffer_free(tmp);
4411 return NULL;
4413 evbuffer_remove(tmp, buf, joined_size);
4415 output = buf;
4416 err:
4417 evbuffer_free(tmp);
4419 return output;
4420 #undef _URI_ADD
4423 const char *
4424 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
4426 return uri->scheme;
4428 const char *
4429 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
4431 return uri->userinfo;
4433 const char *
4434 evhttp_uri_get_host(const struct evhttp_uri *uri)
4436 return uri->host;
4439 evhttp_uri_get_port(const struct evhttp_uri *uri)
4441 return uri->port;
4443 const char *
4444 evhttp_uri_get_path(const struct evhttp_uri *uri)
4446 return uri->path;
4448 const char *
4449 evhttp_uri_get_query(const struct evhttp_uri *uri)
4451 return uri->query;
4453 const char *
4454 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
4456 return uri->fragment;
4459 #define _URI_SET_STR(f) do { \
4460 if (uri->f) \
4461 mm_free(uri->f); \
4462 if (f) { \
4463 if ((uri->f = mm_strdup(f)) == NULL) { \
4464 event_warn("%s: strdup()", __func__); \
4465 return -1; \
4467 } else { \
4468 uri->f = NULL; \
4470 } while(0)
4473 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
4475 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
4476 return -1;
4478 _URI_SET_STR(scheme);
4479 return 0;
4482 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
4484 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
4485 return -1;
4486 _URI_SET_STR(userinfo);
4487 return 0;
4490 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
4492 if (host) {
4493 if (host[0] == '[') {
4494 if (! bracket_addr_ok(host, host+strlen(host)))
4495 return -1;
4496 } else {
4497 if (! regname_ok(host, host+strlen(host)))
4498 return -1;
4502 _URI_SET_STR(host);
4503 return 0;
4506 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
4508 if (port < -1)
4509 return -1;
4510 uri->port = port;
4511 return 0;
4513 #define end_of_cpath(cp,p,f) \
4514 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
4517 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
4519 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
4520 return -1;
4522 _URI_SET_STR(path);
4523 return 0;
4526 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
4528 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
4529 return -1;
4530 _URI_SET_STR(query);
4531 return 0;
4534 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
4536 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
4537 return -1;
4538 _URI_SET_STR(fragment);
4539 return 0;