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
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"
29 #include "evconfig-private.h"
31 #ifdef EVENT__HAVE_SYS_PARAM_H
32 #include <sys/param.h>
34 #ifdef EVENT__HAVE_SYS_TYPES_H
35 #include <sys/types.h>
38 #ifdef HAVE_SYS_IOCCOM_H
39 #include <sys/ioccom.h>
41 #ifdef EVENT__HAVE_SYS_RESOURCE_H
42 #include <sys/resource.h>
44 #ifdef EVENT__HAVE_SYS_TIME_H
47 #ifdef EVENT__HAVE_SYS_WAIT_H
52 #include <sys/socket.h>
59 #ifdef EVENT__HAVE_SYS_UN_H
62 #ifdef EVENT__HAVE_AFUNIX_H
66 #include <sys/queue.h>
68 #ifdef EVENT__HAVE_NETINET_IN_H
69 #include <netinet/in.h>
71 #ifdef EVENT__HAVE_ARPA_INET_H
72 #include <arpa/inet.h>
74 #ifdef EVENT__HAVE_NETDB_H
90 #ifdef EVENT__HAVE_UNISTD_H
93 #ifdef EVENT__HAVE_FCNTL_H
97 #undef timeout_pending
98 #undef timeout_initialized
100 #include "strlcpy-internal.h"
101 #include "event2/http.h"
102 #include "event2/event.h"
103 #include "event2/buffer.h"
104 #include "event2/bufferevent.h"
105 #include "event2/http_struct.h"
106 #include "event2/http_compat.h"
107 #include "event2/util.h"
108 #include "event2/listener.h"
109 #include "log-internal.h"
110 #include "util-internal.h"
111 #include "http-internal.h"
112 #include "mm-internal.h"
113 #include "bufferevent-internal.h"
115 #ifndef EVENT__HAVE_GETNAMEINFO
116 #define NI_MAXSERV 32
117 #define NI_MAXHOST 1025
119 #ifndef NI_NUMERICHOST
120 #define NI_NUMERICHOST 1
123 #ifndef NI_NUMERICSERV
124 #define NI_NUMERICSERV 2
128 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
129 size_t hostlen, char *serv, size_t servlen, int flags)
131 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
135 evutil_snprintf(tmpserv, sizeof(tmpserv),
136 "%d", ntohs(sin->sin_port));
137 if (strlcpy(serv, tmpserv, servlen) >= servlen)
142 if (flags & NI_NUMERICHOST) {
143 if (strlcpy(host, inet_ntoa(sin->sin_addr),
150 hp = gethostbyaddr((char *)&sin->sin_addr,
151 sizeof(struct in_addr), AF_INET);
155 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
166 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \
167 ((req)->major < (major_v) || \
168 ((req)->major == (major_v) && (req)->minor < (minor_v)))
170 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \
171 ((req)->major > (major_v) || \
172 ((req)->major == (major_v) && (req)->minor >= (minor_v)))
175 #define MIN(a,b) (((a)<(b))?(a):(b))
180 static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse);
181 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
182 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
183 static struct evhttp_uri *evhttp_uri_parse_authority(char *source_uri);
184 static int evhttp_associate_new_request_with_connection(
185 struct evhttp_connection *evcon);
186 static void evhttp_connection_start_detectclose(
187 struct evhttp_connection *evcon);
188 static void evhttp_connection_stop_detectclose(
189 struct evhttp_connection *evcon);
190 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
191 static void evhttp_read_firstline(struct evhttp_connection *evcon,
192 struct evhttp_request *req);
193 static void evhttp_read_header(struct evhttp_connection *evcon,
194 struct evhttp_request *req);
195 static int evhttp_add_header_internal(struct evkeyvalq *headers,
196 const char *key, const char *value);
197 static const char *evhttp_response_phrase_internal(int code);
198 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t);
199 static void evhttp_write_buffer(struct evhttp_connection *,
200 void (*)(struct evhttp_connection *, void *), void *);
201 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
202 static int evhttp_method_may_have_body_(struct evhttp_connection *, enum evhttp_cmd_type);
204 /* callbacks for bufferevent */
205 static void evhttp_read_cb(struct bufferevent *, void *);
206 static void evhttp_write_cb(struct bufferevent *, void *);
207 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
208 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp, const char *hostname);
209 static const char *evhttp_method_(struct evhttp_connection *evcon,
210 enum evhttp_cmd_type type, ev_uint16_t *flags);
212 #ifndef EVENT__HAVE_STRSEP
213 /* strsep replacement for platforms that lack it. Only works if
214 * del is one character long. */
216 strsep(char **s, const char *del)
219 EVUTIL_ASSERT(strlen(del) == 1);
223 d = strstr(tok, del);
234 html_replace(const char ch, const char **escaped)
260 * Replaces <, >, ", ' and & with <, >, ",
261 * ' and & correspondingly.
263 * The returned string needs to be freed by the caller.
267 evhttp_htmlescape(const char *html)
270 size_t new_size = 0, old_size = 0;
271 char *escaped_html, *p;
276 old_size = strlen(html);
277 for (i = 0; i < old_size; ++i) {
278 const char *replaced = NULL;
279 const size_t replace_size = html_replace(html[i], &replaced);
280 if (replace_size > EV_SIZE_MAX - new_size) {
281 event_warn("%s: html_replace overflow", __func__);
284 new_size += replace_size;
287 if (new_size == EV_SIZE_MAX)
289 p = escaped_html = mm_malloc(new_size + 1);
290 if (escaped_html == NULL) {
291 event_warn("%s: malloc(%lu)", __func__,
292 (unsigned long)(new_size + 1));
295 for (i = 0; i < old_size; ++i) {
296 const char *replaced = &html[i];
297 const size_t len = html_replace(html[i], &replaced);
298 memcpy(p, replaced, len);
304 return (escaped_html);
307 /** Given an evhttp_cmd_type, returns a constant string containing the
308 * equivalent HTTP command, or NULL if the evhttp_cmd_type is
311 evhttp_method_(struct evhttp_connection *evcon,
312 enum evhttp_cmd_type type, ev_uint16_t *flags)
314 struct evhttp_ext_method ext_method;
315 const char *method = NULL;
316 ev_uint16_t tmp_flags = EVHTTP_METHOD_HAS_BODY;
322 case EVHTTP_REQ_POST:
325 case EVHTTP_REQ_HEAD:
327 tmp_flags &= ~EVHTTP_METHOD_HAS_BODY;
332 case EVHTTP_REQ_DELETE:
335 case EVHTTP_REQ_OPTIONS:
338 case EVHTTP_REQ_TRACE:
340 tmp_flags &= ~EVHTTP_METHOD_HAS_BODY;
342 case EVHTTP_REQ_CONNECT:
345 case EVHTTP_REQ_PATCH:
348 case EVHTTP_REQ_PROPFIND:
351 case EVHTTP_REQ_PROPPATCH:
352 method = "PROPPATCH";
354 case EVHTTP_REQ_MKCOL:
357 case EVHTTP_REQ_LOCK:
360 case EVHTTP_REQ_UNLOCK:
363 case EVHTTP_REQ_COPY:
366 case EVHTTP_REQ_MOVE:
370 /* setup the structure to allow for the cmp.
372 * if the cmp function is set, it has the ability to
373 * modify method and flags. Other fields will be
376 * NOTE: the flags returned are OR'd with the current
380 ext_method.method = NULL;
381 ext_method.type = type;
382 ext_method.flags = tmp_flags;
384 if (evcon->ext_method_cmp != NULL &&
385 evcon->ext_method_cmp(&ext_method) == 0) {
387 if (ext_method.type != type) {
388 event_debug(("%s: callback modified type from %u to %u, not allowed",
389 __func__, type, ext_method.type));
393 method = ext_method.method;
394 tmp_flags |= ext_method.flags;
400 event_debug(("%s: type=%04x => '%s' flags=%04x",
401 __func__, (int)type, method, tmp_flags));
409 * Determines if a response should have a body.
410 * Follows the rules in RFC 2616 section 4.3.
411 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
415 evhttp_response_needs_body(struct evhttp_request *req)
417 return (req->response_code != HTTP_NOCONTENT &&
418 req->response_code != HTTP_NOTMODIFIED &&
419 (req->response_code < 100 || req->response_code >= 200) &&
420 req->type != EVHTTP_REQ_HEAD);
423 /** Helper: called after we've added some data to an evcon's bufferevent's
424 * output buffer. Sets the evconn's writing-is-done callback, and puts
425 * the bufferevent into writing mode.
428 evhttp_write_buffer(struct evhttp_connection *evcon,
429 void (*cb)(struct evhttp_connection *, void *), void *arg)
431 event_debug(("%s: preparing to write buffer\n", __func__));
437 /* Disable the read callback: we don't actually care about data;
438 * we only care about close detection. (We don't disable reading --
439 * EV_READ, since we *do* want to learn about any close events.) */
440 bufferevent_setcb(evcon->bufev,
446 bufferevent_enable(evcon->bufev, EV_READ|EV_WRITE);
450 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
452 bufferevent_disable(evcon->bufev, EV_WRITE);
456 evhttp_send_continue(struct evhttp_connection *evcon,
457 struct evhttp_request *req)
459 bufferevent_enable(evcon->bufev, EV_WRITE);
460 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
461 "HTTP/%d.%d 100 Continue\r\n\r\n",
462 req->major, req->minor);
463 evcon->cb = evhttp_send_continue_done;
464 evcon->cb_arg = NULL;
465 bufferevent_setcb(evcon->bufev,
472 /** Helper: returns true iff evconn is in any connected state. */
474 evhttp_connected(struct evhttp_connection *evcon)
476 switch (evcon->state) {
477 case EVCON_DISCONNECTED:
478 case EVCON_CONNECTING:
481 case EVCON_READING_FIRSTLINE:
482 case EVCON_READING_HEADERS:
483 case EVCON_READING_BODY:
484 case EVCON_READING_TRAILER:
491 /* Create the headers needed for an outgoing HTTP request, adds them to
492 * the request's header list, and writes the request line to the
493 * connection's output buffer.
496 evhttp_make_header_request(struct evhttp_connection *evcon,
497 struct evhttp_request *req)
502 evhttp_remove_header(req->output_headers, "Proxy-Connection");
504 /* Generate request line */
505 if (!(method = evhttp_method_(evcon, req->type, &flags))) {
509 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
510 "%s %s HTTP/%d.%d\r\n",
511 method, req->uri, req->major, req->minor);
513 /* Add the content length on a request if missing
514 * Always add it for POST and PUT requests as clients expect it */
515 if ((flags & EVHTTP_METHOD_HAS_BODY) &&
516 (evbuffer_get_length(req->output_buffer) > 0 ||
517 req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
518 evhttp_find_header(req->output_headers, "Content-Length") == NULL) {
520 evutil_snprintf(size, sizeof(size), EV_SIZE_FMT,
521 EV_SIZE_ARG(evbuffer_get_length(req->output_buffer)));
522 evhttp_add_header(req->output_headers, "Content-Length", size);
526 /** Return true if the list of headers in 'headers', intepreted with respect
527 * to flags, means that we should send a "connection: close" when the request
530 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
532 if (flags & EVHTTP_PROXY_REQUEST) {
533 /* proxy connection */
534 const char *connection = evhttp_find_header(headers, "Proxy-Connection");
535 return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
537 const char *connection = evhttp_find_header(headers, "Connection");
538 return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
542 evhttp_is_request_connection_close(struct evhttp_request *req)
545 evhttp_is_connection_close(req->flags, req->input_headers) ||
546 evhttp_is_connection_close(req->flags, req->output_headers);
549 /* Return true iff 'headers' contains 'Connection: keep-alive' */
551 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
553 const char *connection = evhttp_find_header(headers, "Connection");
554 return (connection != NULL
555 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
558 /* Add a correct "Date" header to headers, unless it already has one. */
560 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
562 if (evhttp_find_header(headers, "Date") == NULL) {
564 if (sizeof(date) - evutil_date_rfc1123(date, sizeof(date), NULL) > 0) {
565 evhttp_add_header(headers, "Date", date);
570 /* Add a "Content-Length" header with value 'content_length' to headers,
571 * unless it already has a content-length or transfer-encoding header. */
573 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
574 size_t content_length)
576 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
577 evhttp_find_header(headers, "Content-Length") == NULL) {
579 evutil_snprintf(len, sizeof(len), EV_SIZE_FMT,
580 EV_SIZE_ARG(content_length));
581 evhttp_add_header(headers, "Content-Length", len);
586 * Create the headers needed for an HTTP reply in req->output_headers,
587 * and write the first HTTP response for req line to evcon.
590 evhttp_make_header_response(struct evhttp_connection *evcon,
591 struct evhttp_request *req)
593 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
594 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
595 "HTTP/%d.%d %d %s\r\n",
596 req->major, req->minor, req->response_code,
597 req->response_code_line);
599 if (req->major == 1) {
601 evhttp_maybe_add_date_header(req->output_headers);
604 * if the protocol is 1.0; and the connection was keep-alive
605 * we need to add a keep-alive header, too.
607 if (req->minor == 0 && is_keepalive)
608 evhttp_add_header(req->output_headers,
609 "Connection", "keep-alive");
611 if ((req->minor >= 1 || is_keepalive) &&
612 evhttp_response_needs_body(req)) {
614 * we need to add the content length if the
615 * user did not give it, this is required for
616 * persistent connections to work.
618 evhttp_maybe_add_content_length_header(
620 evbuffer_get_length(req->output_buffer));
624 /* Potentially add headers for unidentified content. */
625 if (evhttp_response_needs_body(req)) {
626 if (evhttp_find_header(req->output_headers,
627 "Content-Type") == NULL
628 && evcon->http_server->default_content_type) {
629 evhttp_add_header(req->output_headers,
631 evcon->http_server->default_content_type);
635 /* if the request asked for a close, we send a close, too */
636 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
637 evhttp_remove_header(req->output_headers, "Connection");
638 if (!(req->flags & EVHTTP_PROXY_REQUEST))
639 evhttp_add_header(req->output_headers, "Connection", "close");
640 evhttp_remove_header(req->output_headers, "Proxy-Connection");
644 enum expect { NO, CONTINUE, OTHER };
645 static enum expect evhttp_have_expect(struct evhttp_request *req, int input)
648 struct evkeyvalq *h = input ? req->input_headers : req->output_headers;
650 if (!(req->kind == EVHTTP_REQUEST) || !REQ_VERSION_ATLEAST(req, 1, 1))
653 expect = evhttp_find_header(h, "Expect");
657 return !evutil_ascii_strcasecmp(expect, "100-continue") ? CONTINUE : OTHER;
661 /** Generate all headers appropriate for sending the http request in req (or
662 * the response, if we're sending a response), and write them to evcon's
663 * bufferevent. Also writes all data from req->output_buffer */
665 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
667 struct evkeyval *header;
668 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
671 * Depending if this is a HTTP request or response, we might need to
672 * add some new headers or remove existing headers.
674 if (req->kind == EVHTTP_REQUEST) {
675 evhttp_make_header_request(evcon, req);
677 evhttp_make_header_response(evcon, req);
680 TAILQ_FOREACH(header, req->output_headers, next) {
681 evbuffer_add_printf(output, "%s: %s\r\n",
682 header->key, header->value);
684 evbuffer_add(output, "\r\n", 2);
686 if (evhttp_have_expect(req, 0) != CONTINUE &&
687 evbuffer_get_length(req->output_buffer)) {
689 * For a request, we add the POST data, for a reply, this
690 * is the regular data.
692 evbuffer_add_buffer(output, req->output_buffer);
697 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
698 ev_ssize_t new_max_headers_size)
700 if (new_max_headers_size<0)
701 evcon->max_headers_size = EV_SIZE_MAX;
703 evcon->max_headers_size = new_max_headers_size;
706 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
707 ev_ssize_t new_max_body_size)
709 if (new_max_body_size<0)
710 evcon->max_body_size = EV_UINT64_MAX;
712 evcon->max_body_size = new_max_body_size;
716 evhttp_connection_incoming_fail(struct evhttp_request *req,
717 enum evhttp_request_error error)
720 case EVREQ_HTTP_DATA_TOO_LONG:
721 req->response_code = HTTP_ENTITYTOOLARGE;
724 req->response_code = HTTP_BADREQUEST;
728 case EVREQ_HTTP_TIMEOUT:
731 * these are cases in which we probably should just
732 * close the connection and not send a reply. this
733 * case may happen when a browser keeps a persistent
734 * connection open and we timeout on the read. when
735 * the request is still being used for sending, we
736 * need to disassociated it from the connection here.
738 if (!req->userdone) {
739 /* remove it so that it will not be freed */
740 TAILQ_REMOVE(&req->evcon->requests, req, next);
741 /* indicate that this request no longer has a
747 case EVREQ_HTTP_INVALID_HEADER:
748 case EVREQ_HTTP_BUFFER_ERROR:
749 case EVREQ_HTTP_REQUEST_CANCEL:
750 case EVREQ_HTTP_DATA_TOO_LONG:
751 default: /* xxx: probably should just error on default */
752 /* the callback looks at the uri to determine errors */
757 if (req->uri_elems) {
758 evhttp_uri_free(req->uri_elems);
759 req->uri_elems = NULL;
763 * the callback needs to send a reply, once the reply has
764 * been send, the connection should get freed.
766 (*req->cb)(req, req->cb_arg);
772 /* Free connection ownership of which can be acquired by user using
773 * evhttp_request_own(). */
775 evhttp_request_free_auto(struct evhttp_request *req)
777 if (!(req->flags & EVHTTP_USER_OWNED))
778 evhttp_request_free(req);
782 evhttp_request_free_(struct evhttp_connection *evcon, struct evhttp_request *req)
784 TAILQ_REMOVE(&evcon->requests, req, next);
785 evhttp_request_free_auto(req);
789 evhttp_set_timeout_tv_(struct timeval *tv, const struct timeval *timeout, int def)
791 if (timeout == NULL && def != -1) {
800 evutil_timerclear(tv);
804 evhttp_set_timeout_(struct timeval *tv, int timeout, int def)
811 evutil_timerclear(tv);
813 struct timeval timeout_tv;
814 timeout_tv.tv_sec = timeout;
815 timeout_tv.tv_usec = 0;
820 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
821 * given in error. If it's an outgoing connection, reset the connection,
822 * retry any pending requests, and inform the user. If it's incoming,
823 * delegates to evhttp_connection_incoming_fail(). */
825 evhttp_connection_fail_(struct evhttp_connection *evcon,
826 enum evhttp_request_error error)
828 const int errsave = EVUTIL_SOCKET_ERROR();
829 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
830 void (*cb)(struct evhttp_request *, void *);
832 void (*error_cb)(enum evhttp_request_error, void *);
834 EVUTIL_ASSERT(req != NULL);
836 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
838 if (evcon->flags & EVHTTP_CON_INCOMING) {
840 * for incoming requests, there are two different
841 * failure cases. it's either a network level error
842 * or an http layer error. for problems on the network
843 * layer like timeouts we just drop the connections.
844 * For HTTP problems, we might have to send back a
845 * reply before the connection can be freed.
847 if (evhttp_connection_incoming_fail(req, error) == -1)
848 evhttp_connection_free(evcon);
852 error_cb = req->error_cb;
853 error_cb_arg = req->cb_arg;
854 /* when the request was canceled, the callback is not executed */
855 if (error != EVREQ_HTTP_REQUEST_CANCEL) {
856 /* save the callback for later; the cb might free our object */
858 cb_arg = req->cb_arg;
864 /* do not fail all requests; the next request is going to get
865 * send over a new connection. when a user cancels a request,
866 * all other pending requests should be processed as normal
868 evhttp_request_free_(evcon, req);
870 /* reset the connection */
871 evhttp_connection_reset_(evcon);
873 /* We are trying the next request that was queued on us */
874 if (TAILQ_FIRST(&evcon->requests) != NULL)
875 evhttp_connection_connect_(evcon);
877 /* The call to evhttp_connection_reset_ overwrote errno.
878 * Let's restore the original errno, so that the user's
879 * callback can have a better idea of what the error was.
881 EVUTIL_SET_SOCKET_ERROR(errsave);
883 /* inform the user */
884 if (error_cb != NULL)
885 error_cb(error, error_cb_arg);
890 /* Bufferevent callback: invoked when any data has been written from an
891 * http connection's bufferevent */
893 evhttp_write_cb(struct bufferevent *bufev, void *arg)
895 struct evhttp_connection *evcon = arg;
897 /* Activate our call back */
898 if (evcon->cb != NULL)
899 (*evcon->cb)(evcon, evcon->cb_arg);
903 * Advance the connection state.
904 * - If this is an outgoing connection, we've just processed the response;
905 * idle or close the connection.
906 * - If this is an incoming connection, we've just processed the request;
910 evhttp_connection_done(struct evhttp_connection *evcon)
912 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
913 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
917 /* idle or close the connection */
918 int need_close = evhttp_is_request_connection_close(req);
919 TAILQ_REMOVE(&evcon->requests, req, next);
922 evcon->state = EVCON_IDLE;
924 /* check if we got asked to close the connection */
926 evhttp_connection_reset_(evcon);
928 if (TAILQ_FIRST(&evcon->requests) != NULL) {
930 * We have more requests; reset the connection
931 * and deal with the next request.
933 if (!evhttp_connected(evcon))
934 evhttp_connection_connect_(evcon);
936 evhttp_request_dispatch(evcon);
937 } else if (!need_close) {
939 * The connection is going to be persistent, but we
940 * need to detect if the other side closes it.
942 evhttp_connection_start_detectclose(evcon);
943 } else if ((evcon->flags & EVHTTP_CON_AUTOFREE)) {
945 * If we have no more requests that need completion
946 * and we're not waiting for the connection to close
952 * incoming connection - we need to leave the request on the
953 * connection so that we can reply to it.
955 evcon->state = EVCON_WRITING;
958 /* notify the user of the request */
959 (*req->cb)(req, req->cb_arg);
961 /* if this was an outgoing request, we own and it's done. so free it. */
963 evhttp_request_free_auto(req);
966 /* If this was the last request of an outgoing connection and we're
967 * not waiting to receive a connection close event and we want to
968 * automatically free the connection. We check to ensure our request
969 * list is empty one last time just in case our callback added a
972 if (free_evcon && TAILQ_FIRST(&evcon->requests) == NULL) {
973 evhttp_connection_free(evcon);
978 * Handles reading from a chunked request.
979 * return ALL_DATA_READ:
980 * all data has been read
981 * return MORE_DATA_EXPECTED:
982 * more data is expected
983 * return DATA_CORRUPTED:
985 * return REQUEST_CANCELED:
986 * request was canceled by the user calling evhttp_cancel_request
987 * return DATA_TOO_LONG:
988 * ran over the maximum limit
991 static enum message_read_status
992 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
994 if (req == NULL || buf == NULL) {
995 return DATA_CORRUPTED;
1001 if ((buflen = evbuffer_get_length(buf)) == 0) {
1005 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
1006 * check for overflow conditions */
1007 if (buflen > EV_SSIZE_MAX) {
1008 return DATA_CORRUPTED;
1011 if (req->ntoread < 0) {
1012 /* Read chunk size */
1014 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
1019 /* the last chunk is on a new line? */
1020 if (strlen(p) == 0) {
1024 ntoread = evutil_strtoll(p, &endp, 16);
1025 error = (*p == '\0' ||
1026 (*endp != '\0' && *endp != ' ') ||
1030 /* could not get chunk size */
1031 return (DATA_CORRUPTED);
1034 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
1035 if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
1036 return DATA_CORRUPTED;
1039 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
1040 /* failed body length test */
1041 event_debug(("Request body is too long"));
1042 return (DATA_TOO_LONG);
1045 req->body_size += (size_t)ntoread;
1046 req->ntoread = ntoread;
1047 if (req->ntoread == 0) {
1049 return (ALL_DATA_READ);
1054 /* req->ntoread is signed int64, len is ssize_t, based on arch,
1055 * ssize_t could only be 32b, check for these conditions */
1056 if (req->ntoread > EV_SSIZE_MAX) {
1057 return DATA_CORRUPTED;
1060 /* don't have enough to complete a chunk; wait for more */
1061 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
1062 return (MORE_DATA_EXPECTED);
1064 /* Completed chunk */
1065 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
1067 if (req->chunk_cb != NULL) {
1068 req->flags |= EVHTTP_REQ_DEFER_FREE;
1069 (*req->chunk_cb)(req, req->cb_arg);
1070 evbuffer_drain(req->input_buffer,
1071 evbuffer_get_length(req->input_buffer));
1072 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1073 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1074 return (REQUEST_CANCELED);
1079 return (MORE_DATA_EXPECTED);
1083 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
1085 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1087 switch (evhttp_parse_headers_(req, buf)) {
1088 case DATA_CORRUPTED:
1090 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1093 bufferevent_disable(evcon->bufev, EV_READ);
1094 evhttp_connection_done(evcon);
1096 case MORE_DATA_EXPECTED:
1097 case REQUEST_CANCELED: /* ??? */
1104 evhttp_lingering_close(struct evhttp_connection *evcon,
1105 struct evhttp_request *req)
1107 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1109 size_t n = evbuffer_get_length(buf);
1110 if (n > (size_t) req->ntoread)
1111 n = (size_t) req->ntoread;
1113 req->body_size += n;
1115 event_debug(("Request body is too long, left " EV_I64_FMT,
1116 EV_I64_ARG(req->ntoread)));
1118 evbuffer_drain(buf, n);
1120 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1123 evhttp_lingering_fail(struct evhttp_connection *evcon,
1124 struct evhttp_request *req)
1126 if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE)
1127 evhttp_lingering_close(evcon, req);
1129 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1133 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1135 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1138 switch (evhttp_handle_chunked_read(req, buf)) {
1140 /* finished last chunk */
1141 evcon->state = EVCON_READING_TRAILER;
1142 evhttp_read_trailer(evcon, req);
1144 case DATA_CORRUPTED:
1146 /* corrupted data */
1147 evhttp_connection_fail_(evcon,
1148 EVREQ_HTTP_DATA_TOO_LONG);
1150 case REQUEST_CANCELED:
1151 /* request canceled */
1152 evhttp_request_free_auto(req);
1154 case MORE_DATA_EXPECTED:
1158 } else if (req->ntoread < 0) {
1159 /* Read until connection close. */
1160 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
1161 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
1165 req->body_size += evbuffer_get_length(buf);
1166 evbuffer_add_buffer(req->input_buffer, buf);
1167 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
1168 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
1169 /* We've postponed moving the data until now, but we're
1170 * about to use it. */
1171 size_t n = evbuffer_get_length(buf);
1173 if (n > (size_t) req->ntoread)
1174 n = (size_t) req->ntoread;
1176 req->body_size += n;
1177 evbuffer_remove_buffer(buf, req->input_buffer, n);
1180 if (req->body_size > req->evcon->max_body_size ||
1181 (!req->chunked && req->ntoread >= 0 &&
1182 (size_t)req->ntoread > req->evcon->max_body_size)) {
1183 /* XXX: The above casted comparison must checked for overflow */
1184 /* failed body length test */
1186 evhttp_lingering_fail(evcon, req);
1190 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1191 req->flags |= EVHTTP_REQ_DEFER_FREE;
1192 (*req->chunk_cb)(req, req->cb_arg);
1193 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1194 evbuffer_drain(req->input_buffer,
1195 evbuffer_get_length(req->input_buffer));
1196 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1197 evhttp_request_free_auto(req);
1202 if (!req->ntoread) {
1203 bufferevent_disable(evcon->bufev, EV_READ);
1204 /* Completed content length */
1205 evhttp_connection_done(evcon);
1210 #define get_deferred_queue(evcon) \
1214 * Gets called when more data becomes available
1218 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1220 struct evhttp_connection *evcon = arg;
1221 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1223 /* Cancel if it's pending. */
1224 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1225 &evcon->read_more_deferred_cb);
1227 switch (evcon->state) {
1228 case EVCON_READING_FIRSTLINE:
1229 evhttp_read_firstline(evcon, req);
1230 /* note the request may have been freed in
1231 * evhttp_read_body */
1233 case EVCON_READING_HEADERS:
1234 evhttp_read_header(evcon, req);
1235 /* note the request may have been freed in
1236 * evhttp_read_body */
1238 case EVCON_READING_BODY:
1239 evhttp_read_body(evcon, req);
1240 /* note the request may have been freed in
1241 * evhttp_read_body */
1243 case EVCON_READING_TRAILER:
1244 evhttp_read_trailer(evcon, req);
1249 struct evbuffer *input;
1252 input = bufferevent_get_input(evcon->bufev);
1253 total_len = evbuffer_get_length(input);
1254 event_debug(("%s: read "EV_SIZE_FMT
1255 " bytes in EVCON_IDLE state,"
1256 " resetting connection",
1257 __func__, EV_SIZE_ARG(total_len)));
1260 evhttp_connection_reset_(evcon);
1263 case EVCON_DISCONNECTED:
1264 case EVCON_CONNECTING:
1267 event_errx(1, "%s: illegal connection state %d",
1268 __func__, evcon->state);
1273 evhttp_deferred_read_cb(struct event_callback *cb, void *data)
1275 struct evhttp_connection *evcon = data;
1276 struct bufferevent *bev = evcon->bufev;
1278 (bev->readcb)(evcon->bufev, evcon);
1282 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1284 /* This is after writing the request to the server */
1285 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1286 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
1287 EVUTIL_ASSERT(req != NULL);
1289 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1291 /* We need to wait until we've written all of our output data before we can
1293 if (evbuffer_get_length(output) > 0)
1296 /* We are done writing our header and are now expecting the response */
1297 req->kind = EVHTTP_RESPONSE;
1299 evhttp_start_read_(evcon);
1303 * Clean up a connection object
1307 evhttp_connection_free(struct evhttp_connection *evcon)
1309 struct evhttp_request *req;
1312 /* notify interested parties that this connection is going down */
1313 if (evcon->fd != -1) {
1314 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1315 (*evcon->closecb)(evcon, evcon->closecb_arg);
1318 /* remove all requests that might be queued on this
1319 * connection. for server connections, this should be empty.
1320 * because it gets dequeued either in evhttp_connection_done or
1321 * evhttp_connection_fail_.
1323 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1324 evhttp_request_free_(evcon, req);
1327 if (evcon->http_server != NULL) {
1328 struct evhttp *http = evcon->http_server;
1329 TAILQ_REMOVE(&http->connections, evcon, next);
1332 if (event_initialized(&evcon->retry_ev)) {
1333 event_del(&evcon->retry_ev);
1334 event_debug_unassign(&evcon->retry_ev);
1337 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1338 &evcon->read_more_deferred_cb);
1340 if (evcon->bufev != NULL) {
1342 !(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE);
1343 if (evcon->fd == -1)
1344 evcon->fd = bufferevent_getfd(evcon->bufev);
1346 bufferevent_free(evcon->bufev);
1349 if (evcon->fd != -1) {
1350 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1352 evutil_closesocket(evcon->fd);
1355 if (evcon->bind_address != NULL)
1356 mm_free(evcon->bind_address);
1358 if (evcon->address != NULL)
1359 mm_free(evcon->address);
1365 evhttp_connection_free_on_completion(struct evhttp_connection *evcon) {
1366 evcon->flags |= EVHTTP_CON_AUTOFREE;
1370 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1371 const char *address)
1373 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1374 if (evcon->bind_address)
1375 mm_free(evcon->bind_address);
1376 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1377 event_warn("%s: strdup", __func__);
1381 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1384 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1385 evcon->bind_port = port;
1389 evhttp_request_dispatch(struct evhttp_connection* evcon)
1391 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1393 /* this should not usually happy but it's possible */
1397 EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST);
1399 /* delete possible close detection events */
1400 evhttp_connection_stop_detectclose(evcon);
1402 /* we assume that the connection is connected already */
1403 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1405 evcon->state = EVCON_WRITING;
1407 /* Create the header from the store arguments */
1408 evhttp_make_header(evcon, req);
1410 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1413 /* Reset our connection state: disables reading/writing, closes our fd (if
1414 * any), clears out buffers, and puts us in state DISCONNECTED. */
1416 evhttp_connection_reset_(struct evhttp_connection *evcon)
1418 struct evbuffer *tmp;
1421 bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL);
1423 /* XXXX This is not actually an optimal fix. Instead we ought to have
1424 an API for "stop connecting", or use bufferevent_setfd to turn off
1425 connecting. But for Libevent 2.0, this seems like a minimal change
1426 least likely to disrupt the rest of the bufferevent and http code.
1428 Why is this here? If the fd is set in the bufferevent, and the
1429 bufferevent is connecting, then you can't actually stop the
1430 bufferevent from trying to connect with bufferevent_disable(). The
1431 connect will never trigger, since we close the fd, but the timeout
1432 might. That caused an assertion failure in evhttp_connection_fail_.
1434 bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE);
1436 if (evcon->fd == -1)
1437 evcon->fd = bufferevent_getfd(evcon->bufev);
1439 if (evcon->fd != -1) {
1440 /* inform interested parties about connection close */
1441 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1442 (*evcon->closecb)(evcon, evcon->closecb_arg);
1444 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1445 evutil_closesocket(evcon->fd);
1448 err = bufferevent_setfd(evcon->bufev, -1);
1449 EVUTIL_ASSERT(!err && "setfd");
1451 /* we need to clean up any buffered data */
1452 tmp = bufferevent_get_output(evcon->bufev);
1453 err = evbuffer_drain(tmp, -1);
1454 EVUTIL_ASSERT(!err && "drain output");
1455 tmp = bufferevent_get_input(evcon->bufev);
1456 err = evbuffer_drain(tmp, -1);
1457 EVUTIL_ASSERT(!err && "drain input");
1459 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1461 evcon->state = EVCON_DISCONNECTED;
1465 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1467 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1468 bufferevent_enable(evcon->bufev, EV_READ);
1472 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1474 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1475 bufferevent_disable(evcon->bufev, EV_READ);
1479 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1481 struct evhttp_connection *evcon = arg;
1483 evcon->state = EVCON_DISCONNECTED;
1484 evhttp_connection_connect_(evcon);
1488 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1490 struct evcon_requestq requests;
1492 evhttp_connection_reset_(evcon);
1493 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1494 struct timeval tv_retry = evcon->initial_retry_timeout;
1496 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1497 /* XXXX handle failure from evhttp_add_event */
1498 for (i=0; i < evcon->retry_cnt; ++i) {
1499 tv_retry.tv_usec *= 2;
1500 if (tv_retry.tv_usec > 1000000) {
1501 tv_retry.tv_usec -= 1000000;
1502 tv_retry.tv_sec += 1;
1504 tv_retry.tv_sec *= 2;
1505 if (tv_retry.tv_sec > 3600) {
1506 tv_retry.tv_sec = 3600;
1507 tv_retry.tv_usec = 0;
1510 event_add(&evcon->retry_ev, &tv_retry);
1516 * User callback can do evhttp_make_request() on the same
1517 * evcon so new request will be added to evcon->requests. To
1518 * avoid freeing it prematurely we iterate over the copy of
1521 TAILQ_INIT(&requests);
1522 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1523 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1524 TAILQ_REMOVE(&evcon->requests, request, next);
1525 TAILQ_INSERT_TAIL(&requests, request, next);
1528 /* for now, we just signal all requests by executing their callbacks */
1529 while (TAILQ_FIRST(&requests) != NULL) {
1530 struct evhttp_request *request = TAILQ_FIRST(&requests);
1531 TAILQ_REMOVE(&requests, request, next);
1532 request->evcon = NULL;
1534 /* we might want to set an error here */
1535 request->cb(request, request->cb_arg);
1536 evhttp_request_free_auto(request);
1541 evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
1542 struct evhttp_request *req)
1544 struct evbuffer *buf;
1546 /** Second time, we can't read anything */
1547 if (evcon->flags & EVHTTP_CON_READING_ERROR) {
1548 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1549 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1553 req->kind = EVHTTP_RESPONSE;
1555 buf = bufferevent_get_output(evcon->bufev);
1556 evbuffer_unfreeze(buf, 1);
1557 evbuffer_drain(buf, evbuffer_get_length(buf));
1558 evbuffer_freeze(buf, 1);
1560 evhttp_start_read_(evcon);
1561 evcon->flags |= EVHTTP_CON_READING_ERROR;
1565 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1567 struct evhttp_connection *evcon = arg;
1568 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1570 if (evcon->fd == -1)
1571 evcon->fd = bufferevent_getfd(bufev);
1573 switch (evcon->state) {
1574 case EVCON_CONNECTING:
1575 if (what & BEV_EVENT_TIMEOUT) {
1576 event_debug(("%s: connection timeout for \"%s:%d\" on "
1578 __func__, evcon->address, evcon->port,
1579 EV_SOCK_ARG(evcon->fd)));
1580 evhttp_connection_cb_cleanup(evcon);
1585 case EVCON_READING_BODY:
1586 if (!req->chunked && req->ntoread < 0
1587 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1588 /* EOF on read can be benign */
1589 evhttp_connection_done(evcon);
1594 case EVCON_DISCONNECTED:
1596 case EVCON_READING_FIRSTLINE:
1597 case EVCON_READING_HEADERS:
1598 case EVCON_READING_TRAILER:
1604 /* when we are in close detect mode, a read error means that
1605 * the other side closed their connection.
1607 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1608 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1609 EVUTIL_ASSERT(evcon->http_server == NULL);
1610 /* For connections from the client, we just
1611 * reset the connection so that it becomes
1614 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1615 evhttp_connection_reset_(evcon);
1618 * If we have no more requests that need completion
1619 * and we want to auto-free the connection when all
1620 * requests have been completed.
1622 if (TAILQ_FIRST(&evcon->requests) == NULL
1623 && (evcon->flags & EVHTTP_CON_OUTGOING)
1624 && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1625 evhttp_connection_free(evcon);
1630 if (what & BEV_EVENT_TIMEOUT) {
1631 evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
1632 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1633 if (what & BEV_EVENT_WRITING &&
1634 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR) {
1635 evhttp_connection_read_on_write_error(evcon, req);
1639 if (what & BEV_EVENT_READING &&
1640 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR &&
1641 evbuffer_get_length(bufferevent_get_input(bufev))) {
1642 event_deferred_cb_schedule_(get_deferred_queue(evcon),
1643 &evcon->read_more_deferred_cb);
1647 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1648 } else if (what == BEV_EVENT_CONNECTED) {
1650 evhttp_connection_fail_(evcon, EVREQ_HTTP_BUFFER_ERROR);
1655 * Event callback for asynchronous connection attempt.
1658 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1660 struct evhttp_connection *evcon = arg;
1662 ev_socklen_t errsz = sizeof(error);
1664 if (evcon->fd == -1)
1665 evcon->fd = bufferevent_getfd(bufev);
1667 if (!(what & BEV_EVENT_CONNECTED)) {
1668 /* some operating systems return ECONNREFUSED immediately
1669 * when connecting to a local address. the cleanup is going
1670 * to reschedule this function call.
1673 if (errno == ECONNREFUSED)
1676 evhttp_error_cb(bufev, what, arg);
1680 if (evcon->fd == -1) {
1681 event_debug(("%s: bufferevent_getfd returned -1",
1686 /* Check if the connection completed */
1687 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1689 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT,
1690 __func__, evcon->address, evcon->port,
1691 EV_SOCK_ARG(evcon->fd)));
1696 event_debug(("%s: connect failed for \"%s:%d\" on "
1698 __func__, evcon->address, evcon->port,
1699 EV_SOCK_ARG(evcon->fd),
1700 evutil_socket_error_to_string(error)));
1704 /* We are connected to the server now */
1705 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1706 __func__, evcon->address, evcon->port,
1707 EV_SOCK_ARG(evcon->fd)));
1709 /* Reset the retry count as we were successful in connecting */
1710 evcon->retry_cnt = 0;
1711 evcon->state = EVCON_IDLE;
1713 /* reset the bufferevent cbs */
1714 bufferevent_setcb(evcon->bufev,
1720 bufferevent_set_timeouts(evcon->bufev,
1721 &evcon->timeout_read, &evcon->timeout_write);
1723 /* try to start requests that have queued up on this connection */
1724 evhttp_request_dispatch(evcon);
1728 evhttp_connection_cb_cleanup(evcon);
1732 * Check if we got a valid response code.
1736 evhttp_valid_response_code(int code)
1745 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1749 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1750 if (n != 2 || major > 1) {
1751 event_debug(("%s: bad version %s on message %p from %s",
1752 __func__, version, req, req->remote_host));
1760 /* Parses the status line of a web server */
1763 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1767 const char *readable = "";
1769 protocol = strsep(&line, " ");
1772 number = strsep(&line, " ");
1776 if (evhttp_parse_http_version(protocol, req) < 0)
1779 req->response_code = atoi(number);
1780 if (!evhttp_valid_response_code(req->response_code)) {
1781 event_debug(("%s: bad response code \"%s\"",
1786 if (req->response_code_line != NULL)
1787 mm_free(req->response_code_line);
1788 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1789 event_warn("%s: strdup", __func__);
1796 /* Parse the first line of a HTTP request */
1799 evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len)
1801 char *eos = line + len;
1805 const char *hostname;
1808 enum evhttp_cmd_type type = 0;
1810 while (eos > line && *(eos-1) == ' ') {
1815 if (len < strlen("GET / HTTP/1.0"))
1818 /* Parse the request line */
1819 method = strsep(&line, " ");
1823 version = strrchr(uri, ' ');
1824 if (!version || uri == version)
1829 method_len = (uri - method) - 1;
1832 switch (method_len) {
1834 /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1836 /* Since both GET and PUT share the same character 'T' at the end,
1837 * if the string doesn't have 'T', we can immediately determine this
1838 * is an invalid HTTP method */
1840 if (method[2] != 'T') {
1846 /* This first byte is 'G', so make sure the next byte is
1847 * 'E', if it isn't then this isn't a valid method */
1849 if (method[1] == 'E') {
1850 type = EVHTTP_REQ_GET;
1855 /* First byte is P, check second byte for 'U', if not,
1856 * we know it's an invalid method */
1857 if (method[1] == 'U') {
1858 type = EVHTTP_REQ_PUT;
1866 /* The method length is 4 bytes, leaving only the methods POST, HEAD, LOCK, COPY and MOVE */
1869 if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') {
1870 type = EVHTTP_REQ_POST;
1874 if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') {
1875 type = EVHTTP_REQ_HEAD;
1879 if (method[3] == 'K' && method[2] == 'C' && method[1] == 'O') {
1880 type = EVHTTP_REQ_LOCK;
1884 if (method[3] == 'Y' && method[2] == 'P' && method[1] == 'O') {
1885 type = EVHTTP_REQ_COPY;
1889 if (method[3] == 'E' && method[2] == 'V' && method[1] == 'O') {
1890 type = EVHTTP_REQ_MOVE;
1898 /* Method length is 5 bytes, which can only encompass PATCH, TRACE and MKCOL */
1901 if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') {
1902 type = EVHTTP_REQ_PATCH;
1906 if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') {
1907 type = EVHTTP_REQ_TRACE;
1912 if (method[4] == 'L' && method[3] == 'O' && method[2] == 'C' && method[1] == 'K') {
1913 type = EVHTTP_REQ_MKCOL;
1921 /* Method length is 6, only valid methods 6 bytes in length is DELETE and UNLOCK */
1924 if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' &&
1925 method[2] == 'L' && method[1] == 'E') {
1926 type = EVHTTP_REQ_DELETE;
1930 if (method[5] == 'K' && method[4] == 'C' && method[3] == 'O' &&
1931 method[2] == 'L' && method[1] == 'N') {
1932 type = EVHTTP_REQ_UNLOCK;
1940 /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1943 if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' &&
1944 method[3] == 'I' && method[2] == 'T' && method[1] == 'P') {
1945 type = EVHTTP_REQ_OPTIONS;
1950 if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' &&
1951 method[3] == 'N' && method[2] == 'N' && method[1] == 'O') {
1952 type = EVHTTP_REQ_CONNECT;
1961 /* Method length is 8, only valid method 8 bytes in length is PROPFIND */
1963 /* If the first byte isn't 'P' then it's invalid */
1964 if (*method != 'P') {
1968 if (method[7] == 'D' && method[6] == 'N' && method[5] == 'I' &&
1969 method[4] == 'F' && method[3] == 'P' && method[2] == 'O' &&
1971 type = EVHTTP_REQ_PROPFIND;
1976 /* Method length is 9, only valid method 9 bytes in length is PROPPATCH */
1978 /* If the first byte isn't 'P' then it's invalid */
1979 if (*method != 'P') {
1983 if (method[8] == 'H' && method[7] == 'C' && method[6] == 'T' &&
1984 method[5] == 'A' && method[4] == 'P' && method[3] == 'P' &&
1985 method[2] == 'O' && method[1] == 'R') {
1986 type = EVHTTP_REQ_PROPPATCH;
1993 /* check extended methods, we only care about the
1994 * type set by the cmp function if the cmp function
1995 * returns a 0 value.
1997 struct evhttp_ext_method ext_method;
1999 ext_method.method = method;
2000 ext_method.type = 0;
2002 if (req->evcon->ext_method_cmp &&
2003 req->evcon->ext_method_cmp(&ext_method) == 0) {
2004 /* TODO: make sure the other fields in ext_method are
2005 * not changed by the callback.
2007 type = ext_method.type;
2012 event_debug(("%s: bad method %s on request %p from %s",
2013 __func__, method, req, req->remote_host));
2014 /* No error yet; we'll give a better error later when
2015 * we see that req->type is unsupported. */
2020 if (evhttp_parse_http_version(version, req) < 0)
2023 if ((req->uri = mm_strdup(uri)) == NULL) {
2024 event_debug(("%s: mm_strdup", __func__));
2028 if (type == EVHTTP_REQ_CONNECT) {
2029 if ((req->uri_elems = evhttp_uri_parse_authority(req->uri)) == NULL) {
2033 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
2034 EVHTTP_URI_NONCONFORMANT)) == NULL) {
2039 /* If we have an absolute-URI, check to see if it is an http request
2040 for a known vhost or server alias. If we don't know about this
2041 host, we consider it a proxy request. */
2042 scheme = evhttp_uri_get_scheme(req->uri_elems);
2043 hostname = evhttp_uri_get_host(req->uri_elems);
2044 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
2045 !evutil_ascii_strcasecmp(scheme, "https")) &&
2047 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
2048 req->flags |= EVHTTP_PROXY_REQUEST;
2054 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
2056 struct evkeyval *header;
2058 TAILQ_FOREACH(header, headers, next) {
2059 if (evutil_ascii_strcasecmp(header->key, key) == 0)
2060 return (header->value);
2067 evhttp_clear_headers(struct evkeyvalq *headers)
2069 struct evkeyval *header;
2071 for (header = TAILQ_FIRST(headers);
2073 header = TAILQ_FIRST(headers)) {
2074 TAILQ_REMOVE(headers, header, next);
2075 mm_free(header->key);
2076 mm_free(header->value);
2082 * Returns 0, if the header was successfully removed.
2083 * Returns -1, if the header could not be found.
2087 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
2089 struct evkeyval *header;
2091 TAILQ_FOREACH(header, headers, next) {
2092 if (evutil_ascii_strcasecmp(header->key, key) == 0)
2099 /* Free and remove the header that we found */
2100 TAILQ_REMOVE(headers, header, next);
2101 mm_free(header->key);
2102 mm_free(header->value);
2109 evhttp_header_is_valid_value(const char *value)
2111 const char *p = value;
2113 while ((p = strpbrk(p, "\r\n")) != NULL) {
2114 /* we really expect only one new line */
2115 p += strspn(p, "\r\n");
2116 /* we expect a space or tab for continuation */
2117 if (*p != ' ' && *p != '\t')
2124 evhttp_add_header(struct evkeyvalq *headers,
2125 const char *key, const char *value)
2127 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
2129 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
2130 /* drop illegal headers */
2131 event_debug(("%s: dropping illegal header key\n", __func__));
2135 if (!evhttp_header_is_valid_value(value)) {
2136 event_debug(("%s: dropping illegal header value\n", __func__));
2140 return (evhttp_add_header_internal(headers, key, value));
2144 evhttp_add_header_internal(struct evkeyvalq *headers,
2145 const char *key, const char *value)
2147 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
2148 if (header == NULL) {
2149 event_warn("%s: calloc", __func__);
2152 if ((header->key = mm_strdup(key)) == NULL) {
2154 event_warn("%s: strdup", __func__);
2157 if ((header->value = mm_strdup(value)) == NULL) {
2158 mm_free(header->key);
2160 event_warn("%s: strdup", __func__);
2164 TAILQ_INSERT_TAIL(headers, header, next);
2170 * Parses header lines from a request or a response into the specified
2171 * request object given an event buffer.
2174 * DATA_CORRUPTED on error
2175 * MORE_DATA_EXPECTED when we need to read more headers
2176 * ALL_DATA_READ when all headers have been read.
2179 enum message_read_status
2180 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
2183 enum message_read_status status = ALL_DATA_READ;
2187 line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
2189 if (req->evcon != NULL &&
2190 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2191 return (DATA_TOO_LONG);
2193 return (MORE_DATA_EXPECTED);
2196 if (req->evcon != NULL && len > req->evcon->max_headers_size) {
2198 return (DATA_TOO_LONG);
2201 req->headers_size = len;
2203 switch (req->kind) {
2204 case EVHTTP_REQUEST:
2205 if (evhttp_parse_request_line(req, line, len) == -1)
2206 status = DATA_CORRUPTED;
2208 case EVHTTP_RESPONSE:
2209 if (evhttp_parse_response_line(req, line) == -1)
2210 status = DATA_CORRUPTED;
2213 status = DATA_CORRUPTED;
2221 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
2223 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
2225 size_t old_len, line_len;
2230 old_len = strlen(header->value);
2232 /* Strip space from start and end of line. */
2233 while (*line == ' ' || *line == '\t')
2235 evutil_rtrim_lws_(line);
2237 line_len = strlen(line);
2239 newval = mm_realloc(header->value, old_len + line_len + 2);
2243 newval[old_len] = ' ';
2244 memcpy(newval + old_len + 1, line, line_len + 1);
2245 header->value = newval;
2250 enum message_read_status
2251 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
2253 enum message_read_status errcode = DATA_CORRUPTED;
2255 enum message_read_status status = MORE_DATA_EXPECTED;
2257 struct evkeyvalq* headers = req->input_headers;
2259 while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
2261 char *skey, *svalue;
2263 req->headers_size += len;
2265 if (req->evcon != NULL &&
2266 req->headers_size > req->evcon->max_headers_size) {
2267 errcode = DATA_TOO_LONG;
2271 if (*line == '\0') { /* Last header - Done */
2272 status = ALL_DATA_READ;
2277 /* Check if this is a continuation line */
2278 if (*line == ' ' || *line == '\t') {
2279 if (evhttp_append_to_last_header(headers, line) == -1)
2285 /* Processing of header lines */
2287 skey = strsep(&svalue, ":");
2291 svalue += strspn(svalue, " ");
2292 evutil_rtrim_lws_(svalue);
2294 if (evhttp_add_header(headers, skey, svalue) == -1)
2300 if (status == MORE_DATA_EXPECTED) {
2301 if (req->evcon != NULL &&
2302 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2303 return (DATA_TOO_LONG);
2314 evhttp_get_body_length(struct evhttp_request *req)
2316 struct evkeyvalq *headers = req->input_headers;
2317 const char *content_length;
2318 const char *connection;
2320 content_length = evhttp_find_header(headers, "Content-Length");
2321 connection = evhttp_find_header(headers, "Connection");
2323 if (content_length == NULL && connection == NULL)
2325 else if (content_length == NULL &&
2326 evutil_ascii_strcasecmp(connection, "Close") != 0) {
2328 } else if (content_length == NULL) {
2332 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2333 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2334 event_debug(("%s: illegal content length: %s",
2335 __func__, content_length));
2338 req->ntoread = ntoread;
2341 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2342 __func__, EV_I64_ARG(req->ntoread),
2343 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2349 evhttp_method_may_have_body_(struct evhttp_connection *evcon, enum evhttp_cmd_type type)
2352 evhttp_method_(evcon, type, &flags);
2353 return (flags & EVHTTP_METHOD_HAS_BODY) ? 1 : 0;
2357 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2359 const char *xfer_enc;
2361 /* If this is a request without a body, then we are done */
2362 if (req->kind == EVHTTP_REQUEST &&
2363 !evhttp_method_may_have_body_(evcon, req->type)) {
2364 evhttp_connection_done(evcon);
2367 evcon->state = EVCON_READING_BODY;
2368 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
2369 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
2373 if (evhttp_get_body_length(req) == -1) {
2374 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2377 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2378 /* An incoming request with no content-length and no
2379 * transfer-encoding has no body. */
2380 evhttp_connection_done(evcon);
2385 /* Should we send a 100 Continue status line? */
2386 switch (evhttp_have_expect(req, 1)) {
2388 /* XXX It would be nice to do some sanity
2389 checking here. Does the resource exist?
2390 Should the resource accept post requests? If
2391 no, we should respond with an error. For
2392 now, just optimistically tell the client to
2393 send their message body. */
2394 if (req->ntoread > 0) {
2395 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2396 if ((req->evcon->max_body_size <= EV_INT64_MAX) &&
2397 (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2398 evhttp_lingering_fail(evcon, req);
2402 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2403 evhttp_send_continue(evcon, req);
2406 evhttp_send_error(req, HTTP_EXPECTATIONFAILED, NULL);
2411 evhttp_read_body(evcon, req);
2412 /* note the request may have been freed in evhttp_read_body */
2416 evhttp_read_firstline(struct evhttp_connection *evcon,
2417 struct evhttp_request *req)
2419 enum message_read_status res;
2421 res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2422 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2423 /* Error while reading, terminate */
2424 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2425 __func__, EV_SOCK_ARG(evcon->fd)));
2426 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2428 } else if (res == MORE_DATA_EXPECTED) {
2429 /* Need more header lines */
2433 evcon->state = EVCON_READING_HEADERS;
2434 evhttp_read_header(evcon, req);
2438 evhttp_read_header(struct evhttp_connection *evcon,
2439 struct evhttp_request *req)
2441 enum message_read_status res;
2442 evutil_socket_t fd = evcon->fd;
2444 res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2445 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2446 /* Error while reading, terminate */
2447 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2448 __func__, EV_SOCK_ARG(fd)));
2449 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2451 } else if (res == MORE_DATA_EXPECTED) {
2452 /* Need more header lines */
2456 /* Callback can shut down connection with negative return value */
2457 if (req->header_cb != NULL) {
2458 if ((*req->header_cb)(req, req->cb_arg) < 0) {
2459 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2464 /* Done reading headers, do the real work */
2465 switch (req->kind) {
2466 case EVHTTP_REQUEST:
2467 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2468 __func__, EV_SOCK_ARG(fd)));
2469 evhttp_get_body(evcon, req);
2470 /* note the request may have been freed in evhttp_get_body */
2473 case EVHTTP_RESPONSE:
2474 /* Start over if we got a 100 Continue response. */
2475 if (req->response_code == 100) {
2476 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
2477 evbuffer_add_buffer(output, req->output_buffer);
2478 evhttp_start_write_(evcon);
2481 if (!evhttp_response_needs_body(req)) {
2482 event_debug(("%s: skipping body for code %d\n",
2483 __func__, req->response_code));
2484 evhttp_connection_done(evcon);
2486 event_debug(("%s: start of read body for %s on "
2488 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2489 evhttp_get_body(evcon, req);
2490 /* note the request may have been freed in
2491 * evhttp_get_body */
2496 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2498 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2501 /* request may have been freed above */
2505 * Creates a TCP connection to the specified port and executes a callback
2506 * when finished. Failure or success is indicate by the passed connection
2509 * Although this interface accepts a hostname, it is intended to take
2510 * only numeric hostnames so that non-blocking DNS resolution can
2514 struct evhttp_connection *
2515 evhttp_connection_new(const char *address, ev_uint16_t port)
2517 return (evhttp_connection_base_new(NULL, NULL, address, port));
2520 struct evhttp_connection *
2521 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2522 const char *address, ev_uint16_t port)
2524 struct evhttp_connection *evcon = NULL;
2526 event_debug(("Attempting connection to %s:%d\n", address, port));
2528 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2529 event_warn("%s: calloc failed", __func__);
2536 evcon->max_headers_size = EV_SIZE_MAX;
2537 evcon->max_body_size = EV_SIZE_MAX;
2539 evcon->timeout_connect.tv_sec = HTTP_CONNECT_TIMEOUT;
2540 evcon->timeout_read.tv_sec = HTTP_READ_TIMEOUT;
2541 evcon->timeout_write.tv_sec = HTTP_WRITE_TIMEOUT;
2542 evcon->initial_retry_timeout.tv_sec = HTTP_INITIAL_RETRY_TIMEOUT;
2544 evcon->retry_cnt = evcon->retry_max = 0;
2546 if ((evcon->address = mm_strdup(address)) == NULL) {
2547 event_warn("%s: strdup failed", __func__);
2552 if (!(bev = bufferevent_socket_new(base, -1, 0))) {
2553 event_warn("%s: bufferevent_socket_new failed", __func__);
2558 bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2561 evcon->state = EVCON_DISCONNECTED;
2562 TAILQ_INIT(&evcon->requests);
2566 if (bufferevent_get_base(bev) != base)
2567 bufferevent_base_set(base, evcon->bufev);
2570 event_deferred_cb_init_(
2571 &evcon->read_more_deferred_cb,
2572 bufferevent_get_priority(bev),
2573 evhttp_deferred_read_cb, evcon);
2575 evcon->dns_base = dnsbase;
2576 evcon->ai_family = AF_UNSPEC;
2582 evhttp_connection_free(evcon);
2586 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2588 return evcon->bufev;
2592 evhttp_connection_get_server(struct evhttp_connection *evcon)
2594 return evcon->http_server;
2597 struct evhttp_connection *
2598 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2599 const char *address, ev_uint16_t port)
2601 return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2604 void evhttp_connection_set_family(struct evhttp_connection *evcon,
2607 evcon->ai_family = family;
2610 int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2613 int avail_flags = 0;
2614 avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2615 avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2617 if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2619 evcon->flags &= ~avail_flags;
2621 evcon->flags |= flags;
2627 evhttp_connection_set_ext_method_cmp(struct evhttp_connection *evcon,
2628 evhttp_ext_method_cb cmp)
2630 evcon->ext_method_cmp = cmp;
2634 evhttp_connection_set_base(struct evhttp_connection *evcon,
2635 struct event_base *base)
2637 EVUTIL_ASSERT(evcon->base == NULL);
2638 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2640 bufferevent_base_set(base, evcon->bufev);
2644 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2647 if (timeout != -1) {
2648 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2650 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2652 evhttp_set_timeout_(&evcon->timeout_read, timeout, HTTP_READ_TIMEOUT);
2653 evhttp_set_timeout_(&evcon->timeout_write, timeout, HTTP_WRITE_TIMEOUT);
2654 bufferevent_set_timeouts(evcon->bufev,
2655 &evcon->timeout_read, &evcon->timeout_write);
2658 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2659 const struct timeval* tv)
2662 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2664 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2666 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, HTTP_READ_TIMEOUT);
2667 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, HTTP_WRITE_TIMEOUT);
2668 bufferevent_set_timeouts(evcon->bufev,
2669 &evcon->timeout_read, &evcon->timeout_write);
2671 void evhttp_connection_set_connect_timeout_tv(struct evhttp_connection *evcon,
2672 const struct timeval *tv)
2674 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2675 evhttp_set_timeout_tv_(&evcon->timeout_connect, tv, -1);
2676 if (evcon->state == EVCON_CONNECTING)
2677 bufferevent_set_timeouts(evcon->bufev,
2678 &evcon->timeout_connect, &evcon->timeout_connect);
2680 void evhttp_connection_set_read_timeout_tv(struct evhttp_connection *evcon,
2681 const struct timeval *tv)
2683 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2684 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, -1);
2685 if (evcon->state != EVCON_CONNECTING)
2686 bufferevent_set_timeouts(evcon->bufev,
2687 &evcon->timeout_read, &evcon->timeout_write);
2689 void evhttp_connection_set_write_timeout_tv(struct evhttp_connection *evcon,
2690 const struct timeval *tv)
2692 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2693 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, -1);
2694 if (evcon->state != EVCON_CONNECTING)
2695 bufferevent_set_timeouts(evcon->bufev,
2696 &evcon->timeout_read, &evcon->timeout_write);
2700 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2701 const struct timeval *tv)
2704 evcon->initial_retry_timeout = *tv;
2706 evutil_timerclear(&evcon->initial_retry_timeout);
2707 evcon->initial_retry_timeout.tv_sec = 2;
2712 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2715 evcon->retry_max = retry_max;
2719 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2720 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2722 evcon->closecb = cb;
2723 evcon->closecb_arg = cbarg;
2727 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2728 char **address, ev_uint16_t *port)
2730 *address = evcon->address;
2731 *port = evcon->port;
2734 const struct sockaddr*
2735 evhttp_connection_get_addr(struct evhttp_connection *evcon)
2737 return bufferevent_socket_get_conn_address_(evcon->bufev);
2741 evhttp_connection_connect_(struct evhttp_connection *evcon)
2743 int old_state = evcon->state;
2744 const char *address = evcon->address;
2745 const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
2748 if (evcon->state == EVCON_CONNECTING)
2751 evhttp_connection_reset_(evcon);
2753 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2754 evcon->flags |= EVHTTP_CON_OUTGOING;
2756 if (evcon->bind_address || evcon->bind_port) {
2757 evcon->fd = bind_socket(
2758 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2759 if (evcon->fd == -1) {
2760 event_debug(("%s: failed to bind to \"%s\"",
2761 __func__, evcon->bind_address));
2765 if (bufferevent_setfd(evcon->bufev, evcon->fd))
2768 if (bufferevent_setfd(evcon->bufev, -1))
2772 /* Set up a callback for successful connection setup */
2773 bufferevent_setcb(evcon->bufev,
2774 NULL /* evhttp_read_cb */,
2775 NULL /* evhttp_write_cb */,
2776 evhttp_connection_cb,
2778 bufferevent_set_timeouts(evcon->bufev,
2779 &evcon->timeout_connect, &evcon->timeout_connect);
2780 /* make sure that we get a write callback */
2781 if (bufferevent_enable(evcon->bufev, EV_WRITE))
2784 evcon->state = EVCON_CONNECTING;
2786 if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
2788 (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
2789 int socklen = sizeof(struct sockaddr_in);
2790 if (sa->sa_family == AF_INET6) {
2791 socklen = sizeof(struct sockaddr_in6);
2793 ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
2795 ret = bufferevent_socket_connect_hostname(evcon->bufev,
2796 evcon->dns_base, evcon->ai_family, address, evcon->port);
2800 evcon->state = old_state;
2801 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2802 __func__, evcon->address);
2803 /* some operating systems return ECONNREFUSED immediately
2804 * when connecting to a local address. the cleanup is going
2805 * to reschedule this function call.
2807 evhttp_connection_cb_cleanup(evcon);
2815 * Starts an HTTP request on the provided evhttp_connection object.
2816 * If the connection object is not connected to the web server already,
2817 * this will start the connection.
2821 evhttp_make_request(struct evhttp_connection *evcon,
2822 struct evhttp_request *req,
2823 enum evhttp_cmd_type type, const char *uri)
2825 /* We are making a request */
2826 req->kind = EVHTTP_REQUEST;
2828 if (req->uri != NULL)
2830 if ((req->uri = mm_strdup(uri)) == NULL) {
2831 event_warn("%s: strdup", __func__);
2832 evhttp_request_free_auto(req);
2836 /* Set the protocol version if it is not supplied */
2837 if (!req->major && !req->minor) {
2842 EVUTIL_ASSERT(req->evcon == NULL);
2844 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2846 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2848 /* We do not want to conflict with retry_ev */
2849 if (evcon->retry_cnt)
2852 /* If the connection object is not connected; make it so */
2853 if (!evhttp_connected(evcon)) {
2854 int res = evhttp_connection_connect_(evcon);
2855 /* evhttp_connection_fail_(), which is called through
2856 * evhttp_connection_connect_(), assumes that req lies in
2857 * evcon->requests. Thus, enqueue the request in advance and
2858 * remove it in the error case. */
2860 TAILQ_REMOVE(&evcon->requests, req, next);
2866 * If it's connected already and we are the first in the queue,
2867 * then we can dispatch this request immediately. Otherwise, it
2868 * will be dispatched once the pending requests are completed.
2870 if (TAILQ_FIRST(&evcon->requests) == req)
2871 evhttp_request_dispatch(evcon);
2877 evhttp_cancel_request(struct evhttp_request *req)
2879 struct evhttp_connection *evcon = req->evcon;
2880 if (evcon != NULL) {
2881 /* We need to remove it from the connection */
2882 if (TAILQ_FIRST(&evcon->requests) == req) {
2883 /* it's currently being worked on, so reset
2886 evhttp_connection_fail_(evcon,
2887 EVREQ_HTTP_REQUEST_CANCEL);
2889 /* connection fail freed the request */
2892 /* otherwise, we can just remove it from the
2895 TAILQ_REMOVE(&evcon->requests, req, next);
2899 evhttp_request_free_auto(req);
2903 * Reads data from file descriptor into request structure
2904 * Request structure needs to be set up correctly.
2908 evhttp_start_read_(struct evhttp_connection *evcon)
2910 bufferevent_disable(evcon->bufev, EV_WRITE);
2911 bufferevent_enable(evcon->bufev, EV_READ);
2913 evcon->state = EVCON_READING_FIRSTLINE;
2914 /* Reset the bufferevent callbacks */
2915 bufferevent_setcb(evcon->bufev,
2921 /* If there's still data pending, process it next time through the
2922 * loop. Don't do it now; that could get recusive. */
2923 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2924 event_deferred_cb_schedule_(get_deferred_queue(evcon),
2925 &evcon->read_more_deferred_cb);
2930 evhttp_start_write_(struct evhttp_connection *evcon)
2932 bufferevent_disable(evcon->bufev, EV_WRITE);
2933 bufferevent_enable(evcon->bufev, EV_READ);
2935 evcon->state = EVCON_WRITING;
2936 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
2940 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2943 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2944 TAILQ_REMOVE(&evcon->requests, req, next);
2946 if (req->on_complete_cb != NULL) {
2947 req->on_complete_cb(req, req->on_complete_cb_arg);
2951 (REQ_VERSION_BEFORE(req, 1, 1) &&
2952 !evhttp_is_connection_keepalive(req->input_headers)) ||
2953 evhttp_is_request_connection_close(req);
2955 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2956 evhttp_request_free(req);
2959 evhttp_connection_free(evcon);
2963 /* we have a persistent connection; try to accept another request. */
2964 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2965 evhttp_connection_free(evcon);
2970 * Returns an error page.
2974 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2977 #define ERR_FORMAT "<HTML><HEAD>\n" \
2978 "<TITLE>%d %s</TITLE>\n" \
2983 struct evbuffer *buf = evbuffer_new();
2985 /* if we cannot allocate memory; we just drop the connection */
2986 evhttp_connection_free(req->evcon);
2989 if (reason == NULL) {
2990 reason = evhttp_response_phrase_internal(error);
2993 evhttp_response_code_(req, error, reason);
2995 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2997 evhttp_send_page_(req, buf);
3003 /* Requires that headers and response code are already set up */
3006 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
3008 struct evhttp_connection *evcon = req->evcon;
3010 if (evcon == NULL) {
3011 evhttp_request_free(req);
3015 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
3017 /* we expect no more calls form the user on this request */
3020 /* xxx: not sure if we really should expose the data buffer this way */
3021 if (databuf != NULL)
3022 evbuffer_add_buffer(req->output_buffer, databuf);
3024 /* Adds headers to the response */
3025 evhttp_make_header(evcon, req);
3027 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
3031 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
3032 struct evbuffer *databuf)
3034 evhttp_response_code_(req, code, reason);
3036 evhttp_send(req, databuf);
3040 evhttp_send_reply_start(struct evhttp_request *req, int code,
3043 evhttp_response_code_(req, code, reason);
3045 if (req->evcon == NULL)
3048 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
3049 REQ_VERSION_ATLEAST(req, 1, 1) &&
3050 evhttp_response_needs_body(req)) {
3052 * prefer HTTP/1.1 chunked encoding to closing the connection;
3053 * note RFC 2616 section 4.4 forbids it with Content-Length:
3054 * and it's not necessary then anyway.
3056 evhttp_add_header(req->output_headers, "Transfer-Encoding",
3062 evhttp_make_header(req->evcon, req);
3063 evhttp_write_buffer(req->evcon, NULL, NULL);
3067 evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
3068 void (*cb)(struct evhttp_connection *, void *), void *arg)
3070 struct evhttp_connection *evcon = req->evcon;
3071 struct evbuffer *output;
3076 output = bufferevent_get_output(evcon->bufev);
3078 if (evbuffer_get_length(databuf) == 0)
3080 if (!evhttp_response_needs_body(req))
3083 evbuffer_add_printf(output, "%x\r\n",
3084 (unsigned)evbuffer_get_length(databuf));
3086 evbuffer_add_buffer(output, databuf);
3088 evbuffer_add(output, "\r\n", 2);
3090 evhttp_write_buffer(evcon, cb, arg);
3094 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
3096 evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
3099 evhttp_send_reply_end(struct evhttp_request *req)
3101 struct evhttp_connection *evcon = req->evcon;
3102 struct evbuffer *output;
3104 if (evcon == NULL) {
3105 evhttp_request_free(req);
3109 output = bufferevent_get_output(evcon->bufev);
3111 /* we expect no more calls form the user on this request */
3115 evbuffer_add(output, "0\r\n\r\n", 5);
3116 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
3118 } else if (evbuffer_get_length(output) == 0) {
3119 /* let the connection know that we are done with the request */
3120 evhttp_send_done(evcon, NULL);
3122 /* make the callback execute after all data has been written */
3123 evcon->cb = evhttp_send_done;
3124 evcon->cb_arg = NULL;
3128 static const char *informational_phrases[] = {
3129 /* 100 */ "Continue",
3130 /* 101 */ "Switching Protocols"
3133 static const char *success_phrases[] = {
3135 /* 201 */ "Created",
3136 /* 202 */ "Accepted",
3137 /* 203 */ "Non-Authoritative Information",
3138 /* 204 */ "No Content",
3139 /* 205 */ "Reset Content",
3140 /* 206 */ "Partial Content"
3143 static const char *redirection_phrases[] = {
3144 /* 300 */ "Multiple Choices",
3145 /* 301 */ "Moved Permanently",
3147 /* 303 */ "See Other",
3148 /* 304 */ "Not Modified",
3149 /* 305 */ "Use Proxy",
3150 /* 307 */ "Temporary Redirect"
3153 static const char *client_error_phrases[] = {
3154 /* 400 */ "Bad Request",
3155 /* 401 */ "Unauthorized",
3156 /* 402 */ "Payment Required",
3157 /* 403 */ "Forbidden",
3158 /* 404 */ "Not Found",
3159 /* 405 */ "Method Not Allowed",
3160 /* 406 */ "Not Acceptable",
3161 /* 407 */ "Proxy Authentication Required",
3162 /* 408 */ "Request Time-out",
3163 /* 409 */ "Conflict",
3165 /* 411 */ "Length Required",
3166 /* 412 */ "Precondition Failed",
3167 /* 413 */ "Request Entity Too Large",
3168 /* 414 */ "Request-URI Too Large",
3169 /* 415 */ "Unsupported Media Type",
3170 /* 416 */ "Requested range not satisfiable",
3171 /* 417 */ "Expectation Failed"
3174 static const char *server_error_phrases[] = {
3175 /* 500 */ "Internal Server Error",
3176 /* 501 */ "Not Implemented",
3177 /* 502 */ "Bad Gateway",
3178 /* 503 */ "Service Unavailable",
3179 /* 504 */ "Gateway Time-out",
3180 /* 505 */ "HTTP Version not supported"
3183 struct response_class {
3185 size_t num_responses;
3186 const char **responses;
3190 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
3193 static const struct response_class response_classes[] = {
3194 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
3195 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
3196 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
3197 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
3198 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
3202 evhttp_response_phrase_internal(int code)
3204 int klass = code / 100 - 1;
3205 int subcode = code % 100;
3207 /* Unknown class - can't do any better here */
3208 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
3209 return "Unknown Status Class";
3211 /* Unknown sub-code, return class name at least */
3212 if (subcode >= (int) response_classes[klass].num_responses)
3213 return response_classes[klass].name;
3215 return response_classes[klass].responses[subcode];
3219 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
3221 req->kind = EVHTTP_RESPONSE;
3222 req->response_code = code;
3223 if (req->response_code_line != NULL)
3224 mm_free(req->response_code_line);
3226 reason = evhttp_response_phrase_internal(code);
3227 req->response_code_line = mm_strdup(reason);
3228 if (req->response_code_line == NULL) {
3229 event_warn("%s: strdup", __func__);
3230 /* XXX what else can we do? */
3235 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
3237 if (!req->major || !req->minor) {
3242 if (req->kind != EVHTTP_RESPONSE)
3243 evhttp_response_code_(req, 200, "OK");
3245 evhttp_clear_headers(req->output_headers);
3246 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
3247 evhttp_add_header(req->output_headers, "Connection", "close");
3249 evhttp_send(req, databuf);
3252 static const char uri_chars[256] = {
3254 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3255 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
3257 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
3259 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3260 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
3261 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3262 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
3264 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3265 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3266 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3267 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3269 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3271 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3272 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3275 #define CHAR_IS_UNRESERVED(c) \
3276 (uri_chars[(unsigned char)(c)])
3279 * Helper functions to encode/decode a string for inclusion in a URI.
3280 * The returned string must be freed by the caller.
3283 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3285 struct evbuffer *buf = evbuffer_new();
3286 const char *p, *end;
3287 char *result = NULL;
3294 if (uri + len < uri) {
3300 size_t slen = strlen(uri);
3302 if (slen >= EV_SSIZE_MAX) {
3303 /* we don't want to mix signed and unsigned */
3307 if (uri + slen < uri) {
3314 for (p = uri; p < end; p++) {
3315 if (CHAR_IS_UNRESERVED(*p)) {
3316 evbuffer_add(buf, p, 1);
3317 } else if (*p == ' ' && space_as_plus) {
3318 evbuffer_add(buf, "+", 1);
3320 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3324 evbuffer_add(buf, "", 1); /* NUL-terminator. */
3325 result = mm_malloc(evbuffer_get_length(buf));
3328 evbuffer_remove(buf, result, evbuffer_get_length(buf));
3337 evhttp_encode_uri(const char *str)
3339 return evhttp_uriencode(str, -1, 0);
3343 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
3344 * If -1, when true we transform plus to space only after we've seen
3345 * a ?. -1 is deprecated.
3346 * @return the number of bytes written to 'ret'.
3349 evhttp_decode_uri_internal(
3350 const char *uri, size_t length, char *ret, int decode_plus_ctl)
3354 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3357 for (i = j = 0; i < length; i++) {
3360 if (decode_plus_ctl < 0)
3362 } else if (c == '+' && decode_plus) {
3364 } else if ((i + 2) < length && c == '%' &&
3365 EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3370 c = (char)strtol(tmp, NULL, 16);
3382 evhttp_decode_uri(const char *uri)
3386 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3387 event_warn("%s: malloc(%lu)", __func__,
3388 (unsigned long)(strlen(uri) + 1));
3392 evhttp_decode_uri_internal(uri, strlen(uri),
3393 ret, -1 /*always_decode_plus*/);
3399 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3404 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3405 event_warn("%s: malloc(%lu)", __func__,
3406 (unsigned long)(strlen(uri) + 1));
3410 n = evhttp_decode_uri_internal(uri, strlen(uri),
3411 ret, !!decode_plus/*always_decode_plus*/);
3414 EVUTIL_ASSERT(n >= 0);
3415 *size_out = (size_t)n;
3422 * Helper function to parse out arguments in a query.
3423 * The arguments are separated by key and value.
3427 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3428 int is_whole_uri, unsigned flags)
3433 const char *query_part;
3435 struct evhttp_uri *uri=NULL;
3437 TAILQ_INIT(headers);
3440 uri = evhttp_uri_parse(str);
3443 query_part = evhttp_uri_get_query(uri);
3448 /* No arguments - we are done */
3449 if (!query_part || !strlen(query_part)) {
3454 if ((line = mm_strdup(query_part)) == NULL) {
3455 event_warn("%s: strdup", __func__);
3459 p = argument = line;
3460 while (p != NULL && *p != '\0') {
3461 char *key, *value, *decoded_value;
3462 argument = strsep(&p, "&");
3465 key = strsep(&value, "=");
3466 if (flags & EVHTTP_URI_QUERY_NONCONFORMANT) {
3472 if (value == NULL || *key == '\0')
3476 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3477 event_warn("%s: mm_malloc", __func__);
3480 evhttp_decode_uri_internal(value, strlen(value),
3481 decoded_value, 1 /*always_decode_plus*/);
3482 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3483 if (flags & EVHTTP_URI_QUERY_LAST_VAL)
3484 evhttp_remove_header(headers, key);
3485 evhttp_add_header_internal(headers, key, decoded_value);
3486 mm_free(decoded_value);
3492 evhttp_clear_headers(headers);
3497 evhttp_uri_free(uri);
3502 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3504 return evhttp_parse_query_impl(uri, headers, 1, 0);
3507 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3509 return evhttp_parse_query_impl(uri, headers, 0, 0);
3512 evhttp_parse_query_str_flags(const char *uri, struct evkeyvalq *headers, unsigned flags)
3514 return evhttp_parse_query_impl(uri, headers, 0, flags);
3517 static struct evhttp_cb *
3518 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3520 struct evhttp_cb *cb;
3525 /* Test for different URLs */
3526 path = evhttp_uri_get_path(req->uri_elems);
3527 offset = strlen(path);
3528 if ((translated = mm_malloc(offset + 1)) == NULL)
3530 evhttp_decode_uri_internal(path, offset, translated,
3531 0 /* decode_plus */);
3533 TAILQ_FOREACH(cb, callbacks, next) {
3534 if (!strcmp(cb->what, translated)) {
3535 mm_free(translated);
3540 mm_free(translated);
3546 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3551 switch (c = *pattern++) {
3553 return *name == '\0';
3556 while (*name != '\0') {
3557 if (prefix_suffix_match(pattern, name,
3566 EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3576 Search the vhost hierarchy beginning with http for a server alias
3577 matching hostname. If a match is found, and outhttp is non-null,
3578 outhttp is set to the matching http object and 1 is returned.
3582 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3583 const char *hostname)
3585 struct evhttp_server_alias *alias;
3586 struct evhttp *vhost;
3588 TAILQ_FOREACH(alias, &http->aliases, next) {
3589 /* XXX Do we need to handle IP addresses? */
3590 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3597 /* XXX It might be good to avoid recursion here, but I don't
3598 see a way to do that w/o a list. */
3599 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3600 if (evhttp_find_alias(vhost, outhttp, hostname))
3608 Attempts to find the best http object to handle a request for a hostname.
3609 All aliases for the root http object and vhosts are searched for an exact
3610 match. Then, the vhost hierarchy is traversed again for a matching
3613 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3614 is set with the best matching http object. If there are no matches, the
3615 root http object is stored in outhttp and 0 is returned.
3619 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3620 const char *hostname)
3622 struct evhttp *vhost;
3623 struct evhttp *oldhttp;
3624 int match_found = 0;
3626 if (evhttp_find_alias(http, outhttp, hostname))
3631 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3632 if (prefix_suffix_match(vhost->vhost_pattern,
3633 hostname, 1 /* ignorecase */)) {
3639 } while (oldhttp != http);
3648 evhttp_handle_request(struct evhttp_request *req, void *arg)
3650 struct evhttp *http = arg;
3651 struct evhttp_cb *cb = NULL;
3652 const char *hostname;
3654 /* we have a new request on which the user needs to take action */
3657 bufferevent_disable(req->evcon->bufev, EV_READ);
3659 if (req->uri == NULL) {
3660 evhttp_send_error(req, req->response_code, NULL);
3664 if ((http->allowed_methods & req->type) == 0) {
3665 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3666 (unsigned)req->type, (unsigned)http->allowed_methods));
3667 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3671 /* handle potential virtual hosts */
3672 hostname = evhttp_request_get_host(req);
3673 if (hostname != NULL) {
3674 evhttp_find_vhost(http, &http, hostname);
3677 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3678 (*cb->cb)(req, cb->cbarg);
3682 /* Generic call back */
3684 (*http->gencb)(req, http->gencbarg);
3687 /* We need to send a 404 here */
3688 #define ERR_FORMAT "<html><head>" \
3689 "<title>404 Not Found</title>" \
3691 "<h1>Not Found</h1>" \
3692 "<p>The requested URL %s was not found on this server.</p>"\
3696 struct evbuffer *buf;
3698 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3699 evhttp_connection_free(req->evcon);
3703 if ((buf = evbuffer_new()) == NULL) {
3704 mm_free(escaped_html);
3705 evhttp_connection_free(req->evcon);
3709 evhttp_response_code_(req, HTTP_NOTFOUND, "Not Found");
3711 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3713 mm_free(escaped_html);
3715 evhttp_send_page_(req, buf);
3722 /* Listener callback when a connection arrives at a server. */
3724 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3726 struct evhttp *http = arg;
3728 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3732 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3734 struct evhttp_bound_socket *bound =
3735 evhttp_bind_socket_with_handle(http, address, port);
3741 struct evhttp_bound_socket *
3742 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3745 struct evhttp_bound_socket *bound;
3748 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3751 if (listen(fd, 128) == -1) {
3752 serrno = EVUTIL_SOCKET_ERROR();
3753 event_sock_warn(fd, "%s: listen", __func__);
3754 evutil_closesocket(fd);
3755 EVUTIL_SET_SOCKET_ERROR(serrno);
3759 bound = evhttp_accept_socket_with_handle(http, fd);
3761 if (bound != NULL) {
3762 event_debug(("Bound to port %d - Awaiting connections ... ",
3771 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3773 struct evhttp_bound_socket *bound =
3774 evhttp_accept_socket_with_handle(http, fd);
3781 evhttp_foreach_bound_socket(struct evhttp *http,
3782 evhttp_bound_socket_foreach_fn *function,
3785 struct evhttp_bound_socket *bound;
3787 TAILQ_FOREACH(bound, &http->sockets, next)
3788 function(bound, argument);
3791 struct evhttp_bound_socket *
3792 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3794 struct evhttp_bound_socket *bound;
3795 struct evconnlistener *listener;
3797 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3799 listener = evconnlistener_new(http->base, NULL, NULL,
3801 0, /* Backlog is '0' because we already said 'listen' */
3806 bound = evhttp_bind_listener(http, listener);
3808 evconnlistener_free(listener);
3814 struct evhttp_bound_socket *
3815 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3817 struct evhttp_bound_socket *bound;
3819 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3823 bound->listener = listener;
3824 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3826 evconnlistener_set_cb(listener, accept_socket_cb, http);
3831 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3833 return evconnlistener_get_fd(bound->listener);
3836 struct evconnlistener *
3837 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3839 return bound->listener;
3843 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3845 TAILQ_REMOVE(&http->sockets, bound, next);
3846 evconnlistener_free(bound->listener);
3850 static struct evhttp*
3851 evhttp_new_object(void)
3853 struct evhttp *http = NULL;
3855 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3856 event_warn("%s: calloc", __func__);
3860 evutil_timerclear(&http->timeout_read);
3861 evutil_timerclear(&http->timeout_write);
3863 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3864 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3865 evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
3866 evhttp_set_allowed_methods(http,
3873 TAILQ_INIT(&http->sockets);
3874 TAILQ_INIT(&http->callbacks);
3875 TAILQ_INIT(&http->connections);
3876 TAILQ_INIT(&http->virtualhosts);
3877 TAILQ_INIT(&http->aliases);
3883 evhttp_new(struct event_base *base)
3885 struct evhttp *http = NULL;
3887 http = evhttp_new_object();
3896 * Start a web server on the specified address and port.
3900 evhttp_start(const char *address, ev_uint16_t port)
3902 struct evhttp *http = NULL;
3904 http = evhttp_new_object();
3907 if (evhttp_bind_socket(http, address, port) == -1) {
3916 evhttp_free(struct evhttp* http)
3918 struct evhttp_cb *http_cb;
3919 struct evhttp_connection *evcon;
3920 struct evhttp_bound_socket *bound;
3921 struct evhttp* vhost;
3922 struct evhttp_server_alias *alias;
3924 /* Remove the accepting part */
3925 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3926 TAILQ_REMOVE(&http->sockets, bound, next);
3928 evconnlistener_free(bound->listener);
3933 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3934 /* evhttp_connection_free removes the connection */
3935 evhttp_connection_free(evcon);
3938 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3939 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3940 mm_free(http_cb->what);
3944 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3945 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3950 if (http->vhost_pattern != NULL)
3951 mm_free(http->vhost_pattern);
3953 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3954 TAILQ_REMOVE(&http->aliases, alias, next);
3955 mm_free(alias->alias);
3963 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3964 struct evhttp* vhost)
3966 /* a vhost can only be a vhost once and should not have bound sockets */
3967 if (vhost->vhost_pattern != NULL ||
3968 TAILQ_FIRST(&vhost->sockets) != NULL)
3971 vhost->vhost_pattern = mm_strdup(pattern);
3972 if (vhost->vhost_pattern == NULL)
3975 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3981 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3983 if (vhost->vhost_pattern == NULL)
3986 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3988 mm_free(vhost->vhost_pattern);
3989 vhost->vhost_pattern = NULL;
3995 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3997 struct evhttp_server_alias *evalias;
3999 evalias = mm_calloc(1, sizeof(*evalias));
4003 evalias->alias = mm_strdup(alias);
4004 if (!evalias->alias) {
4009 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
4015 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
4017 struct evhttp_server_alias *evalias;
4019 TAILQ_FOREACH(evalias, &http->aliases, next) {
4020 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
4021 TAILQ_REMOVE(&http->aliases, evalias, next);
4022 mm_free(evalias->alias);
4032 evhttp_set_timeout(struct evhttp* http, int timeout)
4034 evhttp_set_timeout_(&http->timeout_read, timeout, -1);
4035 evhttp_set_timeout_(&http->timeout_write, timeout, -1);
4038 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
4040 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4041 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4044 evhttp_set_read_timeout_tv(struct evhttp* http, const struct timeval* tv)
4046 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4049 evhttp_set_write_timeout_tv(struct evhttp* http, const struct timeval* tv)
4051 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4054 int evhttp_set_flags(struct evhttp *http, int flags)
4056 int avail_flags = 0;
4057 avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
4059 if (flags & ~avail_flags)
4061 http->flags &= ~avail_flags;
4063 http->flags |= flags;
4069 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
4071 if (max_headers_size < 0)
4072 http->default_max_headers_size = EV_SIZE_MAX;
4074 http->default_max_headers_size = max_headers_size;
4078 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
4080 if (max_body_size < 0)
4081 http->default_max_body_size = EV_UINT64_MAX;
4083 http->default_max_body_size = max_body_size;
4087 evhttp_set_default_content_type(struct evhttp *http,
4088 const char *content_type) {
4089 http->default_content_type = content_type;
4093 evhttp_set_allowed_methods(struct evhttp* http, ev_uint32_t methods)
4095 http->allowed_methods = methods;
4099 evhttp_set_ext_method_cmp(struct evhttp *http, evhttp_ext_method_cb cmp)
4101 http->ext_method_cmp = cmp;
4105 evhttp_set_cb(struct evhttp *http, const char *uri,
4106 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4108 struct evhttp_cb *http_cb;
4110 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4111 if (strcmp(http_cb->what, uri) == 0)
4115 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
4116 event_warn("%s: calloc", __func__);
4120 http_cb->what = mm_strdup(uri);
4121 if (http_cb->what == NULL) {
4122 event_warn("%s: strdup", __func__);
4127 http_cb->cbarg = cbarg;
4129 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
4135 evhttp_del_cb(struct evhttp *http, const char *uri)
4137 struct evhttp_cb *http_cb;
4139 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4140 if (strcmp(http_cb->what, uri) == 0)
4143 if (http_cb == NULL)
4146 TAILQ_REMOVE(&http->callbacks, http_cb, next);
4147 mm_free(http_cb->what);
4154 evhttp_set_gencb(struct evhttp *http,
4155 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4158 http->gencbarg = cbarg;
4162 evhttp_set_bevcb(struct evhttp *http,
4163 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
4166 http->bevcbarg = cbarg;
4170 evhttp_set_newreqcb(struct evhttp *http,
4171 int (*cb)(struct evhttp_request *, void *), void *cbarg)
4173 http->newreqcb = cb;
4174 http->newreqcbarg = cbarg;
4178 * Request related functions
4181 struct evhttp_request *
4182 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
4184 struct evhttp_request *req = NULL;
4186 /* Allocate request structure */
4187 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
4188 event_warn("%s: calloc", __func__);
4192 req->headers_size = 0;
4195 req->kind = EVHTTP_RESPONSE;
4196 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4197 if (req->input_headers == NULL) {
4198 event_warn("%s: calloc", __func__);
4201 TAILQ_INIT(req->input_headers);
4203 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4204 if (req->output_headers == NULL) {
4205 event_warn("%s: calloc", __func__);
4208 TAILQ_INIT(req->output_headers);
4210 if ((req->input_buffer = evbuffer_new()) == NULL) {
4211 event_warn("%s: evbuffer_new", __func__);
4215 if ((req->output_buffer = evbuffer_new()) == NULL) {
4216 event_warn("%s: evbuffer_new", __func__);
4227 evhttp_request_free(req);
4232 evhttp_request_free(struct evhttp_request *req)
4234 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
4235 req->flags |= EVHTTP_REQ_NEEDS_FREE;
4239 if (req->remote_host != NULL)
4240 mm_free(req->remote_host);
4241 if (req->uri != NULL)
4243 if (req->uri_elems != NULL)
4244 evhttp_uri_free(req->uri_elems);
4245 if (req->response_code_line != NULL)
4246 mm_free(req->response_code_line);
4247 if (req->host_cache != NULL)
4248 mm_free(req->host_cache);
4250 evhttp_clear_headers(req->input_headers);
4251 mm_free(req->input_headers);
4253 evhttp_clear_headers(req->output_headers);
4254 mm_free(req->output_headers);
4256 if (req->input_buffer != NULL)
4257 evbuffer_free(req->input_buffer);
4259 if (req->output_buffer != NULL)
4260 evbuffer_free(req->output_buffer);
4266 evhttp_request_own(struct evhttp_request *req)
4268 req->flags |= EVHTTP_USER_OWNED;
4272 evhttp_request_is_owned(struct evhttp_request *req)
4274 return (req->flags & EVHTTP_USER_OWNED) != 0;
4277 struct evhttp_connection *
4278 evhttp_request_get_connection(struct evhttp_request *req)
4284 evhttp_connection_get_base(struct evhttp_connection *conn)
4290 evhttp_request_set_chunked_cb(struct evhttp_request *req,
4291 void (*cb)(struct evhttp_request *, void *))
4297 evhttp_request_set_header_cb(struct evhttp_request *req,
4298 int (*cb)(struct evhttp_request *, void *))
4300 req->header_cb = cb;
4304 evhttp_request_set_error_cb(struct evhttp_request *req,
4305 void (*cb)(enum evhttp_request_error, void *))
4311 evhttp_request_set_on_complete_cb(struct evhttp_request *req,
4312 void (*cb)(struct evhttp_request *, void *), void *cb_arg)
4314 req->on_complete_cb = cb;
4315 req->on_complete_cb_arg = cb_arg;
4319 * Allows for inspection of the request URI
4323 evhttp_request_get_uri(const struct evhttp_request *req) {
4324 if (req->uri == NULL)
4325 event_debug(("%s: request %p has no uri\n", __func__, req));
4329 const struct evhttp_uri *
4330 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4331 if (req->uri_elems == NULL)
4332 event_debug(("%s: request %p has no uri elems\n",
4334 return (req->uri_elems);
4338 evhttp_request_get_host(struct evhttp_request *req)
4340 const char *host = NULL;
4342 if (req->host_cache)
4343 return req->host_cache;
4346 host = evhttp_uri_get_host(req->uri_elems);
4347 if (!host && req->input_headers) {
4351 host = evhttp_find_header(req->input_headers, "Host");
4352 /* The Host: header may include a port. Remove it here
4353 to be consistent with uri_elems case above. */
4355 p = host + strlen(host) - 1;
4356 while (p > host && EVUTIL_ISDIGIT_(*p))
4358 if (p > host && *p == ':') {
4360 req->host_cache = mm_malloc(len + 1);
4361 if (!req->host_cache) {
4362 event_warn("%s: malloc", __func__);
4365 memcpy(req->host_cache, host, len);
4366 req->host_cache[len] = '\0';
4367 host = req->host_cache;
4375 enum evhttp_cmd_type
4376 evhttp_request_get_command(const struct evhttp_request *req) {
4381 evhttp_request_get_response_code(const struct evhttp_request *req)
4383 return req->response_code;
4387 evhttp_request_get_response_code_line(const struct evhttp_request *req)
4389 return req->response_code_line;
4392 /** Returns the input headers */
4393 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4395 return (req->input_headers);
4398 /** Returns the output headers */
4399 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4401 return (req->output_headers);
4404 /** Returns the input buffer */
4405 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4407 return (req->input_buffer);
4410 /** Returns the output buffer */
4411 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4413 return (req->output_buffer);
4418 * Takes a file descriptor to read a request from.
4419 * The callback is executed once the whole request has been read.
4422 static struct evhttp_connection*
4423 evhttp_get_request_connection(
4424 struct evhttp* http,
4425 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
4427 struct evhttp_connection *evcon;
4428 char *hostname = NULL, *portname = NULL;
4429 struct bufferevent* bev = NULL;
4431 #ifdef EVENT__HAVE_STRUCT_SOCKADDR_UN
4432 if (sa->sa_family == AF_UNIX) {
4433 struct sockaddr_un *sun = (struct sockaddr_un *)sa;
4434 sun->sun_path[0] = '\0';
4438 name_from_addr(sa, salen, &hostname, &portname);
4439 if (hostname == NULL || portname == NULL) {
4440 if (hostname) mm_free(hostname);
4441 if (portname) mm_free(portname);
4445 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4446 __func__, hostname, portname, EV_SOCK_ARG(fd)));
4448 /* we need a connection object to put the http request on */
4449 if (http->bevcb != NULL) {
4450 bev = (*http->bevcb)(http->base, http->bevcbarg);
4452 evcon = evhttp_connection_base_bufferevent_new(
4453 http->base, NULL, bev, hostname, atoi(portname));
4459 evcon->max_headers_size = http->default_max_headers_size;
4460 evcon->max_body_size = http->default_max_body_size;
4461 if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4462 evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4464 evcon->flags |= EVHTTP_CON_INCOMING;
4465 evcon->state = EVCON_READING_FIRSTLINE;
4469 if (bufferevent_setfd(evcon->bufev, fd))
4471 if (bufferevent_enable(evcon->bufev, EV_READ))
4473 if (bufferevent_disable(evcon->bufev, EV_WRITE))
4475 bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
4480 evhttp_connection_free(evcon);
4485 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4487 struct evhttp *http = evcon->http_server;
4488 struct evhttp_request *req;
4489 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4492 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4493 event_warn("%s: strdup", __func__);
4494 evhttp_request_free(req);
4497 req->remote_port = evcon->port;
4499 req->evcon = evcon; /* the request ends up owning the connection */
4500 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4502 /* We did not present the request to the user yet, so treat it
4503 * as if the user was done with the request. This allows us
4504 * to free the request on a persistent connection if the
4505 * client drops it without sending a request.
4508 req->kind = EVHTTP_REQUEST;
4510 if (http->newreqcb && http->newreqcb(req, http->newreqcbarg) == -1) {
4511 evhttp_request_free(req);
4515 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4517 evhttp_start_read_(evcon);
4523 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4524 struct sockaddr *sa, ev_socklen_t salen)
4526 struct evhttp_connection *evcon;
4528 evcon = evhttp_get_request_connection(http, fd, sa, salen);
4529 if (evcon == NULL) {
4530 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4531 __func__, EV_SOCK_ARG(fd));
4532 evutil_closesocket(fd);
4536 /* the timeout can be used by the server to close idle connections */
4537 if (evutil_timerisset(&http->timeout_read))
4538 evhttp_connection_set_read_timeout_tv(evcon, &http->timeout_read);
4539 if (evutil_timerisset(&http->timeout_write))
4540 evhttp_connection_set_write_timeout_tv(evcon, &http->timeout_write);
4543 * if we want to accept more than one request on a connection,
4544 * we need to know which http server it belongs to.
4546 evcon->http_server = http;
4547 evcon->ext_method_cmp = http->ext_method_cmp;
4548 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4550 if (evhttp_associate_new_request_with_connection(evcon) == -1)
4551 evhttp_connection_free(evcon);
4556 * Network helper functions that we do not want to export to the rest of
4561 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4562 char **phost, char **pport)
4564 char ntop[NI_MAXHOST];
4565 char strport[NI_MAXSERV];
4568 #ifdef EVENT__HAVE_GETNAMEINFO
4569 ni_result = getnameinfo(sa, salen,
4570 ntop, sizeof(ntop), strport, sizeof(strport),
4571 NI_NUMERICHOST|NI_NUMERICSERV);
4573 if (ni_result != 0) {
4575 /* Windows doesn't have an EAI_SYSTEM. */
4576 if (ni_result == EAI_SYSTEM)
4577 event_err(1, "getnameinfo failed");
4580 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4584 ni_result = fake_getnameinfo(sa, salen,
4585 ntop, sizeof(ntop), strport, sizeof(strport),
4586 NI_NUMERICHOST|NI_NUMERICSERV);
4591 *phost = mm_strdup(ntop);
4592 *pport = mm_strdup(strport);
4595 /* Create a non-blocking socket and bind it */
4596 /* todo: rename this function */
4597 static evutil_socket_t
4598 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
4605 /* Create listen socket */
4606 fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
4607 SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
4609 event_sock_warn(-1, "socket");
4613 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
4616 if (evutil_make_listen_socket_reuseable(fd) < 0)
4621 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
4629 serrno = EVUTIL_SOCKET_ERROR();
4630 evutil_closesocket(fd);
4631 EVUTIL_SET_SOCKET_ERROR(serrno);
4635 static struct evutil_addrinfo *
4636 make_addrinfo(const char *address, ev_uint16_t port)
4638 struct evutil_addrinfo *ai = NULL;
4640 struct evutil_addrinfo hints;
4641 char strport[NI_MAXSERV];
4644 memset(&hints, 0, sizeof(hints));
4645 hints.ai_family = AF_UNSPEC;
4646 hints.ai_socktype = SOCK_STREAM;
4647 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
4648 * types we don't have an interface to connect to. */
4649 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
4650 evutil_snprintf(strport, sizeof(strport), "%d", port);
4651 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
4653 if (ai_result == EVUTIL_EAI_SYSTEM)
4654 event_warn("getaddrinfo");
4656 event_warnx("getaddrinfo: %s",
4657 evutil_gai_strerror(ai_result));
4664 static evutil_socket_t
4665 bind_socket(const char *address, ev_uint16_t port, int reuse)
4668 struct evutil_addrinfo *aitop = NULL;
4670 /* just create an unbound socket */
4671 if (address == NULL && port == 0)
4672 return bind_socket_ai(NULL, 0);
4674 aitop = make_addrinfo(address, port);
4679 fd = bind_socket_ai(aitop, reuse);
4681 evutil_freeaddrinfo(aitop);
4688 char *scheme; /* scheme; e.g http, ftp etc */
4689 char *userinfo; /* userinfo (typically username:pass), or NULL */
4690 char *host; /* hostname, IP address, or NULL */
4691 int port; /* port, or zero */
4692 char *path; /* path, or "". */
4693 char *query; /* query, or NULL */
4694 char *fragment; /* fragment or NULL */
4698 evhttp_uri_new(void)
4700 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
4707 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
4712 /* Return true if the string starting at s and ending immediately before eos
4713 * is a valid URI scheme according to RFC3986
4716 scheme_ok(const char *s, const char *eos)
4718 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4719 EVUTIL_ASSERT(eos >= s);
4722 if (!EVUTIL_ISALPHA_(*s))
4725 if (! EVUTIL_ISALNUM_(*s) &&
4726 *s != '+' && *s != '-' && *s != '.')
4732 #define SUBDELIMS "!$&'()*+,;="
4734 /* Return true iff [s..eos) is a valid userinfo */
4736 userinfo_ok(const char *s, const char *eos)
4739 if (CHAR_IS_UNRESERVED(*s) ||
4740 strchr(SUBDELIMS, *s) ||
4743 else if (*s == '%' && s+2 < eos &&
4744 EVUTIL_ISXDIGIT_(s[1]) &&
4745 EVUTIL_ISXDIGIT_(s[2]))
4754 regname_ok(const char *s, const char *eos)
4756 while (s && s<eos) {
4757 if (CHAR_IS_UNRESERVED(*s) ||
4758 strchr(SUBDELIMS, *s))
4760 else if (*s == '%' &&
4761 EVUTIL_ISXDIGIT_(s[1]) &&
4762 EVUTIL_ISXDIGIT_(s[2]))
4771 parse_port(const char *s, const char *eos)
4775 if (! EVUTIL_ISDIGIT_(*s))
4777 portnum = (portnum * 10) + (*s - '0');
4780 if (portnum > 65535)
4787 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4789 bracket_addr_ok(const char *s, const char *eos)
4791 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4794 /* IPvFuture, or junk.
4795 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4797 s += 2; /* skip [v */
4799 if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
4801 while (s < eos && *s != '.') {
4802 if (EVUTIL_ISXDIGIT_(*s))
4811 if (CHAR_IS_UNRESERVED(*s) ||
4812 strchr(SUBDELIMS, *s) ||
4822 ev_ssize_t n_chars = eos-s-2;
4823 struct in6_addr in6;
4824 if (n_chars >= 64) /* way too long */
4826 memcpy(buf, s+1, n_chars);
4828 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4833 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4838 uri->host = mm_strdup("");
4839 if (uri->host == NULL) {
4840 event_warn("%s: strdup", __func__);
4846 /* Optionally, we start with "userinfo@" */
4848 cp = strchr(s, '@');
4849 if (cp && cp < eos) {
4850 if (! userinfo_ok(s,cp))
4853 uri->userinfo = mm_strdup(s);
4854 if (uri->userinfo == NULL) {
4855 event_warn("%s: strdup", __func__);
4861 /* Optionally, we end with ":port" */
4862 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
4864 if (port >= cp && *port == ':') {
4865 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4868 else if ((uri->port = parse_port(port+1, eos))<0)
4872 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4873 * an IP-Literal, or a reg-name */
4874 EVUTIL_ASSERT(eos >= cp);
4875 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4876 /* IPv6address, IP-Literal, or junk. */
4877 if (! bracket_addr_ok(cp, eos))
4880 /* Make sure the host part is ok. */
4881 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4884 uri->host = mm_malloc(eos-cp+1);
4885 if (uri->host == NULL) {
4886 event_warn("%s: malloc", __func__);
4889 memcpy(uri->host, cp, eos-cp);
4890 uri->host[eos-cp] = '\0';
4896 end_of_authority(char *cp)
4899 if (*cp == '?' || *cp == '#' || *cp == '/')
4912 /* Return the character after the longest prefix of 'cp' that matches...
4913 * *pchar / "/" if allow_qchars is false, or
4914 * *(pchar / "/" / "?") if allow_qchars is true.
4917 end_of_path(char *cp, enum uri_part part, unsigned flags)
4919 if (flags & EVHTTP_URI_NONCONFORMANT) {
4920 /* If NONCONFORMANT:
4921 * Path is everything up to a # or ? or nul.
4922 * Query is everything up a # or nul
4923 * Fragment is everything up to a nul.
4927 while (*cp && *cp != '#' && *cp != '?')
4931 while (*cp && *cp != '#')
4942 if (CHAR_IS_UNRESERVED(*cp) ||
4943 strchr(SUBDELIMS, *cp) ||
4944 *cp == ':' || *cp == '@' || *cp == '/')
4946 else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
4947 EVUTIL_ISXDIGIT_(cp[2]))
4949 else if (*cp == '?' && part != PART_PATH)
4958 path_matches_noscheme(const char *cp)
4963 else if (*cp == '/')
4971 evhttp_uri_parse(const char *source_uri)
4973 return evhttp_uri_parse_with_flags(source_uri, 0);
4977 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4979 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4980 char *path = NULL, *fragment = NULL;
4981 int got_authority = 0;
4983 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4985 event_warn("%s: calloc", __func__);
4991 readbuf = mm_strdup(source_uri);
4992 if (readbuf == NULL) {
4993 event_warn("%s: strdup", __func__);
5000 /* We try to follow RFC3986 here as much as we can, and match
5003 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
5005 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
5009 token = strchr(readp, ':');
5010 if (token && scheme_ok(readp,token)) {
5012 uri->scheme = mm_strdup(readp);
5013 if (uri->scheme == NULL) {
5014 event_warn("%s: strdup", __func__);
5017 readp = token+1; /* eat : */
5020 /* 2. Optionally, "//" then an 'authority' part. */
5021 if (readp[0]=='/' && readp[1] == '/') {
5025 path = end_of_authority(readp);
5026 if (parse_authority(uri, authority, path) < 0)
5032 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
5035 readp = end_of_path(path, PART_PATH, flags);
5038 if (*readp == '?') {
5042 readp = end_of_path(readp, PART_QUERY, flags);
5045 if (*readp == '#') {
5049 readp = end_of_path(readp, PART_FRAGMENT, flags);
5051 if (*readp != '\0') {
5055 /* These next two cases may be unreachable; I'm leaving them
5056 * in to be defensive. */
5057 /* If you didn't get an authority, the path can't begin with "//" */
5058 if (!got_authority && path[0]=='/' && path[1]=='/')
5060 /* If you did get an authority, the path must begin with "/" or be
5062 if (got_authority && path[0] != '/' && path[0] != '\0')
5064 /* (End of maybe-unreachable cases) */
5066 /* If there was no scheme, the first part of the path (if any) must
5067 * have no colon in it. */
5068 if (! uri->scheme && !path_matches_noscheme(path))
5071 EVUTIL_ASSERT(path);
5072 uri->path = mm_strdup(path);
5073 if (uri->path == NULL) {
5074 event_warn("%s: strdup", __func__);
5079 uri->query = mm_strdup(query);
5080 if (uri->query == NULL) {
5081 event_warn("%s: strdup", __func__);
5086 uri->fragment = mm_strdup(fragment);
5087 if (uri->fragment == NULL) {
5088 event_warn("%s: strdup", __func__);
5098 evhttp_uri_free(uri);
5104 static struct evhttp_uri *
5105 evhttp_uri_parse_authority(char *source_uri)
5107 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
5111 event_warn("%s: calloc", __func__);
5117 end = end_of_authority(source_uri);
5118 if (parse_authority(uri, source_uri, end) < 0)
5121 uri->path = mm_strdup("");
5122 if (uri->path == NULL) {
5123 event_warn("%s: strdup", __func__);
5130 evhttp_uri_free(uri);
5135 evhttp_uri_free(struct evhttp_uri *uri)
5137 #define URI_FREE_STR_(f) \
5142 URI_FREE_STR_(scheme);
5143 URI_FREE_STR_(userinfo);
5144 URI_FREE_STR_(host);
5145 URI_FREE_STR_(path);
5146 URI_FREE_STR_(query);
5147 URI_FREE_STR_(fragment);
5150 #undef URI_FREE_STR_
5154 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
5156 struct evbuffer *tmp = 0;
5157 size_t joined_size = 0;
5158 char *output = NULL;
5160 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
5162 if (!uri || !buf || !limit)
5165 tmp = evbuffer_new();
5171 evbuffer_add(tmp, ":", 1);
5174 evbuffer_add(tmp, "//", 2);
5176 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
5179 evbuffer_add_printf(tmp,":%d", uri->port);
5181 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
5189 evbuffer_add(tmp, "?", 1);
5193 if (uri->fragment) {
5194 evbuffer_add(tmp, "#", 1);
5198 evbuffer_add(tmp, "\0", 1); /* NUL */
5200 joined_size = evbuffer_get_length(tmp);
5202 if (joined_size > limit) {
5203 /* It doesn't fit. */
5207 evbuffer_remove(tmp, buf, joined_size);
5218 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
5223 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
5225 return uri->userinfo;
5228 evhttp_uri_get_host(const struct evhttp_uri *uri)
5233 evhttp_uri_get_port(const struct evhttp_uri *uri)
5238 evhttp_uri_get_path(const struct evhttp_uri *uri)
5243 evhttp_uri_get_query(const struct evhttp_uri *uri)
5248 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
5250 return uri->fragment;
5253 #define URI_SET_STR_(f) do { \
5257 if ((uri->f = mm_strdup(f)) == NULL) { \
5258 event_warn("%s: strdup()", __func__); \
5267 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
5269 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
5272 URI_SET_STR_(scheme);
5276 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
5278 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
5280 URI_SET_STR_(userinfo);
5284 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
5287 if (host[0] == '[') {
5288 if (! bracket_addr_ok(host, host+strlen(host)))
5291 if (! regname_ok(host, host+strlen(host)))
5300 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
5307 #define end_of_cpath(cp,p,f) \
5308 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
5311 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
5313 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
5320 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
5322 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
5324 URI_SET_STR_(query);
5328 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
5330 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
5332 URI_SET_STR_(fragment);