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;
2001 ext_method.flags = 0;
2003 if (req->evcon->ext_method_cmp &&
2004 req->evcon->ext_method_cmp(&ext_method) == 0) {
2005 /* make sure the other fields in ext_method are
2006 * not changed by the callback.
2008 if (strcmp(ext_method.method, method) != 0) {
2009 event_warn("%s: modifying the 'method' field of ext_method_cmp's "
2010 "parameter is not allowed", __func__);
2013 if (ext_method.flags != 0) {
2014 event_warn("%s: modifying the 'flags' field of ext_method_cmp's "
2015 "parameter is not allowed", __func__);
2018 type = ext_method.type;
2023 event_debug(("%s: bad method %s on request %p from %s",
2024 __func__, method, req, req->remote_host));
2025 /* No error yet; we'll give a better error later when
2026 * we see that req->type is unsupported. */
2031 if (evhttp_parse_http_version(version, req) < 0)
2034 if ((req->uri = mm_strdup(uri)) == NULL) {
2035 event_debug(("%s: mm_strdup", __func__));
2039 if (type == EVHTTP_REQ_CONNECT) {
2040 if ((req->uri_elems = evhttp_uri_parse_authority(req->uri)) == NULL) {
2044 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
2045 EVHTTP_URI_NONCONFORMANT)) == NULL) {
2050 /* If we have an absolute-URI, check to see if it is an http request
2051 for a known vhost or server alias. If we don't know about this
2052 host, we consider it a proxy request. */
2053 scheme = evhttp_uri_get_scheme(req->uri_elems);
2054 hostname = evhttp_uri_get_host(req->uri_elems);
2055 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
2056 !evutil_ascii_strcasecmp(scheme, "https")) &&
2058 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
2059 req->flags |= EVHTTP_PROXY_REQUEST;
2065 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
2067 struct evkeyval *header;
2069 TAILQ_FOREACH(header, headers, next) {
2070 if (evutil_ascii_strcasecmp(header->key, key) == 0)
2071 return (header->value);
2078 evhttp_clear_headers(struct evkeyvalq *headers)
2080 struct evkeyval *header;
2082 for (header = TAILQ_FIRST(headers);
2084 header = TAILQ_FIRST(headers)) {
2085 TAILQ_REMOVE(headers, header, next);
2086 mm_free(header->key);
2087 mm_free(header->value);
2093 * Returns 0, if the header was successfully removed.
2094 * Returns -1, if the header could not be found.
2098 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
2100 struct evkeyval *header;
2102 TAILQ_FOREACH(header, headers, next) {
2103 if (evutil_ascii_strcasecmp(header->key, key) == 0)
2110 /* Free and remove the header that we found */
2111 TAILQ_REMOVE(headers, header, next);
2112 mm_free(header->key);
2113 mm_free(header->value);
2120 evhttp_header_is_valid_value(const char *value)
2122 const char *p = value;
2124 while ((p = strpbrk(p, "\r\n")) != NULL) {
2125 /* we really expect only one new line */
2126 p += strspn(p, "\r\n");
2127 /* we expect a space or tab for continuation */
2128 if (*p != ' ' && *p != '\t')
2135 evhttp_add_header(struct evkeyvalq *headers,
2136 const char *key, const char *value)
2138 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
2140 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
2141 /* drop illegal headers */
2142 event_debug(("%s: dropping illegal header key\n", __func__));
2146 if (!evhttp_header_is_valid_value(value)) {
2147 event_debug(("%s: dropping illegal header value\n", __func__));
2151 return (evhttp_add_header_internal(headers, key, value));
2155 evhttp_add_header_internal(struct evkeyvalq *headers,
2156 const char *key, const char *value)
2158 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
2159 if (header == NULL) {
2160 event_warn("%s: calloc", __func__);
2163 if ((header->key = mm_strdup(key)) == NULL) {
2165 event_warn("%s: strdup", __func__);
2168 if ((header->value = mm_strdup(value)) == NULL) {
2169 mm_free(header->key);
2171 event_warn("%s: strdup", __func__);
2175 TAILQ_INSERT_TAIL(headers, header, next);
2181 * Parses header lines from a request or a response into the specified
2182 * request object given an event buffer.
2185 * DATA_CORRUPTED on error
2186 * MORE_DATA_EXPECTED when we need to read more headers
2187 * ALL_DATA_READ when all headers have been read.
2190 enum message_read_status
2191 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
2194 enum message_read_status status = ALL_DATA_READ;
2198 line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
2200 if (req->evcon != NULL &&
2201 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2202 return (DATA_TOO_LONG);
2204 return (MORE_DATA_EXPECTED);
2207 if (req->evcon != NULL && len > req->evcon->max_headers_size) {
2209 return (DATA_TOO_LONG);
2212 req->headers_size = len;
2214 switch (req->kind) {
2215 case EVHTTP_REQUEST:
2216 if (evhttp_parse_request_line(req, line, len) == -1)
2217 status = DATA_CORRUPTED;
2219 case EVHTTP_RESPONSE:
2220 if (evhttp_parse_response_line(req, line) == -1)
2221 status = DATA_CORRUPTED;
2224 status = DATA_CORRUPTED;
2232 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
2234 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
2236 size_t old_len, line_len;
2241 old_len = strlen(header->value);
2243 /* Strip space from start and end of line. */
2244 while (*line == ' ' || *line == '\t')
2246 evutil_rtrim_lws_(line);
2248 line_len = strlen(line);
2250 newval = mm_realloc(header->value, old_len + line_len + 2);
2254 newval[old_len] = ' ';
2255 memcpy(newval + old_len + 1, line, line_len + 1);
2256 header->value = newval;
2261 enum message_read_status
2262 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
2264 enum message_read_status errcode = DATA_CORRUPTED;
2266 enum message_read_status status = MORE_DATA_EXPECTED;
2268 struct evkeyvalq* headers = req->input_headers;
2270 while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
2272 char *skey, *svalue;
2274 req->headers_size += len;
2276 if (req->evcon != NULL &&
2277 req->headers_size > req->evcon->max_headers_size) {
2278 errcode = DATA_TOO_LONG;
2282 if (*line == '\0') { /* Last header - Done */
2283 status = ALL_DATA_READ;
2288 /* Check if this is a continuation line */
2289 if (*line == ' ' || *line == '\t') {
2290 if (evhttp_append_to_last_header(headers, line) == -1)
2296 /* Processing of header lines */
2298 skey = strsep(&svalue, ":");
2302 svalue += strspn(svalue, " ");
2303 evutil_rtrim_lws_(svalue);
2305 if (evhttp_add_header(headers, skey, svalue) == -1)
2311 if (status == MORE_DATA_EXPECTED) {
2312 if (req->evcon != NULL &&
2313 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2314 return (DATA_TOO_LONG);
2325 evhttp_get_body_length(struct evhttp_request *req)
2327 struct evkeyvalq *headers = req->input_headers;
2328 const char *content_length;
2329 const char *connection;
2331 content_length = evhttp_find_header(headers, "Content-Length");
2332 connection = evhttp_find_header(headers, "Connection");
2334 if (content_length == NULL && connection == NULL)
2336 else if (content_length == NULL &&
2337 evutil_ascii_strcasecmp(connection, "Close") != 0) {
2339 } else if (content_length == NULL) {
2343 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2344 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2345 event_debug(("%s: illegal content length: %s",
2346 __func__, content_length));
2349 req->ntoread = ntoread;
2352 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2353 __func__, EV_I64_ARG(req->ntoread),
2354 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2360 evhttp_method_may_have_body_(struct evhttp_connection *evcon, enum evhttp_cmd_type type)
2363 evhttp_method_(evcon, type, &flags);
2364 return (flags & EVHTTP_METHOD_HAS_BODY) ? 1 : 0;
2368 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2370 const char *xfer_enc;
2372 /* If this is a request without a body, then we are done */
2373 if (req->kind == EVHTTP_REQUEST &&
2374 !evhttp_method_may_have_body_(evcon, req->type)) {
2375 evhttp_connection_done(evcon);
2378 evcon->state = EVCON_READING_BODY;
2379 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
2380 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
2384 if (evhttp_get_body_length(req) == -1) {
2385 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2388 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2389 /* An incoming request with no content-length and no
2390 * transfer-encoding has no body. */
2391 evhttp_connection_done(evcon);
2396 /* Should we send a 100 Continue status line? */
2397 switch (evhttp_have_expect(req, 1)) {
2399 /* XXX It would be nice to do some sanity
2400 checking here. Does the resource exist?
2401 Should the resource accept post requests? If
2402 no, we should respond with an error. For
2403 now, just optimistically tell the client to
2404 send their message body. */
2405 if (req->ntoread > 0) {
2406 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2407 if ((req->evcon->max_body_size <= EV_INT64_MAX) &&
2408 (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2409 evhttp_lingering_fail(evcon, req);
2413 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2414 evhttp_send_continue(evcon, req);
2417 evhttp_send_error(req, HTTP_EXPECTATIONFAILED, NULL);
2422 evhttp_read_body(evcon, req);
2423 /* note the request may have been freed in evhttp_read_body */
2427 evhttp_read_firstline(struct evhttp_connection *evcon,
2428 struct evhttp_request *req)
2430 enum message_read_status res;
2432 res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2433 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2434 /* Error while reading, terminate */
2435 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2436 __func__, EV_SOCK_ARG(evcon->fd)));
2437 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2439 } else if (res == MORE_DATA_EXPECTED) {
2440 /* Need more header lines */
2444 evcon->state = EVCON_READING_HEADERS;
2445 evhttp_read_header(evcon, req);
2449 evhttp_read_header(struct evhttp_connection *evcon,
2450 struct evhttp_request *req)
2452 enum message_read_status res;
2453 evutil_socket_t fd = evcon->fd;
2455 res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2456 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2457 /* Error while reading, terminate */
2458 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2459 __func__, EV_SOCK_ARG(fd)));
2460 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2462 } else if (res == MORE_DATA_EXPECTED) {
2463 /* Need more header lines */
2467 /* Callback can shut down connection with negative return value */
2468 if (req->header_cb != NULL) {
2469 if ((*req->header_cb)(req, req->cb_arg) < 0) {
2470 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2475 /* Done reading headers, do the real work */
2476 switch (req->kind) {
2477 case EVHTTP_REQUEST:
2478 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2479 __func__, EV_SOCK_ARG(fd)));
2480 evhttp_get_body(evcon, req);
2481 /* note the request may have been freed in evhttp_get_body */
2484 case EVHTTP_RESPONSE:
2485 /* Start over if we got a 100 Continue response. */
2486 if (req->response_code == 100) {
2487 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
2488 evbuffer_add_buffer(output, req->output_buffer);
2489 evhttp_start_write_(evcon);
2492 if (!evhttp_response_needs_body(req)) {
2493 event_debug(("%s: skipping body for code %d\n",
2494 __func__, req->response_code));
2495 evhttp_connection_done(evcon);
2497 event_debug(("%s: start of read body for %s on "
2499 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2500 evhttp_get_body(evcon, req);
2501 /* note the request may have been freed in
2502 * evhttp_get_body */
2507 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2509 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2512 /* request may have been freed above */
2516 * Creates a TCP connection to the specified port and executes a callback
2517 * when finished. Failure or success is indicate by the passed connection
2520 * Although this interface accepts a hostname, it is intended to take
2521 * only numeric hostnames so that non-blocking DNS resolution can
2525 struct evhttp_connection *
2526 evhttp_connection_new(const char *address, ev_uint16_t port)
2528 return (evhttp_connection_base_new(NULL, NULL, address, port));
2531 struct evhttp_connection *
2532 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2533 const char *address, ev_uint16_t port)
2535 struct evhttp_connection *evcon = NULL;
2537 event_debug(("Attempting connection to %s:%d\n", address, port));
2539 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2540 event_warn("%s: calloc failed", __func__);
2547 evcon->max_headers_size = EV_SIZE_MAX;
2548 evcon->max_body_size = EV_SIZE_MAX;
2550 evcon->timeout_connect.tv_sec = HTTP_CONNECT_TIMEOUT;
2551 evcon->timeout_read.tv_sec = HTTP_READ_TIMEOUT;
2552 evcon->timeout_write.tv_sec = HTTP_WRITE_TIMEOUT;
2553 evcon->initial_retry_timeout.tv_sec = HTTP_INITIAL_RETRY_TIMEOUT;
2555 evcon->retry_cnt = evcon->retry_max = 0;
2557 if ((evcon->address = mm_strdup(address)) == NULL) {
2558 event_warn("%s: strdup failed", __func__);
2563 if (!(bev = bufferevent_socket_new(base, -1, 0))) {
2564 event_warn("%s: bufferevent_socket_new failed", __func__);
2569 bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2572 evcon->state = EVCON_DISCONNECTED;
2573 TAILQ_INIT(&evcon->requests);
2577 if (bufferevent_get_base(bev) != base)
2578 bufferevent_base_set(base, evcon->bufev);
2581 event_deferred_cb_init_(
2582 &evcon->read_more_deferred_cb,
2583 bufferevent_get_priority(bev),
2584 evhttp_deferred_read_cb, evcon);
2586 evcon->dns_base = dnsbase;
2587 evcon->ai_family = AF_UNSPEC;
2593 evhttp_connection_free(evcon);
2597 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2599 return evcon->bufev;
2603 evhttp_connection_get_server(struct evhttp_connection *evcon)
2605 return evcon->http_server;
2608 struct evhttp_connection *
2609 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2610 const char *address, ev_uint16_t port)
2612 return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2615 void evhttp_connection_set_family(struct evhttp_connection *evcon,
2618 evcon->ai_family = family;
2621 int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2624 int avail_flags = 0;
2625 avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2626 avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2628 if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2630 evcon->flags &= ~avail_flags;
2632 evcon->flags |= flags;
2638 evhttp_connection_set_ext_method_cmp(struct evhttp_connection *evcon,
2639 evhttp_ext_method_cb cmp)
2641 evcon->ext_method_cmp = cmp;
2645 evhttp_connection_set_base(struct evhttp_connection *evcon,
2646 struct event_base *base)
2648 EVUTIL_ASSERT(evcon->base == NULL);
2649 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2651 bufferevent_base_set(base, evcon->bufev);
2655 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2658 if (timeout != -1) {
2659 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2661 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2663 evhttp_set_timeout_(&evcon->timeout_read, timeout, HTTP_READ_TIMEOUT);
2664 evhttp_set_timeout_(&evcon->timeout_write, timeout, HTTP_WRITE_TIMEOUT);
2665 bufferevent_set_timeouts(evcon->bufev,
2666 &evcon->timeout_read, &evcon->timeout_write);
2669 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2670 const struct timeval* tv)
2673 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2675 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2677 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, HTTP_READ_TIMEOUT);
2678 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, HTTP_WRITE_TIMEOUT);
2679 bufferevent_set_timeouts(evcon->bufev,
2680 &evcon->timeout_read, &evcon->timeout_write);
2682 void evhttp_connection_set_connect_timeout_tv(struct evhttp_connection *evcon,
2683 const struct timeval *tv)
2685 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2686 evhttp_set_timeout_tv_(&evcon->timeout_connect, tv, -1);
2687 if (evcon->state == EVCON_CONNECTING)
2688 bufferevent_set_timeouts(evcon->bufev,
2689 &evcon->timeout_connect, &evcon->timeout_connect);
2691 void evhttp_connection_set_read_timeout_tv(struct evhttp_connection *evcon,
2692 const struct timeval *tv)
2694 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2695 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, -1);
2696 if (evcon->state != EVCON_CONNECTING)
2697 bufferevent_set_timeouts(evcon->bufev,
2698 &evcon->timeout_read, &evcon->timeout_write);
2700 void evhttp_connection_set_write_timeout_tv(struct evhttp_connection *evcon,
2701 const struct timeval *tv)
2703 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2704 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, -1);
2705 if (evcon->state != EVCON_CONNECTING)
2706 bufferevent_set_timeouts(evcon->bufev,
2707 &evcon->timeout_read, &evcon->timeout_write);
2711 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2712 const struct timeval *tv)
2715 evcon->initial_retry_timeout = *tv;
2717 evutil_timerclear(&evcon->initial_retry_timeout);
2718 evcon->initial_retry_timeout.tv_sec = 2;
2723 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2726 evcon->retry_max = retry_max;
2730 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2731 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2733 evcon->closecb = cb;
2734 evcon->closecb_arg = cbarg;
2738 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2739 char **address, ev_uint16_t *port)
2741 *address = evcon->address;
2742 *port = evcon->port;
2745 const struct sockaddr*
2746 evhttp_connection_get_addr(struct evhttp_connection *evcon)
2748 return bufferevent_socket_get_conn_address_(evcon->bufev);
2752 evhttp_connection_connect_(struct evhttp_connection *evcon)
2754 int old_state = evcon->state;
2755 const char *address = evcon->address;
2756 const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
2759 if (evcon->state == EVCON_CONNECTING)
2762 evhttp_connection_reset_(evcon);
2764 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2765 evcon->flags |= EVHTTP_CON_OUTGOING;
2767 if (evcon->bind_address || evcon->bind_port) {
2768 evcon->fd = bind_socket(
2769 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2770 if (evcon->fd == -1) {
2771 event_debug(("%s: failed to bind to \"%s\"",
2772 __func__, evcon->bind_address));
2776 if (bufferevent_setfd(evcon->bufev, evcon->fd))
2779 if (bufferevent_setfd(evcon->bufev, -1))
2783 /* Set up a callback for successful connection setup */
2784 bufferevent_setcb(evcon->bufev,
2785 NULL /* evhttp_read_cb */,
2786 NULL /* evhttp_write_cb */,
2787 evhttp_connection_cb,
2789 bufferevent_set_timeouts(evcon->bufev,
2790 &evcon->timeout_connect, &evcon->timeout_connect);
2791 /* make sure that we get a write callback */
2792 if (bufferevent_enable(evcon->bufev, EV_WRITE))
2795 evcon->state = EVCON_CONNECTING;
2797 if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
2799 (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
2800 int socklen = sizeof(struct sockaddr_in);
2801 if (sa->sa_family == AF_INET6) {
2802 socklen = sizeof(struct sockaddr_in6);
2804 ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
2806 ret = bufferevent_socket_connect_hostname(evcon->bufev,
2807 evcon->dns_base, evcon->ai_family, address, evcon->port);
2811 evcon->state = old_state;
2812 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2813 __func__, evcon->address);
2814 /* some operating systems return ECONNREFUSED immediately
2815 * when connecting to a local address. the cleanup is going
2816 * to reschedule this function call.
2818 evhttp_connection_cb_cleanup(evcon);
2826 * Starts an HTTP request on the provided evhttp_connection object.
2827 * If the connection object is not connected to the web server already,
2828 * this will start the connection.
2832 evhttp_make_request(struct evhttp_connection *evcon,
2833 struct evhttp_request *req,
2834 enum evhttp_cmd_type type, const char *uri)
2836 /* We are making a request */
2837 req->kind = EVHTTP_REQUEST;
2839 if (req->uri != NULL)
2841 if ((req->uri = mm_strdup(uri)) == NULL) {
2842 event_warn("%s: strdup", __func__);
2843 evhttp_request_free_auto(req);
2847 /* Set the protocol version if it is not supplied */
2848 if (!req->major && !req->minor) {
2853 EVUTIL_ASSERT(req->evcon == NULL);
2855 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2857 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2859 /* We do not want to conflict with retry_ev */
2860 if (evcon->retry_cnt)
2863 /* If the connection object is not connected; make it so */
2864 if (!evhttp_connected(evcon)) {
2865 int res = evhttp_connection_connect_(evcon);
2866 /* evhttp_connection_fail_(), which is called through
2867 * evhttp_connection_connect_(), assumes that req lies in
2868 * evcon->requests. Thus, enqueue the request in advance and
2869 * remove it in the error case. */
2871 TAILQ_REMOVE(&evcon->requests, req, next);
2877 * If it's connected already and we are the first in the queue,
2878 * then we can dispatch this request immediately. Otherwise, it
2879 * will be dispatched once the pending requests are completed.
2881 if (TAILQ_FIRST(&evcon->requests) == req)
2882 evhttp_request_dispatch(evcon);
2888 evhttp_cancel_request(struct evhttp_request *req)
2890 struct evhttp_connection *evcon = req->evcon;
2891 if (evcon != NULL) {
2892 /* We need to remove it from the connection */
2893 if (TAILQ_FIRST(&evcon->requests) == req) {
2894 /* it's currently being worked on, so reset
2897 evhttp_connection_fail_(evcon,
2898 EVREQ_HTTP_REQUEST_CANCEL);
2900 /* connection fail freed the request */
2903 /* otherwise, we can just remove it from the
2906 TAILQ_REMOVE(&evcon->requests, req, next);
2910 evhttp_request_free_auto(req);
2914 * Reads data from file descriptor into request structure
2915 * Request structure needs to be set up correctly.
2919 evhttp_start_read_(struct evhttp_connection *evcon)
2921 bufferevent_disable(evcon->bufev, EV_WRITE);
2922 bufferevent_enable(evcon->bufev, EV_READ);
2924 evcon->state = EVCON_READING_FIRSTLINE;
2925 /* Reset the bufferevent callbacks */
2926 bufferevent_setcb(evcon->bufev,
2932 /* If there's still data pending, process it next time through the
2933 * loop. Don't do it now; that could get recusive. */
2934 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2935 event_deferred_cb_schedule_(get_deferred_queue(evcon),
2936 &evcon->read_more_deferred_cb);
2941 evhttp_start_write_(struct evhttp_connection *evcon)
2943 bufferevent_disable(evcon->bufev, EV_WRITE);
2944 bufferevent_enable(evcon->bufev, EV_READ);
2946 evcon->state = EVCON_WRITING;
2947 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
2951 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2954 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2955 TAILQ_REMOVE(&evcon->requests, req, next);
2957 if (req->on_complete_cb != NULL) {
2958 req->on_complete_cb(req, req->on_complete_cb_arg);
2962 (REQ_VERSION_BEFORE(req, 1, 1) &&
2963 !evhttp_is_connection_keepalive(req->input_headers)) ||
2964 evhttp_is_request_connection_close(req);
2966 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2967 evhttp_request_free(req);
2970 evhttp_connection_free(evcon);
2974 /* we have a persistent connection; try to accept another request. */
2975 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2976 evhttp_connection_free(evcon);
2981 * Returns an error page.
2985 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2988 #define ERR_FORMAT "<HTML><HEAD>\n" \
2989 "<TITLE>%d %s</TITLE>\n" \
2994 struct evbuffer *buf = evbuffer_new();
2996 /* if we cannot allocate memory; we just drop the connection */
2997 evhttp_connection_free(req->evcon);
3000 if (reason == NULL) {
3001 reason = evhttp_response_phrase_internal(error);
3004 evhttp_response_code_(req, error, reason);
3006 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
3008 evhttp_send_page_(req, buf);
3014 /* Requires that headers and response code are already set up */
3017 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
3019 struct evhttp_connection *evcon = req->evcon;
3021 if (evcon == NULL) {
3022 evhttp_request_free(req);
3026 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
3028 /* we expect no more calls form the user on this request */
3031 /* xxx: not sure if we really should expose the data buffer this way */
3032 if (databuf != NULL)
3033 evbuffer_add_buffer(req->output_buffer, databuf);
3035 /* Adds headers to the response */
3036 evhttp_make_header(evcon, req);
3038 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
3042 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
3043 struct evbuffer *databuf)
3045 evhttp_response_code_(req, code, reason);
3047 evhttp_send(req, databuf);
3051 evhttp_send_reply_start(struct evhttp_request *req, int code,
3054 evhttp_response_code_(req, code, reason);
3056 if (req->evcon == NULL)
3059 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
3060 REQ_VERSION_ATLEAST(req, 1, 1) &&
3061 evhttp_response_needs_body(req)) {
3063 * prefer HTTP/1.1 chunked encoding to closing the connection;
3064 * note RFC 2616 section 4.4 forbids it with Content-Length:
3065 * and it's not necessary then anyway.
3067 evhttp_add_header(req->output_headers, "Transfer-Encoding",
3073 evhttp_make_header(req->evcon, req);
3074 evhttp_write_buffer(req->evcon, NULL, NULL);
3078 evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
3079 void (*cb)(struct evhttp_connection *, void *), void *arg)
3081 struct evhttp_connection *evcon = req->evcon;
3082 struct evbuffer *output;
3087 output = bufferevent_get_output(evcon->bufev);
3089 if (evbuffer_get_length(databuf) == 0)
3091 if (!evhttp_response_needs_body(req))
3094 evbuffer_add_printf(output, "%x\r\n",
3095 (unsigned)evbuffer_get_length(databuf));
3097 evbuffer_add_buffer(output, databuf);
3099 evbuffer_add(output, "\r\n", 2);
3101 evhttp_write_buffer(evcon, cb, arg);
3105 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
3107 evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
3110 evhttp_send_reply_end(struct evhttp_request *req)
3112 struct evhttp_connection *evcon = req->evcon;
3113 struct evbuffer *output;
3115 if (evcon == NULL) {
3116 evhttp_request_free(req);
3120 output = bufferevent_get_output(evcon->bufev);
3122 /* we expect no more calls form the user on this request */
3126 evbuffer_add(output, "0\r\n\r\n", 5);
3127 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
3129 } else if (evbuffer_get_length(output) == 0) {
3130 /* let the connection know that we are done with the request */
3131 evhttp_send_done(evcon, NULL);
3133 /* make the callback execute after all data has been written */
3134 evcon->cb = evhttp_send_done;
3135 evcon->cb_arg = NULL;
3139 static const char *informational_phrases[] = {
3140 /* 100 */ "Continue",
3141 /* 101 */ "Switching Protocols"
3144 static const char *success_phrases[] = {
3146 /* 201 */ "Created",
3147 /* 202 */ "Accepted",
3148 /* 203 */ "Non-Authoritative Information",
3149 /* 204 */ "No Content",
3150 /* 205 */ "Reset Content",
3151 /* 206 */ "Partial Content"
3154 static const char *redirection_phrases[] = {
3155 /* 300 */ "Multiple Choices",
3156 /* 301 */ "Moved Permanently",
3158 /* 303 */ "See Other",
3159 /* 304 */ "Not Modified",
3160 /* 305 */ "Use Proxy",
3161 /* 307 */ "Temporary Redirect"
3164 static const char *client_error_phrases[] = {
3165 /* 400 */ "Bad Request",
3166 /* 401 */ "Unauthorized",
3167 /* 402 */ "Payment Required",
3168 /* 403 */ "Forbidden",
3169 /* 404 */ "Not Found",
3170 /* 405 */ "Method Not Allowed",
3171 /* 406 */ "Not Acceptable",
3172 /* 407 */ "Proxy Authentication Required",
3173 /* 408 */ "Request Time-out",
3174 /* 409 */ "Conflict",
3176 /* 411 */ "Length Required",
3177 /* 412 */ "Precondition Failed",
3178 /* 413 */ "Request Entity Too Large",
3179 /* 414 */ "Request-URI Too Large",
3180 /* 415 */ "Unsupported Media Type",
3181 /* 416 */ "Requested range not satisfiable",
3182 /* 417 */ "Expectation Failed"
3185 static const char *server_error_phrases[] = {
3186 /* 500 */ "Internal Server Error",
3187 /* 501 */ "Not Implemented",
3188 /* 502 */ "Bad Gateway",
3189 /* 503 */ "Service Unavailable",
3190 /* 504 */ "Gateway Time-out",
3191 /* 505 */ "HTTP Version not supported"
3194 struct response_class {
3196 size_t num_responses;
3197 const char **responses;
3201 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
3204 static const struct response_class response_classes[] = {
3205 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
3206 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
3207 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
3208 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
3209 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
3213 evhttp_response_phrase_internal(int code)
3215 int klass = code / 100 - 1;
3216 int subcode = code % 100;
3218 /* Unknown class - can't do any better here */
3219 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
3220 return "Unknown Status Class";
3222 /* Unknown sub-code, return class name at least */
3223 if (subcode >= (int) response_classes[klass].num_responses)
3224 return response_classes[klass].name;
3226 return response_classes[klass].responses[subcode];
3230 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
3232 req->kind = EVHTTP_RESPONSE;
3233 req->response_code = code;
3234 if (req->response_code_line != NULL)
3235 mm_free(req->response_code_line);
3237 reason = evhttp_response_phrase_internal(code);
3238 req->response_code_line = mm_strdup(reason);
3239 if (req->response_code_line == NULL) {
3240 event_warn("%s: strdup", __func__);
3241 /* XXX what else can we do? */
3246 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
3248 if (!req->major || !req->minor) {
3253 if (req->kind != EVHTTP_RESPONSE)
3254 evhttp_response_code_(req, 200, "OK");
3256 evhttp_clear_headers(req->output_headers);
3257 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
3258 evhttp_add_header(req->output_headers, "Connection", "close");
3260 evhttp_send(req, databuf);
3263 static const char uri_chars[256] = {
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, 1, 1, 0,
3268 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
3270 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3271 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
3272 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3273 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
3275 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3276 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3277 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3280 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3281 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3282 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3283 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3286 #define CHAR_IS_UNRESERVED(c) \
3287 (uri_chars[(unsigned char)(c)])
3290 * Helper functions to encode/decode a string for inclusion in a URI.
3291 * The returned string must be freed by the caller.
3294 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3296 struct evbuffer *buf = evbuffer_new();
3297 const char *p, *end;
3298 char *result = NULL;
3305 if (uri + len < uri) {
3311 size_t slen = strlen(uri);
3313 if (slen >= EV_SSIZE_MAX) {
3314 /* we don't want to mix signed and unsigned */
3318 if (uri + slen < uri) {
3325 for (p = uri; p < end; p++) {
3326 if (CHAR_IS_UNRESERVED(*p)) {
3327 evbuffer_add(buf, p, 1);
3328 } else if (*p == ' ' && space_as_plus) {
3329 evbuffer_add(buf, "+", 1);
3331 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3335 evbuffer_add(buf, "", 1); /* NUL-terminator. */
3336 result = mm_malloc(evbuffer_get_length(buf));
3339 evbuffer_remove(buf, result, evbuffer_get_length(buf));
3348 evhttp_encode_uri(const char *str)
3350 return evhttp_uriencode(str, -1, 0);
3354 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
3355 * If -1, when true we transform plus to space only after we've seen
3356 * a ?. -1 is deprecated.
3357 * @return the number of bytes written to 'ret'.
3360 evhttp_decode_uri_internal(
3361 const char *uri, size_t length, char *ret, int decode_plus_ctl)
3365 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3368 for (i = j = 0; i < length; i++) {
3371 if (decode_plus_ctl < 0)
3373 } else if (c == '+' && decode_plus) {
3375 } else if ((i + 2) < length && c == '%' &&
3376 EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3381 c = (char)strtol(tmp, NULL, 16);
3393 evhttp_decode_uri(const char *uri)
3397 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3398 event_warn("%s: malloc(%lu)", __func__,
3399 (unsigned long)(strlen(uri) + 1));
3403 evhttp_decode_uri_internal(uri, strlen(uri),
3404 ret, -1 /*always_decode_plus*/);
3410 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3415 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3416 event_warn("%s: malloc(%lu)", __func__,
3417 (unsigned long)(strlen(uri) + 1));
3421 n = evhttp_decode_uri_internal(uri, strlen(uri),
3422 ret, !!decode_plus/*always_decode_plus*/);
3425 EVUTIL_ASSERT(n >= 0);
3426 *size_out = (size_t)n;
3433 * Helper function to parse out arguments in a query.
3434 * The arguments are separated by key and value.
3438 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3439 int is_whole_uri, unsigned flags)
3444 const char *query_part;
3446 struct evhttp_uri *uri=NULL;
3448 TAILQ_INIT(headers);
3451 uri = evhttp_uri_parse(str);
3454 query_part = evhttp_uri_get_query(uri);
3459 /* No arguments - we are done */
3460 if (!query_part || !strlen(query_part)) {
3465 if ((line = mm_strdup(query_part)) == NULL) {
3466 event_warn("%s: strdup", __func__);
3470 p = argument = line;
3471 while (p != NULL && *p != '\0') {
3472 char *key, *value, *decoded_value;
3473 argument = strsep(&p, "&");
3476 key = strsep(&value, "=");
3477 if (flags & EVHTTP_URI_QUERY_NONCONFORMANT) {
3483 if (value == NULL || *key == '\0')
3487 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3488 event_warn("%s: mm_malloc", __func__);
3491 evhttp_decode_uri_internal(value, strlen(value),
3492 decoded_value, 1 /*always_decode_plus*/);
3493 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3494 if (flags & EVHTTP_URI_QUERY_LAST_VAL)
3495 evhttp_remove_header(headers, key);
3496 evhttp_add_header_internal(headers, key, decoded_value);
3497 mm_free(decoded_value);
3503 evhttp_clear_headers(headers);
3508 evhttp_uri_free(uri);
3513 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3515 return evhttp_parse_query_impl(uri, headers, 1, 0);
3518 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3520 return evhttp_parse_query_impl(uri, headers, 0, 0);
3523 evhttp_parse_query_str_flags(const char *uri, struct evkeyvalq *headers, unsigned flags)
3525 return evhttp_parse_query_impl(uri, headers, 0, flags);
3528 static struct evhttp_cb *
3529 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3531 struct evhttp_cb *cb;
3536 /* Test for different URLs */
3537 path = evhttp_uri_get_path(req->uri_elems);
3538 offset = strlen(path);
3539 if ((translated = mm_malloc(offset + 1)) == NULL)
3541 evhttp_decode_uri_internal(path, offset, translated,
3542 0 /* decode_plus */);
3544 TAILQ_FOREACH(cb, callbacks, next) {
3545 if (!strcmp(cb->what, translated)) {
3546 mm_free(translated);
3551 mm_free(translated);
3557 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3562 switch (c = *pattern++) {
3564 return *name == '\0';
3567 while (*name != '\0') {
3568 if (prefix_suffix_match(pattern, name,
3577 EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3587 Search the vhost hierarchy beginning with http for a server alias
3588 matching hostname. If a match is found, and outhttp is non-null,
3589 outhttp is set to the matching http object and 1 is returned.
3593 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3594 const char *hostname)
3596 struct evhttp_server_alias *alias;
3597 struct evhttp *vhost;
3599 TAILQ_FOREACH(alias, &http->aliases, next) {
3600 /* XXX Do we need to handle IP addresses? */
3601 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3608 /* XXX It might be good to avoid recursion here, but I don't
3609 see a way to do that w/o a list. */
3610 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3611 if (evhttp_find_alias(vhost, outhttp, hostname))
3619 Attempts to find the best http object to handle a request for a hostname.
3620 All aliases for the root http object and vhosts are searched for an exact
3621 match. Then, the vhost hierarchy is traversed again for a matching
3624 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3625 is set with the best matching http object. If there are no matches, the
3626 root http object is stored in outhttp and 0 is returned.
3630 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3631 const char *hostname)
3633 struct evhttp *vhost;
3634 struct evhttp *oldhttp;
3635 int match_found = 0;
3637 if (evhttp_find_alias(http, outhttp, hostname))
3642 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3643 if (prefix_suffix_match(vhost->vhost_pattern,
3644 hostname, 1 /* ignorecase */)) {
3650 } while (oldhttp != http);
3659 evhttp_handle_request(struct evhttp_request *req, void *arg)
3661 struct evhttp *http = arg;
3662 struct evhttp_cb *cb = NULL;
3663 const char *hostname;
3665 /* we have a new request on which the user needs to take action */
3668 bufferevent_disable(req->evcon->bufev, EV_READ);
3670 if (req->uri == NULL) {
3671 evhttp_send_error(req, req->response_code, NULL);
3675 if ((http->allowed_methods & req->type) == 0) {
3676 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3677 (unsigned)req->type, (unsigned)http->allowed_methods));
3678 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3682 /* handle potential virtual hosts */
3683 hostname = evhttp_request_get_host(req);
3684 if (hostname != NULL) {
3685 evhttp_find_vhost(http, &http, hostname);
3688 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3689 (*cb->cb)(req, cb->cbarg);
3693 /* Generic call back */
3695 (*http->gencb)(req, http->gencbarg);
3698 /* We need to send a 404 here */
3699 #define ERR_FORMAT "<html><head>" \
3700 "<title>404 Not Found</title>" \
3702 "<h1>Not Found</h1>" \
3703 "<p>The requested URL %s was not found on this server.</p>"\
3707 struct evbuffer *buf;
3709 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3710 evhttp_connection_free(req->evcon);
3714 if ((buf = evbuffer_new()) == NULL) {
3715 mm_free(escaped_html);
3716 evhttp_connection_free(req->evcon);
3720 evhttp_response_code_(req, HTTP_NOTFOUND, "Not Found");
3722 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3724 mm_free(escaped_html);
3726 evhttp_send_page_(req, buf);
3733 /* Listener callback when a connection arrives at a server. */
3735 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3737 struct evhttp *http = arg;
3739 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3743 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3745 struct evhttp_bound_socket *bound =
3746 evhttp_bind_socket_with_handle(http, address, port);
3752 struct evhttp_bound_socket *
3753 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3756 struct evhttp_bound_socket *bound;
3759 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3762 if (listen(fd, 128) == -1) {
3763 serrno = EVUTIL_SOCKET_ERROR();
3764 event_sock_warn(fd, "%s: listen", __func__);
3765 evutil_closesocket(fd);
3766 EVUTIL_SET_SOCKET_ERROR(serrno);
3770 bound = evhttp_accept_socket_with_handle(http, fd);
3772 if (bound != NULL) {
3773 event_debug(("Bound to port %d - Awaiting connections ... ",
3782 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3784 struct evhttp_bound_socket *bound =
3785 evhttp_accept_socket_with_handle(http, fd);
3792 evhttp_foreach_bound_socket(struct evhttp *http,
3793 evhttp_bound_socket_foreach_fn *function,
3796 struct evhttp_bound_socket *bound;
3798 TAILQ_FOREACH(bound, &http->sockets, next)
3799 function(bound, argument);
3802 struct evhttp_bound_socket *
3803 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3805 struct evhttp_bound_socket *bound;
3806 struct evconnlistener *listener;
3808 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3810 listener = evconnlistener_new(http->base, NULL, NULL,
3812 0, /* Backlog is '0' because we already said 'listen' */
3817 bound = evhttp_bind_listener(http, listener);
3819 evconnlistener_free(listener);
3825 struct evhttp_bound_socket *
3826 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3828 struct evhttp_bound_socket *bound;
3830 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3834 bound->listener = listener;
3835 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3837 evconnlistener_set_cb(listener, accept_socket_cb, http);
3842 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3844 return evconnlistener_get_fd(bound->listener);
3847 struct evconnlistener *
3848 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3850 return bound->listener;
3854 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3856 TAILQ_REMOVE(&http->sockets, bound, next);
3857 evconnlistener_free(bound->listener);
3861 static struct evhttp*
3862 evhttp_new_object(void)
3864 struct evhttp *http = NULL;
3866 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3867 event_warn("%s: calloc", __func__);
3871 evutil_timerclear(&http->timeout_read);
3872 evutil_timerclear(&http->timeout_write);
3874 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3875 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3876 evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
3877 evhttp_set_allowed_methods(http,
3884 TAILQ_INIT(&http->sockets);
3885 TAILQ_INIT(&http->callbacks);
3886 TAILQ_INIT(&http->connections);
3887 TAILQ_INIT(&http->virtualhosts);
3888 TAILQ_INIT(&http->aliases);
3894 evhttp_new(struct event_base *base)
3896 struct evhttp *http = NULL;
3898 http = evhttp_new_object();
3907 * Start a web server on the specified address and port.
3911 evhttp_start(const char *address, ev_uint16_t port)
3913 struct evhttp *http = NULL;
3915 http = evhttp_new_object();
3918 if (evhttp_bind_socket(http, address, port) == -1) {
3927 evhttp_free(struct evhttp* http)
3929 struct evhttp_cb *http_cb;
3930 struct evhttp_connection *evcon;
3931 struct evhttp_bound_socket *bound;
3932 struct evhttp* vhost;
3933 struct evhttp_server_alias *alias;
3935 /* Remove the accepting part */
3936 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3937 TAILQ_REMOVE(&http->sockets, bound, next);
3939 evconnlistener_free(bound->listener);
3944 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3945 /* evhttp_connection_free removes the connection */
3946 evhttp_connection_free(evcon);
3949 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3950 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3951 mm_free(http_cb->what);
3955 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3956 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3961 if (http->vhost_pattern != NULL)
3962 mm_free(http->vhost_pattern);
3964 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3965 TAILQ_REMOVE(&http->aliases, alias, next);
3966 mm_free(alias->alias);
3974 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3975 struct evhttp* vhost)
3977 /* a vhost can only be a vhost once and should not have bound sockets */
3978 if (vhost->vhost_pattern != NULL ||
3979 TAILQ_FIRST(&vhost->sockets) != NULL)
3982 vhost->vhost_pattern = mm_strdup(pattern);
3983 if (vhost->vhost_pattern == NULL)
3986 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3992 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3994 if (vhost->vhost_pattern == NULL)
3997 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3999 mm_free(vhost->vhost_pattern);
4000 vhost->vhost_pattern = NULL;
4006 evhttp_add_server_alias(struct evhttp *http, const char *alias)
4008 struct evhttp_server_alias *evalias;
4010 evalias = mm_calloc(1, sizeof(*evalias));
4014 evalias->alias = mm_strdup(alias);
4015 if (!evalias->alias) {
4020 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
4026 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
4028 struct evhttp_server_alias *evalias;
4030 TAILQ_FOREACH(evalias, &http->aliases, next) {
4031 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
4032 TAILQ_REMOVE(&http->aliases, evalias, next);
4033 mm_free(evalias->alias);
4043 evhttp_set_timeout(struct evhttp* http, int timeout)
4045 evhttp_set_timeout_(&http->timeout_read, timeout, -1);
4046 evhttp_set_timeout_(&http->timeout_write, timeout, -1);
4049 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
4051 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4052 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4055 evhttp_set_read_timeout_tv(struct evhttp* http, const struct timeval* tv)
4057 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4060 evhttp_set_write_timeout_tv(struct evhttp* http, const struct timeval* tv)
4062 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4065 int evhttp_set_flags(struct evhttp *http, int flags)
4067 int avail_flags = 0;
4068 avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
4070 if (flags & ~avail_flags)
4072 http->flags &= ~avail_flags;
4074 http->flags |= flags;
4080 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
4082 if (max_headers_size < 0)
4083 http->default_max_headers_size = EV_SIZE_MAX;
4085 http->default_max_headers_size = max_headers_size;
4089 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
4091 if (max_body_size < 0)
4092 http->default_max_body_size = EV_UINT64_MAX;
4094 http->default_max_body_size = max_body_size;
4098 evhttp_set_default_content_type(struct evhttp *http,
4099 const char *content_type) {
4100 http->default_content_type = content_type;
4104 evhttp_set_allowed_methods(struct evhttp* http, ev_uint32_t methods)
4106 http->allowed_methods = methods;
4110 evhttp_set_ext_method_cmp(struct evhttp *http, evhttp_ext_method_cb cmp)
4112 http->ext_method_cmp = cmp;
4116 evhttp_set_cb(struct evhttp *http, const char *uri,
4117 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4119 struct evhttp_cb *http_cb;
4121 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4122 if (strcmp(http_cb->what, uri) == 0)
4126 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
4127 event_warn("%s: calloc", __func__);
4131 http_cb->what = mm_strdup(uri);
4132 if (http_cb->what == NULL) {
4133 event_warn("%s: strdup", __func__);
4138 http_cb->cbarg = cbarg;
4140 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
4146 evhttp_del_cb(struct evhttp *http, const char *uri)
4148 struct evhttp_cb *http_cb;
4150 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4151 if (strcmp(http_cb->what, uri) == 0)
4154 if (http_cb == NULL)
4157 TAILQ_REMOVE(&http->callbacks, http_cb, next);
4158 mm_free(http_cb->what);
4165 evhttp_set_gencb(struct evhttp *http,
4166 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4169 http->gencbarg = cbarg;
4173 evhttp_set_bevcb(struct evhttp *http,
4174 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
4177 http->bevcbarg = cbarg;
4181 evhttp_set_newreqcb(struct evhttp *http,
4182 int (*cb)(struct evhttp_request *, void *), void *cbarg)
4184 http->newreqcb = cb;
4185 http->newreqcbarg = cbarg;
4189 * Request related functions
4192 struct evhttp_request *
4193 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
4195 struct evhttp_request *req = NULL;
4197 /* Allocate request structure */
4198 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
4199 event_warn("%s: calloc", __func__);
4203 req->headers_size = 0;
4206 req->kind = EVHTTP_RESPONSE;
4207 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4208 if (req->input_headers == NULL) {
4209 event_warn("%s: calloc", __func__);
4212 TAILQ_INIT(req->input_headers);
4214 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4215 if (req->output_headers == NULL) {
4216 event_warn("%s: calloc", __func__);
4219 TAILQ_INIT(req->output_headers);
4221 if ((req->input_buffer = evbuffer_new()) == NULL) {
4222 event_warn("%s: evbuffer_new", __func__);
4226 if ((req->output_buffer = evbuffer_new()) == NULL) {
4227 event_warn("%s: evbuffer_new", __func__);
4238 evhttp_request_free(req);
4243 evhttp_request_free(struct evhttp_request *req)
4245 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
4246 req->flags |= EVHTTP_REQ_NEEDS_FREE;
4250 if (req->remote_host != NULL)
4251 mm_free(req->remote_host);
4252 if (req->uri != NULL)
4254 if (req->uri_elems != NULL)
4255 evhttp_uri_free(req->uri_elems);
4256 if (req->response_code_line != NULL)
4257 mm_free(req->response_code_line);
4258 if (req->host_cache != NULL)
4259 mm_free(req->host_cache);
4261 evhttp_clear_headers(req->input_headers);
4262 mm_free(req->input_headers);
4264 evhttp_clear_headers(req->output_headers);
4265 mm_free(req->output_headers);
4267 if (req->input_buffer != NULL)
4268 evbuffer_free(req->input_buffer);
4270 if (req->output_buffer != NULL)
4271 evbuffer_free(req->output_buffer);
4277 evhttp_request_own(struct evhttp_request *req)
4279 req->flags |= EVHTTP_USER_OWNED;
4283 evhttp_request_is_owned(struct evhttp_request *req)
4285 return (req->flags & EVHTTP_USER_OWNED) != 0;
4288 struct evhttp_connection *
4289 evhttp_request_get_connection(struct evhttp_request *req)
4295 evhttp_connection_get_base(struct evhttp_connection *conn)
4301 evhttp_request_set_chunked_cb(struct evhttp_request *req,
4302 void (*cb)(struct evhttp_request *, void *))
4308 evhttp_request_set_header_cb(struct evhttp_request *req,
4309 int (*cb)(struct evhttp_request *, void *))
4311 req->header_cb = cb;
4315 evhttp_request_set_error_cb(struct evhttp_request *req,
4316 void (*cb)(enum evhttp_request_error, void *))
4322 evhttp_request_set_on_complete_cb(struct evhttp_request *req,
4323 void (*cb)(struct evhttp_request *, void *), void *cb_arg)
4325 req->on_complete_cb = cb;
4326 req->on_complete_cb_arg = cb_arg;
4330 * Allows for inspection of the request URI
4334 evhttp_request_get_uri(const struct evhttp_request *req) {
4335 if (req->uri == NULL)
4336 event_debug(("%s: request %p has no uri\n", __func__, req));
4340 const struct evhttp_uri *
4341 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4342 if (req->uri_elems == NULL)
4343 event_debug(("%s: request %p has no uri elems\n",
4345 return (req->uri_elems);
4349 evhttp_request_get_host(struct evhttp_request *req)
4351 const char *host = NULL;
4353 if (req->host_cache)
4354 return req->host_cache;
4357 host = evhttp_uri_get_host(req->uri_elems);
4358 if (!host && req->input_headers) {
4362 host = evhttp_find_header(req->input_headers, "Host");
4363 /* The Host: header may include a port. Remove it here
4364 to be consistent with uri_elems case above. */
4366 p = host + strlen(host) - 1;
4367 while (p > host && EVUTIL_ISDIGIT_(*p))
4369 if (p > host && *p == ':') {
4371 req->host_cache = mm_malloc(len + 1);
4372 if (!req->host_cache) {
4373 event_warn("%s: malloc", __func__);
4376 memcpy(req->host_cache, host, len);
4377 req->host_cache[len] = '\0';
4378 host = req->host_cache;
4386 enum evhttp_cmd_type
4387 evhttp_request_get_command(const struct evhttp_request *req) {
4392 evhttp_request_get_response_code(const struct evhttp_request *req)
4394 return req->response_code;
4398 evhttp_request_get_response_code_line(const struct evhttp_request *req)
4400 return req->response_code_line;
4403 /** Returns the input headers */
4404 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4406 return (req->input_headers);
4409 /** Returns the output headers */
4410 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4412 return (req->output_headers);
4415 /** Returns the input buffer */
4416 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4418 return (req->input_buffer);
4421 /** Returns the output buffer */
4422 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4424 return (req->output_buffer);
4429 * Takes a file descriptor to read a request from.
4430 * The callback is executed once the whole request has been read.
4433 static struct evhttp_connection*
4434 evhttp_get_request_connection(
4435 struct evhttp* http,
4436 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
4438 struct evhttp_connection *evcon;
4439 char *hostname = NULL, *portname = NULL;
4440 struct bufferevent* bev = NULL;
4442 #ifdef EVENT__HAVE_STRUCT_SOCKADDR_UN
4443 if (sa->sa_family == AF_UNIX) {
4444 struct sockaddr_un *sa_un = (struct sockaddr_un *)sa;
4445 sa_un->sun_path[0] = '\0';
4449 name_from_addr(sa, salen, &hostname, &portname);
4450 if (hostname == NULL || portname == NULL) {
4451 if (hostname) mm_free(hostname);
4452 if (portname) mm_free(portname);
4456 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4457 __func__, hostname, portname, EV_SOCK_ARG(fd)));
4459 /* we need a connection object to put the http request on */
4460 if (http->bevcb != NULL) {
4461 bev = (*http->bevcb)(http->base, http->bevcbarg);
4463 evcon = evhttp_connection_base_bufferevent_new(
4464 http->base, NULL, bev, hostname, atoi(portname));
4470 evcon->max_headers_size = http->default_max_headers_size;
4471 evcon->max_body_size = http->default_max_body_size;
4472 if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4473 evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4475 evcon->flags |= EVHTTP_CON_INCOMING;
4476 evcon->state = EVCON_READING_FIRSTLINE;
4480 if (bufferevent_setfd(evcon->bufev, fd))
4482 if (bufferevent_enable(evcon->bufev, EV_READ))
4484 if (bufferevent_disable(evcon->bufev, EV_WRITE))
4486 bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
4491 evhttp_connection_free(evcon);
4496 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4498 struct evhttp *http = evcon->http_server;
4499 struct evhttp_request *req;
4500 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4503 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4504 event_warn("%s: strdup", __func__);
4505 evhttp_request_free(req);
4508 req->remote_port = evcon->port;
4510 req->evcon = evcon; /* the request ends up owning the connection */
4511 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4513 /* We did not present the request to the user yet, so treat it
4514 * as if the user was done with the request. This allows us
4515 * to free the request on a persistent connection if the
4516 * client drops it without sending a request.
4519 req->kind = EVHTTP_REQUEST;
4521 if (http->newreqcb && http->newreqcb(req, http->newreqcbarg) == -1) {
4522 evhttp_request_free(req);
4526 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4528 evhttp_start_read_(evcon);
4534 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4535 struct sockaddr *sa, ev_socklen_t salen)
4537 struct evhttp_connection *evcon;
4539 evcon = evhttp_get_request_connection(http, fd, sa, salen);
4540 if (evcon == NULL) {
4541 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4542 __func__, EV_SOCK_ARG(fd));
4543 evutil_closesocket(fd);
4547 /* the timeout can be used by the server to close idle connections */
4548 if (evutil_timerisset(&http->timeout_read))
4549 evhttp_connection_set_read_timeout_tv(evcon, &http->timeout_read);
4550 if (evutil_timerisset(&http->timeout_write))
4551 evhttp_connection_set_write_timeout_tv(evcon, &http->timeout_write);
4554 * if we want to accept more than one request on a connection,
4555 * we need to know which http server it belongs to.
4557 evcon->http_server = http;
4558 evcon->ext_method_cmp = http->ext_method_cmp;
4559 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4561 if (evhttp_associate_new_request_with_connection(evcon) == -1)
4562 evhttp_connection_free(evcon);
4567 * Network helper functions that we do not want to export to the rest of
4572 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4573 char **phost, char **pport)
4575 char ntop[NI_MAXHOST];
4576 char strport[NI_MAXSERV];
4579 #ifdef EVENT__HAVE_GETNAMEINFO
4580 ni_result = getnameinfo(sa, salen,
4581 ntop, sizeof(ntop), strport, sizeof(strport),
4582 NI_NUMERICHOST|NI_NUMERICSERV);
4584 if (ni_result != 0) {
4586 /* Windows doesn't have an EAI_SYSTEM. */
4587 if (ni_result == EAI_SYSTEM)
4588 event_err(1, "getnameinfo failed");
4591 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4595 ni_result = fake_getnameinfo(sa, salen,
4596 ntop, sizeof(ntop), strport, sizeof(strport),
4597 NI_NUMERICHOST|NI_NUMERICSERV);
4602 *phost = mm_strdup(ntop);
4603 *pport = mm_strdup(strport);
4606 /* Create a non-blocking socket and bind it */
4607 /* todo: rename this function */
4608 static evutil_socket_t
4609 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
4616 /* Create listen socket */
4617 fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
4618 SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
4620 event_sock_warn(-1, "socket");
4624 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
4627 if (evutil_make_listen_socket_reuseable(fd) < 0)
4632 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
4640 serrno = EVUTIL_SOCKET_ERROR();
4641 evutil_closesocket(fd);
4642 EVUTIL_SET_SOCKET_ERROR(serrno);
4646 static struct evutil_addrinfo *
4647 make_addrinfo(const char *address, ev_uint16_t port)
4649 struct evutil_addrinfo *ai = NULL;
4651 struct evutil_addrinfo hints;
4652 char strport[NI_MAXSERV];
4655 memset(&hints, 0, sizeof(hints));
4656 hints.ai_family = AF_UNSPEC;
4657 hints.ai_socktype = SOCK_STREAM;
4658 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
4659 * types we don't have an interface to connect to. */
4660 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
4661 evutil_snprintf(strport, sizeof(strport), "%d", port);
4662 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
4664 if (ai_result == EVUTIL_EAI_SYSTEM)
4665 event_warn("getaddrinfo");
4667 event_warnx("getaddrinfo: %s",
4668 evutil_gai_strerror(ai_result));
4675 static evutil_socket_t
4676 bind_socket(const char *address, ev_uint16_t port, int reuse)
4679 struct evutil_addrinfo *aitop = NULL;
4681 /* just create an unbound socket */
4682 if (address == NULL && port == 0)
4683 return bind_socket_ai(NULL, 0);
4685 aitop = make_addrinfo(address, port);
4690 fd = bind_socket_ai(aitop, reuse);
4692 evutil_freeaddrinfo(aitop);
4699 char *scheme; /* scheme; e.g http, ftp etc */
4700 char *userinfo; /* userinfo (typically username:pass), or NULL */
4701 char *host; /* hostname, IP address, or NULL */
4702 int port; /* port, or zero */
4703 char *path; /* path, or "". */
4704 char *query; /* query, or NULL */
4705 char *fragment; /* fragment or NULL */
4709 evhttp_uri_new(void)
4711 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
4718 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
4723 /* Return true if the string starting at s and ending immediately before eos
4724 * is a valid URI scheme according to RFC3986
4727 scheme_ok(const char *s, const char *eos)
4729 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4730 EVUTIL_ASSERT(eos >= s);
4733 if (!EVUTIL_ISALPHA_(*s))
4736 if (! EVUTIL_ISALNUM_(*s) &&
4737 *s != '+' && *s != '-' && *s != '.')
4743 #define SUBDELIMS "!$&'()*+,;="
4745 /* Return true iff [s..eos) is a valid userinfo */
4747 userinfo_ok(const char *s, const char *eos)
4750 if (CHAR_IS_UNRESERVED(*s) ||
4751 strchr(SUBDELIMS, *s) ||
4754 else if (*s == '%' && s+2 < eos &&
4755 EVUTIL_ISXDIGIT_(s[1]) &&
4756 EVUTIL_ISXDIGIT_(s[2]))
4765 regname_ok(const char *s, const char *eos)
4767 while (s && s<eos) {
4768 if (CHAR_IS_UNRESERVED(*s) ||
4769 strchr(SUBDELIMS, *s))
4771 else if (*s == '%' &&
4772 EVUTIL_ISXDIGIT_(s[1]) &&
4773 EVUTIL_ISXDIGIT_(s[2]))
4782 parse_port(const char *s, const char *eos)
4786 if (! EVUTIL_ISDIGIT_(*s))
4788 portnum = (portnum * 10) + (*s - '0');
4791 if (portnum > 65535)
4798 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4800 bracket_addr_ok(const char *s, const char *eos)
4802 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4805 /* IPvFuture, or junk.
4806 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4808 s += 2; /* skip [v */
4810 if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
4812 while (s < eos && *s != '.') {
4813 if (EVUTIL_ISXDIGIT_(*s))
4822 if (CHAR_IS_UNRESERVED(*s) ||
4823 strchr(SUBDELIMS, *s) ||
4833 ev_ssize_t n_chars = eos-s-2;
4834 struct in6_addr in6;
4835 if (n_chars >= 64) /* way too long */
4837 memcpy(buf, s+1, n_chars);
4839 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4844 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4849 uri->host = mm_strdup("");
4850 if (uri->host == NULL) {
4851 event_warn("%s: strdup", __func__);
4857 /* Optionally, we start with "userinfo@" */
4859 cp = strchr(s, '@');
4860 if (cp && cp < eos) {
4861 if (! userinfo_ok(s,cp))
4864 uri->userinfo = mm_strdup(s);
4865 if (uri->userinfo == NULL) {
4866 event_warn("%s: strdup", __func__);
4872 /* Optionally, we end with ":port" */
4873 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
4875 if (port >= cp && *port == ':') {
4876 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4879 else if ((uri->port = parse_port(port+1, eos))<0)
4883 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4884 * an IP-Literal, or a reg-name */
4885 EVUTIL_ASSERT(eos >= cp);
4886 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4887 /* IPv6address, IP-Literal, or junk. */
4888 if (! bracket_addr_ok(cp, eos))
4891 /* Make sure the host part is ok. */
4892 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4895 uri->host = mm_malloc(eos-cp+1);
4896 if (uri->host == NULL) {
4897 event_warn("%s: malloc", __func__);
4900 memcpy(uri->host, cp, eos-cp);
4901 uri->host[eos-cp] = '\0';
4907 end_of_authority(char *cp)
4910 if (*cp == '?' || *cp == '#' || *cp == '/')
4923 /* Return the character after the longest prefix of 'cp' that matches...
4924 * *pchar / "/" if allow_qchars is false, or
4925 * *(pchar / "/" / "?") if allow_qchars is true.
4928 end_of_path(char *cp, enum uri_part part, unsigned flags)
4930 if (flags & EVHTTP_URI_NONCONFORMANT) {
4931 /* If NONCONFORMANT:
4932 * Path is everything up to a # or ? or nul.
4933 * Query is everything up a # or nul
4934 * Fragment is everything up to a nul.
4938 while (*cp && *cp != '#' && *cp != '?')
4942 while (*cp && *cp != '#')
4953 if (CHAR_IS_UNRESERVED(*cp) ||
4954 strchr(SUBDELIMS, *cp) ||
4955 *cp == ':' || *cp == '@' || *cp == '/')
4957 else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
4958 EVUTIL_ISXDIGIT_(cp[2]))
4960 else if (*cp == '?' && part != PART_PATH)
4969 path_matches_noscheme(const char *cp)
4974 else if (*cp == '/')
4982 evhttp_uri_parse(const char *source_uri)
4984 return evhttp_uri_parse_with_flags(source_uri, 0);
4988 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4990 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4991 char *path = NULL, *fragment = NULL;
4992 int got_authority = 0;
4994 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4996 event_warn("%s: calloc", __func__);
5002 readbuf = mm_strdup(source_uri);
5003 if (readbuf == NULL) {
5004 event_warn("%s: strdup", __func__);
5011 /* We try to follow RFC3986 here as much as we can, and match
5014 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
5016 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
5020 token = strchr(readp, ':');
5021 if (token && scheme_ok(readp,token)) {
5023 uri->scheme = mm_strdup(readp);
5024 if (uri->scheme == NULL) {
5025 event_warn("%s: strdup", __func__);
5028 readp = token+1; /* eat : */
5031 /* 2. Optionally, "//" then an 'authority' part. */
5032 if (readp[0]=='/' && readp[1] == '/') {
5036 path = end_of_authority(readp);
5037 if (parse_authority(uri, authority, path) < 0)
5043 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
5046 readp = end_of_path(path, PART_PATH, flags);
5049 if (*readp == '?') {
5053 readp = end_of_path(readp, PART_QUERY, flags);
5056 if (*readp == '#') {
5060 readp = end_of_path(readp, PART_FRAGMENT, flags);
5062 if (*readp != '\0') {
5066 /* These next two cases may be unreachable; I'm leaving them
5067 * in to be defensive. */
5068 /* If you didn't get an authority, the path can't begin with "//" */
5069 if (!got_authority && path[0]=='/' && path[1]=='/')
5071 /* If you did get an authority, the path must begin with "/" or be
5073 if (got_authority && path[0] != '/' && path[0] != '\0')
5075 /* (End of maybe-unreachable cases) */
5077 /* If there was no scheme, the first part of the path (if any) must
5078 * have no colon in it. */
5079 if (! uri->scheme && !path_matches_noscheme(path))
5082 EVUTIL_ASSERT(path);
5083 uri->path = mm_strdup(path);
5084 if (uri->path == NULL) {
5085 event_warn("%s: strdup", __func__);
5090 uri->query = mm_strdup(query);
5091 if (uri->query == NULL) {
5092 event_warn("%s: strdup", __func__);
5097 uri->fragment = mm_strdup(fragment);
5098 if (uri->fragment == NULL) {
5099 event_warn("%s: strdup", __func__);
5109 evhttp_uri_free(uri);
5115 static struct evhttp_uri *
5116 evhttp_uri_parse_authority(char *source_uri)
5118 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
5122 event_warn("%s: calloc", __func__);
5128 end = end_of_authority(source_uri);
5129 if (parse_authority(uri, source_uri, end) < 0)
5132 uri->path = mm_strdup("");
5133 if (uri->path == NULL) {
5134 event_warn("%s: strdup", __func__);
5141 evhttp_uri_free(uri);
5146 evhttp_uri_free(struct evhttp_uri *uri)
5148 #define URI_FREE_STR_(f) \
5153 URI_FREE_STR_(scheme);
5154 URI_FREE_STR_(userinfo);
5155 URI_FREE_STR_(host);
5156 URI_FREE_STR_(path);
5157 URI_FREE_STR_(query);
5158 URI_FREE_STR_(fragment);
5161 #undef URI_FREE_STR_
5165 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
5167 struct evbuffer *tmp = 0;
5168 size_t joined_size = 0;
5169 char *output = NULL;
5171 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
5173 if (!uri || !buf || !limit)
5176 tmp = evbuffer_new();
5182 evbuffer_add(tmp, ":", 1);
5185 evbuffer_add(tmp, "//", 2);
5187 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
5190 evbuffer_add_printf(tmp,":%d", uri->port);
5192 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
5200 evbuffer_add(tmp, "?", 1);
5204 if (uri->fragment) {
5205 evbuffer_add(tmp, "#", 1);
5209 evbuffer_add(tmp, "\0", 1); /* NUL */
5211 joined_size = evbuffer_get_length(tmp);
5213 if (joined_size > limit) {
5214 /* It doesn't fit. */
5218 evbuffer_remove(tmp, buf, joined_size);
5229 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
5234 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
5236 return uri->userinfo;
5239 evhttp_uri_get_host(const struct evhttp_uri *uri)
5244 evhttp_uri_get_port(const struct evhttp_uri *uri)
5249 evhttp_uri_get_path(const struct evhttp_uri *uri)
5254 evhttp_uri_get_query(const struct evhttp_uri *uri)
5259 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
5261 return uri->fragment;
5264 #define URI_SET_STR_(f) do { \
5268 if ((uri->f = mm_strdup(f)) == NULL) { \
5269 event_warn("%s: strdup()", __func__); \
5278 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
5280 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
5283 URI_SET_STR_(scheme);
5287 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
5289 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
5291 URI_SET_STR_(userinfo);
5295 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
5298 if (host[0] == '[') {
5299 if (! bracket_addr_ok(host, host+strlen(host)))
5302 if (! regname_ok(host, host+strlen(host)))
5311 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
5318 #define end_of_cpath(cp,p,f) \
5319 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
5322 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
5324 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
5331 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
5333 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
5335 URI_SET_STR_(query);
5339 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
5341 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
5343 URI_SET_STR_(fragment);