Changes to update Tomato RAF.
[tomato.git] / release / src / router / dnscrypt / src / libevent / http.c
blobb9714d333d6d2271fdb523e586203dc0bdcff577
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 bufferevent_enable(evcon->bufev, EV_WRITE);
388 /* Disable the read callback: we don't actually care about data;
389 * we only care about close detection. (We don't disable reading,
390 * since we *do* want to learn about any close events.) */
391 bufferevent_setcb(evcon->bufev,
392 NULL, /*read*/
393 evhttp_write_cb,
394 evhttp_error_cb,
395 evcon);
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 switch (evcon->state) {
1329 case EVCON_CONNECTING:
1330 if (what & BEV_EVENT_TIMEOUT) {
1331 event_debug(("%s: connection timeout for \"%s:%d\" on %d",
1332 __func__, evcon->address, evcon->port,
1333 evcon->fd));
1334 evhttp_connection_cb_cleanup(evcon);
1335 return;
1337 break;
1339 case EVCON_READING_BODY:
1340 if (!req->chunked && req->ntoread < 0
1341 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1342 /* EOF on read can be benign */
1343 evhttp_connection_done(evcon);
1344 return;
1346 break;
1348 case EVCON_DISCONNECTED:
1349 case EVCON_IDLE:
1350 case EVCON_READING_FIRSTLINE:
1351 case EVCON_READING_HEADERS:
1352 case EVCON_READING_TRAILER:
1353 case EVCON_WRITING:
1354 default:
1355 break;
1358 /* when we are in close detect mode, a read error means that
1359 * the other side closed their connection.
1361 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1362 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1363 EVUTIL_ASSERT(evcon->http_server == NULL);
1364 /* For connections from the client, we just
1365 * reset the connection so that it becomes
1366 * disconnected.
1368 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1369 evhttp_connection_reset(evcon);
1370 return;
1373 if (what & BEV_EVENT_TIMEOUT) {
1374 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
1375 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1376 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
1377 } else {
1378 evhttp_connection_fail(evcon, EVCON_HTTP_BUFFER_ERROR);
1383 * Event callback for asynchronous connection attempt.
1385 static void
1386 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1388 struct evhttp_connection *evcon = arg;
1389 int error;
1390 ev_socklen_t errsz = sizeof(error);
1392 if (!(what & BEV_EVENT_CONNECTED)) {
1393 /* some operating systems return ECONNREFUSED immediately
1394 * when connecting to a local address. the cleanup is going
1395 * to reschedule this function call.
1397 #ifndef WIN32
1398 if (errno == ECONNREFUSED)
1399 goto cleanup;
1400 #endif
1401 evhttp_error_cb(bufev, what, arg);
1402 return;
1405 /* Check if the connection completed */
1406 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1407 &errsz) == -1) {
1408 event_debug(("%s: getsockopt for \"%s:%d\" on %d",
1409 __func__, evcon->address, evcon->port, evcon->fd));
1410 goto cleanup;
1413 if (error) {
1414 event_debug(("%s: connect failed for \"%s:%d\" on %d: %s",
1415 __func__, evcon->address, evcon->port, evcon->fd,
1416 evutil_socket_error_to_string(error)));
1417 goto cleanup;
1420 /* We are connected to the server now */
1421 event_debug(("%s: connected to \"%s:%d\" on %d\n",
1422 __func__, evcon->address, evcon->port, evcon->fd));
1424 /* Reset the retry count as we were successful in connecting */
1425 evcon->retry_cnt = 0;
1426 evcon->state = EVCON_IDLE;
1428 /* reset the bufferevent cbs */
1429 bufferevent_setcb(evcon->bufev,
1430 evhttp_read_cb,
1431 evhttp_write_cb,
1432 evhttp_error_cb,
1433 evcon);
1435 if (evcon->timeout == -1)
1436 bufferevent_settimeout(evcon->bufev,
1437 HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
1438 else {
1439 struct timeval tv;
1440 tv.tv_sec = evcon->timeout;
1441 tv.tv_usec = 0;
1442 bufferevent_set_timeouts(evcon->bufev, &tv, &tv);
1445 /* try to start requests that have queued up on this connection */
1446 evhttp_request_dispatch(evcon);
1447 return;
1449 cleanup:
1450 evhttp_connection_cb_cleanup(evcon);
1454 * Check if we got a valid response code.
1457 static int
1458 evhttp_valid_response_code(int code)
1460 if (code == 0)
1461 return (0);
1463 return (1);
1466 static int
1467 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1469 int major, minor;
1470 char ch;
1471 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1472 if (n != 2 || major > 1) {
1473 event_debug(("%s: bad version %s on message %p from %s",
1474 __func__, version, req, req->remote_host));
1475 return (-1);
1477 req->major = major;
1478 req->minor = minor;
1479 return (0);
1482 /* Parses the status line of a web server */
1484 static int
1485 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1487 char *protocol;
1488 char *number;
1489 const char *readable = "";
1491 protocol = strsep(&line, " ");
1492 if (line == NULL)
1493 return (-1);
1494 number = strsep(&line, " ");
1495 if (line != NULL)
1496 readable = line;
1498 if (evhttp_parse_http_version(protocol, req) < 0)
1499 return (-1);
1501 req->response_code = atoi(number);
1502 if (!evhttp_valid_response_code(req->response_code)) {
1503 event_debug(("%s: bad response code \"%s\"",
1504 __func__, number));
1505 return (-1);
1508 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1509 event_warn("%s: strdup", __func__);
1510 return (-1);
1513 return (0);
1516 /* Parse the first line of a HTTP request */
1518 static int
1519 evhttp_parse_request_line(struct evhttp_request *req, char *line)
1521 char *method;
1522 char *uri;
1523 char *version;
1524 const char *hostname;
1525 const char *scheme;
1527 /* Parse the request line */
1528 method = strsep(&line, " ");
1529 if (line == NULL)
1530 return (-1);
1531 uri = strsep(&line, " ");
1532 if (line == NULL)
1533 return (-1);
1534 version = strsep(&line, " ");
1535 if (line != NULL)
1536 return (-1);
1538 /* First line */
1539 if (strcmp(method, "GET") == 0) {
1540 req->type = EVHTTP_REQ_GET;
1541 } else if (strcmp(method, "POST") == 0) {
1542 req->type = EVHTTP_REQ_POST;
1543 } else if (strcmp(method, "HEAD") == 0) {
1544 req->type = EVHTTP_REQ_HEAD;
1545 } else if (strcmp(method, "PUT") == 0) {
1546 req->type = EVHTTP_REQ_PUT;
1547 } else if (strcmp(method, "DELETE") == 0) {
1548 req->type = EVHTTP_REQ_DELETE;
1549 } else if (strcmp(method, "OPTIONS") == 0) {
1550 req->type = EVHTTP_REQ_OPTIONS;
1551 } else if (strcmp(method, "TRACE") == 0) {
1552 req->type = EVHTTP_REQ_TRACE;
1553 } else if (strcmp(method, "PATCH") == 0) {
1554 req->type = EVHTTP_REQ_PATCH;
1555 } else {
1556 req->type = _EVHTTP_REQ_UNKNOWN;
1557 event_debug(("%s: bad method %s on request %p from %s",
1558 __func__, method, req, req->remote_host));
1559 /* No error yet; we'll give a better error later when
1560 * we see that req->type is unsupported. */
1563 if (evhttp_parse_http_version(version, req) < 0)
1564 return (-1);
1566 if ((req->uri = mm_strdup(uri)) == NULL) {
1567 event_debug(("%s: mm_strdup", __func__));
1568 return (-1);
1571 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
1572 EVHTTP_URI_NONCONFORMANT)) == NULL) {
1573 return -1;
1576 /* If we have an absolute-URI, check to see if it is an http request
1577 for a known vhost or server alias. If we don't know about this
1578 host, we consider it a proxy request. */
1579 scheme = evhttp_uri_get_scheme(req->uri_elems);
1580 hostname = evhttp_uri_get_host(req->uri_elems);
1581 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1582 !evutil_ascii_strcasecmp(scheme, "https")) &&
1583 hostname &&
1584 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1585 req->flags |= EVHTTP_PROXY_REQUEST;
1587 return (0);
1590 const char *
1591 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1593 struct evkeyval *header;
1595 TAILQ_FOREACH(header, headers, next) {
1596 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1597 return (header->value);
1600 return (NULL);
1603 void
1604 evhttp_clear_headers(struct evkeyvalq *headers)
1606 struct evkeyval *header;
1608 for (header = TAILQ_FIRST(headers);
1609 header != NULL;
1610 header = TAILQ_FIRST(headers)) {
1611 TAILQ_REMOVE(headers, header, next);
1612 mm_free(header->key);
1613 mm_free(header->value);
1614 mm_free(header);
1619 * Returns 0, if the header was successfully removed.
1620 * Returns -1, if the header could not be found.
1624 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1626 struct evkeyval *header;
1628 TAILQ_FOREACH(header, headers, next) {
1629 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1630 break;
1633 if (header == NULL)
1634 return (-1);
1636 /* Free and remove the header that we found */
1637 TAILQ_REMOVE(headers, header, next);
1638 mm_free(header->key);
1639 mm_free(header->value);
1640 mm_free(header);
1642 return (0);
1645 static int
1646 evhttp_header_is_valid_value(const char *value)
1648 const char *p = value;
1650 while ((p = strpbrk(p, "\r\n")) != NULL) {
1651 /* we really expect only one new line */
1652 p += strspn(p, "\r\n");
1653 /* we expect a space or tab for continuation */
1654 if (*p != ' ' && *p != '\t')
1655 return (0);
1657 return (1);
1661 evhttp_add_header(struct evkeyvalq *headers,
1662 const char *key, const char *value)
1664 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1666 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1667 /* drop illegal headers */
1668 event_debug(("%s: dropping illegal header key\n", __func__));
1669 return (-1);
1672 if (!evhttp_header_is_valid_value(value)) {
1673 event_debug(("%s: dropping illegal header value\n", __func__));
1674 return (-1);
1677 return (evhttp_add_header_internal(headers, key, value));
1680 static int
1681 evhttp_add_header_internal(struct evkeyvalq *headers,
1682 const char *key, const char *value)
1684 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
1685 if (header == NULL) {
1686 event_warn("%s: calloc", __func__);
1687 return (-1);
1689 if ((header->key = mm_strdup(key)) == NULL) {
1690 mm_free(header);
1691 event_warn("%s: strdup", __func__);
1692 return (-1);
1694 if ((header->value = mm_strdup(value)) == NULL) {
1695 mm_free(header->key);
1696 mm_free(header);
1697 event_warn("%s: strdup", __func__);
1698 return (-1);
1701 TAILQ_INSERT_TAIL(headers, header, next);
1703 return (0);
1707 * Parses header lines from a request or a response into the specified
1708 * request object given an event buffer.
1710 * Returns
1711 * DATA_CORRUPTED on error
1712 * MORE_DATA_EXPECTED when we need to read more headers
1713 * ALL_DATA_READ when all headers have been read.
1716 enum message_read_status
1717 evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
1719 char *line;
1720 enum message_read_status status = ALL_DATA_READ;
1722 size_t line_length;
1723 /* XXX try */
1724 line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF);
1725 if (line == NULL) {
1726 if (req->evcon != NULL &&
1727 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1728 return (DATA_TOO_LONG);
1729 else
1730 return (MORE_DATA_EXPECTED);
1733 if (req->evcon != NULL &&
1734 line_length > req->evcon->max_headers_size) {
1735 mm_free(line);
1736 return (DATA_TOO_LONG);
1739 req->headers_size = line_length;
1741 switch (req->kind) {
1742 case EVHTTP_REQUEST:
1743 if (evhttp_parse_request_line(req, line) == -1)
1744 status = DATA_CORRUPTED;
1745 break;
1746 case EVHTTP_RESPONSE:
1747 if (evhttp_parse_response_line(req, line) == -1)
1748 status = DATA_CORRUPTED;
1749 break;
1750 default:
1751 status = DATA_CORRUPTED;
1754 mm_free(line);
1755 return (status);
1758 static int
1759 evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
1761 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
1762 char *newval;
1763 size_t old_len, line_len;
1765 if (header == NULL)
1766 return (-1);
1768 old_len = strlen(header->value);
1769 line_len = strlen(line);
1771 newval = mm_realloc(header->value, old_len + line_len + 1);
1772 if (newval == NULL)
1773 return (-1);
1775 memcpy(newval + old_len, line, line_len + 1);
1776 header->value = newval;
1778 return (0);
1781 enum message_read_status
1782 evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
1784 enum message_read_status errcode = DATA_CORRUPTED;
1785 char *line;
1786 enum message_read_status status = MORE_DATA_EXPECTED;
1788 struct evkeyvalq* headers = req->input_headers;
1789 size_t line_length;
1790 while ((line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF))
1791 != NULL) {
1792 char *skey, *svalue;
1794 req->headers_size += line_length;
1796 if (req->evcon != NULL &&
1797 req->headers_size > req->evcon->max_headers_size) {
1798 errcode = DATA_TOO_LONG;
1799 goto error;
1802 if (*line == '\0') { /* Last header - Done */
1803 status = ALL_DATA_READ;
1804 mm_free(line);
1805 break;
1808 /* Check if this is a continuation line */
1809 if (*line == ' ' || *line == '\t') {
1810 if (evhttp_append_to_last_header(headers, line) == -1)
1811 goto error;
1812 mm_free(line);
1813 continue;
1816 /* Processing of header lines */
1817 svalue = line;
1818 skey = strsep(&svalue, ":");
1819 if (svalue == NULL)
1820 goto error;
1822 svalue += strspn(svalue, " ");
1824 if (evhttp_add_header(headers, skey, svalue) == -1)
1825 goto error;
1827 mm_free(line);
1830 if (status == MORE_DATA_EXPECTED) {
1831 if (req->evcon != NULL &&
1832 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1833 return (DATA_TOO_LONG);
1836 return (status);
1838 error:
1839 mm_free(line);
1840 return (errcode);
1843 static int
1844 evhttp_get_body_length(struct evhttp_request *req)
1846 struct evkeyvalq *headers = req->input_headers;
1847 const char *content_length;
1848 const char *connection;
1850 content_length = evhttp_find_header(headers, "Content-Length");
1851 connection = evhttp_find_header(headers, "Connection");
1853 if (content_length == NULL && connection == NULL)
1854 req->ntoread = -1;
1855 else if (content_length == NULL &&
1856 evutil_ascii_strcasecmp(connection, "Close") != 0) {
1857 /* Bad combination, we don't know when it will end */
1858 event_warnx("%s: we got no content length, but the "
1859 "server wants to keep the connection open: %s.",
1860 __func__, connection);
1861 return (-1);
1862 } else if (content_length == NULL) {
1863 req->ntoread = -1;
1864 } else {
1865 char *endp;
1866 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
1867 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
1868 event_debug(("%s: illegal content length: %s",
1869 __func__, content_length));
1870 return (-1);
1872 req->ntoread = ntoread;
1875 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
1876 __func__, EV_I64_ARG(req->ntoread),
1877 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
1879 return (0);
1882 static int
1883 evhttp_method_may_have_body(enum evhttp_cmd_type type)
1885 switch (type) {
1886 case EVHTTP_REQ_POST:
1887 case EVHTTP_REQ_PUT:
1888 case EVHTTP_REQ_PATCH:
1889 return 1;
1890 case EVHTTP_REQ_TRACE:
1891 return 0;
1892 /* XXX May any of the below methods have a body? */
1893 case EVHTTP_REQ_GET:
1894 case EVHTTP_REQ_HEAD:
1895 case EVHTTP_REQ_DELETE:
1896 case EVHTTP_REQ_OPTIONS:
1897 case EVHTTP_REQ_CONNECT:
1898 return 0;
1899 default:
1900 return 0;
1904 static void
1905 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1907 const char *xfer_enc;
1909 /* If this is a request without a body, then we are done */
1910 if (req->kind == EVHTTP_REQUEST &&
1911 !evhttp_method_may_have_body(req->type)) {
1912 evhttp_connection_done(evcon);
1913 return;
1915 evcon->state = EVCON_READING_BODY;
1916 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
1917 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
1918 req->chunked = 1;
1919 req->ntoread = -1;
1920 } else {
1921 if (evhttp_get_body_length(req) == -1) {
1922 evhttp_connection_fail(evcon,
1923 EVCON_HTTP_INVALID_HEADER);
1924 return;
1926 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
1927 /* An incoming request with no content-length and no
1928 * transfer-encoding has no body. */
1929 evhttp_connection_done(evcon);
1930 return;
1934 /* Should we send a 100 Continue status line? */
1935 if (req->kind == EVHTTP_REQUEST && REQ_VERSION_ATLEAST(req, 1, 1)) {
1936 const char *expect;
1938 expect = evhttp_find_header(req->input_headers, "Expect");
1939 if (expect) {
1940 if (!evutil_ascii_strcasecmp(expect, "100-continue")) {
1941 /* XXX It would be nice to do some sanity
1942 checking here. Does the resource exist?
1943 Should the resource accept post requests? If
1944 no, we should respond with an error. For
1945 now, just optimistically tell the client to
1946 send their message body. */
1947 if (req->ntoread > 0) {
1948 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
1949 if ((req->evcon->max_body_size <= EV_INT64_MAX) && (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
1950 evhttp_send_error(req, HTTP_ENTITYTOOLARGE, NULL);
1951 return;
1954 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
1955 evhttp_send_continue(evcon, req);
1956 } else {
1957 evhttp_send_error(req, HTTP_EXPECTATIONFAILED,
1958 NULL);
1959 return;
1964 evhttp_read_body(evcon, req);
1965 /* note the request may have been freed in evhttp_read_body */
1968 static void
1969 evhttp_read_firstline(struct evhttp_connection *evcon,
1970 struct evhttp_request *req)
1972 enum message_read_status res;
1974 res = evhttp_parse_firstline(req, bufferevent_get_input(evcon->bufev));
1975 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
1976 /* Error while reading, terminate */
1977 event_debug(("%s: bad header lines on %d\n",
1978 __func__, evcon->fd));
1979 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1980 return;
1981 } else if (res == MORE_DATA_EXPECTED) {
1982 /* Need more header lines */
1983 return;
1986 evcon->state = EVCON_READING_HEADERS;
1987 evhttp_read_header(evcon, req);
1990 static void
1991 evhttp_read_header(struct evhttp_connection *evcon,
1992 struct evhttp_request *req)
1994 enum message_read_status res;
1995 evutil_socket_t fd = evcon->fd;
1997 res = evhttp_parse_headers(req, bufferevent_get_input(evcon->bufev));
1998 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
1999 /* Error while reading, terminate */
2000 event_debug(("%s: bad header lines on %d\n", __func__, fd));
2001 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
2002 return;
2003 } else if (res == MORE_DATA_EXPECTED) {
2004 /* Need more header lines */
2005 return;
2008 /* Disable reading for now */
2009 bufferevent_disable(evcon->bufev, EV_READ);
2011 /* Done reading headers, do the real work */
2012 switch (req->kind) {
2013 case EVHTTP_REQUEST:
2014 event_debug(("%s: checking for post data on %d\n",
2015 __func__, fd));
2016 evhttp_get_body(evcon, req);
2017 /* note the request may have been freed in evhttp_get_body */
2018 break;
2020 case EVHTTP_RESPONSE:
2021 /* Start over if we got a 100 Continue response. */
2022 if (req->response_code == 100) {
2023 evhttp_start_read(evcon);
2024 return;
2026 if (!evhttp_response_needs_body(req)) {
2027 event_debug(("%s: skipping body for code %d\n",
2028 __func__, req->response_code));
2029 evhttp_connection_done(evcon);
2030 } else {
2031 event_debug(("%s: start of read body for %s on %d\n",
2032 __func__, req->remote_host, fd));
2033 evhttp_get_body(evcon, req);
2034 /* note the request may have been freed in
2035 * evhttp_get_body */
2037 break;
2039 default:
2040 event_warnx("%s: bad header on %d", __func__, fd);
2041 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
2042 break;
2044 /* request may have been freed above */
2048 * Creates a TCP connection to the specified port and executes a callback
2049 * when finished. Failure or success is indicate by the passed connection
2050 * object.
2052 * Although this interface accepts a hostname, it is intended to take
2053 * only numeric hostnames so that non-blocking DNS resolution can
2054 * happen elsewhere.
2057 struct evhttp_connection *
2058 evhttp_connection_new(const char *address, unsigned short port)
2060 return (evhttp_connection_base_new(NULL, NULL, address, port));
2063 struct evhttp_connection *
2064 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2065 const char *address, unsigned short port)
2067 struct evhttp_connection *evcon = NULL;
2069 event_debug(("Attempting connection to %s:%d\n", address, port));
2071 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2072 event_warn("%s: calloc failed", __func__);
2073 goto error;
2076 evcon->fd = -1;
2077 evcon->port = port;
2079 evcon->max_headers_size = EV_SIZE_MAX;
2080 evcon->max_body_size = EV_SIZE_MAX;
2082 evcon->timeout = -1;
2083 evcon->retry_cnt = evcon->retry_max = 0;
2085 if ((evcon->address = mm_strdup(address)) == NULL) {
2086 event_warn("%s: strdup failed", __func__);
2087 goto error;
2090 if ((evcon->bufev = bufferevent_new(-1,
2091 evhttp_read_cb,
2092 evhttp_write_cb,
2093 evhttp_error_cb, evcon)) == NULL) {
2094 event_warn("%s: bufferevent_new failed", __func__);
2095 goto error;
2098 evcon->state = EVCON_DISCONNECTED;
2099 TAILQ_INIT(&evcon->requests);
2101 if (base != NULL) {
2102 evcon->base = base;
2103 bufferevent_base_set(base, evcon->bufev);
2107 event_deferred_cb_init(&evcon->read_more_deferred_cb,
2108 evhttp_deferred_read_cb, evcon);
2110 evcon->dns_base = dnsbase;
2112 return (evcon);
2114 error:
2115 if (evcon != NULL)
2116 evhttp_connection_free(evcon);
2117 return (NULL);
2120 struct bufferevent *
2121 evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2123 return evcon->bufev;
2126 void
2127 evhttp_connection_set_base(struct evhttp_connection *evcon,
2128 struct event_base *base)
2130 EVUTIL_ASSERT(evcon->base == NULL);
2131 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2132 evcon->base = base;
2133 bufferevent_base_set(base, evcon->bufev);
2136 void
2137 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2138 int timeout_in_secs)
2140 evcon->timeout = timeout_in_secs;
2142 if (evcon->timeout == -1)
2143 bufferevent_settimeout(evcon->bufev,
2144 HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
2145 else
2146 bufferevent_settimeout(evcon->bufev,
2147 evcon->timeout, evcon->timeout);
2150 void
2151 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2152 int retry_max)
2154 evcon->retry_max = retry_max;
2157 void
2158 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2159 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2161 evcon->closecb = cb;
2162 evcon->closecb_arg = cbarg;
2165 void
2166 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2167 char **address, ev_uint16_t *port)
2169 *address = evcon->address;
2170 *port = evcon->port;
2174 evhttp_connection_connect(struct evhttp_connection *evcon)
2176 if (evcon->state == EVCON_CONNECTING)
2177 return (0);
2179 evhttp_connection_reset(evcon);
2181 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2182 evcon->flags |= EVHTTP_CON_OUTGOING;
2184 evcon->fd = bind_socket(
2185 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2186 if (evcon->fd == -1) {
2187 event_debug(("%s: failed to bind to \"%s\"",
2188 __func__, evcon->bind_address));
2189 return (-1);
2192 /* Set up a callback for successful connection setup */
2193 bufferevent_setfd(evcon->bufev, evcon->fd);
2194 bufferevent_setcb(evcon->bufev,
2195 NULL /* evhttp_read_cb */,
2196 NULL /* evhttp_write_cb */,
2197 evhttp_connection_cb,
2198 evcon);
2199 bufferevent_settimeout(evcon->bufev, 0,
2200 evcon->timeout != -1 ? evcon->timeout : HTTP_CONNECT_TIMEOUT);
2201 /* make sure that we get a write callback */
2202 bufferevent_enable(evcon->bufev, EV_WRITE);
2204 if (bufferevent_socket_connect_hostname(evcon->bufev, evcon->dns_base,
2205 AF_UNSPEC, evcon->address, evcon->port) < 0) {
2206 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2207 __func__, evcon->address);
2208 /* some operating systems return ECONNREFUSED immediately
2209 * when connecting to a local address. the cleanup is going
2210 * to reschedule this function call.
2212 evhttp_connection_cb_cleanup(evcon);
2213 return (0);
2216 evcon->state = EVCON_CONNECTING;
2218 return (0);
2222 * Starts an HTTP request on the provided evhttp_connection object.
2223 * If the connection object is not connected to the web server already,
2224 * this will start the connection.
2228 evhttp_make_request(struct evhttp_connection *evcon,
2229 struct evhttp_request *req,
2230 enum evhttp_cmd_type type, const char *uri)
2232 /* We are making a request */
2233 req->kind = EVHTTP_REQUEST;
2234 req->type = type;
2235 if (req->uri != NULL)
2236 mm_free(req->uri);
2237 if ((req->uri = mm_strdup(uri)) == NULL) {
2238 event_warn("%s: strdup", __func__);
2239 evhttp_request_free(req);
2240 return (-1);
2243 /* Set the protocol version if it is not supplied */
2244 if (!req->major && !req->minor) {
2245 req->major = 1;
2246 req->minor = 1;
2249 EVUTIL_ASSERT(req->evcon == NULL);
2250 req->evcon = evcon;
2251 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2253 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2255 /* If the connection object is not connected; make it so */
2256 if (!evhttp_connected(evcon)) {
2257 int res = evhttp_connection_connect(evcon);
2258 /* evhttp_connection_fail(), which is called through
2259 * evhttp_connection_connect(), assumes that req lies in
2260 * evcon->requests. Thus, enqueue the request in advance and r
2261 * it in the error case. */
2262 if (res != 0)
2263 TAILQ_REMOVE(&evcon->requests, req, next);
2265 return res;
2269 * If it's connected already and we are the first in the queue,
2270 * then we can dispatch this request immediately. Otherwise, it
2271 * will be dispatched once the pending requests are completed.
2273 if (TAILQ_FIRST(&evcon->requests) == req)
2274 evhttp_request_dispatch(evcon);
2276 return (0);
2279 void
2280 evhttp_cancel_request(struct evhttp_request *req)
2282 struct evhttp_connection *evcon = req->evcon;
2283 if (evcon != NULL) {
2284 /* We need to remove it from the connection */
2285 if (TAILQ_FIRST(&evcon->requests) == req) {
2286 /* it's currently being worked on, so reset
2287 * the connection.
2289 evhttp_connection_fail(evcon,
2290 EVCON_HTTP_REQUEST_CANCEL);
2292 /* connection fail freed the request */
2293 return;
2294 } else {
2295 /* otherwise, we can just remove it from the
2296 * queue
2298 TAILQ_REMOVE(&evcon->requests, req, next);
2302 evhttp_request_free(req);
2306 * Reads data from file descriptor into request structure
2307 * Request structure needs to be set up correctly.
2310 void
2311 evhttp_start_read(struct evhttp_connection *evcon)
2313 /* Set up an event to read the headers */
2314 bufferevent_disable(evcon->bufev, EV_WRITE);
2315 bufferevent_enable(evcon->bufev, EV_READ);
2316 evcon->state = EVCON_READING_FIRSTLINE;
2317 /* Reset the bufferevent callbacks */
2318 bufferevent_setcb(evcon->bufev,
2319 evhttp_read_cb,
2320 evhttp_write_cb,
2321 evhttp_error_cb,
2322 evcon);
2324 /* If there's still data pending, process it next time through the
2325 * loop. Don't do it now; that could get recusive. */
2326 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2327 event_deferred_cb_schedule(get_deferred_queue(evcon),
2328 &evcon->read_more_deferred_cb);
2332 static void
2333 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2335 int need_close;
2336 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2337 TAILQ_REMOVE(&evcon->requests, req, next);
2339 need_close =
2340 (REQ_VERSION_BEFORE(req, 1, 1) &&
2341 !evhttp_is_connection_keepalive(req->input_headers))||
2342 evhttp_is_connection_close(req->flags, req->input_headers) ||
2343 evhttp_is_connection_close(req->flags, req->output_headers);
2345 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2346 evhttp_request_free(req);
2348 if (need_close) {
2349 evhttp_connection_free(evcon);
2350 return;
2353 /* we have a persistent connection; try to accept another request. */
2354 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2355 evhttp_connection_free(evcon);
2360 * Returns an error page.
2363 void
2364 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2367 #define ERR_FORMAT "<HTML><HEAD>\n" \
2368 "<TITLE>%d %s</TITLE>\n" \
2369 "</HEAD><BODY>\n" \
2370 "<H1>%s</H1>\n" \
2371 "</BODY></HTML>\n"
2373 struct evbuffer *buf = evbuffer_new();
2374 if (buf == NULL) {
2375 /* if we cannot allocate memory; we just drop the connection */
2376 evhttp_connection_free(req->evcon);
2377 return;
2379 if (reason == NULL) {
2380 reason = evhttp_response_phrase_internal(error);
2383 evhttp_response_code(req, error, reason);
2385 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2387 evhttp_send_page(req, buf);
2389 evbuffer_free(buf);
2390 #undef ERR_FORMAT
2393 /* Requires that headers and response code are already set up */
2395 static inline void
2396 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2398 struct evhttp_connection *evcon = req->evcon;
2400 if (evcon == NULL) {
2401 evhttp_request_free(req);
2402 return;
2405 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2407 /* we expect no more calls form the user on this request */
2408 req->userdone = 1;
2410 /* xxx: not sure if we really should expose the data buffer this way */
2411 if (databuf != NULL)
2412 evbuffer_add_buffer(req->output_buffer, databuf);
2414 /* Adds headers to the response */
2415 evhttp_make_header(evcon, req);
2417 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2420 void
2421 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2422 struct evbuffer *databuf)
2424 evhttp_response_code(req, code, reason);
2426 evhttp_send(req, databuf);
2429 void
2430 evhttp_send_reply_start(struct evhttp_request *req, int code,
2431 const char *reason)
2433 evhttp_response_code(req, code, reason);
2434 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2435 REQ_VERSION_ATLEAST(req, 1, 1) &&
2436 evhttp_response_needs_body(req)) {
2438 * prefer HTTP/1.1 chunked encoding to closing the connection;
2439 * note RFC 2616 section 4.4 forbids it with Content-Length:
2440 * and it's not necessary then anyway.
2442 evhttp_add_header(req->output_headers, "Transfer-Encoding",
2443 "chunked");
2444 req->chunked = 1;
2445 } else {
2446 req->chunked = 0;
2448 evhttp_make_header(req->evcon, req);
2449 evhttp_write_buffer(req->evcon, NULL, NULL);
2452 void
2453 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
2455 struct evhttp_connection *evcon = req->evcon;
2456 struct evbuffer *output;
2458 if (evcon == NULL)
2459 return;
2461 output = bufferevent_get_output(evcon->bufev);
2463 if (evbuffer_get_length(databuf) == 0)
2464 return;
2465 if (!evhttp_response_needs_body(req))
2466 return;
2467 if (req->chunked) {
2468 evbuffer_add_printf(output, "%x\r\n",
2469 (unsigned)evbuffer_get_length(databuf));
2471 evbuffer_add_buffer(output, databuf);
2472 if (req->chunked) {
2473 evbuffer_add(output, "\r\n", 2);
2475 evhttp_write_buffer(evcon, NULL, NULL);
2478 void
2479 evhttp_send_reply_end(struct evhttp_request *req)
2481 struct evhttp_connection *evcon = req->evcon;
2482 struct evbuffer *output;
2484 if (evcon == NULL) {
2485 evhttp_request_free(req);
2486 return;
2489 output = bufferevent_get_output(evcon->bufev);
2491 /* we expect no more calls form the user on this request */
2492 req->userdone = 1;
2494 if (req->chunked) {
2495 evbuffer_add(output, "0\r\n\r\n", 5);
2496 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2497 req->chunked = 0;
2498 } else if (evbuffer_get_length(output) == 0) {
2499 /* let the connection know that we are done with the request */
2500 evhttp_send_done(evcon, NULL);
2501 } else {
2502 /* make the callback execute after all data has been written */
2503 evcon->cb = evhttp_send_done;
2504 evcon->cb_arg = NULL;
2508 static const char *informational_phrases[] = {
2509 /* 100 */ "Continue",
2510 /* 101 */ "Switching Protocols"
2513 static const char *success_phrases[] = {
2514 /* 200 */ "OK",
2515 /* 201 */ "Created",
2516 /* 202 */ "Accepted",
2517 /* 203 */ "Non-Authoritative Information",
2518 /* 204 */ "No Content",
2519 /* 205 */ "Reset Content",
2520 /* 206 */ "Partial Content"
2523 static const char *redirection_phrases[] = {
2524 /* 300 */ "Multiple Choices",
2525 /* 301 */ "Moved Permanently",
2526 /* 302 */ "Found",
2527 /* 303 */ "See Other",
2528 /* 304 */ "Not Modified",
2529 /* 305 */ "Use Proxy",
2530 /* 307 */ "Temporary Redirect"
2533 static const char *client_error_phrases[] = {
2534 /* 400 */ "Bad Request",
2535 /* 401 */ "Unauthorized",
2536 /* 402 */ "Payment Required",
2537 /* 403 */ "Forbidden",
2538 /* 404 */ "Not Found",
2539 /* 405 */ "Method Not Allowed",
2540 /* 406 */ "Not Acceptable",
2541 /* 407 */ "Proxy Authentication Required",
2542 /* 408 */ "Request Time-out",
2543 /* 409 */ "Conflict",
2544 /* 410 */ "Gone",
2545 /* 411 */ "Length Required",
2546 /* 412 */ "Precondition Failed",
2547 /* 413 */ "Request Entity Too Large",
2548 /* 414 */ "Request-URI Too Large",
2549 /* 415 */ "Unsupported Media Type",
2550 /* 416 */ "Requested range not satisfiable",
2551 /* 417 */ "Expectation Failed"
2554 static const char *server_error_phrases[] = {
2555 /* 500 */ "Internal Server Error",
2556 /* 501 */ "Not Implemented",
2557 /* 502 */ "Bad Gateway",
2558 /* 503 */ "Service Unavailable",
2559 /* 504 */ "Gateway Time-out",
2560 /* 505 */ "HTTP Version not supported"
2563 struct response_class {
2564 const char *name;
2565 size_t num_responses;
2566 const char **responses;
2569 #ifndef MEMBERSOF
2570 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
2571 #endif
2573 static const struct response_class response_classes[] = {
2574 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
2575 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
2576 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
2577 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
2578 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
2581 static const char *
2582 evhttp_response_phrase_internal(int code)
2584 int klass = code / 100 - 1;
2585 int subcode = code % 100;
2587 /* Unknown class - can't do any better here */
2588 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
2589 return "Unknown Status Class";
2591 /* Unknown sub-code, return class name at least */
2592 if (subcode >= (int) response_classes[klass].num_responses)
2593 return response_classes[klass].name;
2595 return response_classes[klass].responses[subcode];
2598 void
2599 evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
2601 req->kind = EVHTTP_RESPONSE;
2602 req->response_code = code;
2603 if (req->response_code_line != NULL)
2604 mm_free(req->response_code_line);
2605 if (reason == NULL)
2606 reason = evhttp_response_phrase_internal(code);
2607 req->response_code_line = mm_strdup(reason);
2608 if (req->response_code_line == NULL) {
2609 event_warn("%s: strdup", __func__);
2610 /* XXX what else can we do? */
2614 void
2615 evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
2617 if (!req->major || !req->minor) {
2618 req->major = 1;
2619 req->minor = 1;
2622 if (req->kind != EVHTTP_RESPONSE)
2623 evhttp_response_code(req, 200, "OK");
2625 evhttp_clear_headers(req->output_headers);
2626 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
2627 evhttp_add_header(req->output_headers, "Connection", "close");
2629 evhttp_send(req, databuf);
2632 static const char uri_chars[256] = {
2633 /* 0 */
2634 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2635 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2636 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
2637 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
2638 /* 64 */
2639 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2640 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
2641 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2642 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
2643 /* 128 */
2644 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2645 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2646 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2647 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2648 /* 192 */
2649 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2650 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2651 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2652 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2655 #define CHAR_IS_UNRESERVED(c) \
2656 (uri_chars[(unsigned char)(c)])
2659 * Helper functions to encode/decode a string for inclusion in a URI.
2660 * The returned string must be freed by the caller.
2662 char *
2663 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
2665 struct evbuffer *buf = evbuffer_new();
2666 const char *p, *end;
2667 char *result;
2669 if (buf == NULL)
2670 return (NULL);
2672 if (len >= 0)
2673 end = uri+len;
2674 else
2675 end = uri+strlen(uri);
2677 for (p = uri; p < end; p++) {
2678 if (CHAR_IS_UNRESERVED(*p)) {
2679 evbuffer_add(buf, p, 1);
2680 } else if (*p == ' ' && space_as_plus) {
2681 evbuffer_add(buf, "+", 1);
2682 } else {
2683 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
2686 evbuffer_add(buf, "", 1); /* NUL-terminator. */
2687 result = mm_malloc(evbuffer_get_length(buf));
2688 if (result)
2689 evbuffer_remove(buf, result, evbuffer_get_length(buf));
2690 evbuffer_free(buf);
2692 return (result);
2695 char *
2696 evhttp_encode_uri(const char *str)
2698 return evhttp_uriencode(str, -1, 0);
2702 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
2703 * If -1, when true we transform plus to space only after we've seen
2704 * a ?. -1 is deprecated.
2705 * @return the number of bytes written to 'ret'.
2707 static int
2708 evhttp_decode_uri_internal(
2709 const char *uri, size_t length, char *ret, int decode_plus_ctl)
2711 char c;
2712 int j;
2713 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
2714 unsigned i;
2716 for (i = j = 0; i < length; i++) {
2717 c = uri[i];
2718 if (c == '?') {
2719 if (decode_plus_ctl < 0)
2720 decode_plus = 1;
2721 } else if (c == '+' && decode_plus) {
2722 c = ' ';
2723 } else if (c == '%' && EVUTIL_ISXDIGIT(uri[i+1]) &&
2724 EVUTIL_ISXDIGIT(uri[i+2])) {
2725 char tmp[3];
2726 tmp[0] = uri[i+1];
2727 tmp[1] = uri[i+2];
2728 tmp[2] = '\0';
2729 c = (char)strtol(tmp, NULL, 16);
2730 i += 2;
2732 ret[j++] = c;
2734 ret[j] = '\0';
2736 return (j);
2739 /* deprecated */
2740 char *
2741 evhttp_decode_uri(const char *uri)
2743 char *ret;
2745 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2746 event_warn("%s: malloc(%lu)", __func__,
2747 (unsigned long)(strlen(uri) + 1));
2748 return (NULL);
2751 evhttp_decode_uri_internal(uri, strlen(uri),
2752 ret, -1 /*always_decode_plus*/);
2754 return (ret);
2757 char *
2758 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
2760 char *ret;
2761 int n;
2763 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2764 event_warn("%s: malloc(%lu)", __func__,
2765 (unsigned long)(strlen(uri) + 1));
2766 return (NULL);
2769 n = evhttp_decode_uri_internal(uri, strlen(uri),
2770 ret, !!decode_plus/*always_decode_plus*/);
2772 if (size_out) {
2773 EVUTIL_ASSERT(n >= 0);
2774 *size_out = (size_t)n;
2777 return (ret);
2781 * Helper function to parse out arguments in a query.
2782 * The arguments are separated by key and value.
2785 static int
2786 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
2787 int is_whole_uri)
2789 char *line=NULL;
2790 char *argument;
2791 char *p;
2792 const char *query_part;
2793 int result = -1;
2794 struct evhttp_uri *uri=NULL;
2796 TAILQ_INIT(headers);
2798 if (is_whole_uri) {
2799 uri = evhttp_uri_parse(str);
2800 if (!uri)
2801 goto error;
2802 query_part = evhttp_uri_get_query(uri);
2803 } else {
2804 query_part = str;
2807 /* No arguments - we are done */
2808 if (!query_part || !strlen(query_part)) {
2809 result = 0;
2810 goto done;
2813 if ((line = mm_strdup(query_part)) == NULL) {
2814 event_warn("%s: strdup", __func__);
2815 goto error;
2818 p = argument = line;
2819 while (p != NULL && *p != '\0') {
2820 char *key, *value, *decoded_value;
2821 argument = strsep(&p, "&");
2823 value = argument;
2824 key = strsep(&value, "=");
2825 if (value == NULL || *key == '\0') {
2826 goto error;
2829 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
2830 event_warn("%s: mm_malloc", __func__);
2831 goto error;
2833 evhttp_decode_uri_internal(value, strlen(value),
2834 decoded_value, 1 /*always_decode_plus*/);
2835 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
2836 evhttp_add_header_internal(headers, key, decoded_value);
2837 mm_free(decoded_value);
2840 result = 0;
2841 goto done;
2842 error:
2843 evhttp_clear_headers(headers);
2844 done:
2845 if (line)
2846 mm_free(line);
2847 if (uri)
2848 evhttp_uri_free(uri);
2849 return result;
2853 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
2855 return evhttp_parse_query_impl(uri, headers, 1);
2858 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
2860 return evhttp_parse_query_impl(uri, headers, 0);
2863 static struct evhttp_cb *
2864 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
2866 struct evhttp_cb *cb;
2867 size_t offset = 0;
2868 char *translated;
2869 const char *path;
2871 /* Test for different URLs */
2872 path = evhttp_uri_get_path(req->uri_elems);
2873 offset = strlen(path);
2874 if ((translated = mm_malloc(offset + 1)) == NULL)
2875 return (NULL);
2876 evhttp_decode_uri_internal(path, offset, translated,
2877 0 /* decode_plus */);
2879 TAILQ_FOREACH(cb, callbacks, next) {
2880 if (!strcmp(cb->what, translated)) {
2881 mm_free(translated);
2882 return (cb);
2886 mm_free(translated);
2887 return (NULL);
2891 static int
2892 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
2894 char c;
2896 while (1) {
2897 switch (c = *pattern++) {
2898 case '\0':
2899 return *name == '\0';
2901 case '*':
2902 while (*name != '\0') {
2903 if (prefix_suffix_match(pattern, name,
2904 ignorecase))
2905 return (1);
2906 ++name;
2908 return (0);
2909 default:
2910 if (c != *name) {
2911 if (!ignorecase ||
2912 EVUTIL_TOLOWER(c) != EVUTIL_TOLOWER(*name))
2913 return (0);
2915 ++name;
2918 /* NOTREACHED */
2922 Search the vhost hierarchy beginning with http for a server alias
2923 matching hostname. If a match is found, and outhttp is non-null,
2924 outhttp is set to the matching http object and 1 is returned.
2927 static int
2928 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
2929 const char *hostname)
2931 struct evhttp_server_alias *alias;
2932 struct evhttp *vhost;
2934 TAILQ_FOREACH(alias, &http->aliases, next) {
2935 /* XXX Do we need to handle IP addresses? */
2936 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
2937 if (outhttp)
2938 *outhttp = http;
2939 return 1;
2943 /* XXX It might be good to avoid recursion here, but I don't
2944 see a way to do that w/o a list. */
2945 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
2946 if (evhttp_find_alias(vhost, outhttp, hostname))
2947 return 1;
2950 return 0;
2954 Attempts to find the best http object to handle a request for a hostname.
2955 All aliases for the root http object and vhosts are searched for an exact
2956 match. Then, the vhost hierarchy is traversed again for a matching
2957 pattern.
2959 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
2960 is set with the best matching http object. If there are no matches, the
2961 root http object is stored in outhttp and 0 is returned.
2964 static int
2965 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
2966 const char *hostname)
2968 struct evhttp *vhost;
2969 struct evhttp *oldhttp;
2970 int match_found = 0;
2972 if (evhttp_find_alias(http, outhttp, hostname))
2973 return 1;
2975 do {
2976 oldhttp = http;
2977 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
2978 if (prefix_suffix_match(vhost->vhost_pattern,
2979 hostname, 1 /* ignorecase */)) {
2980 http = vhost;
2981 match_found = 1;
2982 break;
2985 } while (oldhttp != http);
2987 if (outhttp)
2988 *outhttp = http;
2990 return match_found;
2993 static void
2994 evhttp_handle_request(struct evhttp_request *req, void *arg)
2996 struct evhttp *http = arg;
2997 struct evhttp_cb *cb = NULL;
2998 const char *hostname;
3000 /* we have a new request on which the user needs to take action */
3001 req->userdone = 0;
3003 if (req->type == 0 || req->uri == NULL) {
3004 evhttp_send_error(req, HTTP_BADREQUEST, NULL);
3005 return;
3008 if ((http->allowed_methods & req->type) == 0) {
3009 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3010 (unsigned)req->type, (unsigned)http->allowed_methods));
3011 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3012 return;
3015 /* handle potential virtual hosts */
3016 hostname = evhttp_request_get_host(req);
3017 if (hostname != NULL) {
3018 evhttp_find_vhost(http, &http, hostname);
3021 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3022 (*cb->cb)(req, cb->cbarg);
3023 return;
3026 /* Generic call back */
3027 if (http->gencb) {
3028 (*http->gencb)(req, http->gencbarg);
3029 return;
3030 } else {
3031 /* We need to send a 404 here */
3032 #define ERR_FORMAT "<html><head>" \
3033 "<title>404 Not Found</title>" \
3034 "</head><body>" \
3035 "<h1>Not Found</h1>" \
3036 "<p>The requested URL %s was not found on this server.</p>"\
3037 "</body></html>\n"
3039 char *escaped_html;
3040 struct evbuffer *buf;
3042 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3043 evhttp_connection_free(req->evcon);
3044 return;
3047 if ((buf = evbuffer_new()) == NULL) {
3048 mm_free(escaped_html);
3049 evhttp_connection_free(req->evcon);
3050 return;
3053 evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
3055 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3057 mm_free(escaped_html);
3059 evhttp_send_page(req, buf);
3061 evbuffer_free(buf);
3062 #undef ERR_FORMAT
3066 /* Listener callback when a connection arrives at a server. */
3067 static void
3068 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3070 struct evhttp *http = arg;
3072 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3076 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3078 struct evhttp_bound_socket *bound =
3079 evhttp_bind_socket_with_handle(http, address, port);
3080 if (bound == NULL)
3081 return (-1);
3082 return (0);
3085 struct evhttp_bound_socket *
3086 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3088 evutil_socket_t fd;
3089 struct evhttp_bound_socket *bound;
3091 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3092 return (NULL);
3094 if (listen(fd, 128) == -1) {
3095 event_sock_warn(fd, "%s: listen", __func__);
3096 evutil_closesocket(fd);
3097 return (NULL);
3100 bound = evhttp_accept_socket_with_handle(http, fd);
3102 if (bound != NULL) {
3103 event_debug(("Bound to port %d - Awaiting connections ... ",
3104 port));
3105 return (bound);
3108 return (NULL);
3112 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3114 struct evhttp_bound_socket *bound =
3115 evhttp_accept_socket_with_handle(http, fd);
3116 if (bound == NULL)
3117 return (-1);
3118 return (0);
3122 struct evhttp_bound_socket *
3123 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3125 struct evhttp_bound_socket *bound;
3126 struct evconnlistener *listener;
3127 const int flags =
3128 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3130 listener = evconnlistener_new(http->base, NULL, NULL,
3131 flags,
3132 0, /* Backlog is '0' because we already said 'listen' */
3133 fd);
3134 if (!listener)
3135 return (NULL);
3137 bound = evhttp_bind_listener(http, listener);
3138 if (!bound) {
3139 evconnlistener_free(listener);
3140 return (NULL);
3142 return (bound);
3145 struct evhttp_bound_socket *
3146 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3148 struct evhttp_bound_socket *bound;
3150 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3151 if (bound == NULL)
3152 return (NULL);
3154 bound->listener = listener;
3155 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3157 evconnlistener_set_cb(listener, accept_socket_cb, http);
3158 return bound;
3161 evutil_socket_t
3162 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3164 return evconnlistener_get_fd(bound->listener);
3167 struct evconnlistener *
3168 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3170 return bound->listener;
3173 void
3174 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3176 TAILQ_REMOVE(&http->sockets, bound, next);
3177 evconnlistener_free(bound->listener);
3178 mm_free(bound);
3181 static struct evhttp*
3182 evhttp_new_object(void)
3184 struct evhttp *http = NULL;
3186 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3187 event_warn("%s: calloc", __func__);
3188 return (NULL);
3191 http->timeout = -1;
3192 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3193 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3194 evhttp_set_allowed_methods(http,
3195 EVHTTP_REQ_GET |
3196 EVHTTP_REQ_POST |
3197 EVHTTP_REQ_HEAD |
3198 EVHTTP_REQ_PUT |
3199 EVHTTP_REQ_DELETE);
3201 TAILQ_INIT(&http->sockets);
3202 TAILQ_INIT(&http->callbacks);
3203 TAILQ_INIT(&http->connections);
3204 TAILQ_INIT(&http->virtualhosts);
3205 TAILQ_INIT(&http->aliases);
3207 return (http);
3210 struct evhttp *
3211 evhttp_new(struct event_base *base)
3213 struct evhttp *http = NULL;
3215 http = evhttp_new_object();
3216 if (http == NULL)
3217 return (NULL);
3218 http->base = base;
3220 return (http);
3224 * Start a web server on the specified address and port.
3227 struct evhttp *
3228 evhttp_start(const char *address, unsigned short port)
3230 struct evhttp *http = NULL;
3232 http = evhttp_new_object();
3233 if (http == NULL)
3234 return (NULL);
3235 if (evhttp_bind_socket(http, address, port) == -1) {
3236 mm_free(http);
3237 return (NULL);
3240 return (http);
3243 void
3244 evhttp_free(struct evhttp* http)
3246 struct evhttp_cb *http_cb;
3247 struct evhttp_connection *evcon;
3248 struct evhttp_bound_socket *bound;
3249 struct evhttp* vhost;
3250 struct evhttp_server_alias *alias;
3252 /* Remove the accepting part */
3253 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3254 TAILQ_REMOVE(&http->sockets, bound, next);
3256 evconnlistener_free(bound->listener);
3258 mm_free(bound);
3261 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3262 /* evhttp_connection_free removes the connection */
3263 evhttp_connection_free(evcon);
3266 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3267 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3268 mm_free(http_cb->what);
3269 mm_free(http_cb);
3272 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3273 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3275 evhttp_free(vhost);
3278 if (http->vhost_pattern != NULL)
3279 mm_free(http->vhost_pattern);
3281 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3282 TAILQ_REMOVE(&http->aliases, alias, next);
3283 mm_free(alias->alias);
3284 mm_free(alias);
3287 mm_free(http);
3291 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3292 struct evhttp* vhost)
3294 /* a vhost can only be a vhost once and should not have bound sockets */
3295 if (vhost->vhost_pattern != NULL ||
3296 TAILQ_FIRST(&vhost->sockets) != NULL)
3297 return (-1);
3299 vhost->vhost_pattern = mm_strdup(pattern);
3300 if (vhost->vhost_pattern == NULL)
3301 return (-1);
3303 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3305 return (0);
3309 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3311 if (vhost->vhost_pattern == NULL)
3312 return (-1);
3314 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3316 mm_free(vhost->vhost_pattern);
3317 vhost->vhost_pattern = NULL;
3319 return (0);
3323 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3325 struct evhttp_server_alias *evalias;
3327 evalias = mm_calloc(1, sizeof(*evalias));
3328 if (!evalias)
3329 return -1;
3331 evalias->alias = mm_strdup(alias);
3332 if (!evalias->alias) {
3333 mm_free(evalias);
3334 return -1;
3337 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3339 return 0;
3343 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3345 struct evhttp_server_alias *evalias;
3347 TAILQ_FOREACH(evalias, &http->aliases, next) {
3348 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3349 TAILQ_REMOVE(&http->aliases, evalias, next);
3350 mm_free(evalias->alias);
3351 mm_free(evalias);
3352 return 0;
3356 return -1;
3359 void
3360 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
3362 http->timeout = timeout_in_secs;
3365 void
3366 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
3368 if (max_headers_size < 0)
3369 http->default_max_headers_size = EV_SIZE_MAX;
3370 else
3371 http->default_max_headers_size = max_headers_size;
3374 void
3375 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
3377 if (max_body_size < 0)
3378 http->default_max_body_size = EV_UINT64_MAX;
3379 else
3380 http->default_max_body_size = max_body_size;
3383 void
3384 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
3386 http->allowed_methods = methods;
3390 evhttp_set_cb(struct evhttp *http, const char *uri,
3391 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3393 struct evhttp_cb *http_cb;
3395 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3396 if (strcmp(http_cb->what, uri) == 0)
3397 return (-1);
3400 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
3401 event_warn("%s: calloc", __func__);
3402 return (-2);
3405 http_cb->what = mm_strdup(uri);
3406 if (http_cb->what == NULL) {
3407 event_warn("%s: strdup", __func__);
3408 mm_free(http_cb);
3409 return (-3);
3411 http_cb->cb = cb;
3412 http_cb->cbarg = cbarg;
3414 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
3416 return (0);
3420 evhttp_del_cb(struct evhttp *http, const char *uri)
3422 struct evhttp_cb *http_cb;
3424 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3425 if (strcmp(http_cb->what, uri) == 0)
3426 break;
3428 if (http_cb == NULL)
3429 return (-1);
3431 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3432 mm_free(http_cb->what);
3433 mm_free(http_cb);
3435 return (0);
3438 void
3439 evhttp_set_gencb(struct evhttp *http,
3440 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3442 http->gencb = cb;
3443 http->gencbarg = cbarg;
3447 * Request related functions
3450 struct evhttp_request *
3451 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
3453 struct evhttp_request *req = NULL;
3455 /* Allocate request structure */
3456 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
3457 event_warn("%s: calloc", __func__);
3458 goto error;
3461 req->headers_size = 0;
3462 req->body_size = 0;
3464 req->kind = EVHTTP_RESPONSE;
3465 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3466 if (req->input_headers == NULL) {
3467 event_warn("%s: calloc", __func__);
3468 goto error;
3470 TAILQ_INIT(req->input_headers);
3472 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3473 if (req->output_headers == NULL) {
3474 event_warn("%s: calloc", __func__);
3475 goto error;
3477 TAILQ_INIT(req->output_headers);
3479 if ((req->input_buffer = evbuffer_new()) == NULL) {
3480 event_warn("%s: evbuffer_new", __func__);
3481 goto error;
3484 if ((req->output_buffer = evbuffer_new()) == NULL) {
3485 event_warn("%s: evbuffer_new", __func__);
3486 goto error;
3489 req->cb = cb;
3490 req->cb_arg = arg;
3492 return (req);
3494 error:
3495 if (req != NULL)
3496 evhttp_request_free(req);
3497 return (NULL);
3500 void
3501 evhttp_request_free(struct evhttp_request *req)
3503 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
3504 req->flags |= EVHTTP_REQ_NEEDS_FREE;
3505 return;
3508 if (req->remote_host != NULL)
3509 mm_free(req->remote_host);
3510 if (req->uri != NULL)
3511 mm_free(req->uri);
3512 if (req->uri_elems != NULL)
3513 evhttp_uri_free(req->uri_elems);
3514 if (req->response_code_line != NULL)
3515 mm_free(req->response_code_line);
3516 if (req->host_cache != NULL)
3517 mm_free(req->host_cache);
3519 evhttp_clear_headers(req->input_headers);
3520 mm_free(req->input_headers);
3522 evhttp_clear_headers(req->output_headers);
3523 mm_free(req->output_headers);
3525 if (req->input_buffer != NULL)
3526 evbuffer_free(req->input_buffer);
3528 if (req->output_buffer != NULL)
3529 evbuffer_free(req->output_buffer);
3531 mm_free(req);
3534 void
3535 evhttp_request_own(struct evhttp_request *req)
3537 req->flags |= EVHTTP_USER_OWNED;
3541 evhttp_request_is_owned(struct evhttp_request *req)
3543 return (req->flags & EVHTTP_USER_OWNED) != 0;
3546 struct evhttp_connection *
3547 evhttp_request_get_connection(struct evhttp_request *req)
3549 return req->evcon;
3552 struct event_base *
3553 evhttp_connection_get_base(struct evhttp_connection *conn)
3555 return conn->base;
3558 void
3559 evhttp_request_set_chunked_cb(struct evhttp_request *req,
3560 void (*cb)(struct evhttp_request *, void *))
3562 req->chunk_cb = cb;
3566 * Allows for inspection of the request URI
3569 const char *
3570 evhttp_request_get_uri(const struct evhttp_request *req) {
3571 if (req->uri == NULL)
3572 event_debug(("%s: request %p has no uri\n", __func__, req));
3573 return (req->uri);
3576 const struct evhttp_uri *
3577 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
3578 if (req->uri_elems == NULL)
3579 event_debug(("%s: request %p has no uri elems\n",
3580 __func__, req));
3581 return (req->uri_elems);
3584 const char *
3585 evhttp_request_get_host(struct evhttp_request *req)
3587 const char *host = NULL;
3589 if (req->host_cache)
3590 return req->host_cache;
3592 if (req->uri_elems)
3593 host = evhttp_uri_get_host(req->uri_elems);
3594 if (!host && req->input_headers) {
3595 const char *p;
3596 size_t len;
3598 host = evhttp_find_header(req->input_headers, "Host");
3599 /* The Host: header may include a port. Remove it here
3600 to be consistent with uri_elems case above. */
3601 if (host) {
3602 p = host + strlen(host) - 1;
3603 while (p > host && EVUTIL_ISDIGIT(*p))
3604 --p;
3605 if (p > host && *p == ':') {
3606 len = p - host;
3607 req->host_cache = mm_malloc(len + 1);
3608 if (!req->host_cache) {
3609 event_warn("%s: malloc", __func__);
3610 return NULL;
3612 memcpy(req->host_cache, host, len);
3613 req->host_cache[len] = '\0';
3614 host = req->host_cache;
3619 return host;
3622 enum evhttp_cmd_type
3623 evhttp_request_get_command(const struct evhttp_request *req) {
3624 return (req->type);
3628 evhttp_request_get_response_code(const struct evhttp_request *req)
3630 return req->response_code;
3633 /** Returns the input headers */
3634 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
3636 return (req->input_headers);
3639 /** Returns the output headers */
3640 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
3642 return (req->output_headers);
3645 /** Returns the input buffer */
3646 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
3648 return (req->input_buffer);
3651 /** Returns the output buffer */
3652 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
3654 return (req->output_buffer);
3659 * Takes a file descriptor to read a request from.
3660 * The callback is executed once the whole request has been read.
3663 static struct evhttp_connection*
3664 evhttp_get_request_connection(
3665 struct evhttp* http,
3666 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
3668 struct evhttp_connection *evcon;
3669 char *hostname = NULL, *portname = NULL;
3671 name_from_addr(sa, salen, &hostname, &portname);
3672 if (hostname == NULL || portname == NULL) {
3673 if (hostname) mm_free(hostname);
3674 if (portname) mm_free(portname);
3675 return (NULL);
3678 event_debug(("%s: new request from %s:%s on %d\n",
3679 __func__, hostname, portname, fd));
3681 /* we need a connection object to put the http request on */
3682 evcon = evhttp_connection_base_new(
3683 http->base, NULL, hostname, atoi(portname));
3684 mm_free(hostname);
3685 mm_free(portname);
3686 if (evcon == NULL)
3687 return (NULL);
3689 evcon->max_headers_size = http->default_max_headers_size;
3690 evcon->max_body_size = http->default_max_body_size;
3692 evcon->flags |= EVHTTP_CON_INCOMING;
3693 evcon->state = EVCON_READING_FIRSTLINE;
3695 evcon->fd = fd;
3697 bufferevent_setfd(evcon->bufev, fd);
3699 return (evcon);
3702 static int
3703 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
3705 struct evhttp *http = evcon->http_server;
3706 struct evhttp_request *req;
3707 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
3708 return (-1);
3710 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
3711 event_warn("%s: strdup", __func__);
3712 evhttp_request_free(req);
3713 return (-1);
3715 req->remote_port = evcon->port;
3717 req->evcon = evcon; /* the request ends up owning the connection */
3718 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
3720 /* We did not present the request to the user user yet, so treat it as
3721 * if the user was done with the request. This allows us to free the
3722 * request on a persistent connection if the client drops it without
3723 * sending a request.
3725 req->userdone = 1;
3727 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
3729 req->kind = EVHTTP_REQUEST;
3732 evhttp_start_read(evcon);
3734 return (0);
3737 static void
3738 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
3739 struct sockaddr *sa, ev_socklen_t salen)
3741 struct evhttp_connection *evcon;
3743 evcon = evhttp_get_request_connection(http, fd, sa, salen);
3744 if (evcon == NULL) {
3745 event_sock_warn(fd, "%s: cannot get connection on %d", __func__, fd);
3746 evutil_closesocket(fd);
3747 return;
3750 /* the timeout can be used by the server to close idle connections */
3751 if (http->timeout != -1)
3752 evhttp_connection_set_timeout(evcon, http->timeout);
3755 * if we want to accept more than one request on a connection,
3756 * we need to know which http server it belongs to.
3758 evcon->http_server = http;
3759 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
3761 if (evhttp_associate_new_request_with_connection(evcon) == -1)
3762 evhttp_connection_free(evcon);
3767 * Network helper functions that we do not want to export to the rest of
3768 * the world.
3771 static void
3772 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
3773 char **phost, char **pport)
3775 char ntop[NI_MAXHOST];
3776 char strport[NI_MAXSERV];
3777 int ni_result;
3779 #ifdef _EVENT_HAVE_GETNAMEINFO
3780 ni_result = getnameinfo(sa, salen,
3781 ntop, sizeof(ntop), strport, sizeof(strport),
3782 NI_NUMERICHOST|NI_NUMERICSERV);
3784 if (ni_result != 0) {
3785 #ifdef EAI_SYSTEM
3786 /* Windows doesn't have an EAI_SYSTEM. */
3787 if (ni_result == EAI_SYSTEM)
3788 event_err(1, "getnameinfo failed");
3789 else
3790 #endif
3791 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
3792 return;
3794 #else
3795 ni_result = fake_getnameinfo(sa, salen,
3796 ntop, sizeof(ntop), strport, sizeof(strport),
3797 NI_NUMERICHOST|NI_NUMERICSERV);
3798 if (ni_result != 0)
3799 return;
3800 #endif
3802 *phost = mm_strdup(ntop);
3803 *pport = mm_strdup(strport);
3806 /* Create a non-blocking socket and bind it */
3807 /* todo: rename this function */
3808 static evutil_socket_t
3809 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
3811 evutil_socket_t fd;
3813 int on = 1, r;
3814 int serrno;
3816 /* Create listen socket */
3817 fd = socket(ai ? ai->ai_family : AF_INET, SOCK_STREAM, 0);
3818 if (fd == -1) {
3819 event_sock_warn(-1, "socket");
3820 return (-1);
3823 if (evutil_make_socket_nonblocking(fd) < 0)
3824 goto out;
3825 if (evutil_make_socket_closeonexec(fd) < 0)
3826 goto out;
3828 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
3829 if (reuse)
3830 evutil_make_listen_socket_reuseable(fd);
3832 if (ai != NULL) {
3833 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
3834 if (r == -1)
3835 goto out;
3838 return (fd);
3840 out:
3841 serrno = EVUTIL_SOCKET_ERROR();
3842 evutil_closesocket(fd);
3843 EVUTIL_SET_SOCKET_ERROR(serrno);
3844 return (-1);
3847 static struct evutil_addrinfo *
3848 make_addrinfo(const char *address, ev_uint16_t port)
3850 struct evutil_addrinfo *ai = NULL;
3852 struct evutil_addrinfo hints;
3853 char strport[NI_MAXSERV];
3854 int ai_result;
3856 memset(&hints, 0, sizeof(hints));
3857 hints.ai_family = AF_UNSPEC;
3858 hints.ai_socktype = SOCK_STREAM;
3859 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
3860 * types we don't have an interface to connect to. */
3861 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
3862 evutil_snprintf(strport, sizeof(strport), "%d", port);
3863 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
3864 != 0) {
3865 if (ai_result == EVUTIL_EAI_SYSTEM)
3866 event_warn("getaddrinfo");
3867 else
3868 event_warnx("getaddrinfo: %s",
3869 evutil_gai_strerror(ai_result));
3870 return (NULL);
3873 return (ai);
3876 static evutil_socket_t
3877 bind_socket(const char *address, ev_uint16_t port, int reuse)
3879 evutil_socket_t fd;
3880 struct evutil_addrinfo *aitop = NULL;
3882 /* just create an unbound socket */
3883 if (address == NULL && port == 0)
3884 return bind_socket_ai(NULL, 0);
3886 aitop = make_addrinfo(address, port);
3888 if (aitop == NULL)
3889 return (-1);
3891 fd = bind_socket_ai(aitop, reuse);
3893 evutil_freeaddrinfo(aitop);
3895 return (fd);
3898 struct evhttp_uri {
3899 unsigned flags;
3900 char *scheme; /* scheme; e.g http, ftp etc */
3901 char *userinfo; /* userinfo (typically username:pass), or NULL */
3902 char *host; /* hostname, IP address, or NULL */
3903 int port; /* port, or zero */
3904 char *path; /* path, or "". */
3905 char *query; /* query, or NULL */
3906 char *fragment; /* fragment or NULL */
3909 struct evhttp_uri *
3910 evhttp_uri_new(void)
3912 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
3913 if (uri)
3914 uri->port = -1;
3915 return uri;
3918 void
3919 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
3921 uri->flags = flags;
3924 /* Return true if the string starting at s and ending immediately before eos
3925 * is a valid URI scheme according to RFC3986
3927 static int
3928 scheme_ok(const char *s, const char *eos)
3930 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
3931 EVUTIL_ASSERT(eos >= s);
3932 if (s == eos)
3933 return 0;
3934 if (!EVUTIL_ISALPHA(*s))
3935 return 0;
3936 while (++s < eos) {
3937 if (! EVUTIL_ISALNUM(*s) &&
3938 *s != '+' && *s != '-' && *s != '.')
3939 return 0;
3941 return 1;
3944 #define SUBDELIMS "!$&'()*+,;="
3946 /* Return true iff [s..eos) is a valid userinfo */
3947 static int
3948 userinfo_ok(const char *s, const char *eos)
3950 while (s < eos) {
3951 if (CHAR_IS_UNRESERVED(*s) ||
3952 strchr(SUBDELIMS, *s) ||
3953 *s == ':')
3954 ++s;
3955 else if (*s == '%' && s+2 < eos &&
3956 EVUTIL_ISXDIGIT(s[1]) &&
3957 EVUTIL_ISXDIGIT(s[2]))
3958 s += 3;
3959 else
3960 return 0;
3962 return 1;
3965 static int
3966 regname_ok(const char *s, const char *eos)
3968 while (s && s<eos) {
3969 if (CHAR_IS_UNRESERVED(*s) ||
3970 strchr(SUBDELIMS, *s))
3971 ++s;
3972 else if (*s == '%' &&
3973 EVUTIL_ISXDIGIT(s[1]) &&
3974 EVUTIL_ISXDIGIT(s[2]))
3975 s += 3;
3976 else
3977 return 0;
3979 return 1;
3982 static int
3983 parse_port(const char *s, const char *eos)
3985 int portnum = 0;
3986 while (s < eos) {
3987 if (! EVUTIL_ISDIGIT(*s))
3988 return -1;
3989 portnum = (portnum * 10) + (*s - '0');
3990 if (portnum < 0)
3991 return -1;
3992 ++s;
3994 return portnum;
3997 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
3998 static int
3999 bracket_addr_ok(const char *s, const char *eos)
4001 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4002 return 0;
4003 if (s[1] == 'v') {
4004 /* IPvFuture, or junk.
4005 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4007 s += 2; /* skip [v */
4008 --eos;
4009 if (!EVUTIL_ISXDIGIT(*s)) /*require at least one*/
4010 return 0;
4011 while (s < eos && *s != '.') {
4012 if (EVUTIL_ISXDIGIT(*s))
4013 ++s;
4014 else
4015 return 0;
4017 if (*s != '.')
4018 return 0;
4019 ++s;
4020 while (s < eos) {
4021 if (CHAR_IS_UNRESERVED(*s) ||
4022 strchr(SUBDELIMS, *s) ||
4023 *s == ':')
4024 ++s;
4025 else
4026 return 0;
4028 return 2;
4029 } else {
4030 /* IPv6, or junk */
4031 char buf[64];
4032 ev_ssize_t n_chars = eos-s-2;
4033 struct in6_addr in6;
4034 if (n_chars >= 64) /* way too long */
4035 return 0;
4036 memcpy(buf, s+1, n_chars);
4037 buf[n_chars]='\0';
4038 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4042 static int
4043 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4045 char *cp, *port;
4046 EVUTIL_ASSERT(eos);
4047 if (eos == s) {
4048 uri->host = mm_strdup("");
4049 if (uri->host == NULL) {
4050 event_warn("%s: strdup", __func__);
4051 return -1;
4053 return 0;
4056 /* Optionally, we start with "userinfo@" */
4058 cp = strchr(s, '@');
4059 if (cp && cp < eos) {
4060 if (! userinfo_ok(s,cp))
4061 return -1;
4062 *cp++ = '\0';
4063 uri->userinfo = mm_strdup(s);
4064 if (uri->userinfo == NULL) {
4065 event_warn("%s: strdup", __func__);
4066 return -1;
4068 } else {
4069 cp = s;
4071 /* Optionally, we end with ":port" */
4072 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT(*port); --port)
4074 if (port >= cp && *port == ':') {
4075 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4076 * nil port */
4077 uri->port = -1;
4078 else if ((uri->port = parse_port(port+1, eos))<0)
4079 return -1;
4080 eos = port;
4082 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4083 * an IP-Literal, or a reg-name */
4084 EVUTIL_ASSERT(eos >= cp);
4085 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4086 /* IPv6address, IP-Literal, or junk. */
4087 if (! bracket_addr_ok(cp, eos))
4088 return -1;
4089 } else {
4090 /* Make sure the host part is ok. */
4091 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4092 return -1;
4094 uri->host = mm_malloc(eos-cp+1);
4095 if (uri->host == NULL) {
4096 event_warn("%s: malloc", __func__);
4097 return -1;
4099 memcpy(uri->host, cp, eos-cp);
4100 uri->host[eos-cp] = '\0';
4101 return 0;
4105 static char *
4106 end_of_authority(char *cp)
4108 while (*cp) {
4109 if (*cp == '?' || *cp == '#' || *cp == '/')
4110 return cp;
4111 ++cp;
4113 return cp;
4116 enum uri_part {
4117 PART_PATH,
4118 PART_QUERY,
4119 PART_FRAGMENT
4122 /* Return the character after the longest prefix of 'cp' that matches...
4123 * *pchar / "/" if allow_qchars is false, or
4124 * *(pchar / "/" / "?") if allow_qchars is true.
4126 static char *
4127 end_of_path(char *cp, enum uri_part part, unsigned flags)
4129 if (flags & EVHTTP_URI_NONCONFORMANT) {
4130 /* If NONCONFORMANT:
4131 * Path is everything up to a # or ? or nul.
4132 * Query is everything up a # or nul
4133 * Fragment is everything up to a nul.
4135 switch (part) {
4136 case PART_PATH:
4137 while (*cp && *cp != '#' && *cp != '?')
4138 ++cp;
4139 break;
4140 case PART_QUERY:
4141 while (*cp && *cp != '#')
4142 ++cp;
4143 break;
4144 case PART_FRAGMENT:
4145 cp += strlen(cp);
4146 break;
4148 return cp;
4151 while (*cp) {
4152 if (CHAR_IS_UNRESERVED(*cp) ||
4153 strchr(SUBDELIMS, *cp) ||
4154 *cp == ':' || *cp == '@' || *cp == '/')
4155 ++cp;
4156 else if (*cp == '%' && EVUTIL_ISXDIGIT(cp[1]) &&
4157 EVUTIL_ISXDIGIT(cp[2]))
4158 cp += 3;
4159 else if (*cp == '?' && part != PART_PATH)
4160 ++cp;
4161 else
4162 return cp;
4164 return cp;
4167 static int
4168 path_matches_noscheme(const char *cp)
4170 while (*cp) {
4171 if (*cp == ':')
4172 return 0;
4173 else if (*cp == '/')
4174 return 1;
4175 ++cp;
4177 return 1;
4180 struct evhttp_uri *
4181 evhttp_uri_parse(const char *source_uri)
4183 return evhttp_uri_parse_with_flags(source_uri, 0);
4186 struct evhttp_uri *
4187 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4189 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4190 char *path = NULL, *fragment = NULL;
4191 int got_authority = 0;
4193 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4194 if (uri == NULL) {
4195 event_warn("%s: calloc", __func__);
4196 goto err;
4198 uri->port = -1;
4199 uri->flags = flags;
4201 readbuf = mm_strdup(source_uri);
4202 if (readbuf == NULL) {
4203 event_warn("%s: strdup", __func__);
4204 goto err;
4207 readp = readbuf;
4208 token = NULL;
4210 /* We try to follow RFC3986 here as much as we can, and match
4211 the productions
4213 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4215 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
4218 /* 1. scheme: */
4219 token = strchr(readp, ':');
4220 if (token && scheme_ok(readp,token)) {
4221 *token = '\0';
4222 uri->scheme = mm_strdup(readp);
4223 if (uri->scheme == NULL) {
4224 event_warn("%s: strdup", __func__);
4225 goto err;
4227 readp = token+1; /* eat : */
4230 /* 2. Optionally, "//" then an 'authority' part. */
4231 if (readp[0]=='/' && readp[1] == '/') {
4232 char *authority;
4233 readp += 2;
4234 authority = readp;
4235 path = end_of_authority(readp);
4236 if (parse_authority(uri, authority, path) < 0)
4237 goto err;
4238 readp = path;
4239 got_authority = 1;
4242 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4244 path = readp;
4245 readp = end_of_path(path, PART_PATH, flags);
4247 /* Query */
4248 if (*readp == '?') {
4249 *readp = '\0';
4250 ++readp;
4251 query = readp;
4252 readp = end_of_path(readp, PART_QUERY, flags);
4254 /* fragment */
4255 if (*readp == '#') {
4256 *readp = '\0';
4257 ++readp;
4258 fragment = readp;
4259 readp = end_of_path(readp, PART_FRAGMENT, flags);
4261 if (*readp != '\0') {
4262 goto err;
4265 /* These next two cases may be unreachable; I'm leaving them
4266 * in to be defensive. */
4267 /* If you didn't get an authority, the path can't begin with "//" */
4268 if (!got_authority && path[0]=='/' && path[1]=='/')
4269 goto err;
4270 /* If you did get an authority, the path must begin with "/" or be
4271 * empty. */
4272 if (got_authority && path[0] != '/' && path[0] != '\0')
4273 goto err;
4274 /* (End of maybe-unreachable cases) */
4276 /* If there was no scheme, the first part of the path (if any) must
4277 * have no colon in it. */
4278 if (! uri->scheme && !path_matches_noscheme(path))
4279 goto err;
4281 EVUTIL_ASSERT(path);
4282 uri->path = mm_strdup(path);
4283 if (uri->path == NULL) {
4284 event_warn("%s: strdup", __func__);
4285 goto err;
4288 if (query) {
4289 uri->query = mm_strdup(query);
4290 if (uri->query == NULL) {
4291 event_warn("%s: strdup", __func__);
4292 goto err;
4295 if (fragment) {
4296 uri->fragment = mm_strdup(fragment);
4297 if (uri->fragment == NULL) {
4298 event_warn("%s: strdup", __func__);
4299 goto err;
4303 mm_free(readbuf);
4305 return uri;
4306 err:
4307 if (uri)
4308 evhttp_uri_free(uri);
4309 if (readbuf)
4310 mm_free(readbuf);
4311 return NULL;
4314 void
4315 evhttp_uri_free(struct evhttp_uri *uri)
4317 #define _URI_FREE_STR(f) \
4318 if (uri->f) { \
4319 mm_free(uri->f); \
4322 _URI_FREE_STR(scheme);
4323 _URI_FREE_STR(userinfo);
4324 _URI_FREE_STR(host);
4325 _URI_FREE_STR(path);
4326 _URI_FREE_STR(query);
4327 _URI_FREE_STR(fragment);
4329 mm_free(uri);
4330 #undef _URI_FREE_STR
4333 char *
4334 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
4336 struct evbuffer *tmp = 0;
4337 size_t joined_size = 0;
4338 char *output = NULL;
4340 #define _URI_ADD(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
4342 if (!uri || !buf || !limit)
4343 return NULL;
4345 tmp = evbuffer_new();
4346 if (!tmp)
4347 return NULL;
4349 if (uri->scheme) {
4350 _URI_ADD(scheme);
4351 evbuffer_add(tmp, ":", 1);
4353 if (uri->host) {
4354 evbuffer_add(tmp, "//", 2);
4355 if (uri->userinfo)
4356 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
4357 _URI_ADD(host);
4358 if (uri->port >= 0)
4359 evbuffer_add_printf(tmp,":%d", uri->port);
4361 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
4362 goto err;
4365 if (uri->path)
4366 _URI_ADD(path);
4368 if (uri->query) {
4369 evbuffer_add(tmp, "?", 1);
4370 _URI_ADD(query);
4373 if (uri->fragment) {
4374 evbuffer_add(tmp, "#", 1);
4375 _URI_ADD(fragment);
4378 evbuffer_add(tmp, "\0", 1); /* NUL */
4380 joined_size = evbuffer_get_length(tmp);
4382 if (joined_size > limit) {
4383 /* It doesn't fit. */
4384 evbuffer_free(tmp);
4385 return NULL;
4387 evbuffer_remove(tmp, buf, joined_size);
4389 output = buf;
4390 err:
4391 evbuffer_free(tmp);
4393 return output;
4394 #undef _URI_ADD
4397 const char *
4398 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
4400 return uri->scheme;
4402 const char *
4403 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
4405 return uri->userinfo;
4407 const char *
4408 evhttp_uri_get_host(const struct evhttp_uri *uri)
4410 return uri->host;
4413 evhttp_uri_get_port(const struct evhttp_uri *uri)
4415 return uri->port;
4417 const char *
4418 evhttp_uri_get_path(const struct evhttp_uri *uri)
4420 return uri->path;
4422 const char *
4423 evhttp_uri_get_query(const struct evhttp_uri *uri)
4425 return uri->query;
4427 const char *
4428 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
4430 return uri->fragment;
4433 #define _URI_SET_STR(f) do { \
4434 if (uri->f) \
4435 mm_free(uri->f); \
4436 if (f) { \
4437 if ((uri->f = mm_strdup(f)) == NULL) { \
4438 event_warn("%s: strdup()", __func__); \
4439 return -1; \
4441 } else { \
4442 uri->f = NULL; \
4444 } while(0)
4447 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
4449 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
4450 return -1;
4452 _URI_SET_STR(scheme);
4453 return 0;
4456 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
4458 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
4459 return -1;
4460 _URI_SET_STR(userinfo);
4461 return 0;
4464 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
4466 if (host) {
4467 if (host[0] == '[') {
4468 if (! bracket_addr_ok(host, host+strlen(host)))
4469 return -1;
4470 } else {
4471 if (! regname_ok(host, host+strlen(host)))
4472 return -1;
4476 _URI_SET_STR(host);
4477 return 0;
4480 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
4482 if (port < -1)
4483 return -1;
4484 uri->port = port;
4485 return 0;
4487 #define end_of_cpath(cp,p,f) \
4488 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
4491 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
4493 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
4494 return -1;
4496 _URI_SET_STR(path);
4497 return 0;
4500 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
4502 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
4503 return -1;
4504 _URI_SET_STR(query);
4505 return 0;
4508 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
4510 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
4511 return -1;
4512 _URI_SET_STR(fragment);
4513 return 0;