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 create_bind_socket_nonblock(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_CONNECT &&
421 req->type != EVHTTP_REQ_HEAD);
424 /** Helper: called after we've added some data to an evcon's bufferevent's
425 * output buffer. Sets the evconn's writing-is-done callback, and puts
426 * the bufferevent into writing mode.
429 evhttp_write_buffer(struct evhttp_connection *evcon,
430 void (*cb)(struct evhttp_connection *, void *), void *arg)
432 event_debug(("%s: preparing to write buffer\n", __func__));
438 /* Disable the read callback: we don't actually care about data;
439 * we only care about close detection. (We don't disable reading --
440 * EV_READ, since we *do* want to learn about any close events.) */
441 bufferevent_setcb(evcon->bufev,
447 bufferevent_enable(evcon->bufev, EV_READ|EV_WRITE);
451 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
453 bufferevent_disable(evcon->bufev, EV_WRITE);
457 evhttp_send_continue(struct evhttp_connection *evcon,
458 struct evhttp_request *req)
460 bufferevent_enable(evcon->bufev, EV_WRITE);
461 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
462 "HTTP/%d.%d 100 Continue\r\n\r\n",
463 req->major, req->minor);
464 evcon->cb = evhttp_send_continue_done;
465 evcon->cb_arg = NULL;
466 bufferevent_setcb(evcon->bufev,
473 /** Helper: returns true iff evconn is in any connected state. */
475 evhttp_connected(struct evhttp_connection *evcon)
477 switch (evcon->state) {
478 case EVCON_DISCONNECTED:
479 case EVCON_CONNECTING:
482 case EVCON_READING_FIRSTLINE:
483 case EVCON_READING_HEADERS:
484 case EVCON_READING_BODY:
485 case EVCON_READING_TRAILER:
492 /* Create the headers needed for an outgoing HTTP request, adds them to
493 * the request's header list, and writes the request line to the
494 * connection's output buffer.
497 evhttp_make_header_request(struct evhttp_connection *evcon,
498 struct evhttp_request *req)
503 evhttp_remove_header(req->output_headers, "Proxy-Connection");
505 /* Generate request line */
506 if (!(method = evhttp_method_(evcon, req->type, &flags))) {
510 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
511 "%s %s HTTP/%d.%d\r\n",
512 method, req->uri, req->major, req->minor);
514 /* Add the content length on a request if missing
515 * Always add it for POST and PUT requests as clients expect it */
516 if ((flags & EVHTTP_METHOD_HAS_BODY) &&
517 (evbuffer_get_length(req->output_buffer) > 0 ||
518 req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
519 evhttp_find_header(req->output_headers, "Content-Length") == NULL) {
521 evutil_snprintf(size, sizeof(size), EV_SIZE_FMT,
522 EV_SIZE_ARG(evbuffer_get_length(req->output_buffer)));
523 evhttp_add_header(req->output_headers, "Content-Length", size);
527 /** Return true if the list of headers in 'headers', intepreted with respect
528 * to flags, means that we should send a "connection: close" when the request
531 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
533 if (flags & EVHTTP_PROXY_REQUEST) {
534 /* proxy connection */
535 const char *connection = evhttp_find_header(headers, "Proxy-Connection");
536 return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
538 const char *connection = evhttp_find_header(headers, "Connection");
539 return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
543 evhttp_is_request_connection_close(struct evhttp_request *req)
545 if (req->type == EVHTTP_REQ_CONNECT)
549 evhttp_is_connection_close(req->flags, req->input_headers) ||
550 evhttp_is_connection_close(req->flags, req->output_headers);
553 /* Return true iff 'headers' contains 'Connection: keep-alive' */
555 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
557 const char *connection = evhttp_find_header(headers, "Connection");
558 return (connection != NULL
559 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
562 /* Add a correct "Date" header to headers, unless it already has one. */
564 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
566 if (evhttp_find_header(headers, "Date") == NULL) {
568 if (sizeof(date) - evutil_date_rfc1123(date, sizeof(date), NULL) > 0) {
569 evhttp_add_header(headers, "Date", date);
574 /* Add a "Content-Length" header with value 'content_length' to headers,
575 * unless it already has a content-length or transfer-encoding header. */
577 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
578 size_t content_length)
580 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
581 evhttp_find_header(headers, "Content-Length") == NULL) {
583 evutil_snprintf(len, sizeof(len), EV_SIZE_FMT,
584 EV_SIZE_ARG(content_length));
585 evhttp_add_header(headers, "Content-Length", len);
590 * Create the headers needed for an HTTP reply in req->output_headers,
591 * and write the first HTTP response for req line to evcon.
594 evhttp_make_header_response(struct evhttp_connection *evcon,
595 struct evhttp_request *req)
597 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
598 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
599 "HTTP/%d.%d %d %s\r\n",
600 req->major, req->minor, req->response_code,
601 req->response_code_line);
603 if (req->major == 1) {
605 evhttp_maybe_add_date_header(req->output_headers);
608 * if the protocol is 1.0; and the connection was keep-alive
609 * we need to add a keep-alive header, too.
611 if (req->minor == 0 && is_keepalive)
612 evhttp_add_header(req->output_headers,
613 "Connection", "keep-alive");
615 if ((req->minor >= 1 || is_keepalive) &&
616 evhttp_response_needs_body(req)) {
618 * we need to add the content length if the
619 * user did not give it, this is required for
620 * persistent connections to work.
622 evhttp_maybe_add_content_length_header(
624 evbuffer_get_length(req->output_buffer));
628 /* Potentially add headers for unidentified content. */
629 if (evhttp_response_needs_body(req)) {
630 if (evhttp_find_header(req->output_headers,
631 "Content-Type") == NULL
632 && evcon->http_server->default_content_type) {
633 evhttp_add_header(req->output_headers,
635 evcon->http_server->default_content_type);
639 /* if the request asked for a close, we send a close, too */
640 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
641 evhttp_remove_header(req->output_headers, "Connection");
642 if (!(req->flags & EVHTTP_PROXY_REQUEST))
643 evhttp_add_header(req->output_headers, "Connection", "close");
644 evhttp_remove_header(req->output_headers, "Proxy-Connection");
648 enum expect { NO, CONTINUE, OTHER };
649 static enum expect evhttp_have_expect(struct evhttp_request *req, int input)
652 struct evkeyvalq *h = input ? req->input_headers : req->output_headers;
654 if (!(req->kind == EVHTTP_REQUEST) || !REQ_VERSION_ATLEAST(req, 1, 1))
657 expect = evhttp_find_header(h, "Expect");
661 return !evutil_ascii_strcasecmp(expect, "100-continue") ? CONTINUE : OTHER;
665 /** Generate all headers appropriate for sending the http request in req (or
666 * the response, if we're sending a response), and write them to evcon's
667 * bufferevent. Also writes all data from req->output_buffer */
669 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
671 struct evkeyval *header;
672 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
675 * Depending if this is a HTTP request or response, we might need to
676 * add some new headers or remove existing headers.
678 if (req->kind == EVHTTP_REQUEST) {
679 evhttp_make_header_request(evcon, req);
681 evhttp_make_header_response(evcon, req);
684 TAILQ_FOREACH(header, req->output_headers, next) {
685 evbuffer_add_printf(output, "%s: %s\r\n",
686 header->key, header->value);
688 evbuffer_add(output, "\r\n", 2);
690 if (evhttp_have_expect(req, 0) != CONTINUE &&
691 evbuffer_get_length(req->output_buffer)) {
693 * For a request, we add the POST data, for a reply, this
694 * is the regular data.
696 evbuffer_add_buffer(output, req->output_buffer);
701 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
702 ev_ssize_t new_max_headers_size)
704 if (new_max_headers_size<0)
705 evcon->max_headers_size = EV_SIZE_MAX;
707 evcon->max_headers_size = new_max_headers_size;
710 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
711 ev_ssize_t new_max_body_size)
713 if (new_max_body_size<0)
714 evcon->max_body_size = EV_UINT64_MAX;
716 evcon->max_body_size = new_max_body_size;
720 evhttp_connection_incoming_fail(struct evhttp_request *req,
721 enum evhttp_request_error error)
724 case EVREQ_HTTP_DATA_TOO_LONG:
725 req->response_code = HTTP_ENTITYTOOLARGE;
728 req->response_code = HTTP_BADREQUEST;
732 case EVREQ_HTTP_TIMEOUT:
735 * these are cases in which we probably should just
736 * close the connection and not send a reply. this
737 * case may happen when a browser keeps a persistent
738 * connection open and we timeout on the read. when
739 * the request is still being used for sending, we
740 * need to disassociated it from the connection here.
742 if (!req->userdone) {
743 /* remove it so that it will not be freed */
744 TAILQ_REMOVE(&req->evcon->requests, req, next);
745 /* indicate that this request no longer has a
751 case EVREQ_HTTP_INVALID_HEADER:
752 case EVREQ_HTTP_BUFFER_ERROR:
753 case EVREQ_HTTP_REQUEST_CANCEL:
754 case EVREQ_HTTP_DATA_TOO_LONG:
755 default: /* xxx: probably should just error on default */
756 /* the callback looks at the uri to determine errors */
761 if (req->uri_elems) {
762 evhttp_uri_free(req->uri_elems);
763 req->uri_elems = NULL;
767 * the callback needs to send a reply, once the reply has
768 * been send, the connection should get freed.
770 (*req->cb)(req, req->cb_arg);
776 /* Free connection ownership of which can be acquired by user using
777 * evhttp_request_own(). */
779 evhttp_request_free_auto(struct evhttp_request *req)
781 if (!(req->flags & EVHTTP_USER_OWNED))
782 evhttp_request_free(req);
786 evhttp_request_free_(struct evhttp_connection *evcon, struct evhttp_request *req)
788 TAILQ_REMOVE(&evcon->requests, req, next);
789 evhttp_request_free_auto(req);
793 evhttp_set_timeout_tv_(struct timeval *tv, const struct timeval *timeout, int def)
795 if (timeout == NULL && def != -1) {
804 evutil_timerclear(tv);
808 evhttp_set_timeout_(struct timeval *tv, int timeout, int def)
815 evutil_timerclear(tv);
817 struct timeval timeout_tv;
818 timeout_tv.tv_sec = timeout;
819 timeout_tv.tv_usec = 0;
824 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
825 * given in error. If it's an outgoing connection, reset the connection,
826 * retry any pending requests, and inform the user. If it's incoming,
827 * delegates to evhttp_connection_incoming_fail(). */
829 evhttp_connection_fail_(struct evhttp_connection *evcon,
830 enum evhttp_request_error error)
832 const int errsave = EVUTIL_SOCKET_ERROR();
833 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
834 void (*cb)(struct evhttp_request *, void *);
836 void (*error_cb)(enum evhttp_request_error, void *);
838 EVUTIL_ASSERT(req != NULL);
840 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
842 if (evcon->flags & EVHTTP_CON_INCOMING) {
844 * for incoming requests, there are two different
845 * failure cases. it's either a network level error
846 * or an http layer error. for problems on the network
847 * layer like timeouts we just drop the connections.
848 * For HTTP problems, we might have to send back a
849 * reply before the connection can be freed.
851 if (evhttp_connection_incoming_fail(req, error) == -1)
852 evhttp_connection_free(evcon);
856 error_cb = req->error_cb;
857 error_cb_arg = req->cb_arg;
858 /* when the request was canceled, the callback is not executed */
859 if (error != EVREQ_HTTP_REQUEST_CANCEL) {
860 /* save the callback for later; the cb might free our object */
862 cb_arg = req->cb_arg;
868 /* do not fail all requests; the next request is going to get
869 * send over a new connection. when a user cancels a request,
870 * all other pending requests should be processed as normal
872 evhttp_request_free_(evcon, req);
874 /* reset the connection */
875 evhttp_connection_reset_(evcon);
877 /* We are trying the next request that was queued on us */
878 if (TAILQ_FIRST(&evcon->requests) != NULL)
879 evhttp_connection_connect_(evcon);
881 /* The call to evhttp_connection_reset_ overwrote errno.
882 * Let's restore the original errno, so that the user's
883 * callback can have a better idea of what the error was.
885 EVUTIL_SET_SOCKET_ERROR(errsave);
887 /* inform the user */
888 if (error_cb != NULL)
889 error_cb(error, error_cb_arg);
894 /* Bufferevent callback: invoked when any data has been written from an
895 * http connection's bufferevent */
897 evhttp_write_cb(struct bufferevent *bufev, void *arg)
899 struct evhttp_connection *evcon = arg;
901 /* Activate our call back */
902 if (evcon->cb != NULL)
903 (*evcon->cb)(evcon, evcon->cb_arg);
907 * Advance the connection state.
908 * - If this is an outgoing connection, we've just processed the response;
909 * idle or close the connection.
910 * - If this is an incoming connection, we've just processed the request;
914 evhttp_connection_done(struct evhttp_connection *evcon)
916 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
917 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
921 /* idle or close the connection */
922 int need_close = evhttp_is_request_connection_close(req);
923 TAILQ_REMOVE(&evcon->requests, req, next);
926 evcon->state = EVCON_IDLE;
928 /* check if we got asked to close the connection */
930 evhttp_connection_reset_(evcon);
932 if (TAILQ_FIRST(&evcon->requests) != NULL) {
934 * We have more requests; reset the connection
935 * and deal with the next request.
937 if (!evhttp_connected(evcon))
938 evhttp_connection_connect_(evcon);
940 evhttp_request_dispatch(evcon);
941 } else if (!need_close) {
943 * The connection is going to be persistent, but we
944 * need to detect if the other side closes it.
946 evhttp_connection_start_detectclose(evcon);
947 } else if ((evcon->flags & EVHTTP_CON_AUTOFREE)) {
949 * If we have no more requests that need completion
950 * and we're not waiting for the connection to close
956 * incoming connection - we need to leave the request on the
957 * connection so that we can reply to it.
959 evcon->state = EVCON_WRITING;
962 /* notify the user of the request */
963 (*req->cb)(req, req->cb_arg);
965 /* if this was an outgoing request, we own and it's done. so free it. */
967 evhttp_request_free_auto(req);
970 /* If this was the last request of an outgoing connection and we're
971 * not waiting to receive a connection close event and we want to
972 * automatically free the connection. We check to ensure our request
973 * list is empty one last time just in case our callback added a
976 if (free_evcon && TAILQ_FIRST(&evcon->requests) == NULL) {
977 evhttp_connection_free(evcon);
982 * Handles reading from a chunked request.
983 * return ALL_DATA_READ:
984 * all data has been read
985 * return MORE_DATA_EXPECTED:
986 * more data is expected
987 * return DATA_CORRUPTED:
989 * return REQUEST_CANCELED:
990 * request was canceled by the user calling evhttp_cancel_request
991 * return DATA_TOO_LONG:
992 * ran over the maximum limit
995 static enum message_read_status
996 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
998 if (req == NULL || buf == NULL) {
999 return DATA_CORRUPTED;
1005 if ((buflen = evbuffer_get_length(buf)) == 0) {
1009 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
1010 * check for overflow conditions */
1011 if (buflen > EV_SSIZE_MAX) {
1012 return DATA_CORRUPTED;
1015 if (req->ntoread < 0) {
1016 /* Read chunk size */
1018 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
1023 /* the last chunk is on a new line? */
1024 if (strlen(p) == 0) {
1028 ntoread = evutil_strtoll(p, &endp, 16);
1029 error = (*p == '\0' ||
1030 (*endp != '\0' && *endp != ' ') ||
1034 /* could not get chunk size */
1035 return (DATA_CORRUPTED);
1038 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
1039 if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
1040 return DATA_CORRUPTED;
1043 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
1044 /* failed body length test */
1045 event_debug(("Request body is too long"));
1046 return (DATA_TOO_LONG);
1049 req->body_size += (size_t)ntoread;
1050 req->ntoread = ntoread;
1051 if (req->ntoread == 0) {
1053 return (ALL_DATA_READ);
1058 /* req->ntoread is signed int64, len is ssize_t, based on arch,
1059 * ssize_t could only be 32b, check for these conditions */
1060 if (req->ntoread > EV_SSIZE_MAX) {
1061 return DATA_CORRUPTED;
1064 /* don't have enough to complete a chunk; wait for more */
1065 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
1066 return (MORE_DATA_EXPECTED);
1068 /* Completed chunk */
1069 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
1071 if (req->chunk_cb != NULL) {
1072 req->flags |= EVHTTP_REQ_DEFER_FREE;
1073 (*req->chunk_cb)(req, req->cb_arg);
1074 evbuffer_drain(req->input_buffer,
1075 evbuffer_get_length(req->input_buffer));
1076 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1077 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1078 return (REQUEST_CANCELED);
1083 return (MORE_DATA_EXPECTED);
1087 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
1089 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1091 switch (evhttp_parse_headers_(req, buf)) {
1092 case DATA_CORRUPTED:
1094 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1097 bufferevent_disable(evcon->bufev, EV_READ);
1098 evhttp_connection_done(evcon);
1100 case MORE_DATA_EXPECTED:
1101 case REQUEST_CANCELED: /* ??? */
1108 evhttp_lingering_close(struct evhttp_connection *evcon,
1109 struct evhttp_request *req)
1111 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1113 size_t n = evbuffer_get_length(buf);
1114 if (n > (size_t) req->ntoread)
1115 n = (size_t) req->ntoread;
1117 req->body_size += n;
1119 event_debug(("Request body is too long, left " EV_I64_FMT,
1120 EV_I64_ARG(req->ntoread)));
1122 evbuffer_drain(buf, n);
1124 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1127 evhttp_lingering_fail(struct evhttp_connection *evcon,
1128 struct evhttp_request *req)
1130 if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE)
1131 evhttp_lingering_close(evcon, req);
1133 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1137 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1139 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1142 switch (evhttp_handle_chunked_read(req, buf)) {
1144 /* finished last chunk */
1145 evcon->state = EVCON_READING_TRAILER;
1146 evhttp_read_trailer(evcon, req);
1148 case DATA_CORRUPTED:
1150 /* corrupted data */
1151 evhttp_connection_fail_(evcon,
1152 EVREQ_HTTP_DATA_TOO_LONG);
1154 case REQUEST_CANCELED:
1155 /* request canceled */
1156 evhttp_request_free_auto(req);
1158 case MORE_DATA_EXPECTED:
1162 } else if (req->ntoread < 0) {
1163 /* Read until connection close. */
1164 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
1165 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
1169 req->body_size += evbuffer_get_length(buf);
1170 evbuffer_add_buffer(req->input_buffer, buf);
1171 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
1172 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
1173 /* We've postponed moving the data until now, but we're
1174 * about to use it. */
1175 size_t n = evbuffer_get_length(buf);
1177 if (n > (size_t) req->ntoread)
1178 n = (size_t) req->ntoread;
1180 req->body_size += n;
1181 evbuffer_remove_buffer(buf, req->input_buffer, n);
1184 if (req->body_size > req->evcon->max_body_size ||
1185 (!req->chunked && req->ntoread >= 0 &&
1186 (size_t)req->ntoread > req->evcon->max_body_size)) {
1187 /* XXX: The above casted comparison must checked for overflow */
1188 /* failed body length test */
1190 evhttp_lingering_fail(evcon, req);
1194 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1195 req->flags |= EVHTTP_REQ_DEFER_FREE;
1196 (*req->chunk_cb)(req, req->cb_arg);
1197 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1198 evbuffer_drain(req->input_buffer,
1199 evbuffer_get_length(req->input_buffer));
1200 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1201 evhttp_request_free_auto(req);
1206 if (!req->ntoread) {
1207 bufferevent_disable(evcon->bufev, EV_READ);
1208 /* Completed content length */
1209 evhttp_connection_done(evcon);
1214 #define get_deferred_queue(evcon) \
1218 * Gets called when more data becomes available
1222 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1224 struct evhttp_connection *evcon = arg;
1225 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1227 /* Cancel if it's pending. */
1228 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1229 &evcon->read_more_deferred_cb);
1231 switch (evcon->state) {
1232 case EVCON_READING_FIRSTLINE:
1233 evhttp_read_firstline(evcon, req);
1234 /* note the request may have been freed in
1235 * evhttp_read_body */
1237 case EVCON_READING_HEADERS:
1238 evhttp_read_header(evcon, req);
1239 /* note the request may have been freed in
1240 * evhttp_read_body */
1242 case EVCON_READING_BODY:
1243 evhttp_read_body(evcon, req);
1244 /* note the request may have been freed in
1245 * evhttp_read_body */
1247 case EVCON_READING_TRAILER:
1248 evhttp_read_trailer(evcon, req);
1253 struct evbuffer *input;
1256 input = bufferevent_get_input(evcon->bufev);
1257 total_len = evbuffer_get_length(input);
1258 event_debug(("%s: read "EV_SIZE_FMT
1259 " bytes in EVCON_IDLE state,"
1260 " resetting connection",
1261 __func__, EV_SIZE_ARG(total_len)));
1264 evhttp_connection_reset_(evcon);
1267 case EVCON_DISCONNECTED:
1268 case EVCON_CONNECTING:
1271 event_errx(1, "%s: illegal connection state %d",
1272 __func__, evcon->state);
1277 evhttp_deferred_read_cb(struct event_callback *cb, void *data)
1279 struct evhttp_connection *evcon = data;
1280 struct bufferevent *bev = evcon->bufev;
1282 (bev->readcb)(evcon->bufev, evcon);
1286 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1288 /* This is after writing the request to the server */
1289 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1290 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
1291 EVUTIL_ASSERT(req != NULL);
1293 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1295 /* We need to wait until we've written all of our output data before we can
1297 if (evbuffer_get_length(output) > 0)
1300 /* We are done writing our header and are now expecting the response */
1301 req->kind = EVHTTP_RESPONSE;
1303 evhttp_start_read_(evcon);
1307 * Clean up a connection object
1311 evhttp_connection_free(struct evhttp_connection *evcon)
1313 struct evhttp_request *req;
1316 /* notify interested parties that this connection is going down */
1317 if (evcon->fd != -1) {
1318 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1319 (*evcon->closecb)(evcon, evcon->closecb_arg);
1322 /* remove all requests that might be queued on this
1323 * connection. for server connections, this should be empty.
1324 * because it gets dequeued either in evhttp_connection_done or
1325 * evhttp_connection_fail_.
1327 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1328 evhttp_request_free_(evcon, req);
1331 if (evcon->http_server != NULL) {
1332 struct evhttp *http = evcon->http_server;
1333 TAILQ_REMOVE(&http->connections, evcon, next);
1336 if (event_initialized(&evcon->retry_ev)) {
1337 event_del(&evcon->retry_ev);
1338 event_debug_unassign(&evcon->retry_ev);
1341 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1342 &evcon->read_more_deferred_cb);
1344 if (evcon->bufev != NULL) {
1346 !(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE);
1347 if (evcon->fd == -1)
1348 evcon->fd = bufferevent_getfd(evcon->bufev);
1350 bufferevent_free(evcon->bufev);
1353 if (evcon->fd != -1) {
1354 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1356 evutil_closesocket(evcon->fd);
1359 if (evcon->bind_address != NULL)
1360 mm_free(evcon->bind_address);
1362 if (evcon->address != NULL)
1363 mm_free(evcon->address);
1369 evhttp_connection_free_on_completion(struct evhttp_connection *evcon) {
1370 evcon->flags |= EVHTTP_CON_AUTOFREE;
1374 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1375 const char *address)
1377 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1378 if (evcon->bind_address)
1379 mm_free(evcon->bind_address);
1380 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1381 event_warn("%s: strdup", __func__);
1385 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1388 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1389 evcon->bind_port = port;
1393 evhttp_request_dispatch(struct evhttp_connection* evcon)
1395 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1397 /* this should not usually happy but it's possible */
1401 EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST);
1403 /* delete possible close detection events */
1404 evhttp_connection_stop_detectclose(evcon);
1406 /* we assume that the connection is connected already */
1407 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1409 evcon->state = EVCON_WRITING;
1411 /* Create the header from the store arguments */
1412 evhttp_make_header(evcon, req);
1414 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1417 /* Reset our connection state: disables reading/writing, closes our fd (if
1418 * any), clears out buffers, and puts us in state DISCONNECTED. */
1420 evhttp_connection_reset_(struct evhttp_connection *evcon)
1422 struct evbuffer *tmp;
1425 bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL);
1427 /* XXXX This is not actually an optimal fix. Instead we ought to have
1428 an API for "stop connecting", or use bufferevent_setfd to turn off
1429 connecting. But for Libevent 2.0, this seems like a minimal change
1430 least likely to disrupt the rest of the bufferevent and http code.
1432 Why is this here? If the fd is set in the bufferevent, and the
1433 bufferevent is connecting, then you can't actually stop the
1434 bufferevent from trying to connect with bufferevent_disable(). The
1435 connect will never trigger, since we close the fd, but the timeout
1436 might. That caused an assertion failure in evhttp_connection_fail_.
1438 bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE);
1440 if (evcon->fd == -1)
1441 evcon->fd = bufferevent_getfd(evcon->bufev);
1443 if (evcon->fd != -1) {
1444 /* inform interested parties about connection close */
1445 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1446 (*evcon->closecb)(evcon, evcon->closecb_arg);
1448 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1449 evutil_closesocket(evcon->fd);
1452 err = bufferevent_setfd(evcon->bufev, -1);
1453 EVUTIL_ASSERT(!err && "setfd");
1455 /* we need to clean up any buffered data */
1456 tmp = bufferevent_get_output(evcon->bufev);
1457 err = evbuffer_drain(tmp, -1);
1458 EVUTIL_ASSERT(!err && "drain output");
1459 tmp = bufferevent_get_input(evcon->bufev);
1460 err = evbuffer_drain(tmp, -1);
1461 EVUTIL_ASSERT(!err && "drain input");
1463 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1465 evcon->state = EVCON_DISCONNECTED;
1469 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1471 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1472 bufferevent_enable(evcon->bufev, EV_READ);
1476 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1478 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1479 bufferevent_disable(evcon->bufev, EV_READ);
1483 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1485 struct evhttp_connection *evcon = arg;
1487 evcon->state = EVCON_DISCONNECTED;
1488 evhttp_connection_connect_(evcon);
1492 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1494 struct evcon_requestq requests;
1496 evhttp_connection_reset_(evcon);
1497 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1498 struct timeval tv_retry = evcon->initial_retry_timeout;
1500 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1501 /* XXXX handle failure from evhttp_add_event */
1502 for (i=0; i < evcon->retry_cnt; ++i) {
1503 tv_retry.tv_usec *= 2;
1504 if (tv_retry.tv_usec > 1000000) {
1505 tv_retry.tv_usec -= 1000000;
1506 tv_retry.tv_sec += 1;
1508 tv_retry.tv_sec *= 2;
1509 if (tv_retry.tv_sec > 3600) {
1510 tv_retry.tv_sec = 3600;
1511 tv_retry.tv_usec = 0;
1514 event_add(&evcon->retry_ev, &tv_retry);
1520 * User callback can do evhttp_make_request() on the same
1521 * evcon so new request will be added to evcon->requests. To
1522 * avoid freeing it prematurely we iterate over the copy of
1525 TAILQ_INIT(&requests);
1526 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1527 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1528 TAILQ_REMOVE(&evcon->requests, request, next);
1529 TAILQ_INSERT_TAIL(&requests, request, next);
1532 /* for now, we just signal all requests by executing their callbacks */
1533 while (TAILQ_FIRST(&requests) != NULL) {
1534 struct evhttp_request *request = TAILQ_FIRST(&requests);
1535 TAILQ_REMOVE(&requests, request, next);
1536 request->evcon = NULL;
1538 /* we might want to set an error here */
1539 request->cb(request, request->cb_arg);
1540 evhttp_request_free_auto(request);
1545 evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
1546 struct evhttp_request *req)
1548 struct evbuffer *buf;
1550 /** Second time, we can't read anything */
1551 if (evcon->flags & EVHTTP_CON_READING_ERROR) {
1552 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1553 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1557 req->kind = EVHTTP_RESPONSE;
1559 buf = bufferevent_get_output(evcon->bufev);
1560 evbuffer_unfreeze(buf, 1);
1561 evbuffer_drain(buf, evbuffer_get_length(buf));
1562 evbuffer_freeze(buf, 1);
1564 evhttp_start_read_(evcon);
1565 evcon->flags |= EVHTTP_CON_READING_ERROR;
1569 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1571 struct evhttp_connection *evcon = arg;
1572 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1574 if (evcon->fd == -1)
1575 evcon->fd = bufferevent_getfd(bufev);
1577 switch (evcon->state) {
1578 case EVCON_CONNECTING:
1579 if (what & BEV_EVENT_TIMEOUT) {
1580 event_debug(("%s: connection timeout for \"%s:%d\" on "
1582 __func__, evcon->address, evcon->port,
1583 EV_SOCK_ARG(evcon->fd)));
1584 evhttp_connection_cb_cleanup(evcon);
1589 case EVCON_READING_BODY:
1590 if (!req->chunked && req->ntoread < 0
1591 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1592 /* EOF on read can be benign */
1593 evhttp_connection_done(evcon);
1598 case EVCON_DISCONNECTED:
1600 case EVCON_READING_FIRSTLINE:
1601 case EVCON_READING_HEADERS:
1602 case EVCON_READING_TRAILER:
1608 /* when we are in close detect mode, a read error means that
1609 * the other side closed their connection.
1611 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1612 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1613 EVUTIL_ASSERT(evcon->http_server == NULL);
1614 /* For connections from the client, we just
1615 * reset the connection so that it becomes
1618 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1619 evhttp_connection_reset_(evcon);
1622 * If we have no more requests that need completion
1623 * and we want to auto-free the connection when all
1624 * requests have been completed.
1626 if (TAILQ_FIRST(&evcon->requests) == NULL
1627 && (evcon->flags & EVHTTP_CON_OUTGOING)
1628 && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1629 evhttp_connection_free(evcon);
1634 if (what & BEV_EVENT_TIMEOUT) {
1635 evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
1636 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1637 if (what & BEV_EVENT_WRITING &&
1638 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR) {
1639 evhttp_connection_read_on_write_error(evcon, req);
1643 if (what & BEV_EVENT_READING &&
1644 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR &&
1645 evbuffer_get_length(bufferevent_get_input(bufev))) {
1646 event_deferred_cb_schedule_(get_deferred_queue(evcon),
1647 &evcon->read_more_deferred_cb);
1651 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1652 } else if (what == BEV_EVENT_CONNECTED) {
1654 evhttp_connection_fail_(evcon, EVREQ_HTTP_BUFFER_ERROR);
1659 * Event callback for asynchronous connection attempt.
1662 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1664 struct evhttp_connection *evcon = arg;
1666 ev_socklen_t errsz = sizeof(error);
1668 if (evcon->fd == -1)
1669 evcon->fd = bufferevent_getfd(bufev);
1671 if (!(what & BEV_EVENT_CONNECTED)) {
1672 /* some operating systems return ECONNREFUSED immediately
1673 * when connecting to a local address. the cleanup is going
1674 * to reschedule this function call.
1677 if (errno == ECONNREFUSED)
1680 evhttp_error_cb(bufev, what, arg);
1684 if (evcon->fd == -1) {
1685 event_debug(("%s: bufferevent_getfd returned -1",
1690 /* Check if the connection completed */
1691 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1693 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT,
1694 __func__, evcon->address, evcon->port,
1695 EV_SOCK_ARG(evcon->fd)));
1700 event_debug(("%s: connect failed for \"%s:%d\" on "
1702 __func__, evcon->address, evcon->port,
1703 EV_SOCK_ARG(evcon->fd),
1704 evutil_socket_error_to_string(error)));
1708 /* We are connected to the server now */
1709 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1710 __func__, evcon->address, evcon->port,
1711 EV_SOCK_ARG(evcon->fd)));
1713 /* Reset the retry count as we were successful in connecting */
1714 evcon->retry_cnt = 0;
1715 evcon->state = EVCON_IDLE;
1717 /* reset the bufferevent cbs */
1718 bufferevent_setcb(evcon->bufev,
1724 bufferevent_set_timeouts(evcon->bufev,
1725 &evcon->timeout_read, &evcon->timeout_write);
1727 /* try to start requests that have queued up on this connection */
1728 evhttp_request_dispatch(evcon);
1732 evhttp_connection_cb_cleanup(evcon);
1736 * Check if we got a valid response code.
1740 evhttp_valid_response_code(int code)
1749 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1753 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1754 if (n != 2 || major > 1) {
1755 event_debug(("%s: bad version %s on message %p from %s",
1756 __func__, version, req, req->remote_host));
1764 /* Parses the status line of a web server */
1767 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1771 const char *readable = "";
1773 protocol = strsep(&line, " ");
1776 number = strsep(&line, " ");
1780 if (evhttp_parse_http_version(protocol, req) < 0)
1783 req->response_code = atoi(number);
1784 if (!evhttp_valid_response_code(req->response_code)) {
1785 event_debug(("%s: bad response code \"%s\"",
1790 if (req->response_code_line != NULL)
1791 mm_free(req->response_code_line);
1792 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1793 event_warn("%s: strdup", __func__);
1800 /* Parse the first line of a HTTP request */
1803 evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len)
1805 char *eos = line + len;
1809 const char *hostname;
1812 enum evhttp_cmd_type type = 0;
1814 while (eos > line && *(eos-1) == ' ') {
1819 if (len < strlen("GET / HTTP/1.0"))
1822 /* Parse the request line */
1823 method = strsep(&line, " ");
1827 version = strrchr(uri, ' ');
1828 if (!version || uri == version)
1833 method_len = (uri - method) - 1;
1836 switch (method_len) {
1838 /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1840 /* Since both GET and PUT share the same character 'T' at the end,
1841 * if the string doesn't have 'T', we can immediately determine this
1842 * is an invalid HTTP method */
1844 if (method[2] != 'T') {
1850 /* This first byte is 'G', so make sure the next byte is
1851 * 'E', if it isn't then this isn't a valid method */
1853 if (method[1] == 'E') {
1854 type = EVHTTP_REQ_GET;
1859 /* First byte is P, check second byte for 'U', if not,
1860 * we know it's an invalid method */
1861 if (method[1] == 'U') {
1862 type = EVHTTP_REQ_PUT;
1870 /* The method length is 4 bytes, leaving only the methods POST, HEAD, LOCK, COPY and MOVE */
1873 if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') {
1874 type = EVHTTP_REQ_POST;
1878 if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') {
1879 type = EVHTTP_REQ_HEAD;
1883 if (method[3] == 'K' && method[2] == 'C' && method[1] == 'O') {
1884 type = EVHTTP_REQ_LOCK;
1888 if (method[3] == 'Y' && method[2] == 'P' && method[1] == 'O') {
1889 type = EVHTTP_REQ_COPY;
1893 if (method[3] == 'E' && method[2] == 'V' && method[1] == 'O') {
1894 type = EVHTTP_REQ_MOVE;
1902 /* Method length is 5 bytes, which can only encompass PATCH, TRACE and MKCOL */
1905 if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') {
1906 type = EVHTTP_REQ_PATCH;
1910 if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') {
1911 type = EVHTTP_REQ_TRACE;
1916 if (method[4] == 'L' && method[3] == 'O' && method[2] == 'C' && method[1] == 'K') {
1917 type = EVHTTP_REQ_MKCOL;
1925 /* Method length is 6, only valid methods 6 bytes in length is DELETE and UNLOCK */
1928 if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' &&
1929 method[2] == 'L' && method[1] == 'E') {
1930 type = EVHTTP_REQ_DELETE;
1934 if (method[5] == 'K' && method[4] == 'C' && method[3] == 'O' &&
1935 method[2] == 'L' && method[1] == 'N') {
1936 type = EVHTTP_REQ_UNLOCK;
1944 /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1947 if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' &&
1948 method[3] == 'I' && method[2] == 'T' && method[1] == 'P') {
1949 type = EVHTTP_REQ_OPTIONS;
1954 if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' &&
1955 method[3] == 'N' && method[2] == 'N' && method[1] == 'O') {
1956 type = EVHTTP_REQ_CONNECT;
1965 /* Method length is 8, only valid method 8 bytes in length is PROPFIND */
1967 /* If the first byte isn't 'P' then it's invalid */
1968 if (*method != 'P') {
1972 if (method[7] == 'D' && method[6] == 'N' && method[5] == 'I' &&
1973 method[4] == 'F' && method[3] == 'P' && method[2] == 'O' &&
1975 type = EVHTTP_REQ_PROPFIND;
1980 /* Method length is 9, only valid method 9 bytes in length is PROPPATCH */
1982 /* If the first byte isn't 'P' then it's invalid */
1983 if (*method != 'P') {
1987 if (method[8] == 'H' && method[7] == 'C' && method[6] == 'T' &&
1988 method[5] == 'A' && method[4] == 'P' && method[3] == 'P' &&
1989 method[2] == 'O' && method[1] == 'R') {
1990 type = EVHTTP_REQ_PROPPATCH;
1997 /* check extended methods, we only care about the
1998 * type set by the cmp function if the cmp function
1999 * returns a 0 value.
2001 struct evhttp_ext_method ext_method;
2003 ext_method.method = method;
2004 ext_method.type = 0;
2005 ext_method.flags = 0;
2007 if (req->evcon->ext_method_cmp &&
2008 req->evcon->ext_method_cmp(&ext_method) == 0) {
2009 /* make sure the other fields in ext_method are
2010 * not changed by the callback.
2012 if (strcmp(ext_method.method, method) != 0) {
2013 event_warn("%s: modifying the 'method' field of ext_method_cmp's "
2014 "parameter is not allowed", __func__);
2017 if (ext_method.flags != 0) {
2018 event_warn("%s: modifying the 'flags' field of ext_method_cmp's "
2019 "parameter is not allowed", __func__);
2022 type = ext_method.type;
2027 event_debug(("%s: bad method %s on request %p from %s",
2028 __func__, method, req, req->remote_host));
2029 /* No error yet; we'll give a better error later when
2030 * we see that req->type is unsupported. */
2035 if (evhttp_parse_http_version(version, req) < 0)
2038 if ((req->uri = mm_strdup(uri)) == NULL) {
2039 event_debug(("%s: mm_strdup", __func__));
2043 if (type == EVHTTP_REQ_CONNECT) {
2044 if ((req->uri_elems = evhttp_uri_parse_authority(req->uri)) == NULL) {
2048 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
2049 EVHTTP_URI_NONCONFORMANT)) == NULL) {
2054 /* If we have an absolute-URI, check to see if it is an http request
2055 for a known vhost or server alias. If we don't know about this
2056 host, we consider it a proxy request. */
2057 scheme = evhttp_uri_get_scheme(req->uri_elems);
2058 hostname = evhttp_uri_get_host(req->uri_elems);
2059 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
2060 !evutil_ascii_strcasecmp(scheme, "https")) &&
2062 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
2063 req->flags |= EVHTTP_PROXY_REQUEST;
2069 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
2071 struct evkeyval *header;
2073 TAILQ_FOREACH(header, headers, next) {
2074 if (evutil_ascii_strcasecmp(header->key, key) == 0)
2075 return (header->value);
2082 evhttp_clear_headers(struct evkeyvalq *headers)
2084 struct evkeyval *header;
2086 for (header = TAILQ_FIRST(headers);
2088 header = TAILQ_FIRST(headers)) {
2089 TAILQ_REMOVE(headers, header, next);
2090 mm_free(header->key);
2091 mm_free(header->value);
2097 * Returns 0, if the header was successfully removed.
2098 * Returns -1, if the header could not be found.
2102 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
2104 struct evkeyval *header;
2106 TAILQ_FOREACH(header, headers, next) {
2107 if (evutil_ascii_strcasecmp(header->key, key) == 0)
2114 /* Free and remove the header that we found */
2115 TAILQ_REMOVE(headers, header, next);
2116 mm_free(header->key);
2117 mm_free(header->value);
2124 evhttp_header_is_valid_value(const char *value)
2126 const char *p = value;
2128 while ((p = strpbrk(p, "\r\n")) != NULL) {
2129 /* we really expect only one new line */
2130 p += strspn(p, "\r\n");
2131 /* we expect a space or tab for continuation */
2132 if (*p != ' ' && *p != '\t')
2139 evhttp_add_header(struct evkeyvalq *headers,
2140 const char *key, const char *value)
2142 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
2144 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
2145 /* drop illegal headers */
2146 event_debug(("%s: dropping illegal header key\n", __func__));
2150 if (!evhttp_header_is_valid_value(value)) {
2151 event_debug(("%s: dropping illegal header value\n", __func__));
2155 return (evhttp_add_header_internal(headers, key, value));
2159 evhttp_add_header_internal(struct evkeyvalq *headers,
2160 const char *key, const char *value)
2162 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
2163 if (header == NULL) {
2164 event_warn("%s: calloc", __func__);
2167 if ((header->key = mm_strdup(key)) == NULL) {
2169 event_warn("%s: strdup", __func__);
2172 if ((header->value = mm_strdup(value)) == NULL) {
2173 mm_free(header->key);
2175 event_warn("%s: strdup", __func__);
2179 TAILQ_INSERT_TAIL(headers, header, next);
2185 * Parses header lines from a request or a response into the specified
2186 * request object given an event buffer.
2189 * DATA_CORRUPTED on error
2190 * MORE_DATA_EXPECTED when we need to read more headers
2191 * ALL_DATA_READ when all headers have been read.
2194 enum message_read_status
2195 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
2198 enum message_read_status status = ALL_DATA_READ;
2202 line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
2204 if (req->evcon != NULL &&
2205 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2206 return (DATA_TOO_LONG);
2208 return (MORE_DATA_EXPECTED);
2211 if (req->evcon != NULL && len > req->evcon->max_headers_size) {
2213 return (DATA_TOO_LONG);
2216 req->headers_size = len;
2218 switch (req->kind) {
2219 case EVHTTP_REQUEST:
2220 if (evhttp_parse_request_line(req, line, len) == -1)
2221 status = DATA_CORRUPTED;
2223 case EVHTTP_RESPONSE:
2224 if (evhttp_parse_response_line(req, line) == -1)
2225 status = DATA_CORRUPTED;
2228 status = DATA_CORRUPTED;
2236 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
2238 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
2240 size_t old_len, line_len;
2245 old_len = strlen(header->value);
2247 /* Strip space from start and end of line. */
2248 while (*line == ' ' || *line == '\t')
2250 evutil_rtrim_lws_(line);
2252 line_len = strlen(line);
2254 newval = mm_realloc(header->value, old_len + line_len + 2);
2258 newval[old_len] = ' ';
2259 memcpy(newval + old_len + 1, line, line_len + 1);
2260 header->value = newval;
2265 enum message_read_status
2266 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
2268 enum message_read_status errcode = DATA_CORRUPTED;
2270 enum message_read_status status = MORE_DATA_EXPECTED;
2272 struct evkeyvalq* headers = req->input_headers;
2274 while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
2276 char *skey, *svalue;
2278 req->headers_size += len;
2280 if (req->evcon != NULL &&
2281 req->headers_size > req->evcon->max_headers_size) {
2282 errcode = DATA_TOO_LONG;
2286 if (*line == '\0') { /* Last header - Done */
2287 status = ALL_DATA_READ;
2292 /* Check if this is a continuation line */
2293 if (*line == ' ' || *line == '\t') {
2294 if (evhttp_append_to_last_header(headers, line) == -1)
2300 /* Processing of header lines */
2302 skey = strsep(&svalue, ":");
2306 svalue += strspn(svalue, " ");
2307 evutil_rtrim_lws_(svalue);
2309 if (evhttp_add_header(headers, skey, svalue) == -1)
2315 if (status == MORE_DATA_EXPECTED) {
2316 if (req->evcon != NULL &&
2317 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2318 return (DATA_TOO_LONG);
2329 evhttp_get_body_length(struct evhttp_request *req)
2331 struct evkeyvalq *headers = req->input_headers;
2332 const char *content_length;
2333 const char *connection;
2335 content_length = evhttp_find_header(headers, "Content-Length");
2336 connection = evhttp_find_header(headers, "Connection");
2338 if (content_length == NULL && connection == NULL)
2340 else if (content_length == NULL &&
2341 evutil_ascii_strcasecmp(connection, "Close") != 0) {
2343 } else if (content_length == NULL) {
2347 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2348 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2349 event_debug(("%s: illegal content length: %s",
2350 __func__, content_length));
2353 req->ntoread = ntoread;
2356 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2357 __func__, EV_I64_ARG(req->ntoread),
2358 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2364 evhttp_method_may_have_body_(struct evhttp_connection *evcon, enum evhttp_cmd_type type)
2367 evhttp_method_(evcon, type, &flags);
2368 return (flags & EVHTTP_METHOD_HAS_BODY) ? 1 : 0;
2372 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2374 const char *xfer_enc;
2376 /* If this is a request without a body, then we are done */
2377 if (req->kind == EVHTTP_REQUEST &&
2378 !evhttp_method_may_have_body_(evcon, req->type)) {
2379 evhttp_connection_done(evcon);
2382 evcon->state = EVCON_READING_BODY;
2383 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
2384 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
2388 if (evhttp_get_body_length(req) == -1) {
2389 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2392 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2393 /* An incoming request with no content-length and no
2394 * transfer-encoding has no body. */
2395 evhttp_connection_done(evcon);
2400 /* Should we send a 100 Continue status line? */
2401 switch (evhttp_have_expect(req, 1)) {
2403 /* XXX It would be nice to do some sanity
2404 checking here. Does the resource exist?
2405 Should the resource accept post requests? If
2406 no, we should respond with an error. For
2407 now, just optimistically tell the client to
2408 send their message body. */
2409 if (req->ntoread > 0) {
2410 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2411 if ((req->evcon->max_body_size <= EV_INT64_MAX) &&
2412 (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2413 evhttp_lingering_fail(evcon, req);
2417 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2418 evhttp_send_continue(evcon, req);
2421 evhttp_send_error(req, HTTP_EXPECTATIONFAILED, NULL);
2426 evhttp_read_body(evcon, req);
2427 /* note the request may have been freed in evhttp_read_body */
2431 evhttp_read_firstline(struct evhttp_connection *evcon,
2432 struct evhttp_request *req)
2434 enum message_read_status res;
2436 res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2437 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2438 /* Error while reading, terminate */
2439 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2440 __func__, EV_SOCK_ARG(evcon->fd)));
2441 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2443 } else if (res == MORE_DATA_EXPECTED) {
2444 /* Need more header lines */
2448 evcon->state = EVCON_READING_HEADERS;
2449 evhttp_read_header(evcon, req);
2453 evhttp_read_header(struct evhttp_connection *evcon,
2454 struct evhttp_request *req)
2456 enum message_read_status res;
2457 evutil_socket_t fd = evcon->fd;
2459 res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2460 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2461 /* Error while reading, terminate */
2462 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2463 __func__, EV_SOCK_ARG(fd)));
2464 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2466 } else if (res == MORE_DATA_EXPECTED) {
2467 /* Need more header lines */
2471 /* Callback can shut down connection with negative return value */
2472 if (req->header_cb != NULL) {
2473 if ((*req->header_cb)(req, req->cb_arg) < 0) {
2474 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2479 /* Done reading headers, do the real work */
2480 switch (req->kind) {
2481 case EVHTTP_REQUEST:
2482 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2483 __func__, EV_SOCK_ARG(fd)));
2484 evhttp_get_body(evcon, req);
2485 /* note the request may have been freed in evhttp_get_body */
2488 case EVHTTP_RESPONSE:
2489 /* Start over if we got a 100 Continue response. */
2490 if (req->response_code == 100) {
2491 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
2492 evbuffer_add_buffer(output, req->output_buffer);
2493 evhttp_start_write_(evcon);
2496 if (!evhttp_response_needs_body(req)) {
2497 event_debug(("%s: skipping body for code %d\n",
2498 __func__, req->response_code));
2499 evhttp_connection_done(evcon);
2501 event_debug(("%s: start of read body for %s on "
2503 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2504 evhttp_get_body(evcon, req);
2505 /* note the request may have been freed in
2506 * evhttp_get_body */
2511 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2513 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2516 /* request may have been freed above */
2520 * Creates a TCP connection to the specified port and executes a callback
2521 * when finished. Failure or success is indicate by the passed connection
2524 * Although this interface accepts a hostname, it is intended to take
2525 * only numeric hostnames so that non-blocking DNS resolution can
2529 struct evhttp_connection *
2530 evhttp_connection_new(const char *address, ev_uint16_t port)
2532 return (evhttp_connection_base_new(NULL, NULL, address, port));
2535 struct evhttp_connection *
2536 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2537 const char *address, ev_uint16_t port)
2539 struct evhttp_connection *evcon = NULL;
2541 event_debug(("Attempting connection to %s:%d\n", address, port));
2543 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2544 event_warn("%s: calloc failed", __func__);
2551 evcon->max_headers_size = EV_SIZE_MAX;
2552 evcon->max_body_size = EV_SIZE_MAX;
2554 evcon->timeout_connect.tv_sec = HTTP_CONNECT_TIMEOUT;
2555 evcon->timeout_read.tv_sec = HTTP_READ_TIMEOUT;
2556 evcon->timeout_write.tv_sec = HTTP_WRITE_TIMEOUT;
2557 evcon->initial_retry_timeout.tv_sec = HTTP_INITIAL_RETRY_TIMEOUT;
2559 evcon->retry_cnt = evcon->retry_max = 0;
2561 if ((evcon->address = mm_strdup(address)) == NULL) {
2562 event_warn("%s: strdup failed", __func__);
2567 if (!(bev = bufferevent_socket_new(base, -1, 0))) {
2568 event_warn("%s: bufferevent_socket_new failed", __func__);
2573 bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2576 evcon->state = EVCON_DISCONNECTED;
2577 TAILQ_INIT(&evcon->requests);
2581 if (bufferevent_get_base(bev) != base)
2582 bufferevent_base_set(base, evcon->bufev);
2585 event_deferred_cb_init_(
2586 &evcon->read_more_deferred_cb,
2587 bufferevent_get_priority(bev),
2588 evhttp_deferred_read_cb, evcon);
2590 evcon->dns_base = dnsbase;
2591 evcon->ai_family = AF_UNSPEC;
2597 evhttp_connection_free(evcon);
2601 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2603 return evcon->bufev;
2607 evhttp_connection_get_server(struct evhttp_connection *evcon)
2609 return evcon->http_server;
2612 struct evhttp_connection *
2613 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2614 const char *address, ev_uint16_t port)
2616 return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2619 void evhttp_connection_set_family(struct evhttp_connection *evcon,
2622 evcon->ai_family = family;
2625 int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2628 int avail_flags = 0;
2629 avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2630 avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2632 if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2634 evcon->flags &= ~avail_flags;
2636 evcon->flags |= flags;
2642 evhttp_connection_set_ext_method_cmp(struct evhttp_connection *evcon,
2643 evhttp_ext_method_cb cmp)
2645 evcon->ext_method_cmp = cmp;
2649 evhttp_connection_set_base(struct evhttp_connection *evcon,
2650 struct event_base *base)
2652 EVUTIL_ASSERT(evcon->base == NULL);
2653 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2655 bufferevent_base_set(base, evcon->bufev);
2659 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2662 if (timeout != -1) {
2663 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2665 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2667 evhttp_set_timeout_(&evcon->timeout_read, timeout, HTTP_READ_TIMEOUT);
2668 evhttp_set_timeout_(&evcon->timeout_write, timeout, HTTP_WRITE_TIMEOUT);
2669 bufferevent_set_timeouts(evcon->bufev,
2670 &evcon->timeout_read, &evcon->timeout_write);
2673 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2674 const struct timeval* tv)
2677 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2679 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2681 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, HTTP_READ_TIMEOUT);
2682 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, HTTP_WRITE_TIMEOUT);
2683 bufferevent_set_timeouts(evcon->bufev,
2684 &evcon->timeout_read, &evcon->timeout_write);
2686 void evhttp_connection_set_connect_timeout_tv(struct evhttp_connection *evcon,
2687 const struct timeval *tv)
2689 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2690 evhttp_set_timeout_tv_(&evcon->timeout_connect, tv, -1);
2691 if (evcon->state == EVCON_CONNECTING)
2692 bufferevent_set_timeouts(evcon->bufev,
2693 &evcon->timeout_connect, &evcon->timeout_connect);
2695 void evhttp_connection_set_read_timeout_tv(struct evhttp_connection *evcon,
2696 const struct timeval *tv)
2698 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2699 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, -1);
2700 if (evcon->state != EVCON_CONNECTING)
2701 bufferevent_set_timeouts(evcon->bufev,
2702 &evcon->timeout_read, &evcon->timeout_write);
2704 void evhttp_connection_set_write_timeout_tv(struct evhttp_connection *evcon,
2705 const struct timeval *tv)
2707 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2708 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, -1);
2709 if (evcon->state != EVCON_CONNECTING)
2710 bufferevent_set_timeouts(evcon->bufev,
2711 &evcon->timeout_read, &evcon->timeout_write);
2715 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2716 const struct timeval *tv)
2719 evcon->initial_retry_timeout = *tv;
2721 evutil_timerclear(&evcon->initial_retry_timeout);
2722 evcon->initial_retry_timeout.tv_sec = 2;
2727 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2730 evcon->retry_max = retry_max;
2734 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2735 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2737 evcon->closecb = cb;
2738 evcon->closecb_arg = cbarg;
2742 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2743 char **address, ev_uint16_t *port)
2745 *address = evcon->address;
2746 *port = evcon->port;
2749 const struct sockaddr*
2750 evhttp_connection_get_addr(struct evhttp_connection *evcon)
2752 return bufferevent_socket_get_conn_address_(evcon->bufev);
2756 evhttp_connection_connect_(struct evhttp_connection *evcon)
2758 int old_state = evcon->state;
2759 const char *address = evcon->address;
2760 const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
2763 if (evcon->state == EVCON_CONNECTING)
2766 evhttp_connection_reset_(evcon);
2768 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2769 evcon->flags |= EVHTTP_CON_OUTGOING;
2771 if (evcon->bind_address || evcon->bind_port) {
2772 evcon->fd = bind_socket(
2773 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2774 if (evcon->fd == -1) {
2775 event_debug(("%s: failed to bind to \"%s\"",
2776 __func__, evcon->bind_address));
2780 if (bufferevent_setfd(evcon->bufev, evcon->fd))
2783 if (bufferevent_setfd(evcon->bufev, -1))
2787 /* Set up a callback for successful connection setup */
2788 bufferevent_setcb(evcon->bufev,
2789 NULL /* evhttp_read_cb */,
2790 NULL /* evhttp_write_cb */,
2791 evhttp_connection_cb,
2793 bufferevent_set_timeouts(evcon->bufev,
2794 &evcon->timeout_connect, &evcon->timeout_connect);
2795 /* make sure that we get a write callback */
2796 if (bufferevent_enable(evcon->bufev, EV_WRITE))
2799 evcon->state = EVCON_CONNECTING;
2801 if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
2803 (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
2804 int socklen = sizeof(struct sockaddr_in);
2805 if (sa->sa_family == AF_INET6) {
2806 socklen = sizeof(struct sockaddr_in6);
2808 ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
2810 ret = bufferevent_socket_connect_hostname(evcon->bufev,
2811 evcon->dns_base, evcon->ai_family, address, evcon->port);
2815 evcon->state = old_state;
2816 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2817 __func__, evcon->address);
2818 /* some operating systems return ECONNREFUSED immediately
2819 * when connecting to a local address. the cleanup is going
2820 * to reschedule this function call.
2822 evhttp_connection_cb_cleanup(evcon);
2830 * Starts an HTTP request on the provided evhttp_connection object.
2831 * If the connection object is not connected to the web server already,
2832 * this will start the connection.
2836 evhttp_make_request(struct evhttp_connection *evcon,
2837 struct evhttp_request *req,
2838 enum evhttp_cmd_type type, const char *uri)
2840 /* We are making a request */
2841 req->kind = EVHTTP_REQUEST;
2843 if (req->uri != NULL)
2845 if ((req->uri = mm_strdup(uri)) == NULL) {
2846 event_warn("%s: strdup", __func__);
2847 evhttp_request_free_auto(req);
2851 /* Set the protocol version if it is not supplied */
2852 if (!req->major && !req->minor) {
2857 EVUTIL_ASSERT(req->evcon == NULL);
2859 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2861 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2863 /* We do not want to conflict with retry_ev */
2864 if (evcon->retry_cnt)
2867 /* If the connection object is not connected; make it so */
2868 if (!evhttp_connected(evcon)) {
2869 int res = evhttp_connection_connect_(evcon);
2870 /* evhttp_connection_fail_(), which is called through
2871 * evhttp_connection_connect_(), assumes that req lies in
2872 * evcon->requests. Thus, enqueue the request in advance and
2873 * remove it in the error case. */
2875 TAILQ_REMOVE(&evcon->requests, req, next);
2881 * If it's connected already and we are the first in the queue,
2882 * then we can dispatch this request immediately. Otherwise, it
2883 * will be dispatched once the pending requests are completed.
2885 if (TAILQ_FIRST(&evcon->requests) == req)
2886 evhttp_request_dispatch(evcon);
2892 evhttp_cancel_request(struct evhttp_request *req)
2894 struct evhttp_connection *evcon = req->evcon;
2895 if (evcon != NULL) {
2896 /* We need to remove it from the connection */
2897 if (TAILQ_FIRST(&evcon->requests) == req) {
2898 /* it's currently being worked on, so reset
2901 evhttp_connection_fail_(evcon,
2902 EVREQ_HTTP_REQUEST_CANCEL);
2904 /* connection fail freed the request */
2907 /* otherwise, we can just remove it from the
2910 TAILQ_REMOVE(&evcon->requests, req, next);
2914 evhttp_request_free_auto(req);
2918 * Reads data from file descriptor into request structure
2919 * Request structure needs to be set up correctly.
2923 evhttp_start_read_(struct evhttp_connection *evcon)
2925 bufferevent_disable(evcon->bufev, EV_WRITE);
2926 bufferevent_enable(evcon->bufev, EV_READ);
2928 evcon->state = EVCON_READING_FIRSTLINE;
2929 /* Reset the bufferevent callbacks */
2930 bufferevent_setcb(evcon->bufev,
2936 /* If there's still data pending, process it next time through the
2937 * loop. Don't do it now; that could get recusive. */
2938 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2939 event_deferred_cb_schedule_(get_deferred_queue(evcon),
2940 &evcon->read_more_deferred_cb);
2945 evhttp_start_write_(struct evhttp_connection *evcon)
2947 bufferevent_disable(evcon->bufev, EV_WRITE);
2948 bufferevent_enable(evcon->bufev, EV_READ);
2950 evcon->state = EVCON_WRITING;
2951 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
2955 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2958 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2959 TAILQ_REMOVE(&evcon->requests, req, next);
2961 if (req->on_complete_cb != NULL) {
2962 req->on_complete_cb(req, req->on_complete_cb_arg);
2966 (REQ_VERSION_BEFORE(req, 1, 1) &&
2967 !evhttp_is_connection_keepalive(req->input_headers)) ||
2968 evhttp_is_request_connection_close(req);
2970 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2971 evhttp_request_free(req);
2974 evhttp_connection_free(evcon);
2978 /* we have a persistent connection; try to accept another request. */
2979 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2980 evhttp_connection_free(evcon);
2985 * Returns an error page.
2989 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2992 #define ERR_FORMAT "<HTML><HEAD>\n" \
2993 "<TITLE>%d %s</TITLE>\n" \
2998 struct evbuffer *buf = evbuffer_new();
3000 /* if we cannot allocate memory; we just drop the connection */
3001 evhttp_connection_free(req->evcon);
3004 if (reason == NULL) {
3005 reason = evhttp_response_phrase_internal(error);
3008 evhttp_response_code_(req, error, reason);
3010 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
3012 evhttp_send_page_(req, buf);
3018 /* Requires that headers and response code are already set up */
3021 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
3023 struct evhttp_connection *evcon = req->evcon;
3025 if (evcon == NULL) {
3026 evhttp_request_free(req);
3030 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
3032 /* we expect no more calls form the user on this request */
3035 /* xxx: not sure if we really should expose the data buffer this way */
3036 if (databuf != NULL)
3037 evbuffer_add_buffer(req->output_buffer, databuf);
3039 /* Adds headers to the response */
3040 evhttp_make_header(evcon, req);
3042 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
3046 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
3047 struct evbuffer *databuf)
3049 evhttp_response_code_(req, code, reason);
3051 evhttp_send(req, databuf);
3055 evhttp_send_reply_start(struct evhttp_request *req, int code,
3058 evhttp_response_code_(req, code, reason);
3060 if (req->evcon == NULL)
3063 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
3064 REQ_VERSION_ATLEAST(req, 1, 1) &&
3065 evhttp_response_needs_body(req)) {
3067 * prefer HTTP/1.1 chunked encoding to closing the connection;
3068 * note RFC 2616 section 4.4 forbids it with Content-Length:
3069 * and it's not necessary then anyway.
3071 evhttp_add_header(req->output_headers, "Transfer-Encoding",
3077 evhttp_make_header(req->evcon, req);
3078 evhttp_write_buffer(req->evcon, NULL, NULL);
3082 evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
3083 void (*cb)(struct evhttp_connection *, void *), void *arg)
3085 struct evhttp_connection *evcon = req->evcon;
3086 struct evbuffer *output;
3091 output = bufferevent_get_output(evcon->bufev);
3093 if (evbuffer_get_length(databuf) == 0)
3095 if (!evhttp_response_needs_body(req))
3098 evbuffer_add_printf(output, "%x\r\n",
3099 (unsigned)evbuffer_get_length(databuf));
3101 evbuffer_add_buffer(output, databuf);
3103 evbuffer_add(output, "\r\n", 2);
3105 evhttp_write_buffer(evcon, cb, arg);
3109 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
3111 evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
3114 evhttp_send_reply_end(struct evhttp_request *req)
3116 struct evhttp_connection *evcon = req->evcon;
3117 struct evbuffer *output;
3119 if (evcon == NULL) {
3120 evhttp_request_free(req);
3124 output = bufferevent_get_output(evcon->bufev);
3126 /* we expect no more calls form the user on this request */
3130 evbuffer_add(output, "0\r\n\r\n", 5);
3131 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
3133 } else if (evbuffer_get_length(output) == 0) {
3134 /* let the connection know that we are done with the request */
3135 evhttp_send_done(evcon, NULL);
3137 /* make the callback execute after all data has been written */
3138 evcon->cb = evhttp_send_done;
3139 evcon->cb_arg = NULL;
3143 static const char *informational_phrases[] = {
3144 /* 100 */ "Continue",
3145 /* 101 */ "Switching Protocols"
3148 static const char *success_phrases[] = {
3150 /* 201 */ "Created",
3151 /* 202 */ "Accepted",
3152 /* 203 */ "Non-Authoritative Information",
3153 /* 204 */ "No Content",
3154 /* 205 */ "Reset Content",
3155 /* 206 */ "Partial Content"
3158 static const char *redirection_phrases[] = {
3159 /* 300 */ "Multiple Choices",
3160 /* 301 */ "Moved Permanently",
3162 /* 303 */ "See Other",
3163 /* 304 */ "Not Modified",
3164 /* 305 */ "Use Proxy",
3165 /* 307 */ "Temporary Redirect"
3168 static const char *client_error_phrases[] = {
3169 /* 400 */ "Bad Request",
3170 /* 401 */ "Unauthorized",
3171 /* 402 */ "Payment Required",
3172 /* 403 */ "Forbidden",
3173 /* 404 */ "Not Found",
3174 /* 405 */ "Method Not Allowed",
3175 /* 406 */ "Not Acceptable",
3176 /* 407 */ "Proxy Authentication Required",
3177 /* 408 */ "Request Time-out",
3178 /* 409 */ "Conflict",
3180 /* 411 */ "Length Required",
3181 /* 412 */ "Precondition Failed",
3182 /* 413 */ "Request Entity Too Large",
3183 /* 414 */ "Request-URI Too Large",
3184 /* 415 */ "Unsupported Media Type",
3185 /* 416 */ "Requested range not satisfiable",
3186 /* 417 */ "Expectation Failed"
3189 static const char *server_error_phrases[] = {
3190 /* 500 */ "Internal Server Error",
3191 /* 501 */ "Not Implemented",
3192 /* 502 */ "Bad Gateway",
3193 /* 503 */ "Service Unavailable",
3194 /* 504 */ "Gateway Time-out",
3195 /* 505 */ "HTTP Version not supported"
3198 struct response_class {
3200 size_t num_responses;
3201 const char **responses;
3205 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
3208 static const struct response_class response_classes[] = {
3209 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
3210 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
3211 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
3212 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
3213 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
3217 evhttp_response_phrase_internal(int code)
3219 int klass = code / 100 - 1;
3220 int subcode = code % 100;
3222 /* Unknown class - can't do any better here */
3223 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
3224 return "Unknown Status Class";
3226 /* Unknown sub-code, return class name at least */
3227 if (subcode >= (int) response_classes[klass].num_responses)
3228 return response_classes[klass].name;
3230 return response_classes[klass].responses[subcode];
3234 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
3236 req->kind = EVHTTP_RESPONSE;
3237 req->response_code = code;
3238 if (req->response_code_line != NULL)
3239 mm_free(req->response_code_line);
3241 reason = evhttp_response_phrase_internal(code);
3242 req->response_code_line = mm_strdup(reason);
3243 if (req->response_code_line == NULL) {
3244 event_warn("%s: strdup", __func__);
3245 /* XXX what else can we do? */
3250 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
3252 if (!req->major || !req->minor) {
3257 if (req->kind != EVHTTP_RESPONSE)
3258 evhttp_response_code_(req, 200, "OK");
3260 evhttp_clear_headers(req->output_headers);
3261 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
3262 evhttp_add_header(req->output_headers, "Connection", "close");
3264 evhttp_send(req, databuf);
3267 static const char uri_chars[256] = {
3269 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3271 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
3272 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
3274 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3275 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
3276 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3277 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
3279 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,
3284 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3285 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3286 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3287 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3290 #define CHAR_IS_UNRESERVED(c) \
3291 (uri_chars[(unsigned char)(c)])
3294 * Helper functions to encode/decode a string for inclusion in a URI.
3295 * The returned string must be freed by the caller.
3298 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3300 struct evbuffer *buf = evbuffer_new();
3301 const char *p, *end;
3302 char *result = NULL;
3309 if (uri + len < uri) {
3315 size_t slen = strlen(uri);
3317 if (slen >= EV_SSIZE_MAX) {
3318 /* we don't want to mix signed and unsigned */
3322 if (uri + slen < uri) {
3329 for (p = uri; p < end; p++) {
3330 if (CHAR_IS_UNRESERVED(*p)) {
3331 evbuffer_add(buf, p, 1);
3332 } else if (*p == ' ' && space_as_plus) {
3333 evbuffer_add(buf, "+", 1);
3335 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3339 evbuffer_add(buf, "", 1); /* NUL-terminator. */
3340 result = mm_malloc(evbuffer_get_length(buf));
3343 evbuffer_remove(buf, result, evbuffer_get_length(buf));
3352 evhttp_encode_uri(const char *str)
3354 return evhttp_uriencode(str, -1, 0);
3358 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
3359 * If -1, when true we transform plus to space only after we've seen
3360 * a ?. -1 is deprecated.
3361 * @return the number of bytes written to 'ret'.
3364 evhttp_decode_uri_internal(
3365 const char *uri, size_t length, char *ret, int decode_plus_ctl)
3369 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3372 for (i = j = 0; i < length; i++) {
3375 if (decode_plus_ctl < 0)
3377 } else if (c == '+' && decode_plus) {
3379 } else if ((i + 2) < length && c == '%' &&
3380 EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3385 c = (char)strtol(tmp, NULL, 16);
3397 evhttp_decode_uri(const char *uri)
3401 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3402 event_warn("%s: malloc(%lu)", __func__,
3403 (unsigned long)(strlen(uri) + 1));
3407 evhttp_decode_uri_internal(uri, strlen(uri),
3408 ret, -1 /*always_decode_plus*/);
3414 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3419 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3420 event_warn("%s: malloc(%lu)", __func__,
3421 (unsigned long)(strlen(uri) + 1));
3425 n = evhttp_decode_uri_internal(uri, strlen(uri),
3426 ret, !!decode_plus/*always_decode_plus*/);
3429 EVUTIL_ASSERT(n >= 0);
3430 *size_out = (size_t)n;
3437 * Helper function to parse out arguments in a query.
3438 * The arguments are separated by key and value.
3442 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3443 int is_whole_uri, unsigned flags)
3448 const char *query_part;
3450 struct evhttp_uri *uri=NULL;
3452 TAILQ_INIT(headers);
3455 uri = evhttp_uri_parse(str);
3458 query_part = evhttp_uri_get_query(uri);
3463 /* No arguments - we are done */
3464 if (!query_part || !strlen(query_part)) {
3469 if ((line = mm_strdup(query_part)) == NULL) {
3470 event_warn("%s: strdup", __func__);
3474 p = argument = line;
3475 while (p != NULL && *p != '\0') {
3476 char *key, *value, *decoded_value;
3477 argument = strsep(&p, "&");
3480 key = strsep(&value, "=");
3481 if (flags & EVHTTP_URI_QUERY_NONCONFORMANT) {
3487 if (value == NULL || *key == '\0')
3491 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3492 event_warn("%s: mm_malloc", __func__);
3495 evhttp_decode_uri_internal(value, strlen(value),
3496 decoded_value, 1 /*always_decode_plus*/);
3497 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3498 if (flags & EVHTTP_URI_QUERY_LAST_VAL)
3499 evhttp_remove_header(headers, key);
3500 evhttp_add_header_internal(headers, key, decoded_value);
3501 mm_free(decoded_value);
3507 evhttp_clear_headers(headers);
3512 evhttp_uri_free(uri);
3517 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3519 return evhttp_parse_query_impl(uri, headers, 1, 0);
3522 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3524 return evhttp_parse_query_impl(uri, headers, 0, 0);
3527 evhttp_parse_query_str_flags(const char *uri, struct evkeyvalq *headers, unsigned flags)
3529 return evhttp_parse_query_impl(uri, headers, 0, flags);
3532 static struct evhttp_cb *
3533 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3535 struct evhttp_cb *cb;
3540 /* Test for different URLs */
3541 path = evhttp_uri_get_path(req->uri_elems);
3542 offset = strlen(path);
3543 if ((translated = mm_malloc(offset + 1)) == NULL)
3545 evhttp_decode_uri_internal(path, offset, translated,
3546 0 /* decode_plus */);
3548 TAILQ_FOREACH(cb, callbacks, next) {
3549 if (!strcmp(cb->what, translated)) {
3550 mm_free(translated);
3555 mm_free(translated);
3561 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3566 switch (c = *pattern++) {
3568 return *name == '\0';
3571 while (*name != '\0') {
3572 if (prefix_suffix_match(pattern, name,
3581 EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3591 Search the vhost hierarchy beginning with http for a server alias
3592 matching hostname. If a match is found, and outhttp is non-null,
3593 outhttp is set to the matching http object and 1 is returned.
3597 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3598 const char *hostname)
3600 struct evhttp_server_alias *alias;
3601 struct evhttp *vhost;
3603 TAILQ_FOREACH(alias, &http->aliases, next) {
3604 /* XXX Do we need to handle IP addresses? */
3605 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3612 /* XXX It might be good to avoid recursion here, but I don't
3613 see a way to do that w/o a list. */
3614 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3615 if (evhttp_find_alias(vhost, outhttp, hostname))
3623 Attempts to find the best http object to handle a request for a hostname.
3624 All aliases for the root http object and vhosts are searched for an exact
3625 match. Then, the vhost hierarchy is traversed again for a matching
3628 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3629 is set with the best matching http object. If there are no matches, the
3630 root http object is stored in outhttp and 0 is returned.
3634 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3635 const char *hostname)
3637 struct evhttp *vhost;
3638 struct evhttp *oldhttp;
3639 int match_found = 0;
3641 if (evhttp_find_alias(http, outhttp, hostname))
3646 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3647 if (prefix_suffix_match(vhost->vhost_pattern,
3648 hostname, 1 /* ignorecase */)) {
3654 } while (oldhttp != http);
3663 evhttp_handle_request(struct evhttp_request *req, void *arg)
3665 struct evhttp *http = arg;
3666 struct evhttp_cb *cb = NULL;
3667 const char *hostname;
3669 /* we have a new request on which the user needs to take action */
3672 bufferevent_disable(req->evcon->bufev, EV_READ);
3674 if (req->uri == NULL) {
3675 evhttp_send_error(req, req->response_code, NULL);
3679 if ((http->allowed_methods & req->type) == 0) {
3680 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3681 (unsigned)req->type, (unsigned)http->allowed_methods));
3682 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3686 /* handle potential virtual hosts */
3687 hostname = evhttp_request_get_host(req);
3688 if (hostname != NULL) {
3689 evhttp_find_vhost(http, &http, hostname);
3692 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3693 (*cb->cb)(req, cb->cbarg);
3697 /* Generic call back */
3699 (*http->gencb)(req, http->gencbarg);
3702 /* We need to send a 404 here */
3703 #define ERR_FORMAT "<html><head>" \
3704 "<title>404 Not Found</title>" \
3706 "<h1>Not Found</h1>" \
3707 "<p>The requested URL %s was not found on this server.</p>"\
3711 struct evbuffer *buf;
3713 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3714 evhttp_connection_free(req->evcon);
3718 if ((buf = evbuffer_new()) == NULL) {
3719 mm_free(escaped_html);
3720 evhttp_connection_free(req->evcon);
3724 evhttp_response_code_(req, HTTP_NOTFOUND, "Not Found");
3726 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3728 mm_free(escaped_html);
3730 evhttp_send_page_(req, buf);
3737 /* Listener callback when a connection arrives at a server. */
3739 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3741 struct evhttp *http = arg;
3743 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3747 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3749 struct evhttp_bound_socket *bound =
3750 evhttp_bind_socket_with_handle(http, address, port);
3756 struct evhttp_bound_socket *
3757 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3760 struct evhttp_bound_socket *bound;
3763 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3766 if (listen(fd, 128) == -1) {
3767 serrno = EVUTIL_SOCKET_ERROR();
3768 event_sock_warn(fd, "%s: listen", __func__);
3769 evutil_closesocket(fd);
3770 EVUTIL_SET_SOCKET_ERROR(serrno);
3774 bound = evhttp_accept_socket_with_handle(http, fd);
3776 if (bound != NULL) {
3777 event_debug(("Bound to port %d - Awaiting connections ... ",
3786 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3788 struct evhttp_bound_socket *bound =
3789 evhttp_accept_socket_with_handle(http, fd);
3796 evhttp_foreach_bound_socket(struct evhttp *http,
3797 evhttp_bound_socket_foreach_fn *function,
3800 struct evhttp_bound_socket *bound;
3802 TAILQ_FOREACH(bound, &http->sockets, next)
3803 function(bound, argument);
3806 struct evhttp_bound_socket *
3807 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3809 struct evhttp_bound_socket *bound;
3810 struct evconnlistener *listener;
3812 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3814 listener = evconnlistener_new(http->base, NULL, NULL,
3816 0, /* Backlog is '0' because we already said 'listen' */
3821 bound = evhttp_bind_listener(http, listener);
3823 evconnlistener_free(listener);
3829 struct evhttp_bound_socket *
3830 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3832 struct evhttp_bound_socket *bound;
3834 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3838 bound->listener = listener;
3839 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3841 evconnlistener_set_cb(listener, accept_socket_cb, http);
3846 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3848 return evconnlistener_get_fd(bound->listener);
3851 struct evconnlistener *
3852 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3854 return bound->listener;
3858 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3860 TAILQ_REMOVE(&http->sockets, bound, next);
3861 evconnlistener_free(bound->listener);
3865 static struct evhttp*
3866 evhttp_new_object(void)
3868 struct evhttp *http = NULL;
3870 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3871 event_warn("%s: calloc", __func__);
3875 evutil_timerclear(&http->timeout_read);
3876 evutil_timerclear(&http->timeout_write);
3878 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3879 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3880 evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
3881 evhttp_set_allowed_methods(http,
3888 TAILQ_INIT(&http->sockets);
3889 TAILQ_INIT(&http->callbacks);
3890 TAILQ_INIT(&http->connections);
3891 TAILQ_INIT(&http->virtualhosts);
3892 TAILQ_INIT(&http->aliases);
3898 evhttp_new(struct event_base *base)
3900 struct evhttp *http = NULL;
3902 http = evhttp_new_object();
3911 * Start a web server on the specified address and port.
3915 evhttp_start(const char *address, ev_uint16_t port)
3917 struct evhttp *http = NULL;
3919 http = evhttp_new_object();
3922 if (evhttp_bind_socket(http, address, port) == -1) {
3931 evhttp_free(struct evhttp* http)
3933 struct evhttp_cb *http_cb;
3934 struct evhttp_connection *evcon;
3935 struct evhttp_bound_socket *bound;
3936 struct evhttp* vhost;
3937 struct evhttp_server_alias *alias;
3939 /* Remove the accepting part */
3940 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3941 TAILQ_REMOVE(&http->sockets, bound, next);
3943 evconnlistener_free(bound->listener);
3948 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3949 /* evhttp_connection_free removes the connection */
3950 evhttp_connection_free(evcon);
3953 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3954 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3955 mm_free(http_cb->what);
3959 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3960 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3965 if (http->vhost_pattern != NULL)
3966 mm_free(http->vhost_pattern);
3968 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3969 TAILQ_REMOVE(&http->aliases, alias, next);
3970 mm_free(alias->alias);
3978 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3979 struct evhttp* vhost)
3981 /* a vhost can only be a vhost once and should not have bound sockets */
3982 if (vhost->vhost_pattern != NULL ||
3983 TAILQ_FIRST(&vhost->sockets) != NULL)
3986 vhost->vhost_pattern = mm_strdup(pattern);
3987 if (vhost->vhost_pattern == NULL)
3990 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3996 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3998 if (vhost->vhost_pattern == NULL)
4001 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
4003 mm_free(vhost->vhost_pattern);
4004 vhost->vhost_pattern = NULL;
4010 evhttp_add_server_alias(struct evhttp *http, const char *alias)
4012 struct evhttp_server_alias *evalias;
4014 evalias = mm_calloc(1, sizeof(*evalias));
4018 evalias->alias = mm_strdup(alias);
4019 if (!evalias->alias) {
4024 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
4030 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
4032 struct evhttp_server_alias *evalias;
4034 TAILQ_FOREACH(evalias, &http->aliases, next) {
4035 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
4036 TAILQ_REMOVE(&http->aliases, evalias, next);
4037 mm_free(evalias->alias);
4047 evhttp_set_timeout(struct evhttp* http, int timeout)
4049 evhttp_set_timeout_(&http->timeout_read, timeout, -1);
4050 evhttp_set_timeout_(&http->timeout_write, timeout, -1);
4053 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
4055 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4056 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4059 evhttp_set_read_timeout_tv(struct evhttp* http, const struct timeval* tv)
4061 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4064 evhttp_set_write_timeout_tv(struct evhttp* http, const struct timeval* tv)
4066 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4069 int evhttp_set_flags(struct evhttp *http, int flags)
4071 int avail_flags = 0;
4072 avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
4074 if (flags & ~avail_flags)
4076 http->flags &= ~avail_flags;
4078 http->flags |= flags;
4084 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
4086 if (max_headers_size < 0)
4087 http->default_max_headers_size = EV_SIZE_MAX;
4089 http->default_max_headers_size = max_headers_size;
4093 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
4095 if (max_body_size < 0)
4096 http->default_max_body_size = EV_UINT64_MAX;
4098 http->default_max_body_size = max_body_size;
4102 evhttp_set_default_content_type(struct evhttp *http,
4103 const char *content_type) {
4104 http->default_content_type = content_type;
4108 evhttp_set_allowed_methods(struct evhttp* http, ev_uint32_t methods)
4110 http->allowed_methods = methods;
4114 evhttp_set_ext_method_cmp(struct evhttp *http, evhttp_ext_method_cb cmp)
4116 http->ext_method_cmp = cmp;
4120 evhttp_set_cb(struct evhttp *http, const char *uri,
4121 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4123 struct evhttp_cb *http_cb;
4125 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4126 if (strcmp(http_cb->what, uri) == 0)
4130 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
4131 event_warn("%s: calloc", __func__);
4135 http_cb->what = mm_strdup(uri);
4136 if (http_cb->what == NULL) {
4137 event_warn("%s: strdup", __func__);
4142 http_cb->cbarg = cbarg;
4144 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
4150 evhttp_del_cb(struct evhttp *http, const char *uri)
4152 struct evhttp_cb *http_cb;
4154 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4155 if (strcmp(http_cb->what, uri) == 0)
4158 if (http_cb == NULL)
4161 TAILQ_REMOVE(&http->callbacks, http_cb, next);
4162 mm_free(http_cb->what);
4169 evhttp_set_gencb(struct evhttp *http,
4170 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4173 http->gencbarg = cbarg;
4177 evhttp_set_bevcb(struct evhttp *http,
4178 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
4181 http->bevcbarg = cbarg;
4185 evhttp_set_newreqcb(struct evhttp *http,
4186 int (*cb)(struct evhttp_request *, void *), void *cbarg)
4188 http->newreqcb = cb;
4189 http->newreqcbarg = cbarg;
4193 * Request related functions
4196 struct evhttp_request *
4197 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
4199 struct evhttp_request *req = NULL;
4201 /* Allocate request structure */
4202 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
4203 event_warn("%s: calloc", __func__);
4207 req->headers_size = 0;
4210 req->kind = EVHTTP_RESPONSE;
4211 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4212 if (req->input_headers == NULL) {
4213 event_warn("%s: calloc", __func__);
4216 TAILQ_INIT(req->input_headers);
4218 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4219 if (req->output_headers == NULL) {
4220 event_warn("%s: calloc", __func__);
4223 TAILQ_INIT(req->output_headers);
4225 if ((req->input_buffer = evbuffer_new()) == NULL) {
4226 event_warn("%s: evbuffer_new", __func__);
4230 if ((req->output_buffer = evbuffer_new()) == NULL) {
4231 event_warn("%s: evbuffer_new", __func__);
4242 evhttp_request_free(req);
4247 evhttp_request_free(struct evhttp_request *req)
4249 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
4250 req->flags |= EVHTTP_REQ_NEEDS_FREE;
4254 if (req->remote_host != NULL)
4255 mm_free(req->remote_host);
4256 if (req->uri != NULL)
4258 if (req->uri_elems != NULL)
4259 evhttp_uri_free(req->uri_elems);
4260 if (req->response_code_line != NULL)
4261 mm_free(req->response_code_line);
4262 if (req->host_cache != NULL)
4263 mm_free(req->host_cache);
4265 evhttp_clear_headers(req->input_headers);
4266 mm_free(req->input_headers);
4268 evhttp_clear_headers(req->output_headers);
4269 mm_free(req->output_headers);
4271 if (req->input_buffer != NULL)
4272 evbuffer_free(req->input_buffer);
4274 if (req->output_buffer != NULL)
4275 evbuffer_free(req->output_buffer);
4281 evhttp_request_own(struct evhttp_request *req)
4283 req->flags |= EVHTTP_USER_OWNED;
4287 evhttp_request_is_owned(struct evhttp_request *req)
4289 return (req->flags & EVHTTP_USER_OWNED) != 0;
4292 struct evhttp_connection *
4293 evhttp_request_get_connection(struct evhttp_request *req)
4299 evhttp_connection_get_base(struct evhttp_connection *conn)
4305 evhttp_request_set_chunked_cb(struct evhttp_request *req,
4306 void (*cb)(struct evhttp_request *, void *))
4312 evhttp_request_set_header_cb(struct evhttp_request *req,
4313 int (*cb)(struct evhttp_request *, void *))
4315 req->header_cb = cb;
4319 evhttp_request_set_error_cb(struct evhttp_request *req,
4320 void (*cb)(enum evhttp_request_error, void *))
4326 evhttp_request_set_on_complete_cb(struct evhttp_request *req,
4327 void (*cb)(struct evhttp_request *, void *), void *cb_arg)
4329 req->on_complete_cb = cb;
4330 req->on_complete_cb_arg = cb_arg;
4334 * Allows for inspection of the request URI
4338 evhttp_request_get_uri(const struct evhttp_request *req) {
4339 if (req->uri == NULL)
4340 event_debug(("%s: request %p has no uri\n", __func__, req));
4344 const struct evhttp_uri *
4345 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4346 if (req->uri_elems == NULL)
4347 event_debug(("%s: request %p has no uri elems\n",
4349 return (req->uri_elems);
4353 evhttp_request_get_host(struct evhttp_request *req)
4355 const char *host = NULL;
4357 if (req->host_cache)
4358 return req->host_cache;
4361 host = evhttp_uri_get_host(req->uri_elems);
4362 if (!host && req->input_headers) {
4366 host = evhttp_find_header(req->input_headers, "Host");
4367 /* The Host: header may include a port. Remove it here
4368 to be consistent with uri_elems case above. */
4370 p = host + strlen(host) - 1;
4371 while (p > host && EVUTIL_ISDIGIT_(*p))
4373 if (p > host && *p == ':') {
4375 req->host_cache = mm_malloc(len + 1);
4376 if (!req->host_cache) {
4377 event_warn("%s: malloc", __func__);
4380 memcpy(req->host_cache, host, len);
4381 req->host_cache[len] = '\0';
4382 host = req->host_cache;
4390 enum evhttp_cmd_type
4391 evhttp_request_get_command(const struct evhttp_request *req) {
4396 evhttp_request_get_response_code(const struct evhttp_request *req)
4398 return req->response_code;
4402 evhttp_request_get_response_code_line(const struct evhttp_request *req)
4404 return req->response_code_line;
4407 /** Returns the input headers */
4408 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4410 return (req->input_headers);
4413 /** Returns the output headers */
4414 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4416 return (req->output_headers);
4419 /** Returns the input buffer */
4420 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4422 return (req->input_buffer);
4425 /** Returns the output buffer */
4426 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4428 return (req->output_buffer);
4433 * Takes a file descriptor to read a request from.
4434 * The callback is executed once the whole request has been read.
4437 static struct evhttp_connection*
4438 evhttp_get_request_connection(
4439 struct evhttp* http,
4440 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
4442 struct evhttp_connection *evcon;
4443 char *hostname = NULL, *portname = NULL;
4444 struct bufferevent* bev = NULL;
4446 #ifdef EVENT__HAVE_STRUCT_SOCKADDR_UN
4447 if (sa->sa_family == AF_UNIX) {
4448 struct sockaddr_un *sa_un = (struct sockaddr_un *)sa;
4449 sa_un->sun_path[0] = '\0';
4453 name_from_addr(sa, salen, &hostname, &portname);
4454 if (hostname == NULL || portname == NULL) {
4455 if (hostname) mm_free(hostname);
4456 if (portname) mm_free(portname);
4460 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4461 __func__, hostname, portname, EV_SOCK_ARG(fd)));
4463 /* we need a connection object to put the http request on */
4464 if (http->bevcb != NULL) {
4465 bev = (*http->bevcb)(http->base, http->bevcbarg);
4467 evcon = evhttp_connection_base_bufferevent_new(
4468 http->base, NULL, bev, hostname, atoi(portname));
4474 evcon->max_headers_size = http->default_max_headers_size;
4475 evcon->max_body_size = http->default_max_body_size;
4476 if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4477 evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4479 evcon->flags |= EVHTTP_CON_INCOMING;
4480 evcon->state = EVCON_READING_FIRSTLINE;
4484 if (bufferevent_setfd(evcon->bufev, fd))
4486 if (bufferevent_enable(evcon->bufev, EV_READ))
4488 if (bufferevent_disable(evcon->bufev, EV_WRITE))
4490 bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
4495 evhttp_connection_free(evcon);
4500 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4502 struct evhttp *http = evcon->http_server;
4503 struct evhttp_request *req;
4504 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4507 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4508 event_warn("%s: strdup", __func__);
4509 evhttp_request_free(req);
4512 req->remote_port = evcon->port;
4514 req->evcon = evcon; /* the request ends up owning the connection */
4515 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4517 /* We did not present the request to the user yet, so treat it
4518 * as if the user was done with the request. This allows us
4519 * to free the request on a persistent connection if the
4520 * client drops it without sending a request.
4523 req->kind = EVHTTP_REQUEST;
4525 if (http->newreqcb && http->newreqcb(req, http->newreqcbarg) == -1) {
4526 evhttp_request_free(req);
4530 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4532 evhttp_start_read_(evcon);
4538 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4539 struct sockaddr *sa, ev_socklen_t salen)
4541 struct evhttp_connection *evcon;
4543 evcon = evhttp_get_request_connection(http, fd, sa, salen);
4544 if (evcon == NULL) {
4545 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4546 __func__, EV_SOCK_ARG(fd));
4547 evutil_closesocket(fd);
4551 /* the timeout can be used by the server to close idle connections */
4552 if (evutil_timerisset(&http->timeout_read))
4553 evhttp_connection_set_read_timeout_tv(evcon, &http->timeout_read);
4554 if (evutil_timerisset(&http->timeout_write))
4555 evhttp_connection_set_write_timeout_tv(evcon, &http->timeout_write);
4558 * if we want to accept more than one request on a connection,
4559 * we need to know which http server it belongs to.
4561 evcon->http_server = http;
4562 evcon->ext_method_cmp = http->ext_method_cmp;
4563 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4565 if (evhttp_associate_new_request_with_connection(evcon) == -1)
4566 evhttp_connection_free(evcon);
4571 * Network helper functions that we do not want to export to the rest of
4576 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4577 char **phost, char **pport)
4579 char ntop[NI_MAXHOST];
4580 char strport[NI_MAXSERV];
4583 #ifdef EVENT__HAVE_GETNAMEINFO
4584 ni_result = getnameinfo(sa, salen,
4585 ntop, sizeof(ntop), strport, sizeof(strport),
4586 NI_NUMERICHOST|NI_NUMERICSERV);
4588 if (ni_result != 0) {
4590 /* Windows doesn't have an EAI_SYSTEM. */
4591 if (ni_result == EAI_SYSTEM)
4592 event_err(1, "getnameinfo failed");
4595 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4599 ni_result = fake_getnameinfo(sa, salen,
4600 ntop, sizeof(ntop), strport, sizeof(strport),
4601 NI_NUMERICHOST|NI_NUMERICSERV);
4606 *phost = mm_strdup(ntop);
4607 *pport = mm_strdup(strport);
4610 /* Create a non-blocking socket and bind it */
4611 static evutil_socket_t
4612 create_bind_socket_nonblock(struct evutil_addrinfo *ai, int reuse)
4619 /* Create listen socket */
4620 fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
4621 SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
4623 event_sock_warn(-1, "socket");
4627 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
4630 if (evutil_make_listen_socket_reuseable(fd) < 0)
4635 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
4643 serrno = EVUTIL_SOCKET_ERROR();
4644 evutil_closesocket(fd);
4645 EVUTIL_SET_SOCKET_ERROR(serrno);
4649 static struct evutil_addrinfo *
4650 make_addrinfo(const char *address, ev_uint16_t port)
4652 struct evutil_addrinfo *ai = NULL;
4654 struct evutil_addrinfo hints;
4655 char strport[NI_MAXSERV];
4658 memset(&hints, 0, sizeof(hints));
4659 hints.ai_family = AF_UNSPEC;
4660 hints.ai_socktype = SOCK_STREAM;
4661 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
4662 * types we don't have an interface to connect to. */
4663 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
4664 evutil_snprintf(strport, sizeof(strport), "%d", port);
4665 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
4667 if (ai_result == EVUTIL_EAI_SYSTEM)
4668 event_warn("getaddrinfo");
4670 event_warnx("getaddrinfo: %s",
4671 evutil_gai_strerror(ai_result));
4678 static evutil_socket_t
4679 bind_socket(const char *address, ev_uint16_t port, int reuse)
4682 struct evutil_addrinfo *aitop = NULL;
4684 /* just create an unbound socket */
4685 if (address == NULL && port == 0)
4686 return create_bind_socket_nonblock(NULL, 0);
4688 aitop = make_addrinfo(address, port);
4693 fd = create_bind_socket_nonblock(aitop, reuse);
4695 evutil_freeaddrinfo(aitop);
4702 char *scheme; /* scheme; e.g http, ftp etc */
4703 char *userinfo; /* userinfo (typically username:pass), or NULL */
4704 char *host; /* hostname, IP address, or NULL */
4705 int port; /* port, or zero */
4706 char *path; /* path, or "". */
4707 char *query; /* query, or NULL */
4708 char *fragment; /* fragment or NULL */
4712 evhttp_uri_new(void)
4714 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
4721 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
4726 /* Return true if the string starting at s and ending immediately before eos
4727 * is a valid URI scheme according to RFC3986
4730 scheme_ok(const char *s, const char *eos)
4732 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4733 EVUTIL_ASSERT(eos >= s);
4736 if (!EVUTIL_ISALPHA_(*s))
4739 if (! EVUTIL_ISALNUM_(*s) &&
4740 *s != '+' && *s != '-' && *s != '.')
4746 #define SUBDELIMS "!$&'()*+,;="
4748 /* Return true iff [s..eos) is a valid userinfo */
4750 userinfo_ok(const char *s, const char *eos)
4753 if (CHAR_IS_UNRESERVED(*s) ||
4754 strchr(SUBDELIMS, *s) ||
4757 else if (*s == '%' && s+2 < eos &&
4758 EVUTIL_ISXDIGIT_(s[1]) &&
4759 EVUTIL_ISXDIGIT_(s[2]))
4768 regname_ok(const char *s, const char *eos)
4770 while (s && s<eos) {
4771 if (CHAR_IS_UNRESERVED(*s) ||
4772 strchr(SUBDELIMS, *s))
4774 else if (*s == '%' &&
4775 EVUTIL_ISXDIGIT_(s[1]) &&
4776 EVUTIL_ISXDIGIT_(s[2]))
4785 parse_port(const char *s, const char *eos)
4789 if (! EVUTIL_ISDIGIT_(*s))
4791 portnum = (portnum * 10) + (*s - '0');
4794 if (portnum > 65535)
4801 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4803 bracket_addr_ok(const char *s, const char *eos)
4805 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4808 /* IPvFuture, or junk.
4809 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4811 s += 2; /* skip [v */
4813 if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
4815 while (s < eos && *s != '.') {
4816 if (EVUTIL_ISXDIGIT_(*s))
4825 if (CHAR_IS_UNRESERVED(*s) ||
4826 strchr(SUBDELIMS, *s) ||
4836 ev_ssize_t n_chars = eos-s-2;
4837 struct in6_addr in6;
4838 if (n_chars >= 64) /* way too long */
4840 memcpy(buf, s+1, n_chars);
4842 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4847 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4852 uri->host = mm_strdup("");
4853 if (uri->host == NULL) {
4854 event_warn("%s: strdup", __func__);
4860 /* Optionally, we start with "userinfo@" */
4862 cp = strchr(s, '@');
4863 if (cp && cp < eos) {
4864 if (! userinfo_ok(s,cp))
4867 uri->userinfo = mm_strdup(s);
4868 if (uri->userinfo == NULL) {
4869 event_warn("%s: strdup", __func__);
4875 /* Optionally, we end with ":port" */
4876 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
4878 if (port >= cp && *port == ':') {
4879 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4882 else if ((uri->port = parse_port(port+1, eos))<0)
4886 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4887 * an IP-Literal, or a reg-name */
4888 EVUTIL_ASSERT(eos >= cp);
4889 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4890 /* IPv6address, IP-Literal, or junk. */
4891 if (! bracket_addr_ok(cp, eos))
4894 /* Make sure the host part is ok. */
4895 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4898 uri->host = mm_malloc(eos-cp+1);
4899 if (uri->host == NULL) {
4900 event_warn("%s: malloc", __func__);
4903 memcpy(uri->host, cp, eos-cp);
4904 uri->host[eos-cp] = '\0';
4910 end_of_authority(char *cp)
4913 if (*cp == '?' || *cp == '#' || *cp == '/')
4926 /* Return the character after the longest prefix of 'cp' that matches...
4927 * *pchar / "/" if allow_qchars is false, or
4928 * *(pchar / "/" / "?") if allow_qchars is true.
4931 end_of_path(char *cp, enum uri_part part, unsigned flags)
4933 if (flags & EVHTTP_URI_NONCONFORMANT) {
4934 /* If NONCONFORMANT:
4935 * Path is everything up to a # or ? or nul.
4936 * Query is everything up a # or nul
4937 * Fragment is everything up to a nul.
4941 while (*cp && *cp != '#' && *cp != '?')
4945 while (*cp && *cp != '#')
4956 if (CHAR_IS_UNRESERVED(*cp) ||
4957 strchr(SUBDELIMS, *cp) ||
4958 *cp == ':' || *cp == '@' || *cp == '/')
4960 else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
4961 EVUTIL_ISXDIGIT_(cp[2]))
4963 else if (*cp == '?' && part != PART_PATH)
4972 path_matches_noscheme(const char *cp)
4977 else if (*cp == '/')
4985 evhttp_uri_parse(const char *source_uri)
4987 return evhttp_uri_parse_with_flags(source_uri, 0);
4991 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4993 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4994 char *path = NULL, *fragment = NULL;
4995 int got_authority = 0;
4997 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4999 event_warn("%s: calloc", __func__);
5005 readbuf = mm_strdup(source_uri);
5006 if (readbuf == NULL) {
5007 event_warn("%s: strdup", __func__);
5014 /* We try to follow RFC3986 here as much as we can, and match
5017 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
5019 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
5023 token = strchr(readp, ':');
5024 if (token && scheme_ok(readp,token)) {
5026 uri->scheme = mm_strdup(readp);
5027 if (uri->scheme == NULL) {
5028 event_warn("%s: strdup", __func__);
5031 readp = token+1; /* eat : */
5034 /* 2. Optionally, "//" then an 'authority' part. */
5035 if (readp[0]=='/' && readp[1] == '/') {
5039 path = end_of_authority(readp);
5040 if (parse_authority(uri, authority, path) < 0)
5046 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
5049 readp = end_of_path(path, PART_PATH, flags);
5052 if (*readp == '?') {
5056 readp = end_of_path(readp, PART_QUERY, flags);
5059 if (*readp == '#') {
5063 readp = end_of_path(readp, PART_FRAGMENT, flags);
5065 if (*readp != '\0') {
5069 /* These next two cases may be unreachable; I'm leaving them
5070 * in to be defensive. */
5071 /* If you didn't get an authority, the path can't begin with "//" */
5072 if (!got_authority && path[0]=='/' && path[1]=='/')
5074 /* If you did get an authority, the path must begin with "/" or be
5076 if (got_authority && path[0] != '/' && path[0] != '\0')
5078 /* (End of maybe-unreachable cases) */
5080 /* If there was no scheme, the first part of the path (if any) must
5081 * have no colon in it. */
5082 if (! uri->scheme && !path_matches_noscheme(path))
5085 EVUTIL_ASSERT(path);
5086 uri->path = mm_strdup(path);
5087 if (uri->path == NULL) {
5088 event_warn("%s: strdup", __func__);
5093 uri->query = mm_strdup(query);
5094 if (uri->query == NULL) {
5095 event_warn("%s: strdup", __func__);
5100 uri->fragment = mm_strdup(fragment);
5101 if (uri->fragment == NULL) {
5102 event_warn("%s: strdup", __func__);
5112 evhttp_uri_free(uri);
5118 static struct evhttp_uri *
5119 evhttp_uri_parse_authority(char *source_uri)
5121 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
5125 event_warn("%s: calloc", __func__);
5131 end = end_of_authority(source_uri);
5132 if (parse_authority(uri, source_uri, end) < 0)
5135 uri->path = mm_strdup("");
5136 if (uri->path == NULL) {
5137 event_warn("%s: strdup", __func__);
5144 evhttp_uri_free(uri);
5149 evhttp_uri_free(struct evhttp_uri *uri)
5151 #define URI_FREE_STR_(f) \
5156 URI_FREE_STR_(scheme);
5157 URI_FREE_STR_(userinfo);
5158 URI_FREE_STR_(host);
5159 URI_FREE_STR_(path);
5160 URI_FREE_STR_(query);
5161 URI_FREE_STR_(fragment);
5164 #undef URI_FREE_STR_
5168 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
5170 struct evbuffer *tmp = 0;
5171 size_t joined_size = 0;
5172 char *output = NULL;
5174 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
5176 if (!uri || !buf || !limit)
5179 tmp = evbuffer_new();
5185 evbuffer_add(tmp, ":", 1);
5188 evbuffer_add(tmp, "//", 2);
5190 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
5193 evbuffer_add_printf(tmp,":%d", uri->port);
5195 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
5203 evbuffer_add(tmp, "?", 1);
5207 if (uri->fragment) {
5208 evbuffer_add(tmp, "#", 1);
5212 evbuffer_add(tmp, "\0", 1); /* NUL */
5214 joined_size = evbuffer_get_length(tmp);
5216 if (joined_size > limit) {
5217 /* It doesn't fit. */
5221 evbuffer_remove(tmp, buf, joined_size);
5232 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
5237 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
5239 return uri->userinfo;
5242 evhttp_uri_get_host(const struct evhttp_uri *uri)
5247 evhttp_uri_get_port(const struct evhttp_uri *uri)
5252 evhttp_uri_get_path(const struct evhttp_uri *uri)
5257 evhttp_uri_get_query(const struct evhttp_uri *uri)
5262 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
5264 return uri->fragment;
5267 #define URI_SET_STR_(f) do { \
5271 if ((uri->f = mm_strdup(f)) == NULL) { \
5272 event_warn("%s: strdup()", __func__); \
5281 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
5283 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
5286 URI_SET_STR_(scheme);
5290 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
5292 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
5294 URI_SET_STR_(userinfo);
5298 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
5301 if (host[0] == '[') {
5302 if (! bracket_addr_ok(host, host+strlen(host)))
5305 if (! regname_ok(host, host+strlen(host)))
5314 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
5321 #define end_of_cpath(cp,p,f) \
5322 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
5325 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
5327 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
5334 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
5336 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
5338 URI_SET_STR_(query);
5342 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
5344 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
5346 URI_SET_STR_(fragment);