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 if ((evcon->flags & EVHTTP_CON_OUTGOING) &&
882 (evcon->flags & EVHTTP_CON_AUTOFREE)) {
883 evhttp_connection_free(evcon);
886 /* The call to evhttp_connection_reset_ overwrote errno.
887 * Let's restore the original errno, so that the user's
888 * callback can have a better idea of what the error was.
890 EVUTIL_SET_SOCKET_ERROR(errsave);
892 /* inform the user */
893 if (error_cb != NULL)
894 error_cb(error, error_cb_arg);
899 /* Bufferevent callback: invoked when any data has been written from an
900 * http connection's bufferevent */
902 evhttp_write_cb(struct bufferevent *bufev, void *arg)
904 struct evhttp_connection *evcon = arg;
906 /* Activate our call back */
907 if (evcon->cb != NULL)
908 (*evcon->cb)(evcon, evcon->cb_arg);
912 * Advance the connection state.
913 * - If this is an outgoing connection, we've just processed the response;
914 * idle or close the connection.
915 * - If this is an incoming connection, we've just processed the request;
919 evhttp_connection_done(struct evhttp_connection *evcon)
921 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
922 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
926 /* idle or close the connection */
927 int need_close = evhttp_is_request_connection_close(req);
928 TAILQ_REMOVE(&evcon->requests, req, next);
931 evcon->state = EVCON_IDLE;
933 /* check if we got asked to close the connection */
935 evhttp_connection_reset_(evcon);
937 if (TAILQ_FIRST(&evcon->requests) != NULL) {
939 * We have more requests; reset the connection
940 * and deal with the next request.
942 if (!evhttp_connected(evcon))
943 evhttp_connection_connect_(evcon);
945 evhttp_request_dispatch(evcon);
946 } else if (!need_close) {
948 * The connection is going to be persistent, but we
949 * need to detect if the other side closes it.
951 evhttp_connection_start_detectclose(evcon);
952 } else if ((evcon->flags & EVHTTP_CON_AUTOFREE)) {
954 * If we have no more requests that need completion
955 * and we're not waiting for the connection to close
961 * incoming connection - we need to leave the request on the
962 * connection so that we can reply to it.
964 evcon->state = EVCON_WRITING;
967 /* notify the user of the request */
968 (*req->cb)(req, req->cb_arg);
970 /* if this was an outgoing request, we own and it's done. so free it. */
972 evhttp_request_free_auto(req);
975 /* If this was the last request of an outgoing connection and we're
976 * not waiting to receive a connection close event and we want to
977 * automatically free the connection. We check to ensure our request
978 * list is empty one last time just in case our callback added a
981 if (free_evcon && TAILQ_FIRST(&evcon->requests) == NULL) {
982 evhttp_connection_free(evcon);
987 * Handles reading from a chunked request.
988 * return ALL_DATA_READ:
989 * all data has been read
990 * return MORE_DATA_EXPECTED:
991 * more data is expected
992 * return DATA_CORRUPTED:
994 * return REQUEST_CANCELED:
995 * request was canceled by the user calling evhttp_cancel_request
996 * return DATA_TOO_LONG:
997 * ran over the maximum limit
1000 static enum message_read_status
1001 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
1003 if (req == NULL || buf == NULL) {
1004 return DATA_CORRUPTED;
1010 if ((buflen = evbuffer_get_length(buf)) == 0) {
1014 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
1015 * check for overflow conditions */
1016 if (buflen > EV_SSIZE_MAX) {
1017 return DATA_CORRUPTED;
1020 if (req->ntoread < 0) {
1021 /* Read chunk size */
1023 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
1028 /* the last chunk is on a new line? */
1029 if (strlen(p) == 0) {
1033 ntoread = evutil_strtoll(p, &endp, 16);
1034 error = (*p == '\0' ||
1035 (*endp != '\0' && *endp != ' ') ||
1039 /* could not get chunk size */
1040 return (DATA_CORRUPTED);
1043 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
1044 if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
1045 return DATA_CORRUPTED;
1048 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
1049 /* failed body length test */
1050 event_debug(("Request body is too long"));
1051 return (DATA_TOO_LONG);
1054 req->body_size += (size_t)ntoread;
1055 req->ntoread = ntoread;
1056 if (req->ntoread == 0) {
1058 return (ALL_DATA_READ);
1063 /* req->ntoread is signed int64, len is ssize_t, based on arch,
1064 * ssize_t could only be 32b, check for these conditions */
1065 if (req->ntoread > EV_SSIZE_MAX) {
1066 return DATA_CORRUPTED;
1069 /* don't have enough to complete a chunk; wait for more */
1070 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
1071 return (MORE_DATA_EXPECTED);
1073 /* Completed chunk */
1074 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
1076 if (req->chunk_cb != NULL) {
1077 req->flags |= EVHTTP_REQ_DEFER_FREE;
1078 (*req->chunk_cb)(req, req->cb_arg);
1079 evbuffer_drain(req->input_buffer,
1080 evbuffer_get_length(req->input_buffer));
1081 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1082 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1083 return (REQUEST_CANCELED);
1088 return (MORE_DATA_EXPECTED);
1092 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
1094 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1096 switch (evhttp_parse_headers_(req, buf)) {
1097 case DATA_CORRUPTED:
1099 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1102 bufferevent_disable(evcon->bufev, EV_READ);
1103 evhttp_connection_done(evcon);
1105 case MORE_DATA_EXPECTED:
1106 case REQUEST_CANCELED: /* ??? */
1113 evhttp_lingering_close(struct evhttp_connection *evcon,
1114 struct evhttp_request *req)
1116 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1118 size_t n = evbuffer_get_length(buf);
1119 if (n > (size_t) req->ntoread)
1120 n = (size_t) req->ntoread;
1122 req->body_size += n;
1124 event_debug(("Request body is too long, left " EV_I64_FMT,
1125 EV_I64_ARG(req->ntoread)));
1127 evbuffer_drain(buf, n);
1129 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1132 evhttp_lingering_fail(struct evhttp_connection *evcon,
1133 struct evhttp_request *req)
1135 if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE)
1136 evhttp_lingering_close(evcon, req);
1138 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1142 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1144 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1147 switch (evhttp_handle_chunked_read(req, buf)) {
1149 /* finished last chunk */
1150 evcon->state = EVCON_READING_TRAILER;
1151 evhttp_read_trailer(evcon, req);
1153 case DATA_CORRUPTED:
1155 /* corrupted data */
1156 evhttp_connection_fail_(evcon,
1157 EVREQ_HTTP_DATA_TOO_LONG);
1159 case REQUEST_CANCELED:
1160 /* request canceled */
1161 evhttp_request_free_auto(req);
1163 case MORE_DATA_EXPECTED:
1167 } else if (req->ntoread < 0) {
1168 /* Read until connection close. */
1169 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
1170 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
1174 req->body_size += evbuffer_get_length(buf);
1175 evbuffer_add_buffer(req->input_buffer, buf);
1176 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
1177 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
1178 /* We've postponed moving the data until now, but we're
1179 * about to use it. */
1180 size_t n = evbuffer_get_length(buf);
1182 if (n > (size_t) req->ntoread)
1183 n = (size_t) req->ntoread;
1185 req->body_size += n;
1186 evbuffer_remove_buffer(buf, req->input_buffer, n);
1189 if (req->body_size > req->evcon->max_body_size ||
1190 (!req->chunked && req->ntoread >= 0 &&
1191 (size_t)req->ntoread > req->evcon->max_body_size)) {
1192 /* XXX: The above casted comparison must checked for overflow */
1193 /* failed body length test */
1195 evhttp_lingering_fail(evcon, req);
1199 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1200 req->flags |= EVHTTP_REQ_DEFER_FREE;
1201 (*req->chunk_cb)(req, req->cb_arg);
1202 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1203 evbuffer_drain(req->input_buffer,
1204 evbuffer_get_length(req->input_buffer));
1205 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1206 evhttp_request_free_auto(req);
1211 if (!req->ntoread) {
1212 bufferevent_disable(evcon->bufev, EV_READ);
1213 /* Completed content length */
1214 evhttp_connection_done(evcon);
1219 #define get_deferred_queue(evcon) \
1223 * Gets called when more data becomes available
1227 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1229 struct evhttp_connection *evcon = arg;
1230 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1232 /* Cancel if it's pending. */
1233 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1234 &evcon->read_more_deferred_cb);
1236 switch (evcon->state) {
1237 case EVCON_READING_FIRSTLINE:
1238 evhttp_read_firstline(evcon, req);
1239 /* note the request may have been freed in
1240 * evhttp_read_body */
1242 case EVCON_READING_HEADERS:
1243 evhttp_read_header(evcon, req);
1244 /* note the request may have been freed in
1245 * evhttp_read_body */
1247 case EVCON_READING_BODY:
1248 evhttp_read_body(evcon, req);
1249 /* note the request may have been freed in
1250 * evhttp_read_body */
1252 case EVCON_READING_TRAILER:
1253 evhttp_read_trailer(evcon, req);
1258 struct evbuffer *input;
1261 input = bufferevent_get_input(evcon->bufev);
1262 total_len = evbuffer_get_length(input);
1263 event_debug(("%s: read "EV_SIZE_FMT
1264 " bytes in EVCON_IDLE state,"
1265 " resetting connection",
1266 __func__, EV_SIZE_ARG(total_len)));
1269 evhttp_connection_reset_(evcon);
1272 case EVCON_DISCONNECTED:
1273 case EVCON_CONNECTING:
1276 event_errx(1, "%s: illegal connection state %d",
1277 __func__, evcon->state);
1282 evhttp_deferred_read_cb(struct event_callback *cb, void *data)
1284 struct evhttp_connection *evcon = data;
1285 struct bufferevent *bev = evcon->bufev;
1287 (bev->readcb)(evcon->bufev, evcon);
1291 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1293 /* This is after writing the request to the server */
1294 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1295 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
1296 EVUTIL_ASSERT(req != NULL);
1298 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1300 /* We need to wait until we've written all of our output data before we can
1302 if (evbuffer_get_length(output) > 0)
1305 /* We are done writing our header and are now expecting the response */
1306 req->kind = EVHTTP_RESPONSE;
1308 evhttp_start_read_(evcon);
1312 * Clean up a connection object
1316 evhttp_connection_free(struct evhttp_connection *evcon)
1318 struct evhttp_request *req;
1321 /* notify interested parties that this connection is going down */
1322 if (evcon->fd != -1) {
1323 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1324 (*evcon->closecb)(evcon, evcon->closecb_arg);
1327 /* remove all requests that might be queued on this
1328 * connection. for server connections, this should be empty.
1329 * because it gets dequeued either in evhttp_connection_done or
1330 * evhttp_connection_fail_.
1332 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1333 evhttp_request_free_(evcon, req);
1336 if (evcon->http_server != NULL) {
1337 struct evhttp *http = evcon->http_server;
1338 TAILQ_REMOVE(&http->connections, evcon, next);
1339 http->connection_cnt--;
1342 if (event_initialized(&evcon->retry_ev)) {
1343 event_del(&evcon->retry_ev);
1344 event_debug_unassign(&evcon->retry_ev);
1347 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1348 &evcon->read_more_deferred_cb);
1350 if (evcon->bufev != NULL) {
1352 !(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE);
1353 if (evcon->fd == -1)
1354 evcon->fd = bufferevent_getfd(evcon->bufev);
1356 bufferevent_free(evcon->bufev);
1359 if (evcon->fd != -1) {
1360 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1362 evutil_closesocket(evcon->fd);
1365 if (evcon->bind_address != NULL)
1366 mm_free(evcon->bind_address);
1368 if (evcon->address != NULL)
1369 mm_free(evcon->address);
1375 evhttp_connection_free_on_completion(struct evhttp_connection *evcon) {
1376 evcon->flags |= EVHTTP_CON_AUTOFREE;
1380 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1381 const char *address)
1383 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1384 if (evcon->bind_address)
1385 mm_free(evcon->bind_address);
1386 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1387 event_warn("%s: strdup", __func__);
1391 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1394 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1395 evcon->bind_port = port;
1399 evhttp_request_dispatch(struct evhttp_connection* evcon)
1401 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1403 /* this should not usually happy but it's possible */
1407 EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST);
1409 /* delete possible close detection events */
1410 evhttp_connection_stop_detectclose(evcon);
1412 /* we assume that the connection is connected already */
1413 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1415 evcon->state = EVCON_WRITING;
1417 /* Create the header from the store arguments */
1418 evhttp_make_header(evcon, req);
1420 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1423 /* Reset our connection state: disables reading/writing, closes our fd (if
1424 * any), clears out buffers, and puts us in state DISCONNECTED. */
1426 evhttp_connection_reset_(struct evhttp_connection *evcon)
1428 struct evbuffer *tmp;
1431 bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL);
1433 /* XXXX This is not actually an optimal fix. Instead we ought to have
1434 an API for "stop connecting", or use bufferevent_setfd to turn off
1435 connecting. But for Libevent 2.0, this seems like a minimal change
1436 least likely to disrupt the rest of the bufferevent and http code.
1438 Why is this here? If the fd is set in the bufferevent, and the
1439 bufferevent is connecting, then you can't actually stop the
1440 bufferevent from trying to connect with bufferevent_disable(). The
1441 connect will never trigger, since we close the fd, but the timeout
1442 might. That caused an assertion failure in evhttp_connection_fail_.
1444 bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE);
1446 if (evcon->fd == -1)
1447 evcon->fd = bufferevent_getfd(evcon->bufev);
1449 if (evcon->fd != -1) {
1450 /* inform interested parties about connection close */
1451 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1452 (*evcon->closecb)(evcon, evcon->closecb_arg);
1454 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1455 evutil_closesocket(evcon->fd);
1458 err = bufferevent_setfd(evcon->bufev, -1);
1459 EVUTIL_ASSERT(!err && "setfd");
1461 /* we need to clean up any buffered data */
1462 tmp = bufferevent_get_output(evcon->bufev);
1463 err = evbuffer_drain(tmp, -1);
1464 EVUTIL_ASSERT(!err && "drain output");
1465 tmp = bufferevent_get_input(evcon->bufev);
1466 err = evbuffer_drain(tmp, -1);
1467 EVUTIL_ASSERT(!err && "drain input");
1469 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1471 evcon->state = EVCON_DISCONNECTED;
1475 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1477 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1478 bufferevent_enable(evcon->bufev, EV_READ);
1482 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1484 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1485 bufferevent_disable(evcon->bufev, EV_READ);
1489 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1491 struct evhttp_connection *evcon = arg;
1493 evcon->state = EVCON_DISCONNECTED;
1494 evhttp_connection_connect_(evcon);
1498 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1500 struct evcon_requestq requests;
1501 EVUTIL_ASSERT(evcon->flags & EVHTTP_CON_OUTGOING);
1503 evhttp_connection_reset_(evcon);
1505 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1506 struct timeval tv_retry = evcon->initial_retry_timeout;
1508 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1509 /* XXXX handle failure from evhttp_add_event */
1510 for (i=0; i < evcon->retry_cnt; ++i) {
1511 tv_retry.tv_usec *= 2;
1512 if (tv_retry.tv_usec > 1000000) {
1513 tv_retry.tv_usec -= 1000000;
1514 tv_retry.tv_sec += 1;
1516 tv_retry.tv_sec *= 2;
1517 if (tv_retry.tv_sec > 3600) {
1518 tv_retry.tv_sec = 3600;
1519 tv_retry.tv_usec = 0;
1522 event_add(&evcon->retry_ev, &tv_retry);
1528 * User callback can do evhttp_make_request() on the same
1529 * evcon so new request will be added to evcon->requests. To
1530 * avoid freeing it prematurely we iterate over the copy of
1533 TAILQ_INIT(&requests);
1534 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1535 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1536 TAILQ_REMOVE(&evcon->requests, request, next);
1537 TAILQ_INSERT_TAIL(&requests, request, next);
1540 /* for now, we just signal all requests by executing their callbacks */
1541 while (TAILQ_FIRST(&requests) != NULL) {
1542 struct evhttp_request *request = TAILQ_FIRST(&requests);
1543 TAILQ_REMOVE(&requests, request, next);
1544 request->evcon = NULL;
1546 /* we might want to set an error here */
1547 request->cb(request, request->cb_arg);
1548 evhttp_request_free_auto(request);
1551 if (TAILQ_FIRST(&evcon->requests) == NULL
1552 && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1553 evhttp_connection_free(evcon);
1559 evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
1560 struct evhttp_request *req)
1562 struct evbuffer *buf;
1564 /** Second time, we can't read anything */
1565 if (evcon->flags & EVHTTP_CON_READING_ERROR) {
1566 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1567 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1571 req->kind = EVHTTP_RESPONSE;
1573 buf = bufferevent_get_output(evcon->bufev);
1574 evbuffer_unfreeze(buf, 1);
1575 evbuffer_drain(buf, evbuffer_get_length(buf));
1576 evbuffer_freeze(buf, 1);
1578 evhttp_start_read_(evcon);
1579 evcon->flags |= EVHTTP_CON_READING_ERROR;
1583 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1585 struct evhttp_connection *evcon = arg;
1586 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1588 if (evcon->fd == -1)
1589 evcon->fd = bufferevent_getfd(bufev);
1591 switch (evcon->state) {
1592 case EVCON_CONNECTING:
1593 if (what & BEV_EVENT_TIMEOUT) {
1594 event_debug(("%s: connection timeout for \"%s:%d\" on "
1596 __func__, evcon->address, evcon->port,
1597 EV_SOCK_ARG(evcon->fd)));
1598 evhttp_connection_cb_cleanup(evcon);
1603 case EVCON_READING_BODY:
1604 if (!req->chunked && req->ntoread < 0
1605 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1606 /* EOF on read can be benign */
1607 evhttp_connection_done(evcon);
1612 case EVCON_DISCONNECTED:
1614 case EVCON_READING_FIRSTLINE:
1615 case EVCON_READING_HEADERS:
1616 case EVCON_READING_TRAILER:
1622 /* when we are in close detect mode, a read error means that
1623 * the other side closed their connection.
1625 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1626 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1627 EVUTIL_ASSERT(evcon->http_server == NULL);
1628 /* For connections from the client, we just
1629 * reset the connection so that it becomes
1632 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1633 evhttp_connection_reset_(evcon);
1636 * If we have no more requests that need completion
1637 * and we want to auto-free the connection when all
1638 * requests have been completed.
1640 if (TAILQ_FIRST(&evcon->requests) == NULL
1641 && (evcon->flags & EVHTTP_CON_OUTGOING)
1642 && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1643 evhttp_connection_free(evcon);
1648 if (what & BEV_EVENT_TIMEOUT) {
1649 evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
1650 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1651 if (what & BEV_EVENT_WRITING &&
1652 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR) {
1653 evhttp_connection_read_on_write_error(evcon, req);
1657 if (what & BEV_EVENT_READING &&
1658 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR &&
1659 evbuffer_get_length(bufferevent_get_input(bufev))) {
1660 event_deferred_cb_schedule_(get_deferred_queue(evcon),
1661 &evcon->read_more_deferred_cb);
1665 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1666 } else if (what == BEV_EVENT_CONNECTED) {
1668 evhttp_connection_fail_(evcon, EVREQ_HTTP_BUFFER_ERROR);
1673 * Event callback for asynchronous connection attempt.
1676 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1678 struct evhttp_connection *evcon = arg;
1680 ev_socklen_t errsz = sizeof(error);
1682 if (evcon->fd == -1)
1683 evcon->fd = bufferevent_getfd(bufev);
1685 if (!(what & BEV_EVENT_CONNECTED)) {
1686 /* some operating systems return ECONNREFUSED immediately
1687 * when connecting to a local address. the cleanup is going
1688 * to reschedule this function call.
1691 if (errno == ECONNREFUSED)
1694 evhttp_error_cb(bufev, what, arg);
1698 if (evcon->fd == -1) {
1699 event_debug(("%s: bufferevent_getfd returned -1",
1704 /* Check if the connection completed */
1705 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1707 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT,
1708 __func__, evcon->address, evcon->port,
1709 EV_SOCK_ARG(evcon->fd)));
1714 event_debug(("%s: connect failed for \"%s:%d\" on "
1716 __func__, evcon->address, evcon->port,
1717 EV_SOCK_ARG(evcon->fd),
1718 evutil_socket_error_to_string(error)));
1722 /* We are connected to the server now */
1723 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1724 __func__, evcon->address, evcon->port,
1725 EV_SOCK_ARG(evcon->fd)));
1727 /* Reset the retry count as we were successful in connecting */
1728 evcon->retry_cnt = 0;
1729 evcon->state = EVCON_IDLE;
1731 /* reset the bufferevent cbs */
1732 bufferevent_setcb(evcon->bufev,
1738 bufferevent_set_timeouts(evcon->bufev,
1739 &evcon->timeout_read, &evcon->timeout_write);
1741 /* try to start requests that have queued up on this connection */
1742 evhttp_request_dispatch(evcon);
1746 evhttp_connection_cb_cleanup(evcon);
1750 * Check if we got a valid response code.
1754 evhttp_valid_response_code(int code)
1763 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1767 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1768 if (n != 2 || major > 1) {
1769 event_debug(("%s: bad version %s on message %p from %s",
1770 __func__, version, req, req->remote_host));
1778 /* Parses the status line of a web server */
1781 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1785 const char *readable = "";
1787 protocol = strsep(&line, " ");
1790 number = strsep(&line, " ");
1794 if (evhttp_parse_http_version(protocol, req) < 0)
1797 req->response_code = atoi(number);
1798 if (!evhttp_valid_response_code(req->response_code)) {
1799 event_debug(("%s: bad response code \"%s\"",
1804 if (req->response_code_line != NULL)
1805 mm_free(req->response_code_line);
1806 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1807 event_warn("%s: strdup", __func__);
1814 /* Parse the first line of a HTTP request */
1817 evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len)
1819 char *eos = line + len;
1823 const char *hostname;
1826 enum evhttp_cmd_type type = 0;
1828 while (eos > line && *(eos-1) == ' ') {
1833 if (len < strlen("GET / HTTP/1.0"))
1836 /* Parse the request line */
1837 method = strsep(&line, " ");
1841 version = strrchr(uri, ' ');
1842 if (!version || uri == version)
1847 method_len = (uri - method) - 1;
1850 switch (method_len) {
1852 /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1854 /* Since both GET and PUT share the same character 'T' at the end,
1855 * if the string doesn't have 'T', we can immediately determine this
1856 * is an invalid HTTP method */
1858 if (method[2] != 'T') {
1864 /* This first byte is 'G', so make sure the next byte is
1865 * 'E', if it isn't then this isn't a valid method */
1867 if (method[1] == 'E') {
1868 type = EVHTTP_REQ_GET;
1873 /* First byte is P, check second byte for 'U', if not,
1874 * we know it's an invalid method */
1875 if (method[1] == 'U') {
1876 type = EVHTTP_REQ_PUT;
1884 /* The method length is 4 bytes, leaving only the methods POST, HEAD, LOCK, COPY and MOVE */
1887 if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') {
1888 type = EVHTTP_REQ_POST;
1892 if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') {
1893 type = EVHTTP_REQ_HEAD;
1897 if (method[3] == 'K' && method[2] == 'C' && method[1] == 'O') {
1898 type = EVHTTP_REQ_LOCK;
1902 if (method[3] == 'Y' && method[2] == 'P' && method[1] == 'O') {
1903 type = EVHTTP_REQ_COPY;
1907 if (method[3] == 'E' && method[2] == 'V' && method[1] == 'O') {
1908 type = EVHTTP_REQ_MOVE;
1916 /* Method length is 5 bytes, which can only encompass PATCH, TRACE and MKCOL */
1919 if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') {
1920 type = EVHTTP_REQ_PATCH;
1924 if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') {
1925 type = EVHTTP_REQ_TRACE;
1930 if (method[4] == 'L' && method[3] == 'O' && method[2] == 'C' && method[1] == 'K') {
1931 type = EVHTTP_REQ_MKCOL;
1939 /* Method length is 6, only valid methods 6 bytes in length is DELETE and UNLOCK */
1942 if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' &&
1943 method[2] == 'L' && method[1] == 'E') {
1944 type = EVHTTP_REQ_DELETE;
1948 if (method[5] == 'K' && method[4] == 'C' && method[3] == 'O' &&
1949 method[2] == 'L' && method[1] == 'N') {
1950 type = EVHTTP_REQ_UNLOCK;
1958 /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1961 if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' &&
1962 method[3] == 'I' && method[2] == 'T' && method[1] == 'P') {
1963 type = EVHTTP_REQ_OPTIONS;
1968 if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' &&
1969 method[3] == 'N' && method[2] == 'N' && method[1] == 'O') {
1970 type = EVHTTP_REQ_CONNECT;
1979 /* Method length is 8, only valid method 8 bytes in length is PROPFIND */
1981 /* If the first byte isn't 'P' then it's invalid */
1982 if (*method != 'P') {
1986 if (method[7] == 'D' && method[6] == 'N' && method[5] == 'I' &&
1987 method[4] == 'F' && method[3] == 'P' && method[2] == 'O' &&
1989 type = EVHTTP_REQ_PROPFIND;
1994 /* Method length is 9, only valid method 9 bytes in length is PROPPATCH */
1996 /* If the first byte isn't 'P' then it's invalid */
1997 if (*method != 'P') {
2001 if (method[8] == 'H' && method[7] == 'C' && method[6] == 'T' &&
2002 method[5] == 'A' && method[4] == 'P' && method[3] == 'P' &&
2003 method[2] == 'O' && method[1] == 'R') {
2004 type = EVHTTP_REQ_PROPPATCH;
2011 /* check extended methods, we only care about the
2012 * type set by the cmp function if the cmp function
2013 * returns a 0 value.
2015 struct evhttp_ext_method ext_method;
2017 ext_method.method = method;
2018 ext_method.type = 0;
2019 ext_method.flags = 0;
2021 if (req->evcon->ext_method_cmp &&
2022 req->evcon->ext_method_cmp(&ext_method) == 0) {
2023 /* make sure the other fields in ext_method are
2024 * not changed by the callback.
2026 if (strcmp(ext_method.method, method) != 0) {
2027 event_warn("%s: modifying the 'method' field of ext_method_cmp's "
2028 "parameter is not allowed", __func__);
2031 if (ext_method.flags != 0) {
2032 event_warn("%s: modifying the 'flags' field of ext_method_cmp's "
2033 "parameter is not allowed", __func__);
2036 type = ext_method.type;
2041 event_debug(("%s: bad method %s on request %p from %s",
2042 __func__, method, req, req->remote_host));
2043 /* No error yet; we'll give a better error later when
2044 * we see that req->type is unsupported. */
2049 if (evhttp_parse_http_version(version, req) < 0)
2052 if ((req->uri = mm_strdup(uri)) == NULL) {
2053 event_debug(("%s: mm_strdup", __func__));
2057 if (type == EVHTTP_REQ_CONNECT) {
2058 if ((req->uri_elems = evhttp_uri_parse_authority(req->uri)) == NULL) {
2062 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
2063 EVHTTP_URI_NONCONFORMANT)) == NULL) {
2068 /* If we have an absolute-URI, check to see if it is an http request
2069 for a known vhost or server alias. If we don't know about this
2070 host, we consider it a proxy request. */
2071 scheme = evhttp_uri_get_scheme(req->uri_elems);
2072 hostname = evhttp_uri_get_host(req->uri_elems);
2073 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
2074 !evutil_ascii_strcasecmp(scheme, "https")) &&
2076 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
2077 req->flags |= EVHTTP_PROXY_REQUEST;
2083 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
2085 struct evkeyval *header;
2087 TAILQ_FOREACH(header, headers, next) {
2088 if (evutil_ascii_strcasecmp(header->key, key) == 0)
2089 return (header->value);
2096 evhttp_clear_headers(struct evkeyvalq *headers)
2098 struct evkeyval *header;
2100 for (header = TAILQ_FIRST(headers);
2102 header = TAILQ_FIRST(headers)) {
2103 TAILQ_REMOVE(headers, header, next);
2104 mm_free(header->key);
2105 mm_free(header->value);
2111 * Returns 0, if the header was successfully removed.
2112 * Returns -1, if the header could not be found.
2116 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
2118 struct evkeyval *header;
2120 TAILQ_FOREACH(header, headers, next) {
2121 if (evutil_ascii_strcasecmp(header->key, key) == 0)
2128 /* Free and remove the header that we found */
2129 TAILQ_REMOVE(headers, header, next);
2130 mm_free(header->key);
2131 mm_free(header->value);
2138 evhttp_header_is_valid_value(const char *value)
2140 const char *p = value;
2142 while ((p = strpbrk(p, "\r\n")) != NULL) {
2143 /* we really expect only one new line */
2144 p += strspn(p, "\r\n");
2145 /* we expect a space or tab for continuation */
2146 if (*p != ' ' && *p != '\t')
2153 evhttp_add_header(struct evkeyvalq *headers,
2154 const char *key, const char *value)
2156 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
2158 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
2159 /* drop illegal headers */
2160 event_debug(("%s: dropping illegal header key\n", __func__));
2164 if (!evhttp_header_is_valid_value(value)) {
2165 event_debug(("%s: dropping illegal header value\n", __func__));
2169 return (evhttp_add_header_internal(headers, key, value));
2173 evhttp_add_header_internal(struct evkeyvalq *headers,
2174 const char *key, const char *value)
2176 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
2177 if (header == NULL) {
2178 event_warn("%s: calloc", __func__);
2181 if ((header->key = mm_strdup(key)) == NULL) {
2183 event_warn("%s: strdup", __func__);
2186 if ((header->value = mm_strdup(value)) == NULL) {
2187 mm_free(header->key);
2189 event_warn("%s: strdup", __func__);
2193 TAILQ_INSERT_TAIL(headers, header, next);
2199 * Parses header lines from a request or a response into the specified
2200 * request object given an event buffer.
2203 * DATA_CORRUPTED on error
2204 * MORE_DATA_EXPECTED when we need to read more headers
2205 * ALL_DATA_READ when all headers have been read.
2208 enum message_read_status
2209 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
2212 enum message_read_status status = ALL_DATA_READ;
2216 line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
2218 if (req->evcon != NULL &&
2219 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2220 return (DATA_TOO_LONG);
2222 return (MORE_DATA_EXPECTED);
2225 if (req->evcon != NULL && len > req->evcon->max_headers_size) {
2227 return (DATA_TOO_LONG);
2230 req->headers_size = len;
2232 switch (req->kind) {
2233 case EVHTTP_REQUEST:
2234 if (evhttp_parse_request_line(req, line, len) == -1)
2235 status = DATA_CORRUPTED;
2237 case EVHTTP_RESPONSE:
2238 if (evhttp_parse_response_line(req, line) == -1)
2239 status = DATA_CORRUPTED;
2242 status = DATA_CORRUPTED;
2250 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
2252 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
2254 size_t old_len, line_len;
2259 old_len = strlen(header->value);
2261 /* Strip space from start and end of line. */
2262 while (*line == ' ' || *line == '\t')
2264 evutil_rtrim_lws_(line);
2266 line_len = strlen(line);
2268 newval = mm_realloc(header->value, old_len + line_len + 2);
2272 newval[old_len] = ' ';
2273 memcpy(newval + old_len + 1, line, line_len + 1);
2274 header->value = newval;
2279 enum message_read_status
2280 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
2282 enum message_read_status errcode = DATA_CORRUPTED;
2284 enum message_read_status status = MORE_DATA_EXPECTED;
2286 struct evkeyvalq* headers = req->input_headers;
2288 while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
2290 char *skey, *svalue;
2292 req->headers_size += len;
2294 if (req->evcon != NULL &&
2295 req->headers_size > req->evcon->max_headers_size) {
2296 errcode = DATA_TOO_LONG;
2300 if (*line == '\0') { /* Last header - Done */
2301 status = ALL_DATA_READ;
2306 /* Check if this is a continuation line */
2307 if (*line == ' ' || *line == '\t') {
2308 if (evhttp_append_to_last_header(headers, line) == -1)
2314 /* Processing of header lines */
2316 skey = strsep(&svalue, ":");
2320 svalue += strspn(svalue, " ");
2321 evutil_rtrim_lws_(svalue);
2323 if (evhttp_add_header(headers, skey, svalue) == -1)
2329 if (status == MORE_DATA_EXPECTED) {
2330 if (req->evcon != NULL &&
2331 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2332 return (DATA_TOO_LONG);
2343 evhttp_get_body_length(struct evhttp_request *req)
2345 struct evkeyvalq *headers = req->input_headers;
2346 const char *content_length;
2347 const char *connection;
2349 content_length = evhttp_find_header(headers, "Content-Length");
2350 connection = evhttp_find_header(headers, "Connection");
2352 if (content_length == NULL && connection == NULL)
2354 else if (content_length == NULL &&
2355 evutil_ascii_strcasecmp(connection, "Close") != 0) {
2357 } else if (content_length == NULL) {
2361 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2362 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2363 event_debug(("%s: illegal content length: %s",
2364 __func__, content_length));
2367 req->ntoread = ntoread;
2370 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2371 __func__, EV_I64_ARG(req->ntoread),
2372 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2378 evhttp_method_may_have_body_(struct evhttp_connection *evcon, enum evhttp_cmd_type type)
2381 evhttp_method_(evcon, type, &flags);
2382 return (flags & EVHTTP_METHOD_HAS_BODY) ? 1 : 0;
2386 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2388 const char *xfer_enc;
2390 /* If this is a request without a body, then we are done */
2391 if (req->kind == EVHTTP_REQUEST &&
2392 !evhttp_method_may_have_body_(evcon, req->type)) {
2393 evhttp_connection_done(evcon);
2396 evcon->state = EVCON_READING_BODY;
2397 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
2398 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
2402 if (evhttp_get_body_length(req) == -1) {
2403 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2406 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2407 /* An incoming request with no content-length and no
2408 * transfer-encoding has no body. */
2409 evhttp_connection_done(evcon);
2414 /* Should we send a 100 Continue status line? */
2415 switch (evhttp_have_expect(req, 1)) {
2417 /* XXX It would be nice to do some sanity
2418 checking here. Does the resource exist?
2419 Should the resource accept post requests? If
2420 no, we should respond with an error. For
2421 now, just optimistically tell the client to
2422 send their message body. */
2423 if (req->ntoread > 0) {
2424 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2425 if ((req->evcon->max_body_size <= EV_INT64_MAX) &&
2426 (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2427 evhttp_lingering_fail(evcon, req);
2431 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2432 evhttp_send_continue(evcon, req);
2435 evhttp_send_error(req, HTTP_EXPECTATIONFAILED, NULL);
2440 evhttp_read_body(evcon, req);
2441 /* note the request may have been freed in evhttp_read_body */
2445 evhttp_read_firstline(struct evhttp_connection *evcon,
2446 struct evhttp_request *req)
2448 enum message_read_status res;
2450 res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2451 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2452 /* Error while reading, terminate */
2453 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2454 __func__, EV_SOCK_ARG(evcon->fd)));
2455 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2457 } else if (res == MORE_DATA_EXPECTED) {
2458 /* Need more header lines */
2462 evcon->state = EVCON_READING_HEADERS;
2463 evhttp_read_header(evcon, req);
2467 evhttp_read_header(struct evhttp_connection *evcon,
2468 struct evhttp_request *req)
2470 enum message_read_status res;
2471 evutil_socket_t fd = evcon->fd;
2473 res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2474 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2475 /* Error while reading, terminate */
2476 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2477 __func__, EV_SOCK_ARG(fd)));
2478 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2480 } else if (res == MORE_DATA_EXPECTED) {
2481 /* Need more header lines */
2485 /* Callback can shut down connection with negative return value */
2486 if (req->header_cb != NULL) {
2487 if ((*req->header_cb)(req, req->cb_arg) < 0) {
2488 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2493 /* Done reading headers, do the real work */
2494 switch (req->kind) {
2495 case EVHTTP_REQUEST:
2496 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2497 __func__, EV_SOCK_ARG(fd)));
2498 evhttp_get_body(evcon, req);
2499 /* note the request may have been freed in evhttp_get_body */
2502 case EVHTTP_RESPONSE:
2503 /* Start over if we got a 100 Continue response. */
2504 if (req->response_code == 100) {
2505 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
2506 evbuffer_add_buffer(output, req->output_buffer);
2507 evhttp_start_write_(evcon);
2510 if (!evhttp_response_needs_body(req)) {
2511 event_debug(("%s: skipping body for code %d\n",
2512 __func__, req->response_code));
2513 evhttp_connection_done(evcon);
2515 event_debug(("%s: start of read body for %s on "
2517 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2518 evhttp_get_body(evcon, req);
2519 /* note the request may have been freed in
2520 * evhttp_get_body */
2525 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2527 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2530 /* request may have been freed above */
2534 * Creates a TCP connection to the specified port and executes a callback
2535 * when finished. Failure or success is indicate by the passed connection
2538 * Although this interface accepts a hostname, it is intended to take
2539 * only numeric hostnames so that non-blocking DNS resolution can
2543 struct evhttp_connection *
2544 evhttp_connection_new(const char *address, ev_uint16_t port)
2546 return (evhttp_connection_base_new(NULL, NULL, address, port));
2549 struct evhttp_connection *
2550 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2551 const char *address, ev_uint16_t port)
2553 struct evhttp_connection *evcon = NULL;
2555 event_debug(("Attempting connection to %s:%d\n", address, port));
2557 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2558 event_warn("%s: calloc failed", __func__);
2565 evcon->max_headers_size = EV_SIZE_MAX;
2566 evcon->max_body_size = EV_SIZE_MAX;
2568 evcon->timeout_connect.tv_sec = HTTP_CONNECT_TIMEOUT;
2569 evcon->timeout_read.tv_sec = HTTP_READ_TIMEOUT;
2570 evcon->timeout_write.tv_sec = HTTP_WRITE_TIMEOUT;
2571 evcon->initial_retry_timeout.tv_sec = HTTP_INITIAL_RETRY_TIMEOUT;
2573 evcon->retry_cnt = evcon->retry_max = 0;
2575 if ((evcon->address = mm_strdup(address)) == NULL) {
2576 event_warn("%s: strdup failed", __func__);
2581 if (!(bev = bufferevent_socket_new(base, -1, 0))) {
2582 event_warn("%s: bufferevent_socket_new failed", __func__);
2587 bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2590 evcon->state = EVCON_DISCONNECTED;
2591 TAILQ_INIT(&evcon->requests);
2595 if (bufferevent_get_base(bev) != base)
2596 bufferevent_base_set(base, evcon->bufev);
2599 event_deferred_cb_init_(
2600 &evcon->read_more_deferred_cb,
2601 bufferevent_get_priority(bev),
2602 evhttp_deferred_read_cb, evcon);
2604 evcon->dns_base = dnsbase;
2605 evcon->ai_family = AF_UNSPEC;
2611 evhttp_connection_free(evcon);
2615 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2617 return evcon->bufev;
2621 evhttp_connection_get_server(struct evhttp_connection *evcon)
2623 return evcon->http_server;
2626 struct evhttp_connection *
2627 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2628 const char *address, ev_uint16_t port)
2630 return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2633 void evhttp_connection_set_family(struct evhttp_connection *evcon,
2636 evcon->ai_family = family;
2639 int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2642 int avail_flags = 0;
2643 avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2644 avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2646 if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2648 evcon->flags &= ~avail_flags;
2650 evcon->flags |= flags;
2656 evhttp_connection_set_ext_method_cmp(struct evhttp_connection *evcon,
2657 evhttp_ext_method_cb cmp)
2659 evcon->ext_method_cmp = cmp;
2663 evhttp_connection_set_base(struct evhttp_connection *evcon,
2664 struct event_base *base)
2666 EVUTIL_ASSERT(evcon->base == NULL);
2667 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2669 bufferevent_base_set(base, evcon->bufev);
2673 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2676 if (timeout != -1) {
2677 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2679 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2681 evhttp_set_timeout_(&evcon->timeout_read, timeout, HTTP_READ_TIMEOUT);
2682 evhttp_set_timeout_(&evcon->timeout_write, timeout, HTTP_WRITE_TIMEOUT);
2683 bufferevent_set_timeouts(evcon->bufev,
2684 &evcon->timeout_read, &evcon->timeout_write);
2687 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2688 const struct timeval* tv)
2691 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2693 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2695 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, HTTP_READ_TIMEOUT);
2696 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, HTTP_WRITE_TIMEOUT);
2697 bufferevent_set_timeouts(evcon->bufev,
2698 &evcon->timeout_read, &evcon->timeout_write);
2700 void evhttp_connection_set_connect_timeout_tv(struct evhttp_connection *evcon,
2701 const struct timeval *tv)
2703 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2704 evhttp_set_timeout_tv_(&evcon->timeout_connect, tv, -1);
2705 if (evcon->state == EVCON_CONNECTING)
2706 bufferevent_set_timeouts(evcon->bufev,
2707 &evcon->timeout_connect, &evcon->timeout_connect);
2709 void evhttp_connection_set_read_timeout_tv(struct evhttp_connection *evcon,
2710 const struct timeval *tv)
2712 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2713 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, -1);
2714 if (evcon->state != EVCON_CONNECTING)
2715 bufferevent_set_timeouts(evcon->bufev,
2716 &evcon->timeout_read, &evcon->timeout_write);
2718 void evhttp_connection_set_write_timeout_tv(struct evhttp_connection *evcon,
2719 const struct timeval *tv)
2721 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2722 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, -1);
2723 if (evcon->state != EVCON_CONNECTING)
2724 bufferevent_set_timeouts(evcon->bufev,
2725 &evcon->timeout_read, &evcon->timeout_write);
2729 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2730 const struct timeval *tv)
2733 evcon->initial_retry_timeout = *tv;
2735 evutil_timerclear(&evcon->initial_retry_timeout);
2736 evcon->initial_retry_timeout.tv_sec = 2;
2741 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2744 evcon->retry_max = retry_max;
2748 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2749 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2751 evcon->closecb = cb;
2752 evcon->closecb_arg = cbarg;
2756 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2757 char **address, ev_uint16_t *port)
2759 *address = evcon->address;
2760 *port = evcon->port;
2763 const struct sockaddr*
2764 evhttp_connection_get_addr(struct evhttp_connection *evcon)
2766 return bufferevent_socket_get_conn_address_(evcon->bufev);
2770 evhttp_connection_connect_(struct evhttp_connection *evcon)
2772 int old_state = evcon->state;
2773 const char *address = evcon->address;
2774 const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
2777 if (evcon->state == EVCON_CONNECTING)
2780 evhttp_connection_reset_(evcon);
2782 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2783 evcon->flags |= EVHTTP_CON_OUTGOING;
2785 if (evcon->bind_address || evcon->bind_port) {
2786 evcon->fd = bind_socket(
2787 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2788 if (evcon->fd == -1) {
2789 event_debug(("%s: failed to bind to \"%s\"",
2790 __func__, evcon->bind_address));
2794 if (bufferevent_setfd(evcon->bufev, evcon->fd))
2797 if (bufferevent_setfd(evcon->bufev, -1))
2801 /* Set up a callback for successful connection setup */
2802 bufferevent_setcb(evcon->bufev,
2803 NULL /* evhttp_read_cb */,
2804 NULL /* evhttp_write_cb */,
2805 evhttp_connection_cb,
2807 bufferevent_set_timeouts(evcon->bufev,
2808 &evcon->timeout_connect, &evcon->timeout_connect);
2809 /* make sure that we get a write callback */
2810 if (bufferevent_enable(evcon->bufev, EV_WRITE))
2813 evcon->state = EVCON_CONNECTING;
2815 if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
2817 (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
2818 int socklen = sizeof(struct sockaddr_in);
2819 if (sa->sa_family == AF_INET6) {
2820 socklen = sizeof(struct sockaddr_in6);
2822 ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
2824 ret = bufferevent_socket_connect_hostname(evcon->bufev,
2825 evcon->dns_base, evcon->ai_family, address, evcon->port);
2829 evcon->state = old_state;
2830 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2831 __func__, evcon->address);
2832 /* some operating systems return ECONNREFUSED immediately
2833 * when connecting to a local address. the cleanup is going
2834 * to reschedule this function call.
2836 evhttp_connection_cb_cleanup(evcon);
2844 * Starts an HTTP request on the provided evhttp_connection object.
2845 * If the connection object is not connected to the web server already,
2846 * this will start the connection.
2850 evhttp_make_request(struct evhttp_connection *evcon,
2851 struct evhttp_request *req,
2852 enum evhttp_cmd_type type, const char *uri)
2854 /* We are making a request */
2855 req->kind = EVHTTP_REQUEST;
2857 if (req->uri != NULL)
2859 if ((req->uri = mm_strdup(uri)) == NULL) {
2860 event_warn("%s: strdup", __func__);
2861 evhttp_request_free_auto(req);
2865 /* Set the protocol version if it is not supplied */
2866 if (!req->major && !req->minor) {
2871 EVUTIL_ASSERT(req->evcon == NULL);
2873 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2875 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2877 /* We do not want to conflict with retry_ev */
2878 if (evcon->retry_cnt)
2881 /* If the connection object is not connected; make it so */
2882 if (!evhttp_connected(evcon)) {
2883 int res = evhttp_connection_connect_(evcon);
2884 /* evhttp_connection_fail_(), which is called through
2885 * evhttp_connection_connect_(), assumes that req lies in
2886 * evcon->requests. Thus, enqueue the request in advance and
2887 * remove it in the error case. */
2889 TAILQ_REMOVE(&evcon->requests, req, next);
2895 * If it's connected already and we are the first in the queue,
2896 * then we can dispatch this request immediately. Otherwise, it
2897 * will be dispatched once the pending requests are completed.
2899 if (TAILQ_FIRST(&evcon->requests) == req)
2900 evhttp_request_dispatch(evcon);
2906 evhttp_cancel_request(struct evhttp_request *req)
2908 struct evhttp_connection *evcon = req->evcon;
2909 if (evcon != NULL) {
2910 /* We need to remove it from the connection */
2911 if (TAILQ_FIRST(&evcon->requests) == req) {
2912 /* it's currently being worked on, so reset
2915 evhttp_connection_fail_(evcon,
2916 EVREQ_HTTP_REQUEST_CANCEL);
2918 /* connection fail freed the request */
2921 /* otherwise, we can just remove it from the
2924 TAILQ_REMOVE(&evcon->requests, req, next);
2928 evhttp_request_free_auto(req);
2932 * Reads data from file descriptor into request structure
2933 * Request structure needs to be set up correctly.
2937 evhttp_start_read_(struct evhttp_connection *evcon)
2939 bufferevent_disable(evcon->bufev, EV_WRITE);
2940 bufferevent_enable(evcon->bufev, EV_READ);
2942 evcon->state = EVCON_READING_FIRSTLINE;
2943 /* Reset the bufferevent callbacks */
2944 bufferevent_setcb(evcon->bufev,
2950 /* If there's still data pending, process it next time through the
2951 * loop. Don't do it now; that could get recusive. */
2952 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2953 event_deferred_cb_schedule_(get_deferred_queue(evcon),
2954 &evcon->read_more_deferred_cb);
2959 evhttp_start_write_(struct evhttp_connection *evcon)
2961 bufferevent_disable(evcon->bufev, EV_WRITE);
2962 bufferevent_enable(evcon->bufev, EV_READ);
2964 evcon->state = EVCON_WRITING;
2965 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
2969 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2972 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2973 TAILQ_REMOVE(&evcon->requests, req, next);
2975 if (req->on_complete_cb != NULL) {
2976 req->on_complete_cb(req, req->on_complete_cb_arg);
2980 (REQ_VERSION_BEFORE(req, 1, 1) &&
2981 !evhttp_is_connection_keepalive(req->input_headers)) ||
2982 evhttp_is_request_connection_close(req);
2984 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2985 evhttp_request_free(req);
2988 evhttp_connection_free(evcon);
2992 /* we have a persistent connection; try to accept another request. */
2993 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2994 evhttp_connection_free(evcon);
2999 * Returns an error page.
3002 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
3004 #define ERR_FORMAT "<html><head>" \
3005 "<title>%d %s</title>" \
3007 "<h1>%d %s</h1>%s" \
3010 struct evbuffer *buf = evbuffer_new();
3011 struct evhttp *http = req->evcon->http_server;
3014 /* if we cannot allocate memory; we just drop the connection */
3015 evhttp_connection_free(req->evcon);
3019 evhttp_response_code_(req, error, reason);
3021 /* Output error using callback for connection's evhttp, if available */
3022 if ((http->errorcb == NULL) ||
3023 ((*http->errorcb)(req, buf, error, reason, http->errorcbarg) < 0))
3025 const char *heading = evhttp_response_phrase_internal(error);
3027 evbuffer_drain(buf, evbuffer_get_length(buf));
3028 evbuffer_add_printf(buf, ERR_FORMAT,
3029 error, heading, error, heading,
3030 (reason ? reason : ""));
3033 evhttp_send_page_(req, buf);
3039 evhttp_send_notfound(struct evhttp_request *req, const char *url)
3041 #define REASON_FORMAT "<p>The requested URL %s was not found on this server.</p>"
3042 char *escaped_url = NULL;
3043 char *reason = NULL;
3046 url = (url != NULL ? url : req->uri);
3048 escaped_url = evhttp_htmlescape(url);
3050 if (escaped_url != NULL) {
3051 reason_len = strlen(REASON_FORMAT)+strlen(escaped_url)+1;
3052 reason = mm_malloc(reason_len);
3055 if ((escaped_url != NULL) && (reason != NULL))
3056 evutil_snprintf(reason, reason_len, REASON_FORMAT, escaped_url);
3058 evhttp_send_error(req, HTTP_NOTFOUND, reason);
3062 if (escaped_url != NULL)
3063 mm_free(escaped_url);
3064 #undef REASON_FORMAT
3068 /* Requires that headers and response code are already set up */
3071 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
3073 struct evhttp_connection *evcon = req->evcon;
3075 if (evcon == NULL) {
3076 evhttp_request_free(req);
3080 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
3082 /* we expect no more calls form the user on this request */
3085 /* xxx: not sure if we really should expose the data buffer this way */
3086 if (databuf != NULL)
3087 evbuffer_add_buffer(req->output_buffer, databuf);
3089 /* Adds headers to the response */
3090 evhttp_make_header(evcon, req);
3092 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
3096 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
3097 struct evbuffer *databuf)
3099 evhttp_response_code_(req, code, reason);
3101 evhttp_send(req, databuf);
3105 evhttp_send_reply_start(struct evhttp_request *req, int code,
3108 evhttp_response_code_(req, code, reason);
3110 if (req->evcon == NULL)
3113 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
3114 REQ_VERSION_ATLEAST(req, 1, 1) &&
3115 evhttp_response_needs_body(req)) {
3117 * prefer HTTP/1.1 chunked encoding to closing the connection;
3118 * note RFC 2616 section 4.4 forbids it with Content-Length:
3119 * and it's not necessary then anyway.
3121 evhttp_add_header(req->output_headers, "Transfer-Encoding",
3127 evhttp_make_header(req->evcon, req);
3128 evhttp_write_buffer(req->evcon, NULL, NULL);
3132 evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
3133 void (*cb)(struct evhttp_connection *, void *), void *arg)
3135 struct evhttp_connection *evcon = req->evcon;
3136 struct evbuffer *output;
3141 output = bufferevent_get_output(evcon->bufev);
3143 if (evbuffer_get_length(databuf) == 0)
3145 if (!evhttp_response_needs_body(req))
3148 evbuffer_add_printf(output, "%x\r\n",
3149 (unsigned)evbuffer_get_length(databuf));
3151 evbuffer_add_buffer(output, databuf);
3153 evbuffer_add(output, "\r\n", 2);
3155 evhttp_write_buffer(evcon, cb, arg);
3159 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
3161 evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
3164 evhttp_send_reply_end(struct evhttp_request *req)
3166 struct evhttp_connection *evcon = req->evcon;
3167 struct evbuffer *output;
3169 if (evcon == NULL) {
3170 evhttp_request_free(req);
3174 output = bufferevent_get_output(evcon->bufev);
3176 /* we expect no more calls form the user on this request */
3180 evbuffer_add(output, "0\r\n\r\n", 5);
3181 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
3183 } else if (evbuffer_get_length(output) == 0) {
3184 /* let the connection know that we are done with the request */
3185 evhttp_send_done(evcon, NULL);
3187 /* make the callback execute after all data has been written */
3188 evcon->cb = evhttp_send_done;
3189 evcon->cb_arg = NULL;
3193 static const char *informational_phrases[] = {
3194 /* 100 */ "Continue",
3195 /* 101 */ "Switching Protocols"
3198 static const char *success_phrases[] = {
3200 /* 201 */ "Created",
3201 /* 202 */ "Accepted",
3202 /* 203 */ "Non-Authoritative Information",
3203 /* 204 */ "No Content",
3204 /* 205 */ "Reset Content",
3205 /* 206 */ "Partial Content"
3208 static const char *redirection_phrases[] = {
3209 /* 300 */ "Multiple Choices",
3210 /* 301 */ "Moved Permanently",
3212 /* 303 */ "See Other",
3213 /* 304 */ "Not Modified",
3214 /* 305 */ "Use Proxy",
3215 /* 307 */ "Temporary Redirect"
3218 static const char *client_error_phrases[] = {
3219 /* 400 */ "Bad Request",
3220 /* 401 */ "Unauthorized",
3221 /* 402 */ "Payment Required",
3222 /* 403 */ "Forbidden",
3223 /* 404 */ "Not Found",
3224 /* 405 */ "Method Not Allowed",
3225 /* 406 */ "Not Acceptable",
3226 /* 407 */ "Proxy Authentication Required",
3227 /* 408 */ "Request Time-out",
3228 /* 409 */ "Conflict",
3230 /* 411 */ "Length Required",
3231 /* 412 */ "Precondition Failed",
3232 /* 413 */ "Request Entity Too Large",
3233 /* 414 */ "Request-URI Too Large",
3234 /* 415 */ "Unsupported Media Type",
3235 /* 416 */ "Requested range not satisfiable",
3236 /* 417 */ "Expectation Failed"
3239 static const char *server_error_phrases[] = {
3240 /* 500 */ "Internal Server Error",
3241 /* 501 */ "Not Implemented",
3242 /* 502 */ "Bad Gateway",
3243 /* 503 */ "Service Unavailable",
3244 /* 504 */ "Gateway Time-out",
3245 /* 505 */ "HTTP Version not supported"
3248 struct response_class {
3250 size_t num_responses;
3251 const char **responses;
3255 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
3258 static const struct response_class response_classes[] = {
3259 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
3260 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
3261 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
3262 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
3263 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
3267 evhttp_response_phrase_internal(int code)
3269 int klass = code / 100 - 1;
3270 int subcode = code % 100;
3272 /* Unknown class - can't do any better here */
3273 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
3274 return "Unknown Status Class";
3276 /* Unknown sub-code, return class name at least */
3277 if (subcode >= (int) response_classes[klass].num_responses)
3278 return response_classes[klass].name;
3280 return response_classes[klass].responses[subcode];
3284 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
3286 req->kind = EVHTTP_RESPONSE;
3287 req->response_code = code;
3288 if (req->response_code_line != NULL)
3289 mm_free(req->response_code_line);
3291 reason = evhttp_response_phrase_internal(code);
3292 req->response_code_line = mm_strdup(reason);
3293 if (req->response_code_line == NULL) {
3294 event_warn("%s: strdup", __func__);
3295 /* XXX what else can we do? */
3300 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
3302 if (!req->major || !req->minor) {
3307 if (req->kind != EVHTTP_RESPONSE)
3308 evhttp_response_code_(req, 200, "OK");
3310 evhttp_clear_headers(req->output_headers);
3311 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
3312 evhttp_add_header(req->output_headers, "Connection", "close");
3314 evhttp_send(req, databuf);
3317 static const char uri_chars[256] = {
3319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
3322 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
3324 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3325 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
3326 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3327 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
3329 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3334 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3335 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3336 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3340 #define CHAR_IS_UNRESERVED(c) \
3341 (uri_chars[(unsigned char)(c)])
3344 * Helper functions to encode/decode a string for inclusion in a URI.
3345 * The returned string must be freed by the caller.
3348 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3350 struct evbuffer *buf = evbuffer_new();
3351 const char *p, *end;
3352 char *result = NULL;
3359 if (uri + len < uri) {
3365 size_t slen = strlen(uri);
3367 if (slen >= EV_SSIZE_MAX) {
3368 /* we don't want to mix signed and unsigned */
3372 if (uri + slen < uri) {
3379 for (p = uri; p < end; p++) {
3380 if (CHAR_IS_UNRESERVED(*p)) {
3381 evbuffer_add(buf, p, 1);
3382 } else if (*p == ' ' && space_as_plus) {
3383 evbuffer_add(buf, "+", 1);
3385 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3389 evbuffer_add(buf, "", 1); /* NUL-terminator. */
3390 result = mm_malloc(evbuffer_get_length(buf));
3393 evbuffer_remove(buf, result, evbuffer_get_length(buf));
3402 evhttp_encode_uri(const char *str)
3404 return evhttp_uriencode(str, -1, 0);
3408 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
3409 * If -1, when true we transform plus to space only after we've seen
3410 * a ?. -1 is deprecated.
3411 * @return the number of bytes written to 'ret'.
3414 evhttp_decode_uri_internal(
3415 const char *uri, size_t length, char *ret, int decode_plus_ctl)
3419 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3422 for (i = j = 0; i < length; i++) {
3425 if (decode_plus_ctl < 0)
3427 } else if (c == '+' && decode_plus) {
3429 } else if ((i + 2) < length && c == '%' &&
3430 EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3435 c = (char)strtol(tmp, NULL, 16);
3447 evhttp_decode_uri(const char *uri)
3451 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3452 event_warn("%s: malloc(%lu)", __func__,
3453 (unsigned long)(strlen(uri) + 1));
3457 evhttp_decode_uri_internal(uri, strlen(uri),
3458 ret, -1 /*always_decode_plus*/);
3464 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3469 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3470 event_warn("%s: malloc(%lu)", __func__,
3471 (unsigned long)(strlen(uri) + 1));
3475 n = evhttp_decode_uri_internal(uri, strlen(uri),
3476 ret, !!decode_plus/*always_decode_plus*/);
3479 EVUTIL_ASSERT(n >= 0);
3480 *size_out = (size_t)n;
3487 * Helper function to parse out arguments in a query.
3488 * The arguments are separated by key and value.
3492 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3493 int is_whole_uri, unsigned flags)
3498 const char *query_part;
3500 struct evhttp_uri *uri=NULL;
3502 TAILQ_INIT(headers);
3505 uri = evhttp_uri_parse(str);
3508 query_part = evhttp_uri_get_query(uri);
3513 /* No arguments - we are done */
3514 if (!query_part || !strlen(query_part)) {
3519 if ((line = mm_strdup(query_part)) == NULL) {
3520 event_warn("%s: strdup", __func__);
3524 p = argument = line;
3525 while (p != NULL && *p != '\0') {
3526 char *key, *value, *decoded_value;
3527 argument = strsep(&p, "&");
3530 key = strsep(&value, "=");
3531 if (flags & EVHTTP_URI_QUERY_NONCONFORMANT) {
3537 if (value == NULL || *key == '\0')
3541 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3542 event_warn("%s: mm_malloc", __func__);
3545 evhttp_decode_uri_internal(value, strlen(value),
3546 decoded_value, 1 /*always_decode_plus*/);
3547 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3548 if (flags & EVHTTP_URI_QUERY_LAST_VAL)
3549 evhttp_remove_header(headers, key);
3550 evhttp_add_header_internal(headers, key, decoded_value);
3551 mm_free(decoded_value);
3557 evhttp_clear_headers(headers);
3562 evhttp_uri_free(uri);
3567 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3569 return evhttp_parse_query_impl(uri, headers, 1, 0);
3572 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3574 return evhttp_parse_query_impl(uri, headers, 0, 0);
3577 evhttp_parse_query_str_flags(const char *uri, struct evkeyvalq *headers, unsigned flags)
3579 return evhttp_parse_query_impl(uri, headers, 0, flags);
3582 static struct evhttp_cb *
3583 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3585 struct evhttp_cb *cb;
3590 /* Test for different URLs */
3591 path = evhttp_uri_get_path(req->uri_elems);
3592 offset = strlen(path);
3593 if ((translated = mm_malloc(offset + 1)) == NULL)
3595 evhttp_decode_uri_internal(path, offset, translated,
3596 0 /* decode_plus */);
3598 TAILQ_FOREACH(cb, callbacks, next) {
3599 if (!strcmp(cb->what, translated)) {
3600 mm_free(translated);
3605 mm_free(translated);
3611 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3616 switch (c = *pattern++) {
3618 return *name == '\0';
3621 while (*name != '\0') {
3622 if (prefix_suffix_match(pattern, name,
3631 EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3641 Search the vhost hierarchy beginning with http for a server alias
3642 matching hostname. If a match is found, and outhttp is non-null,
3643 outhttp is set to the matching http object and 1 is returned.
3647 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3648 const char *hostname)
3650 struct evhttp_server_alias *alias;
3651 struct evhttp *vhost;
3653 TAILQ_FOREACH(alias, &http->aliases, next) {
3654 /* XXX Do we need to handle IP addresses? */
3655 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3662 /* XXX It might be good to avoid recursion here, but I don't
3663 see a way to do that w/o a list. */
3664 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3665 if (evhttp_find_alias(vhost, outhttp, hostname))
3673 Attempts to find the best http object to handle a request for a hostname.
3674 All aliases for the root http object and vhosts are searched for an exact
3675 match. Then, the vhost hierarchy is traversed again for a matching
3678 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3679 is set with the best matching http object. If there are no matches, the
3680 root http object is stored in outhttp and 0 is returned.
3684 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3685 const char *hostname)
3687 struct evhttp *vhost;
3688 struct evhttp *oldhttp;
3689 int match_found = 0;
3691 if (evhttp_find_alias(http, outhttp, hostname))
3696 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3697 if (prefix_suffix_match(vhost->vhost_pattern,
3698 hostname, 1 /* ignorecase */)) {
3704 } while (oldhttp != http);
3713 evhttp_handle_request(struct evhttp_request *req, void *arg)
3715 struct evhttp *http = arg;
3716 struct evhttp_cb *cb = NULL;
3717 const char *hostname;
3719 /* we have a new request on which the user needs to take action */
3722 bufferevent_disable(req->evcon->bufev, EV_READ);
3724 if (req->uri == NULL) {
3725 evhttp_send_error(req, req->response_code, NULL);
3729 if ((http->allowed_methods & req->type) == 0) {
3730 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3731 (unsigned)req->type, (unsigned)http->allowed_methods));
3732 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3736 /* handle potential virtual hosts */
3737 hostname = evhttp_request_get_host(req);
3738 if (hostname != NULL) {
3739 evhttp_find_vhost(http, &http, hostname);
3742 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3743 (*cb->cb)(req, cb->cbarg);
3747 /* Generic call back */
3749 (*http->gencb)(req, http->gencbarg);
3752 evhttp_send_notfound(req, NULL);
3755 /* Listener callback when a connection arrives at a server. */
3757 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3759 struct evhttp *http = arg;
3761 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3765 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3767 struct evhttp_bound_socket *bound =
3768 evhttp_bind_socket_with_handle(http, address, port);
3774 struct evhttp_bound_socket *
3775 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3778 struct evhttp_bound_socket *bound;
3781 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3784 if (listen(fd, 128) == -1) {
3785 serrno = EVUTIL_SOCKET_ERROR();
3786 event_sock_warn(fd, "%s: listen", __func__);
3787 evutil_closesocket(fd);
3788 EVUTIL_SET_SOCKET_ERROR(serrno);
3792 bound = evhttp_accept_socket_with_handle(http, fd);
3794 if (bound != NULL) {
3795 event_debug(("Bound to port %d - Awaiting connections ... ",
3804 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3806 struct evhttp_bound_socket *bound =
3807 evhttp_accept_socket_with_handle(http, fd);
3814 evhttp_foreach_bound_socket(struct evhttp *http,
3815 evhttp_bound_socket_foreach_fn *function,
3818 struct evhttp_bound_socket *bound;
3820 TAILQ_FOREACH(bound, &http->sockets, next)
3821 function(bound, argument);
3824 struct evhttp_bound_socket *
3825 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3827 struct evhttp_bound_socket *bound;
3828 struct evconnlistener *listener;
3830 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3832 listener = evconnlistener_new(http->base, NULL, NULL,
3834 0, /* Backlog is '0' because we already said 'listen' */
3839 bound = evhttp_bind_listener(http, listener);
3841 evconnlistener_free(listener);
3847 struct evhttp_bound_socket *
3848 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3850 struct evhttp_bound_socket *bound;
3852 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3856 bound->listener = listener;
3857 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3859 evconnlistener_set_cb(listener, accept_socket_cb, http);
3864 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3866 return evconnlistener_get_fd(bound->listener);
3869 struct evconnlistener *
3870 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3872 return bound->listener;
3876 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3878 TAILQ_REMOVE(&http->sockets, bound, next);
3879 evconnlistener_free(bound->listener);
3883 static struct evhttp*
3884 evhttp_new_object(void)
3886 struct evhttp *http = NULL;
3888 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3889 event_warn("%s: calloc", __func__);
3893 evutil_timerclear(&http->timeout_read);
3894 evutil_timerclear(&http->timeout_write);
3896 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3897 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3898 evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
3899 evhttp_set_allowed_methods(http,
3906 TAILQ_INIT(&http->sockets);
3907 TAILQ_INIT(&http->callbacks);
3908 TAILQ_INIT(&http->connections);
3909 TAILQ_INIT(&http->virtualhosts);
3910 TAILQ_INIT(&http->aliases);
3916 evhttp_new(struct event_base *base)
3918 struct evhttp *http = NULL;
3920 http = evhttp_new_object();
3929 * Start a web server on the specified address and port.
3933 evhttp_start(const char *address, ev_uint16_t port)
3935 struct evhttp *http = NULL;
3937 http = evhttp_new_object();
3940 if (evhttp_bind_socket(http, address, port) == -1) {
3949 evhttp_free(struct evhttp* http)
3951 struct evhttp_cb *http_cb;
3952 struct evhttp_connection *evcon;
3953 struct evhttp_bound_socket *bound;
3954 struct evhttp* vhost;
3955 struct evhttp_server_alias *alias;
3957 /* Remove the accepting part */
3958 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3959 TAILQ_REMOVE(&http->sockets, bound, next);
3961 evconnlistener_free(bound->listener);
3966 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3967 /* evhttp_connection_free removes the connection */
3968 evhttp_connection_free(evcon);
3971 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3972 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3973 mm_free(http_cb->what);
3977 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3978 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3983 if (http->vhost_pattern != NULL)
3984 mm_free(http->vhost_pattern);
3986 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3987 TAILQ_REMOVE(&http->aliases, alias, next);
3988 mm_free(alias->alias);
3996 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3997 struct evhttp* vhost)
3999 /* a vhost can only be a vhost once and should not have bound sockets */
4000 if (vhost->vhost_pattern != NULL ||
4001 TAILQ_FIRST(&vhost->sockets) != NULL)
4004 vhost->vhost_pattern = mm_strdup(pattern);
4005 if (vhost->vhost_pattern == NULL)
4008 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
4014 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
4016 if (vhost->vhost_pattern == NULL)
4019 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
4021 mm_free(vhost->vhost_pattern);
4022 vhost->vhost_pattern = NULL;
4028 evhttp_add_server_alias(struct evhttp *http, const char *alias)
4030 struct evhttp_server_alias *evalias;
4032 evalias = mm_calloc(1, sizeof(*evalias));
4036 evalias->alias = mm_strdup(alias);
4037 if (!evalias->alias) {
4042 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
4048 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
4050 struct evhttp_server_alias *evalias;
4052 TAILQ_FOREACH(evalias, &http->aliases, next) {
4053 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
4054 TAILQ_REMOVE(&http->aliases, evalias, next);
4055 mm_free(evalias->alias);
4065 evhttp_set_timeout(struct evhttp* http, int timeout)
4067 evhttp_set_timeout_(&http->timeout_read, timeout, -1);
4068 evhttp_set_timeout_(&http->timeout_write, timeout, -1);
4071 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
4073 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4074 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4077 evhttp_set_read_timeout_tv(struct evhttp* http, const struct timeval* tv)
4079 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4082 evhttp_set_write_timeout_tv(struct evhttp* http, const struct timeval* tv)
4084 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4087 int evhttp_set_flags(struct evhttp *http, int flags)
4089 int avail_flags = 0;
4090 avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
4092 if (flags & ~avail_flags)
4094 http->flags &= ~avail_flags;
4096 http->flags |= flags;
4102 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
4104 if (max_headers_size < 0)
4105 http->default_max_headers_size = EV_SIZE_MAX;
4107 http->default_max_headers_size = max_headers_size;
4111 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
4113 if (max_body_size < 0)
4114 http->default_max_body_size = EV_UINT64_MAX;
4116 http->default_max_body_size = max_body_size;
4120 evhttp_set_max_connections(struct evhttp* http, int max_connections)
4122 if (max_connections < 0)
4123 http->connection_max = 0;
4125 http->connection_max = max_connections;
4129 evhttp_get_connection_count(struct evhttp* http)
4131 return http->connection_cnt;
4135 evhttp_set_default_content_type(struct evhttp *http,
4136 const char *content_type) {
4137 http->default_content_type = content_type;
4141 evhttp_set_allowed_methods(struct evhttp* http, ev_uint32_t methods)
4143 http->allowed_methods = methods;
4147 evhttp_set_ext_method_cmp(struct evhttp *http, evhttp_ext_method_cb cmp)
4149 http->ext_method_cmp = cmp;
4153 evhttp_set_cb(struct evhttp *http, const char *uri,
4154 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4156 struct evhttp_cb *http_cb;
4158 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4159 if (strcmp(http_cb->what, uri) == 0)
4163 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
4164 event_warn("%s: calloc", __func__);
4168 http_cb->what = mm_strdup(uri);
4169 if (http_cb->what == NULL) {
4170 event_warn("%s: strdup", __func__);
4175 http_cb->cbarg = cbarg;
4177 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
4183 evhttp_del_cb(struct evhttp *http, const char *uri)
4185 struct evhttp_cb *http_cb;
4187 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4188 if (strcmp(http_cb->what, uri) == 0)
4191 if (http_cb == NULL)
4194 TAILQ_REMOVE(&http->callbacks, http_cb, next);
4195 mm_free(http_cb->what);
4202 evhttp_set_gencb(struct evhttp *http,
4203 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4206 http->gencbarg = cbarg;
4210 evhttp_set_bevcb(struct evhttp *http,
4211 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
4214 http->bevcbarg = cbarg;
4218 evhttp_set_newreqcb(struct evhttp *http,
4219 int (*cb)(struct evhttp_request *, void *), void *cbarg)
4221 http->newreqcb = cb;
4222 http->newreqcbarg = cbarg;
4225 evhttp_set_errorcb(struct evhttp *http,
4226 int (*cb)(struct evhttp_request *, struct evbuffer *, int, const char *, void *),
4230 http->errorcbarg = cbarg;
4234 * Request related functions
4237 struct evhttp_request *
4238 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
4240 struct evhttp_request *req = NULL;
4242 /* Allocate request structure */
4243 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
4244 event_warn("%s: calloc", __func__);
4248 req->headers_size = 0;
4251 req->kind = EVHTTP_RESPONSE;
4252 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4253 if (req->input_headers == NULL) {
4254 event_warn("%s: calloc", __func__);
4257 TAILQ_INIT(req->input_headers);
4259 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4260 if (req->output_headers == NULL) {
4261 event_warn("%s: calloc", __func__);
4264 TAILQ_INIT(req->output_headers);
4266 if ((req->input_buffer = evbuffer_new()) == NULL) {
4267 event_warn("%s: evbuffer_new", __func__);
4271 if ((req->output_buffer = evbuffer_new()) == NULL) {
4272 event_warn("%s: evbuffer_new", __func__);
4283 evhttp_request_free(req);
4288 evhttp_request_free(struct evhttp_request *req)
4290 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
4291 req->flags |= EVHTTP_REQ_NEEDS_FREE;
4295 if (req->remote_host != NULL)
4296 mm_free(req->remote_host);
4297 if (req->uri != NULL)
4299 if (req->uri_elems != NULL)
4300 evhttp_uri_free(req->uri_elems);
4301 if (req->response_code_line != NULL)
4302 mm_free(req->response_code_line);
4303 if (req->host_cache != NULL)
4304 mm_free(req->host_cache);
4306 evhttp_clear_headers(req->input_headers);
4307 mm_free(req->input_headers);
4309 evhttp_clear_headers(req->output_headers);
4310 mm_free(req->output_headers);
4312 if (req->input_buffer != NULL)
4313 evbuffer_free(req->input_buffer);
4315 if (req->output_buffer != NULL)
4316 evbuffer_free(req->output_buffer);
4322 evhttp_request_own(struct evhttp_request *req)
4324 req->flags |= EVHTTP_USER_OWNED;
4328 evhttp_request_is_owned(struct evhttp_request *req)
4330 return (req->flags & EVHTTP_USER_OWNED) != 0;
4333 struct evhttp_connection *
4334 evhttp_request_get_connection(struct evhttp_request *req)
4340 evhttp_connection_get_base(struct evhttp_connection *conn)
4346 evhttp_request_set_chunked_cb(struct evhttp_request *req,
4347 void (*cb)(struct evhttp_request *, void *))
4353 evhttp_request_set_header_cb(struct evhttp_request *req,
4354 int (*cb)(struct evhttp_request *, void *))
4356 req->header_cb = cb;
4360 evhttp_request_set_error_cb(struct evhttp_request *req,
4361 void (*cb)(enum evhttp_request_error, void *))
4367 evhttp_request_set_on_complete_cb(struct evhttp_request *req,
4368 void (*cb)(struct evhttp_request *, void *), void *cb_arg)
4370 req->on_complete_cb = cb;
4371 req->on_complete_cb_arg = cb_arg;
4375 * Allows for inspection of the request URI
4379 evhttp_request_get_uri(const struct evhttp_request *req) {
4380 if (req->uri == NULL)
4381 event_debug(("%s: request %p has no uri\n", __func__, req));
4385 const struct evhttp_uri *
4386 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4387 if (req->uri_elems == NULL)
4388 event_debug(("%s: request %p has no uri elems\n",
4390 return (req->uri_elems);
4394 evhttp_request_get_host(struct evhttp_request *req)
4396 const char *host = NULL;
4398 if (req->host_cache)
4399 return req->host_cache;
4402 host = evhttp_uri_get_host(req->uri_elems);
4403 if (!host && req->input_headers) {
4407 host = evhttp_find_header(req->input_headers, "Host");
4408 /* The Host: header may include a port. Remove it here
4409 to be consistent with uri_elems case above. */
4411 p = host + strlen(host) - 1;
4412 while (p > host && EVUTIL_ISDIGIT_(*p))
4414 if (p > host && *p == ':') {
4416 req->host_cache = mm_malloc(len + 1);
4417 if (!req->host_cache) {
4418 event_warn("%s: malloc", __func__);
4421 memcpy(req->host_cache, host, len);
4422 req->host_cache[len] = '\0';
4423 host = req->host_cache;
4431 enum evhttp_cmd_type
4432 evhttp_request_get_command(const struct evhttp_request *req) {
4437 evhttp_request_get_response_code(const struct evhttp_request *req)
4439 return req->response_code;
4443 evhttp_request_get_response_code_line(const struct evhttp_request *req)
4445 return req->response_code_line;
4448 /** Returns the input headers */
4449 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4451 return (req->input_headers);
4454 /** Returns the output headers */
4455 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4457 return (req->output_headers);
4460 /** Returns the input buffer */
4461 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4463 return (req->input_buffer);
4466 /** Returns the output buffer */
4467 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4469 return (req->output_buffer);
4474 * Takes a file descriptor to read a request from.
4475 * The callback is executed once the whole request has been read.
4478 static struct evhttp_connection*
4479 evhttp_get_request_connection(
4480 struct evhttp* http,
4481 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
4483 struct evhttp_connection *evcon;
4484 char *hostname = NULL, *portname = NULL;
4485 struct bufferevent* bev = NULL;
4487 #ifdef EVENT__HAVE_STRUCT_SOCKADDR_UN
4488 if (sa->sa_family == AF_UNIX) {
4489 struct sockaddr_un *sa_un = (struct sockaddr_un *)sa;
4490 sa_un->sun_path[0] = '\0';
4494 name_from_addr(sa, salen, &hostname, &portname);
4495 if (hostname == NULL || portname == NULL) {
4496 if (hostname) mm_free(hostname);
4497 if (portname) mm_free(portname);
4501 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4502 __func__, hostname, portname, EV_SOCK_ARG(fd)));
4504 /* we need a connection object to put the http request on */
4505 if (http->bevcb != NULL) {
4506 bev = (*http->bevcb)(http->base, http->bevcbarg);
4508 evcon = evhttp_connection_base_bufferevent_new(
4509 http->base, NULL, bev, hostname, atoi(portname));
4515 evcon->max_headers_size = http->default_max_headers_size;
4516 evcon->max_body_size = http->default_max_body_size;
4517 if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4518 evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4520 evcon->flags |= EVHTTP_CON_INCOMING;
4521 evcon->state = EVCON_READING_FIRSTLINE;
4525 if (bufferevent_setfd(evcon->bufev, fd))
4527 if (bufferevent_enable(evcon->bufev, EV_READ))
4529 if (bufferevent_disable(evcon->bufev, EV_WRITE))
4531 bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
4536 evhttp_connection_free(evcon);
4541 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4543 struct evhttp *http = evcon->http_server;
4544 struct evhttp_request *req;
4545 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4548 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4549 event_warn("%s: strdup", __func__);
4550 evhttp_request_free(req);
4553 req->remote_port = evcon->port;
4555 req->evcon = evcon; /* the request ends up owning the connection */
4556 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4558 /* We did not present the request to the user yet, so treat it
4559 * as if the user was done with the request. This allows us
4560 * to free the request on a persistent connection if the
4561 * client drops it without sending a request.
4564 req->kind = EVHTTP_REQUEST;
4566 if (http->newreqcb && http->newreqcb(req, http->newreqcbarg) == -1) {
4567 evhttp_request_free(req);
4571 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4573 evhttp_start_read_(evcon);
4579 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4580 struct sockaddr *sa, ev_socklen_t salen)
4582 struct evhttp_connection *evcon;
4584 evcon = evhttp_get_request_connection(http, fd, sa, salen);
4585 if (evcon == NULL) {
4586 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4587 __func__, EV_SOCK_ARG(fd));
4588 evutil_closesocket(fd);
4592 /* the timeout can be used by the server to close idle connections */
4593 if (evutil_timerisset(&http->timeout_read))
4594 evhttp_connection_set_read_timeout_tv(evcon, &http->timeout_read);
4595 if (evutil_timerisset(&http->timeout_write))
4596 evhttp_connection_set_write_timeout_tv(evcon, &http->timeout_write);
4599 * if we want to accept more than one request on a connection,
4600 * we need to know which http server it belongs to.
4602 evcon->http_server = http;
4603 evcon->ext_method_cmp = http->ext_method_cmp;
4604 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4605 http->connection_cnt++;
4607 /* send "service unavailable" if we've reached the connection limit */
4608 if (http->connection_max && http->connection_max < http->connection_cnt) {
4609 struct evhttp_request *req;
4611 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL) {
4612 evhttp_connection_free(evcon);
4616 req->evcon = evcon; /* the request owns the connection */
4617 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4618 req->kind = EVHTTP_REQUEST;
4619 /* note, req->remote_host not needed since we don't read */
4621 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4623 /* send error to client */
4624 evcon->state = EVCON_WRITING;
4625 bufferevent_enable(evcon->bufev, EV_READ); /* enable close events */
4626 evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL);
4628 } else if (evhttp_associate_new_request_with_connection(evcon) == -1)
4629 evhttp_connection_free(evcon);
4634 * Network helper functions that we do not want to export to the rest of
4639 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4640 char **phost, char **pport)
4642 char ntop[NI_MAXHOST];
4643 char strport[NI_MAXSERV];
4646 #ifdef EVENT__HAVE_GETNAMEINFO
4647 ni_result = getnameinfo(sa, salen,
4648 ntop, sizeof(ntop), strport, sizeof(strport),
4649 NI_NUMERICHOST|NI_NUMERICSERV);
4651 if (ni_result != 0) {
4653 /* Windows doesn't have an EAI_SYSTEM. */
4654 if (ni_result == EAI_SYSTEM)
4655 event_err(1, "getnameinfo failed");
4658 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4662 ni_result = fake_getnameinfo(sa, salen,
4663 ntop, sizeof(ntop), strport, sizeof(strport),
4664 NI_NUMERICHOST|NI_NUMERICSERV);
4669 *phost = mm_strdup(ntop);
4670 *pport = mm_strdup(strport);
4673 /* Create a non-blocking socket and bind it */
4674 static evutil_socket_t
4675 create_bind_socket_nonblock(struct evutil_addrinfo *ai, int reuse)
4682 /* Create listen socket */
4683 fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
4684 SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
4686 event_sock_warn(-1, "socket");
4690 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
4693 if (evutil_make_listen_socket_reuseable(fd) < 0)
4698 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
4706 serrno = EVUTIL_SOCKET_ERROR();
4707 evutil_closesocket(fd);
4708 EVUTIL_SET_SOCKET_ERROR(serrno);
4712 static struct evutil_addrinfo *
4713 make_addrinfo(const char *address, ev_uint16_t port)
4715 struct evutil_addrinfo *ai = NULL;
4717 struct evutil_addrinfo hints;
4718 char strport[NI_MAXSERV];
4721 memset(&hints, 0, sizeof(hints));
4722 hints.ai_family = AF_UNSPEC;
4723 hints.ai_socktype = SOCK_STREAM;
4724 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
4725 * types we don't have an interface to connect to. */
4726 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
4727 evutil_snprintf(strport, sizeof(strport), "%d", port);
4728 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
4730 if (ai_result == EVUTIL_EAI_SYSTEM)
4731 event_warn("getaddrinfo");
4733 event_warnx("getaddrinfo: %s",
4734 evutil_gai_strerror(ai_result));
4741 static evutil_socket_t
4742 bind_socket(const char *address, ev_uint16_t port, int reuse)
4745 struct evutil_addrinfo *aitop = NULL;
4747 /* just create an unbound socket */
4748 if (address == NULL && port == 0)
4749 return create_bind_socket_nonblock(NULL, 0);
4751 aitop = make_addrinfo(address, port);
4756 fd = create_bind_socket_nonblock(aitop, reuse);
4758 evutil_freeaddrinfo(aitop);
4765 char *scheme; /* scheme; e.g http, ftp etc */
4766 char *userinfo; /* userinfo (typically username:pass), or NULL */
4767 char *host; /* hostname, IP address, or NULL */
4768 int port; /* port, or zero */
4769 char *path; /* path, or "". */
4770 char *query; /* query, or NULL */
4771 char *fragment; /* fragment or NULL */
4775 evhttp_uri_new(void)
4777 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
4784 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
4789 /* Return true if the string starting at s and ending immediately before eos
4790 * is a valid URI scheme according to RFC3986
4793 scheme_ok(const char *s, const char *eos)
4795 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4796 EVUTIL_ASSERT(eos >= s);
4799 if (!EVUTIL_ISALPHA_(*s))
4802 if (! EVUTIL_ISALNUM_(*s) &&
4803 *s != '+' && *s != '-' && *s != '.')
4809 #define SUBDELIMS "!$&'()*+,;="
4811 /* Return true iff [s..eos) is a valid userinfo */
4813 userinfo_ok(const char *s, const char *eos)
4816 if (CHAR_IS_UNRESERVED(*s) ||
4817 strchr(SUBDELIMS, *s) ||
4820 else if (*s == '%' && s+2 < eos &&
4821 EVUTIL_ISXDIGIT_(s[1]) &&
4822 EVUTIL_ISXDIGIT_(s[2]))
4831 regname_ok(const char *s, const char *eos)
4833 while (s && s<eos) {
4834 if (CHAR_IS_UNRESERVED(*s) ||
4835 strchr(SUBDELIMS, *s))
4837 else if (*s == '%' &&
4838 EVUTIL_ISXDIGIT_(s[1]) &&
4839 EVUTIL_ISXDIGIT_(s[2]))
4848 parse_port(const char *s, const char *eos)
4852 if (! EVUTIL_ISDIGIT_(*s))
4854 portnum = (portnum * 10) + (*s - '0');
4857 if (portnum > 65535)
4864 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4866 bracket_addr_ok(const char *s, const char *eos)
4868 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4871 /* IPvFuture, or junk.
4872 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4874 s += 2; /* skip [v */
4876 if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
4878 while (s < eos && *s != '.') {
4879 if (EVUTIL_ISXDIGIT_(*s))
4888 if (CHAR_IS_UNRESERVED(*s) ||
4889 strchr(SUBDELIMS, *s) ||
4899 ev_ssize_t n_chars = eos-s-2;
4900 struct in6_addr in6;
4901 if (n_chars >= 64) /* way too long */
4903 memcpy(buf, s+1, n_chars);
4905 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4910 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4915 uri->host = mm_strdup("");
4916 if (uri->host == NULL) {
4917 event_warn("%s: strdup", __func__);
4923 /* Optionally, we start with "userinfo@" */
4925 cp = strchr(s, '@');
4926 if (cp && cp < eos) {
4927 if (! userinfo_ok(s,cp))
4930 uri->userinfo = mm_strdup(s);
4931 if (uri->userinfo == NULL) {
4932 event_warn("%s: strdup", __func__);
4938 /* Optionally, we end with ":port" */
4939 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
4941 if (port >= cp && *port == ':') {
4942 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4945 else if ((uri->port = parse_port(port+1, eos))<0)
4949 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4950 * an IP-Literal, or a reg-name */
4951 EVUTIL_ASSERT(eos >= cp);
4952 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4953 /* IPv6address, IP-Literal, or junk. */
4954 if (! bracket_addr_ok(cp, eos))
4957 /* Make sure the host part is ok. */
4958 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4961 uri->host = mm_malloc(eos-cp+1);
4962 if (uri->host == NULL) {
4963 event_warn("%s: malloc", __func__);
4966 memcpy(uri->host, cp, eos-cp);
4967 uri->host[eos-cp] = '\0';
4973 end_of_authority(char *cp)
4976 if (*cp == '?' || *cp == '#' || *cp == '/')
4989 /* Return the character after the longest prefix of 'cp' that matches...
4990 * *pchar / "/" if allow_qchars is false, or
4991 * *(pchar / "/" / "?") if allow_qchars is true.
4994 end_of_path(char *cp, enum uri_part part, unsigned flags)
4996 if (flags & EVHTTP_URI_NONCONFORMANT) {
4997 /* If NONCONFORMANT:
4998 * Path is everything up to a # or ? or nul.
4999 * Query is everything up a # or nul
5000 * Fragment is everything up to a nul.
5004 while (*cp && *cp != '#' && *cp != '?')
5008 while (*cp && *cp != '#')
5019 if (CHAR_IS_UNRESERVED(*cp) ||
5020 strchr(SUBDELIMS, *cp) ||
5021 *cp == ':' || *cp == '@' || *cp == '/')
5023 else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
5024 EVUTIL_ISXDIGIT_(cp[2]))
5026 else if (*cp == '?' && part != PART_PATH)
5035 path_matches_noscheme(const char *cp)
5040 else if (*cp == '/')
5048 evhttp_uri_parse(const char *source_uri)
5050 return evhttp_uri_parse_with_flags(source_uri, 0);
5054 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
5056 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
5057 char *path = NULL, *fragment = NULL;
5058 int got_authority = 0;
5060 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
5062 event_warn("%s: calloc", __func__);
5068 readbuf = mm_strdup(source_uri);
5069 if (readbuf == NULL) {
5070 event_warn("%s: strdup", __func__);
5077 /* We try to follow RFC3986 here as much as we can, and match
5080 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
5082 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
5086 token = strchr(readp, ':');
5087 if (token && scheme_ok(readp,token)) {
5089 uri->scheme = mm_strdup(readp);
5090 if (uri->scheme == NULL) {
5091 event_warn("%s: strdup", __func__);
5094 readp = token+1; /* eat : */
5097 /* 2. Optionally, "//" then an 'authority' part. */
5098 if (readp[0]=='/' && readp[1] == '/') {
5102 path = end_of_authority(readp);
5103 if (parse_authority(uri, authority, path) < 0)
5109 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
5112 readp = end_of_path(path, PART_PATH, flags);
5115 if (*readp == '?') {
5119 readp = end_of_path(readp, PART_QUERY, flags);
5122 if (*readp == '#') {
5126 readp = end_of_path(readp, PART_FRAGMENT, flags);
5128 if (*readp != '\0') {
5132 /* These next two cases may be unreachable; I'm leaving them
5133 * in to be defensive. */
5134 /* If you didn't get an authority, the path can't begin with "//" */
5135 if (!got_authority && path[0]=='/' && path[1]=='/')
5137 /* If you did get an authority, the path must begin with "/" or be
5139 if (got_authority && path[0] != '/' && path[0] != '\0')
5141 /* (End of maybe-unreachable cases) */
5143 /* If there was no scheme, the first part of the path (if any) must
5144 * have no colon in it. */
5145 if (! uri->scheme && !path_matches_noscheme(path))
5148 EVUTIL_ASSERT(path);
5149 uri->path = mm_strdup(path);
5150 if (uri->path == NULL) {
5151 event_warn("%s: strdup", __func__);
5156 uri->query = mm_strdup(query);
5157 if (uri->query == NULL) {
5158 event_warn("%s: strdup", __func__);
5163 uri->fragment = mm_strdup(fragment);
5164 if (uri->fragment == NULL) {
5165 event_warn("%s: strdup", __func__);
5175 evhttp_uri_free(uri);
5181 static struct evhttp_uri *
5182 evhttp_uri_parse_authority(char *source_uri)
5184 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
5188 event_warn("%s: calloc", __func__);
5194 end = end_of_authority(source_uri);
5195 if (parse_authority(uri, source_uri, end) < 0)
5198 uri->path = mm_strdup("");
5199 if (uri->path == NULL) {
5200 event_warn("%s: strdup", __func__);
5207 evhttp_uri_free(uri);
5212 evhttp_uri_free(struct evhttp_uri *uri)
5214 #define URI_FREE_STR_(f) \
5219 URI_FREE_STR_(scheme);
5220 URI_FREE_STR_(userinfo);
5221 URI_FREE_STR_(host);
5222 URI_FREE_STR_(path);
5223 URI_FREE_STR_(query);
5224 URI_FREE_STR_(fragment);
5227 #undef URI_FREE_STR_
5231 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
5233 struct evbuffer *tmp = 0;
5234 size_t joined_size = 0;
5235 char *output = NULL;
5237 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
5239 if (!uri || !buf || !limit)
5242 tmp = evbuffer_new();
5248 evbuffer_add(tmp, ":", 1);
5251 evbuffer_add(tmp, "//", 2);
5253 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
5256 evbuffer_add_printf(tmp,":%d", uri->port);
5258 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
5266 evbuffer_add(tmp, "?", 1);
5270 if (uri->fragment) {
5271 evbuffer_add(tmp, "#", 1);
5275 evbuffer_add(tmp, "\0", 1); /* NUL */
5277 joined_size = evbuffer_get_length(tmp);
5279 if (joined_size > limit) {
5280 /* It doesn't fit. */
5284 evbuffer_remove(tmp, buf, joined_size);
5295 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
5300 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
5302 return uri->userinfo;
5305 evhttp_uri_get_host(const struct evhttp_uri *uri)
5310 evhttp_uri_get_port(const struct evhttp_uri *uri)
5315 evhttp_uri_get_path(const struct evhttp_uri *uri)
5320 evhttp_uri_get_query(const struct evhttp_uri *uri)
5325 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
5327 return uri->fragment;
5330 #define URI_SET_STR_(f) do { \
5334 if ((uri->f = mm_strdup(f)) == NULL) { \
5335 event_warn("%s: strdup()", __func__); \
5344 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
5346 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
5349 URI_SET_STR_(scheme);
5353 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
5355 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
5357 URI_SET_STR_(userinfo);
5361 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
5364 if (host[0] == '[') {
5365 if (! bracket_addr_ok(host, host+strlen(host)))
5368 if (! regname_ok(host, host+strlen(host)))
5377 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
5384 #define end_of_cpath(cp,p,f) \
5385 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
5388 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
5390 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
5397 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
5399 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
5401 URI_SET_STR_(query);
5405 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
5407 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
5409 URI_SET_STR_(fragment);