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 #include <sys/queue.h>
61 #ifdef EVENT__HAVE_NETINET_IN_H
62 #include <netinet/in.h>
64 #ifdef EVENT__HAVE_ARPA_INET_H
65 #include <arpa/inet.h>
67 #ifdef EVENT__HAVE_NETDB_H
83 #ifdef EVENT__HAVE_UNISTD_H
86 #ifdef EVENT__HAVE_FCNTL_H
90 #undef timeout_pending
91 #undef timeout_initialized
93 #include "strlcpy-internal.h"
94 #include "event2/http.h"
95 #include "event2/event.h"
96 #include "event2/buffer.h"
97 #include "event2/bufferevent.h"
98 #include "event2/http_struct.h"
99 #include "event2/http_compat.h"
100 #include "event2/util.h"
101 #include "event2/listener.h"
102 #include "log-internal.h"
103 #include "util-internal.h"
104 #include "http-internal.h"
105 #include "mm-internal.h"
106 #include "bufferevent-internal.h"
108 #ifndef EVENT__HAVE_GETNAMEINFO
109 #define NI_MAXSERV 32
110 #define NI_MAXHOST 1025
112 #ifndef NI_NUMERICHOST
113 #define NI_NUMERICHOST 1
116 #ifndef NI_NUMERICSERV
117 #define NI_NUMERICSERV 2
121 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
122 size_t hostlen, char *serv, size_t servlen, int flags)
124 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
128 evutil_snprintf(tmpserv, sizeof(tmpserv),
129 "%d", ntohs(sin->sin_port));
130 if (strlcpy(serv, tmpserv, servlen) >= servlen)
135 if (flags & NI_NUMERICHOST) {
136 if (strlcpy(host, inet_ntoa(sin->sin_addr),
143 hp = gethostbyaddr((char *)&sin->sin_addr,
144 sizeof(struct in_addr), AF_INET);
148 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
159 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \
160 ((req)->major < (major_v) || \
161 ((req)->major == (major_v) && (req)->minor < (minor_v)))
163 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \
164 ((req)->major > (major_v) || \
165 ((req)->major == (major_v) && (req)->minor >= (minor_v)))
168 #define MIN(a,b) (((a)<(b))?(a):(b))
173 static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse);
174 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
175 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
176 static struct evhttp_uri *evhttp_uri_parse_authority(char *source_uri);
177 static int evhttp_associate_new_request_with_connection(
178 struct evhttp_connection *evcon);
179 static void evhttp_connection_start_detectclose(
180 struct evhttp_connection *evcon);
181 static void evhttp_connection_stop_detectclose(
182 struct evhttp_connection *evcon);
183 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
184 static void evhttp_read_firstline(struct evhttp_connection *evcon,
185 struct evhttp_request *req);
186 static void evhttp_read_header(struct evhttp_connection *evcon,
187 struct evhttp_request *req);
188 static int evhttp_add_header_internal(struct evkeyvalq *headers,
189 const char *key, const char *value);
190 static const char *evhttp_response_phrase_internal(int code);
191 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t);
192 static void evhttp_write_buffer(struct evhttp_connection *,
193 void (*)(struct evhttp_connection *, void *), void *);
194 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
196 /* callbacks for bufferevent */
197 static void evhttp_read_cb(struct bufferevent *, void *);
198 static void evhttp_write_cb(struct bufferevent *, void *);
199 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
200 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
201 const char *hostname);
203 #ifndef EVENT__HAVE_STRSEP
204 /* strsep replacement for platforms that lack it. Only works if
205 * del is one character long. */
207 strsep(char **s, const char *del)
210 EVUTIL_ASSERT(strlen(del) == 1);
214 d = strstr(tok, del);
225 html_replace(const char ch, const char **escaped)
251 * Replaces <, >, ", ' and & with <, >, ",
252 * ' and & correspondingly.
254 * The returned string needs to be freed by the caller.
258 evhttp_htmlescape(const char *html)
261 size_t new_size = 0, old_size = 0;
262 char *escaped_html, *p;
267 old_size = strlen(html);
268 for (i = 0; i < old_size; ++i) {
269 const char *replaced = NULL;
270 const size_t replace_size = html_replace(html[i], &replaced);
271 if (replace_size > EV_SIZE_MAX - new_size) {
272 event_warn("%s: html_replace overflow", __func__);
275 new_size += replace_size;
278 if (new_size == EV_SIZE_MAX)
280 p = escaped_html = mm_malloc(new_size + 1);
281 if (escaped_html == NULL) {
282 event_warn("%s: malloc(%lu)", __func__,
283 (unsigned long)(new_size + 1));
286 for (i = 0; i < old_size; ++i) {
287 const char *replaced = &html[i];
288 const size_t len = html_replace(html[i], &replaced);
289 memcpy(p, replaced, len);
295 return (escaped_html);
298 /** Given an evhttp_cmd_type, returns a constant string containing the
299 * equivalent HTTP command, or NULL if the evhttp_command_type is
302 evhttp_method(enum evhttp_cmd_type type)
310 case EVHTTP_REQ_POST:
313 case EVHTTP_REQ_HEAD:
319 case EVHTTP_REQ_DELETE:
322 case EVHTTP_REQ_OPTIONS:
325 case EVHTTP_REQ_TRACE:
328 case EVHTTP_REQ_CONNECT:
331 case EVHTTP_REQ_PATCH:
343 * Determines if a response should have a body.
344 * Follows the rules in RFC 2616 section 4.3.
345 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
349 evhttp_response_needs_body(struct evhttp_request *req)
351 return (req->response_code != HTTP_NOCONTENT &&
352 req->response_code != HTTP_NOTMODIFIED &&
353 (req->response_code < 100 || req->response_code >= 200) &&
354 req->type != EVHTTP_REQ_HEAD);
357 /** Helper: called after we've added some data to an evcon's bufferevent's
358 * output buffer. Sets the evconn's writing-is-done callback, and puts
359 * the bufferevent into writing mode.
362 evhttp_write_buffer(struct evhttp_connection *evcon,
363 void (*cb)(struct evhttp_connection *, void *), void *arg)
365 event_debug(("%s: preparing to write buffer\n", __func__));
371 /* Disable the read callback: we don't actually care about data;
372 * we only care about close detection. (We don't disable reading --
373 * EV_READ, since we *do* want to learn about any close events.) */
374 bufferevent_setcb(evcon->bufev,
380 bufferevent_enable(evcon->bufev, EV_READ|EV_WRITE);
384 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
386 bufferevent_disable(evcon->bufev, EV_WRITE);
390 evhttp_send_continue(struct evhttp_connection *evcon,
391 struct evhttp_request *req)
393 bufferevent_enable(evcon->bufev, EV_WRITE);
394 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
395 "HTTP/%d.%d 100 Continue\r\n\r\n",
396 req->major, req->minor);
397 evcon->cb = evhttp_send_continue_done;
398 evcon->cb_arg = NULL;
399 bufferevent_setcb(evcon->bufev,
406 /** Helper: returns true iff evconn is in any connected state. */
408 evhttp_connected(struct evhttp_connection *evcon)
410 switch (evcon->state) {
411 case EVCON_DISCONNECTED:
412 case EVCON_CONNECTING:
415 case EVCON_READING_FIRSTLINE:
416 case EVCON_READING_HEADERS:
417 case EVCON_READING_BODY:
418 case EVCON_READING_TRAILER:
425 /* Create the headers needed for an outgoing HTTP request, adds them to
426 * the request's header list, and writes the request line to the
427 * connection's output buffer.
430 evhttp_make_header_request(struct evhttp_connection *evcon,
431 struct evhttp_request *req)
435 evhttp_remove_header(req->output_headers, "Proxy-Connection");
437 /* Generate request line */
438 if (!(method = evhttp_method(req->type))) {
442 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
443 "%s %s HTTP/%d.%d\r\n",
444 method, req->uri, req->major, req->minor);
446 /* Add the content length on a post or put request if missing */
447 if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
448 evhttp_find_header(req->output_headers, "Content-Length") == NULL){
450 evutil_snprintf(size, sizeof(size), EV_SIZE_FMT,
451 EV_SIZE_ARG(evbuffer_get_length(req->output_buffer)));
452 evhttp_add_header(req->output_headers, "Content-Length", size);
456 /** Return true if the list of headers in 'headers', intepreted with respect
457 * to flags, means that we should send a "connection: close" when the request
460 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
462 if (flags & EVHTTP_PROXY_REQUEST) {
463 /* proxy connection */
464 const char *connection = evhttp_find_header(headers, "Proxy-Connection");
465 return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
467 const char *connection = evhttp_find_header(headers, "Connection");
468 return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
472 evhttp_is_request_connection_close(struct evhttp_request *req)
475 evhttp_is_connection_close(req->flags, req->input_headers) ||
476 evhttp_is_connection_close(req->flags, req->output_headers);
479 /* Return true iff 'headers' contains 'Connection: keep-alive' */
481 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
483 const char *connection = evhttp_find_header(headers, "Connection");
484 return (connection != NULL
485 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
488 /* Add a correct "Date" header to headers, unless it already has one. */
490 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
492 if (evhttp_find_header(headers, "Date") == NULL) {
494 if (sizeof(date) - evutil_date_rfc1123(date, sizeof(date), NULL) > 0) {
495 evhttp_add_header(headers, "Date", date);
500 /* Add a "Content-Length" header with value 'content_length' to headers,
501 * unless it already has a content-length or transfer-encoding header. */
503 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
504 size_t content_length)
506 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
507 evhttp_find_header(headers, "Content-Length") == NULL) {
509 evutil_snprintf(len, sizeof(len), EV_SIZE_FMT,
510 EV_SIZE_ARG(content_length));
511 evhttp_add_header(headers, "Content-Length", len);
516 * Create the headers needed for an HTTP reply in req->output_headers,
517 * and write the first HTTP response for req line to evcon.
520 evhttp_make_header_response(struct evhttp_connection *evcon,
521 struct evhttp_request *req)
523 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
524 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
525 "HTTP/%d.%d %d %s\r\n",
526 req->major, req->minor, req->response_code,
527 req->response_code_line);
529 if (req->major == 1) {
531 evhttp_maybe_add_date_header(req->output_headers);
534 * if the protocol is 1.0; and the connection was keep-alive
535 * we need to add a keep-alive header, too.
537 if (req->minor == 0 && is_keepalive)
538 evhttp_add_header(req->output_headers,
539 "Connection", "keep-alive");
541 if ((req->minor >= 1 || is_keepalive) &&
542 evhttp_response_needs_body(req)) {
544 * we need to add the content length if the
545 * user did not give it, this is required for
546 * persistent connections to work.
548 evhttp_maybe_add_content_length_header(
550 evbuffer_get_length(req->output_buffer));
554 /* Potentially add headers for unidentified content. */
555 if (evhttp_response_needs_body(req)) {
556 if (evhttp_find_header(req->output_headers,
557 "Content-Type") == NULL
558 && evcon->http_server->default_content_type) {
559 evhttp_add_header(req->output_headers,
561 evcon->http_server->default_content_type);
565 /* if the request asked for a close, we send a close, too */
566 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
567 evhttp_remove_header(req->output_headers, "Connection");
568 if (!(req->flags & EVHTTP_PROXY_REQUEST))
569 evhttp_add_header(req->output_headers, "Connection", "close");
570 evhttp_remove_header(req->output_headers, "Proxy-Connection");
574 enum expect { NO, CONTINUE, OTHER };
575 static enum expect evhttp_have_expect(struct evhttp_request *req, int input)
578 struct evkeyvalq *h = input ? req->input_headers : req->output_headers;
580 if (!(req->kind == EVHTTP_REQUEST) || !REQ_VERSION_ATLEAST(req, 1, 1))
583 expect = evhttp_find_header(h, "Expect");
587 return !evutil_ascii_strcasecmp(expect, "100-continue") ? CONTINUE : OTHER;
591 /** Generate all headers appropriate for sending the http request in req (or
592 * the response, if we're sending a response), and write them to evcon's
593 * bufferevent. Also writes all data from req->output_buffer */
595 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
597 struct evkeyval *header;
598 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
601 * Depending if this is a HTTP request or response, we might need to
602 * add some new headers or remove existing headers.
604 if (req->kind == EVHTTP_REQUEST) {
605 evhttp_make_header_request(evcon, req);
607 evhttp_make_header_response(evcon, req);
610 TAILQ_FOREACH(header, req->output_headers, next) {
611 evbuffer_add_printf(output, "%s: %s\r\n",
612 header->key, header->value);
614 evbuffer_add(output, "\r\n", 2);
616 if (evhttp_have_expect(req, 0) != CONTINUE &&
617 evbuffer_get_length(req->output_buffer)) {
619 * For a request, we add the POST data, for a reply, this
620 * is the regular data.
622 evbuffer_add_buffer(output, req->output_buffer);
627 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
628 ev_ssize_t new_max_headers_size)
630 if (new_max_headers_size<0)
631 evcon->max_headers_size = EV_SIZE_MAX;
633 evcon->max_headers_size = new_max_headers_size;
636 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
637 ev_ssize_t new_max_body_size)
639 if (new_max_body_size<0)
640 evcon->max_body_size = EV_UINT64_MAX;
642 evcon->max_body_size = new_max_body_size;
646 evhttp_connection_incoming_fail(struct evhttp_request *req,
647 enum evhttp_request_error error)
650 case EVREQ_HTTP_DATA_TOO_LONG:
651 req->response_code = HTTP_ENTITYTOOLARGE;
654 req->response_code = HTTP_BADREQUEST;
658 case EVREQ_HTTP_TIMEOUT:
661 * these are cases in which we probably should just
662 * close the connection and not send a reply. this
663 * case may happen when a browser keeps a persistent
664 * connection open and we timeout on the read. when
665 * the request is still being used for sending, we
666 * need to disassociated it from the connection here.
668 if (!req->userdone) {
669 /* remove it so that it will not be freed */
670 TAILQ_REMOVE(&req->evcon->requests, req, next);
671 /* indicate that this request no longer has a
677 case EVREQ_HTTP_INVALID_HEADER:
678 case EVREQ_HTTP_BUFFER_ERROR:
679 case EVREQ_HTTP_REQUEST_CANCEL:
680 case EVREQ_HTTP_DATA_TOO_LONG:
681 default: /* xxx: probably should just error on default */
682 /* the callback looks at the uri to determine errors */
687 if (req->uri_elems) {
688 evhttp_uri_free(req->uri_elems);
689 req->uri_elems = NULL;
693 * the callback needs to send a reply, once the reply has
694 * been send, the connection should get freed.
696 (*req->cb)(req, req->cb_arg);
702 /* Free connection ownership of which can be acquired by user using
703 * evhttp_request_own(). */
705 evhttp_request_free_auto(struct evhttp_request *req)
707 if (!(req->flags & EVHTTP_USER_OWNED))
708 evhttp_request_free(req);
712 evhttp_request_free_(struct evhttp_connection *evcon, struct evhttp_request *req)
714 TAILQ_REMOVE(&evcon->requests, req, next);
715 evhttp_request_free_auto(req);
718 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
719 * given in error. If it's an outgoing connection, reset the connection,
720 * retry any pending requests, and inform the user. If it's incoming,
721 * delegates to evhttp_connection_incoming_fail(). */
723 evhttp_connection_fail_(struct evhttp_connection *evcon,
724 enum evhttp_request_error error)
726 const int errsave = EVUTIL_SOCKET_ERROR();
727 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
728 void (*cb)(struct evhttp_request *, void *);
730 void (*error_cb)(enum evhttp_request_error, void *);
732 EVUTIL_ASSERT(req != NULL);
734 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
736 if (evcon->flags & EVHTTP_CON_INCOMING) {
738 * for incoming requests, there are two different
739 * failure cases. it's either a network level error
740 * or an http layer error. for problems on the network
741 * layer like timeouts we just drop the connections.
742 * For HTTP problems, we might have to send back a
743 * reply before the connection can be freed.
745 if (evhttp_connection_incoming_fail(req, error) == -1)
746 evhttp_connection_free(evcon);
750 error_cb = req->error_cb;
751 error_cb_arg = req->cb_arg;
752 /* when the request was canceled, the callback is not executed */
753 if (error != EVREQ_HTTP_REQUEST_CANCEL) {
754 /* save the callback for later; the cb might free our object */
756 cb_arg = req->cb_arg;
762 /* do not fail all requests; the next request is going to get
763 * send over a new connection. when a user cancels a request,
764 * all other pending requests should be processed as normal
766 evhttp_request_free_(evcon, req);
768 /* reset the connection */
769 evhttp_connection_reset_(evcon);
771 /* We are trying the next request that was queued on us */
772 if (TAILQ_FIRST(&evcon->requests) != NULL)
773 evhttp_connection_connect_(evcon);
775 /* The call to evhttp_connection_reset_ overwrote errno.
776 * Let's restore the original errno, so that the user's
777 * callback can have a better idea of what the error was.
779 EVUTIL_SET_SOCKET_ERROR(errsave);
781 /* inform the user */
782 if (error_cb != NULL)
783 error_cb(error, error_cb_arg);
788 /* Bufferevent callback: invoked when any data has been written from an
789 * http connection's bufferevent */
791 evhttp_write_cb(struct bufferevent *bufev, void *arg)
793 struct evhttp_connection *evcon = arg;
795 /* Activate our call back */
796 if (evcon->cb != NULL)
797 (*evcon->cb)(evcon, evcon->cb_arg);
801 * Advance the connection state.
802 * - If this is an outgoing connection, we've just processed the response;
803 * idle or close the connection.
804 * - If this is an incoming connection, we've just processed the request;
808 evhttp_connection_done(struct evhttp_connection *evcon)
810 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
811 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
815 /* idle or close the connection */
816 int need_close = evhttp_is_request_connection_close(req);
817 TAILQ_REMOVE(&evcon->requests, req, next);
820 evcon->state = EVCON_IDLE;
822 /* check if we got asked to close the connection */
824 evhttp_connection_reset_(evcon);
826 if (TAILQ_FIRST(&evcon->requests) != NULL) {
828 * We have more requests; reset the connection
829 * and deal with the next request.
831 if (!evhttp_connected(evcon))
832 evhttp_connection_connect_(evcon);
834 evhttp_request_dispatch(evcon);
835 } else if (!need_close) {
837 * The connection is going to be persistent, but we
838 * need to detect if the other side closes it.
840 evhttp_connection_start_detectclose(evcon);
841 } else if ((evcon->flags & EVHTTP_CON_AUTOFREE)) {
843 * If we have no more requests that need completion
844 * and we're not waiting for the connection to close
850 * incoming connection - we need to leave the request on the
851 * connection so that we can reply to it.
853 evcon->state = EVCON_WRITING;
856 /* notify the user of the request */
857 (*req->cb)(req, req->cb_arg);
859 /* if this was an outgoing request, we own and it's done. so free it. */
861 evhttp_request_free_auto(req);
864 /* If this was the last request of an outgoing connection and we're
865 * not waiting to receive a connection close event and we want to
866 * automatically free the connection. We check to ensure our request
867 * list is empty one last time just in case our callback added a
870 if (free_evcon && TAILQ_FIRST(&evcon->requests) == NULL) {
871 evhttp_connection_free(evcon);
876 * Handles reading from a chunked request.
877 * return ALL_DATA_READ:
878 * all data has been read
879 * return MORE_DATA_EXPECTED:
880 * more data is expected
881 * return DATA_CORRUPTED:
883 * return REQUEST_CANCELED:
884 * request was canceled by the user calling evhttp_cancel_request
885 * return DATA_TOO_LONG:
886 * ran over the maximum limit
889 static enum message_read_status
890 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
892 if (req == NULL || buf == NULL) {
893 return DATA_CORRUPTED;
899 if ((buflen = evbuffer_get_length(buf)) == 0) {
903 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
904 * check for overflow conditions */
905 if (buflen > EV_SSIZE_MAX) {
906 return DATA_CORRUPTED;
909 if (req->ntoread < 0) {
910 /* Read chunk size */
912 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
917 /* the last chunk is on a new line? */
918 if (strlen(p) == 0) {
922 ntoread = evutil_strtoll(p, &endp, 16);
923 error = (*p == '\0' ||
924 (*endp != '\0' && *endp != ' ') ||
928 /* could not get chunk size */
929 return (DATA_CORRUPTED);
932 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
933 if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
934 return DATA_CORRUPTED;
937 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
938 /* failed body length test */
939 event_debug(("Request body is too long"));
940 return (DATA_TOO_LONG);
943 req->body_size += (size_t)ntoread;
944 req->ntoread = ntoread;
945 if (req->ntoread == 0) {
947 return (ALL_DATA_READ);
952 /* req->ntoread is signed int64, len is ssize_t, based on arch,
953 * ssize_t could only be 32b, check for these conditions */
954 if (req->ntoread > EV_SSIZE_MAX) {
955 return DATA_CORRUPTED;
958 /* don't have enough to complete a chunk; wait for more */
959 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
960 return (MORE_DATA_EXPECTED);
962 /* Completed chunk */
963 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
965 if (req->chunk_cb != NULL) {
966 req->flags |= EVHTTP_REQ_DEFER_FREE;
967 (*req->chunk_cb)(req, req->cb_arg);
968 evbuffer_drain(req->input_buffer,
969 evbuffer_get_length(req->input_buffer));
970 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
971 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
972 return (REQUEST_CANCELED);
977 return (MORE_DATA_EXPECTED);
981 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
983 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
985 switch (evhttp_parse_headers_(req, buf)) {
988 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
991 bufferevent_disable(evcon->bufev, EV_READ);
992 evhttp_connection_done(evcon);
994 case MORE_DATA_EXPECTED:
995 case REQUEST_CANCELED: /* ??? */
1002 evhttp_lingering_close(struct evhttp_connection *evcon,
1003 struct evhttp_request *req)
1005 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1007 size_t n = evbuffer_get_length(buf);
1008 if (n > (size_t) req->ntoread)
1009 n = (size_t) req->ntoread;
1011 req->body_size += n;
1013 event_debug(("Request body is too long, left " EV_I64_FMT,
1014 EV_I64_ARG(req->ntoread)));
1016 evbuffer_drain(buf, n);
1018 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1021 evhttp_lingering_fail(struct evhttp_connection *evcon,
1022 struct evhttp_request *req)
1024 if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE)
1025 evhttp_lingering_close(evcon, req);
1027 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1031 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1033 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1036 switch (evhttp_handle_chunked_read(req, buf)) {
1038 /* finished last chunk */
1039 evcon->state = EVCON_READING_TRAILER;
1040 evhttp_read_trailer(evcon, req);
1042 case DATA_CORRUPTED:
1044 /* corrupted data */
1045 evhttp_connection_fail_(evcon,
1046 EVREQ_HTTP_DATA_TOO_LONG);
1048 case REQUEST_CANCELED:
1049 /* request canceled */
1050 evhttp_request_free_auto(req);
1052 case MORE_DATA_EXPECTED:
1056 } else if (req->ntoread < 0) {
1057 /* Read until connection close. */
1058 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
1059 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
1063 req->body_size += evbuffer_get_length(buf);
1064 evbuffer_add_buffer(req->input_buffer, buf);
1065 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
1066 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
1067 /* We've postponed moving the data until now, but we're
1068 * about to use it. */
1069 size_t n = evbuffer_get_length(buf);
1071 if (n > (size_t) req->ntoread)
1072 n = (size_t) req->ntoread;
1074 req->body_size += n;
1075 evbuffer_remove_buffer(buf, req->input_buffer, n);
1078 if (req->body_size > req->evcon->max_body_size ||
1079 (!req->chunked && req->ntoread >= 0 &&
1080 (size_t)req->ntoread > req->evcon->max_body_size)) {
1081 /* XXX: The above casted comparison must checked for overflow */
1082 /* failed body length test */
1084 evhttp_lingering_fail(evcon, req);
1088 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1089 req->flags |= EVHTTP_REQ_DEFER_FREE;
1090 (*req->chunk_cb)(req, req->cb_arg);
1091 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1092 evbuffer_drain(req->input_buffer,
1093 evbuffer_get_length(req->input_buffer));
1094 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1095 evhttp_request_free_auto(req);
1100 if (!req->ntoread) {
1101 bufferevent_disable(evcon->bufev, EV_READ);
1102 /* Completed content length */
1103 evhttp_connection_done(evcon);
1108 #define get_deferred_queue(evcon) \
1112 * Gets called when more data becomes available
1116 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1118 struct evhttp_connection *evcon = arg;
1119 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1121 /* Cancel if it's pending. */
1122 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1123 &evcon->read_more_deferred_cb);
1125 switch (evcon->state) {
1126 case EVCON_READING_FIRSTLINE:
1127 evhttp_read_firstline(evcon, req);
1128 /* note the request may have been freed in
1129 * evhttp_read_body */
1131 case EVCON_READING_HEADERS:
1132 evhttp_read_header(evcon, req);
1133 /* note the request may have been freed in
1134 * evhttp_read_body */
1136 case EVCON_READING_BODY:
1137 evhttp_read_body(evcon, req);
1138 /* note the request may have been freed in
1139 * evhttp_read_body */
1141 case EVCON_READING_TRAILER:
1142 evhttp_read_trailer(evcon, req);
1147 struct evbuffer *input;
1150 input = bufferevent_get_input(evcon->bufev);
1151 total_len = evbuffer_get_length(input);
1152 event_debug(("%s: read "EV_SIZE_FMT
1153 " bytes in EVCON_IDLE state,"
1154 " resetting connection",
1155 __func__, EV_SIZE_ARG(total_len)));
1158 evhttp_connection_reset_(evcon);
1161 case EVCON_DISCONNECTED:
1162 case EVCON_CONNECTING:
1165 event_errx(1, "%s: illegal connection state %d",
1166 __func__, evcon->state);
1171 evhttp_deferred_read_cb(struct event_callback *cb, void *data)
1173 struct evhttp_connection *evcon = data;
1174 struct bufferevent *bev = evcon->bufev;
1176 (bev->readcb)(evcon->bufev, evcon);
1180 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1182 /* This is after writing the request to the server */
1183 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1184 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
1185 EVUTIL_ASSERT(req != NULL);
1187 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1189 /* We need to wait until we've written all of our output data before we can
1191 if (evbuffer_get_length(output) > 0)
1194 /* We are done writing our header and are now expecting the response */
1195 req->kind = EVHTTP_RESPONSE;
1197 evhttp_start_read_(evcon);
1201 * Clean up a connection object
1205 evhttp_connection_free(struct evhttp_connection *evcon)
1207 struct evhttp_request *req;
1210 /* notify interested parties that this connection is going down */
1211 if (evcon->fd != -1) {
1212 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1213 (*evcon->closecb)(evcon, evcon->closecb_arg);
1216 /* remove all requests that might be queued on this
1217 * connection. for server connections, this should be empty.
1218 * because it gets dequeued either in evhttp_connection_done or
1219 * evhttp_connection_fail_.
1221 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1222 evhttp_request_free_(evcon, req);
1225 if (evcon->http_server != NULL) {
1226 struct evhttp *http = evcon->http_server;
1227 TAILQ_REMOVE(&http->connections, evcon, next);
1230 if (event_initialized(&evcon->retry_ev)) {
1231 event_del(&evcon->retry_ev);
1232 event_debug_unassign(&evcon->retry_ev);
1235 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1236 &evcon->read_more_deferred_cb);
1238 if (evcon->bufev != NULL) {
1240 !(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE);
1241 if (evcon->fd == -1)
1242 evcon->fd = bufferevent_getfd(evcon->bufev);
1244 bufferevent_free(evcon->bufev);
1247 if (evcon->fd != -1) {
1248 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1250 evutil_closesocket(evcon->fd);
1253 if (evcon->bind_address != NULL)
1254 mm_free(evcon->bind_address);
1256 if (evcon->address != NULL)
1257 mm_free(evcon->address);
1263 evhttp_connection_free_on_completion(struct evhttp_connection *evcon) {
1264 evcon->flags |= EVHTTP_CON_AUTOFREE;
1268 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1269 const char *address)
1271 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1272 if (evcon->bind_address)
1273 mm_free(evcon->bind_address);
1274 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1275 event_warn("%s: strdup", __func__);
1279 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1282 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1283 evcon->bind_port = port;
1287 evhttp_request_dispatch(struct evhttp_connection* evcon)
1289 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1291 /* this should not usually happy but it's possible */
1295 EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST);
1297 /* delete possible close detection events */
1298 evhttp_connection_stop_detectclose(evcon);
1300 /* we assume that the connection is connected already */
1301 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1303 evcon->state = EVCON_WRITING;
1305 /* Create the header from the store arguments */
1306 evhttp_make_header(evcon, req);
1308 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1311 /* Reset our connection state: disables reading/writing, closes our fd (if
1312 * any), clears out buffers, and puts us in state DISCONNECTED. */
1314 evhttp_connection_reset_(struct evhttp_connection *evcon)
1316 struct evbuffer *tmp;
1319 bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL);
1321 /* XXXX This is not actually an optimal fix. Instead we ought to have
1322 an API for "stop connecting", or use bufferevent_setfd to turn off
1323 connecting. But for Libevent 2.0, this seems like a minimal change
1324 least likely to disrupt the rest of the bufferevent and http code.
1326 Why is this here? If the fd is set in the bufferevent, and the
1327 bufferevent is connecting, then you can't actually stop the
1328 bufferevent from trying to connect with bufferevent_disable(). The
1329 connect will never trigger, since we close the fd, but the timeout
1330 might. That caused an assertion failure in evhttp_connection_fail_.
1332 bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE);
1334 if (evcon->fd == -1)
1335 evcon->fd = bufferevent_getfd(evcon->bufev);
1337 if (evcon->fd != -1) {
1338 /* inform interested parties about connection close */
1339 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1340 (*evcon->closecb)(evcon, evcon->closecb_arg);
1342 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1343 evutil_closesocket(evcon->fd);
1346 err = bufferevent_setfd(evcon->bufev, -1);
1347 EVUTIL_ASSERT(!err && "setfd");
1349 /* we need to clean up any buffered data */
1350 tmp = bufferevent_get_output(evcon->bufev);
1351 err = evbuffer_drain(tmp, -1);
1352 EVUTIL_ASSERT(!err && "drain output");
1353 tmp = bufferevent_get_input(evcon->bufev);
1354 err = evbuffer_drain(tmp, -1);
1355 EVUTIL_ASSERT(!err && "drain input");
1357 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1359 evcon->state = EVCON_DISCONNECTED;
1363 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1365 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1366 bufferevent_enable(evcon->bufev, EV_READ);
1370 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1372 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1373 bufferevent_disable(evcon->bufev, EV_READ);
1377 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1379 struct evhttp_connection *evcon = arg;
1381 evcon->state = EVCON_DISCONNECTED;
1382 evhttp_connection_connect_(evcon);
1386 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1388 struct evcon_requestq requests;
1390 evhttp_connection_reset_(evcon);
1391 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1392 struct timeval tv_retry = evcon->initial_retry_timeout;
1394 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1395 /* XXXX handle failure from evhttp_add_event */
1396 for (i=0; i < evcon->retry_cnt; ++i) {
1397 tv_retry.tv_usec *= 2;
1398 if (tv_retry.tv_usec > 1000000) {
1399 tv_retry.tv_usec -= 1000000;
1400 tv_retry.tv_sec += 1;
1402 tv_retry.tv_sec *= 2;
1403 if (tv_retry.tv_sec > 3600) {
1404 tv_retry.tv_sec = 3600;
1405 tv_retry.tv_usec = 0;
1408 event_add(&evcon->retry_ev, &tv_retry);
1414 * User callback can do evhttp_make_request() on the same
1415 * evcon so new request will be added to evcon->requests. To
1416 * avoid freeing it prematurely we iterate over the copy of
1419 TAILQ_INIT(&requests);
1420 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1421 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1422 TAILQ_REMOVE(&evcon->requests, request, next);
1423 TAILQ_INSERT_TAIL(&requests, request, next);
1426 /* for now, we just signal all requests by executing their callbacks */
1427 while (TAILQ_FIRST(&requests) != NULL) {
1428 struct evhttp_request *request = TAILQ_FIRST(&requests);
1429 TAILQ_REMOVE(&requests, request, next);
1430 request->evcon = NULL;
1432 /* we might want to set an error here */
1433 request->cb(request, request->cb_arg);
1434 evhttp_request_free_auto(request);
1439 evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
1440 struct evhttp_request *req)
1442 struct evbuffer *buf;
1444 /** Second time, we can't read anything */
1445 if (evcon->flags & EVHTTP_CON_READING_ERROR) {
1446 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1447 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1451 req->kind = EVHTTP_RESPONSE;
1453 buf = bufferevent_get_output(evcon->bufev);
1454 evbuffer_unfreeze(buf, 1);
1455 evbuffer_drain(buf, evbuffer_get_length(buf));
1456 evbuffer_freeze(buf, 1);
1458 evhttp_start_read_(evcon);
1459 evcon->flags |= EVHTTP_CON_READING_ERROR;
1463 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1465 struct evhttp_connection *evcon = arg;
1466 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1468 if (evcon->fd == -1)
1469 evcon->fd = bufferevent_getfd(bufev);
1471 switch (evcon->state) {
1472 case EVCON_CONNECTING:
1473 if (what & BEV_EVENT_TIMEOUT) {
1474 event_debug(("%s: connection timeout for \"%s:%d\" on "
1476 __func__, evcon->address, evcon->port,
1477 EV_SOCK_ARG(evcon->fd)));
1478 evhttp_connection_cb_cleanup(evcon);
1483 case EVCON_READING_BODY:
1484 if (!req->chunked && req->ntoread < 0
1485 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1486 /* EOF on read can be benign */
1487 evhttp_connection_done(evcon);
1492 case EVCON_DISCONNECTED:
1494 case EVCON_READING_FIRSTLINE:
1495 case EVCON_READING_HEADERS:
1496 case EVCON_READING_TRAILER:
1502 /* when we are in close detect mode, a read error means that
1503 * the other side closed their connection.
1505 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1506 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1507 EVUTIL_ASSERT(evcon->http_server == NULL);
1508 /* For connections from the client, we just
1509 * reset the connection so that it becomes
1512 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1513 evhttp_connection_reset_(evcon);
1516 * If we have no more requests that need completion
1517 * and we want to auto-free the connection when all
1518 * requests have been completed.
1520 if (TAILQ_FIRST(&evcon->requests) == NULL
1521 && (evcon->flags & EVHTTP_CON_OUTGOING)
1522 && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1523 evhttp_connection_free(evcon);
1528 if (what & BEV_EVENT_TIMEOUT) {
1529 evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
1530 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1531 if (what & BEV_EVENT_WRITING &&
1532 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR) {
1533 evhttp_connection_read_on_write_error(evcon, req);
1537 if (what & BEV_EVENT_READING &&
1538 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR &&
1539 evbuffer_get_length(bufferevent_get_input(bufev))) {
1540 event_deferred_cb_schedule_(get_deferred_queue(evcon),
1541 &evcon->read_more_deferred_cb);
1545 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1546 } else if (what == BEV_EVENT_CONNECTED) {
1548 evhttp_connection_fail_(evcon, EVREQ_HTTP_BUFFER_ERROR);
1553 * Event callback for asynchronous connection attempt.
1556 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1558 struct evhttp_connection *evcon = arg;
1560 ev_socklen_t errsz = sizeof(error);
1562 if (evcon->fd == -1)
1563 evcon->fd = bufferevent_getfd(bufev);
1565 if (!(what & BEV_EVENT_CONNECTED)) {
1566 /* some operating systems return ECONNREFUSED immediately
1567 * when connecting to a local address. the cleanup is going
1568 * to reschedule this function call.
1571 if (errno == ECONNREFUSED)
1574 evhttp_error_cb(bufev, what, arg);
1578 if (evcon->fd == -1) {
1579 event_debug(("%s: bufferevent_getfd returned -1",
1584 /* Check if the connection completed */
1585 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1587 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT,
1588 __func__, evcon->address, evcon->port,
1589 EV_SOCK_ARG(evcon->fd)));
1594 event_debug(("%s: connect failed for \"%s:%d\" on "
1596 __func__, evcon->address, evcon->port,
1597 EV_SOCK_ARG(evcon->fd),
1598 evutil_socket_error_to_string(error)));
1602 /* We are connected to the server now */
1603 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1604 __func__, evcon->address, evcon->port,
1605 EV_SOCK_ARG(evcon->fd)));
1607 /* Reset the retry count as we were successful in connecting */
1608 evcon->retry_cnt = 0;
1609 evcon->state = EVCON_IDLE;
1611 /* reset the bufferevent cbs */
1612 bufferevent_setcb(evcon->bufev,
1618 if (!evutil_timerisset(&evcon->timeout)) {
1619 const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 };
1620 const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 };
1621 bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv);
1623 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
1626 /* try to start requests that have queued up on this connection */
1627 evhttp_request_dispatch(evcon);
1631 evhttp_connection_cb_cleanup(evcon);
1635 * Check if we got a valid response code.
1639 evhttp_valid_response_code(int code)
1648 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1652 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1653 if (n != 2 || major > 1) {
1654 event_debug(("%s: bad version %s on message %p from %s",
1655 __func__, version, req, req->remote_host));
1663 /* Parses the status line of a web server */
1666 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1670 const char *readable = "";
1672 protocol = strsep(&line, " ");
1675 number = strsep(&line, " ");
1679 if (evhttp_parse_http_version(protocol, req) < 0)
1682 req->response_code = atoi(number);
1683 if (!evhttp_valid_response_code(req->response_code)) {
1684 event_debug(("%s: bad response code \"%s\"",
1689 if (req->response_code_line != NULL)
1690 mm_free(req->response_code_line);
1691 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1692 event_warn("%s: strdup", __func__);
1699 /* Parse the first line of a HTTP request */
1702 evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len)
1704 char *eos = line + len;
1708 const char *hostname;
1711 enum evhttp_cmd_type type;
1713 while (eos > line && *(eos-1) == ' ') {
1718 if (len < strlen("GET / HTTP/1.0"))
1721 /* Parse the request line */
1722 method = strsep(&line, " ");
1726 version = strrchr(uri, ' ');
1727 if (!version || uri == version)
1732 method_len = (uri - method) - 1;
1733 type = EVHTTP_REQ_UNKNOWN_;
1736 switch (method_len) {
1738 /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1740 /* Since both GET and PUT share the same character 'T' at the end,
1741 * if the string doesn't have 'T', we can immediately determine this
1742 * is an invalid HTTP method */
1744 if (method[2] != 'T') {
1750 /* This first byte is 'G', so make sure the next byte is
1751 * 'E', if it isn't then this isn't a valid method */
1753 if (method[1] == 'E') {
1754 type = EVHTTP_REQ_GET;
1759 /* First byte is P, check second byte for 'U', if not,
1760 * we know it's an invalid method */
1761 if (method[1] == 'U') {
1762 type = EVHTTP_REQ_PUT;
1770 /* The method length is 4 bytes, leaving only the methods "POST" and "HEAD" */
1773 if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') {
1774 type = EVHTTP_REQ_POST;
1778 if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') {
1779 type = EVHTTP_REQ_HEAD;
1787 /* Method length is 5 bytes, which can only encompass PATCH and TRACE */
1790 if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') {
1791 type = EVHTTP_REQ_PATCH;
1795 if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') {
1796 type = EVHTTP_REQ_TRACE;
1805 /* Method length is 6, only valid method 6 bytes in length is DELEte */
1807 /* If the first byte isn't 'D' then it's invalid */
1808 if (*method != 'D') {
1812 if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' && method[2] == 'L' && method[1] == 'E') {
1813 type = EVHTTP_REQ_DELETE;
1818 /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1821 if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' &&
1822 method[3] == 'I' && method[2] == 'T' && method[1] == 'P') {
1823 type = EVHTTP_REQ_OPTIONS;
1828 if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' &&
1829 method[3] == 'N' && method[2] == 'N' && method[1] == 'O') {
1830 type = EVHTTP_REQ_CONNECT;
1840 if ((int)type == EVHTTP_REQ_UNKNOWN_) {
1841 event_debug(("%s: bad method %s on request %p from %s",
1842 __func__, method, req, req->remote_host));
1843 /* No error yet; we'll give a better error later when
1844 * we see that req->type is unsupported. */
1849 if (evhttp_parse_http_version(version, req) < 0)
1852 if ((req->uri = mm_strdup(uri)) == NULL) {
1853 event_debug(("%s: mm_strdup", __func__));
1857 if (type == EVHTTP_REQ_CONNECT) {
1858 if ((req->uri_elems = evhttp_uri_parse_authority(req->uri)) == NULL) {
1862 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
1863 EVHTTP_URI_NONCONFORMANT)) == NULL) {
1868 /* If we have an absolute-URI, check to see if it is an http request
1869 for a known vhost or server alias. If we don't know about this
1870 host, we consider it a proxy request. */
1871 scheme = evhttp_uri_get_scheme(req->uri_elems);
1872 hostname = evhttp_uri_get_host(req->uri_elems);
1873 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1874 !evutil_ascii_strcasecmp(scheme, "https")) &&
1876 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1877 req->flags |= EVHTTP_PROXY_REQUEST;
1883 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1885 struct evkeyval *header;
1887 TAILQ_FOREACH(header, headers, next) {
1888 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1889 return (header->value);
1896 evhttp_clear_headers(struct evkeyvalq *headers)
1898 struct evkeyval *header;
1900 for (header = TAILQ_FIRST(headers);
1902 header = TAILQ_FIRST(headers)) {
1903 TAILQ_REMOVE(headers, header, next);
1904 mm_free(header->key);
1905 mm_free(header->value);
1911 * Returns 0, if the header was successfully removed.
1912 * Returns -1, if the header could not be found.
1916 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1918 struct evkeyval *header;
1920 TAILQ_FOREACH(header, headers, next) {
1921 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1928 /* Free and remove the header that we found */
1929 TAILQ_REMOVE(headers, header, next);
1930 mm_free(header->key);
1931 mm_free(header->value);
1938 evhttp_header_is_valid_value(const char *value)
1940 const char *p = value;
1942 while ((p = strpbrk(p, "\r\n")) != NULL) {
1943 /* we really expect only one new line */
1944 p += strspn(p, "\r\n");
1945 /* we expect a space or tab for continuation */
1946 if (*p != ' ' && *p != '\t')
1953 evhttp_add_header(struct evkeyvalq *headers,
1954 const char *key, const char *value)
1956 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1958 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1959 /* drop illegal headers */
1960 event_debug(("%s: dropping illegal header key\n", __func__));
1964 if (!evhttp_header_is_valid_value(value)) {
1965 event_debug(("%s: dropping illegal header value\n", __func__));
1969 return (evhttp_add_header_internal(headers, key, value));
1973 evhttp_add_header_internal(struct evkeyvalq *headers,
1974 const char *key, const char *value)
1976 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
1977 if (header == NULL) {
1978 event_warn("%s: calloc", __func__);
1981 if ((header->key = mm_strdup(key)) == NULL) {
1983 event_warn("%s: strdup", __func__);
1986 if ((header->value = mm_strdup(value)) == NULL) {
1987 mm_free(header->key);
1989 event_warn("%s: strdup", __func__);
1993 TAILQ_INSERT_TAIL(headers, header, next);
1999 * Parses header lines from a request or a response into the specified
2000 * request object given an event buffer.
2003 * DATA_CORRUPTED on error
2004 * MORE_DATA_EXPECTED when we need to read more headers
2005 * ALL_DATA_READ when all headers have been read.
2008 enum message_read_status
2009 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
2012 enum message_read_status status = ALL_DATA_READ;
2016 line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
2018 if (req->evcon != NULL &&
2019 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2020 return (DATA_TOO_LONG);
2022 return (MORE_DATA_EXPECTED);
2025 if (req->evcon != NULL && len > req->evcon->max_headers_size) {
2027 return (DATA_TOO_LONG);
2030 req->headers_size = len;
2032 switch (req->kind) {
2033 case EVHTTP_REQUEST:
2034 if (evhttp_parse_request_line(req, line, len) == -1)
2035 status = DATA_CORRUPTED;
2037 case EVHTTP_RESPONSE:
2038 if (evhttp_parse_response_line(req, line) == -1)
2039 status = DATA_CORRUPTED;
2042 status = DATA_CORRUPTED;
2050 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
2052 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
2054 size_t old_len, line_len;
2059 old_len = strlen(header->value);
2061 /* Strip space from start and end of line. */
2062 while (*line == ' ' || *line == '\t')
2064 evutil_rtrim_lws_(line);
2066 line_len = strlen(line);
2068 newval = mm_realloc(header->value, old_len + line_len + 2);
2072 newval[old_len] = ' ';
2073 memcpy(newval + old_len + 1, line, line_len + 1);
2074 header->value = newval;
2079 enum message_read_status
2080 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
2082 enum message_read_status errcode = DATA_CORRUPTED;
2084 enum message_read_status status = MORE_DATA_EXPECTED;
2086 struct evkeyvalq* headers = req->input_headers;
2088 while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
2090 char *skey, *svalue;
2092 req->headers_size += len;
2094 if (req->evcon != NULL &&
2095 req->headers_size > req->evcon->max_headers_size) {
2096 errcode = DATA_TOO_LONG;
2100 if (*line == '\0') { /* Last header - Done */
2101 status = ALL_DATA_READ;
2106 /* Check if this is a continuation line */
2107 if (*line == ' ' || *line == '\t') {
2108 if (evhttp_append_to_last_header(headers, line) == -1)
2114 /* Processing of header lines */
2116 skey = strsep(&svalue, ":");
2120 svalue += strspn(svalue, " ");
2121 evutil_rtrim_lws_(svalue);
2123 if (evhttp_add_header(headers, skey, svalue) == -1)
2129 if (status == MORE_DATA_EXPECTED) {
2130 if (req->evcon != NULL &&
2131 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2132 return (DATA_TOO_LONG);
2143 evhttp_get_body_length(struct evhttp_request *req)
2145 struct evkeyvalq *headers = req->input_headers;
2146 const char *content_length;
2147 const char *connection;
2149 content_length = evhttp_find_header(headers, "Content-Length");
2150 connection = evhttp_find_header(headers, "Connection");
2152 if (content_length == NULL && connection == NULL)
2154 else if (content_length == NULL &&
2155 evutil_ascii_strcasecmp(connection, "Close") != 0) {
2157 } else if (content_length == NULL) {
2161 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2162 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2163 event_debug(("%s: illegal content length: %s",
2164 __func__, content_length));
2167 req->ntoread = ntoread;
2170 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2171 __func__, EV_I64_ARG(req->ntoread),
2172 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2178 evhttp_method_may_have_body(enum evhttp_cmd_type type)
2181 case EVHTTP_REQ_POST:
2182 case EVHTTP_REQ_PUT:
2183 case EVHTTP_REQ_PATCH:
2185 case EVHTTP_REQ_GET:
2186 case EVHTTP_REQ_DELETE:
2187 case EVHTTP_REQ_OPTIONS:
2188 case EVHTTP_REQ_CONNECT:
2191 case EVHTTP_REQ_TRACE:
2192 case EVHTTP_REQ_HEAD:
2199 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2201 const char *xfer_enc;
2203 /* If this is a request without a body, then we are done */
2204 if (req->kind == EVHTTP_REQUEST &&
2205 !evhttp_method_may_have_body(req->type)) {
2206 evhttp_connection_done(evcon);
2209 evcon->state = EVCON_READING_BODY;
2210 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
2211 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
2215 if (evhttp_get_body_length(req) == -1) {
2216 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2219 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2220 /* An incoming request with no content-length and no
2221 * transfer-encoding has no body. */
2222 evhttp_connection_done(evcon);
2227 /* Should we send a 100 Continue status line? */
2228 switch (evhttp_have_expect(req, 1)) {
2230 /* XXX It would be nice to do some sanity
2231 checking here. Does the resource exist?
2232 Should the resource accept post requests? If
2233 no, we should respond with an error. For
2234 now, just optimistically tell the client to
2235 send their message body. */
2236 if (req->ntoread > 0) {
2237 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2238 if ((req->evcon->max_body_size <= EV_INT64_MAX) &&
2239 (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2240 evhttp_lingering_fail(evcon, req);
2244 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2245 evhttp_send_continue(evcon, req);
2248 evhttp_send_error(req, HTTP_EXPECTATIONFAILED, NULL);
2253 evhttp_read_body(evcon, req);
2254 /* note the request may have been freed in evhttp_read_body */
2258 evhttp_read_firstline(struct evhttp_connection *evcon,
2259 struct evhttp_request *req)
2261 enum message_read_status res;
2263 res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2264 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2265 /* Error while reading, terminate */
2266 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2267 __func__, EV_SOCK_ARG(evcon->fd)));
2268 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2270 } else if (res == MORE_DATA_EXPECTED) {
2271 /* Need more header lines */
2275 evcon->state = EVCON_READING_HEADERS;
2276 evhttp_read_header(evcon, req);
2280 evhttp_read_header(struct evhttp_connection *evcon,
2281 struct evhttp_request *req)
2283 enum message_read_status res;
2284 evutil_socket_t fd = evcon->fd;
2286 res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2287 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2288 /* Error while reading, terminate */
2289 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2290 __func__, EV_SOCK_ARG(fd)));
2291 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2293 } else if (res == MORE_DATA_EXPECTED) {
2294 /* Need more header lines */
2298 /* Callback can shut down connection with negative return value */
2299 if (req->header_cb != NULL) {
2300 if ((*req->header_cb)(req, req->cb_arg) < 0) {
2301 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2306 /* Done reading headers, do the real work */
2307 switch (req->kind) {
2308 case EVHTTP_REQUEST:
2309 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2310 __func__, EV_SOCK_ARG(fd)));
2311 evhttp_get_body(evcon, req);
2312 /* note the request may have been freed in evhttp_get_body */
2315 case EVHTTP_RESPONSE:
2316 /* Start over if we got a 100 Continue response. */
2317 if (req->response_code == 100) {
2318 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
2319 evbuffer_add_buffer(output, req->output_buffer);
2320 evhttp_start_write_(evcon);
2323 if (!evhttp_response_needs_body(req)) {
2324 event_debug(("%s: skipping body for code %d\n",
2325 __func__, req->response_code));
2326 evhttp_connection_done(evcon);
2328 event_debug(("%s: start of read body for %s on "
2330 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2331 evhttp_get_body(evcon, req);
2332 /* note the request may have been freed in
2333 * evhttp_get_body */
2338 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2340 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2343 /* request may have been freed above */
2347 * Creates a TCP connection to the specified port and executes a callback
2348 * when finished. Failure or success is indicate by the passed connection
2351 * Although this interface accepts a hostname, it is intended to take
2352 * only numeric hostnames so that non-blocking DNS resolution can
2356 struct evhttp_connection *
2357 evhttp_connection_new(const char *address, ev_uint16_t port)
2359 return (evhttp_connection_base_new(NULL, NULL, address, port));
2362 struct evhttp_connection *
2363 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2364 const char *address, ev_uint16_t port)
2366 struct evhttp_connection *evcon = NULL;
2368 event_debug(("Attempting connection to %s:%d\n", address, port));
2370 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2371 event_warn("%s: calloc failed", __func__);
2378 evcon->max_headers_size = EV_SIZE_MAX;
2379 evcon->max_body_size = EV_SIZE_MAX;
2381 evutil_timerclear(&evcon->timeout);
2382 evcon->retry_cnt = evcon->retry_max = 0;
2384 if ((evcon->address = mm_strdup(address)) == NULL) {
2385 event_warn("%s: strdup failed", __func__);
2390 if (!(bev = bufferevent_socket_new(base, -1, 0))) {
2391 event_warn("%s: bufferevent_socket_new failed", __func__);
2396 bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2399 evcon->state = EVCON_DISCONNECTED;
2400 TAILQ_INIT(&evcon->requests);
2402 evcon->initial_retry_timeout.tv_sec = 2;
2403 evcon->initial_retry_timeout.tv_usec = 0;
2407 if (bufferevent_get_base(bev) != base)
2408 bufferevent_base_set(base, evcon->bufev);
2411 event_deferred_cb_init_(
2412 &evcon->read_more_deferred_cb,
2413 bufferevent_get_priority(bev),
2414 evhttp_deferred_read_cb, evcon);
2416 evcon->dns_base = dnsbase;
2417 evcon->ai_family = AF_UNSPEC;
2423 evhttp_connection_free(evcon);
2427 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2429 return evcon->bufev;
2433 evhttp_connection_get_server(struct evhttp_connection *evcon)
2435 return evcon->http_server;
2438 struct evhttp_connection *
2439 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2440 const char *address, ev_uint16_t port)
2442 return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2445 void evhttp_connection_set_family(struct evhttp_connection *evcon,
2448 evcon->ai_family = family;
2451 int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2454 int avail_flags = 0;
2455 avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2456 avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2458 if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2460 evcon->flags &= ~avail_flags;
2462 evcon->flags |= flags;
2468 evhttp_connection_set_base(struct evhttp_connection *evcon,
2469 struct event_base *base)
2471 EVUTIL_ASSERT(evcon->base == NULL);
2472 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2474 bufferevent_base_set(base, evcon->bufev);
2478 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2479 int timeout_in_secs)
2481 if (timeout_in_secs == -1)
2482 evhttp_connection_set_timeout_tv(evcon, NULL);
2485 tv.tv_sec = timeout_in_secs;
2487 evhttp_connection_set_timeout_tv(evcon, &tv);
2492 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2493 const struct timeval* tv)
2496 evcon->timeout = *tv;
2497 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
2499 const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 };
2500 const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 };
2501 evutil_timerclear(&evcon->timeout);
2502 bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv);
2507 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2508 const struct timeval *tv)
2511 evcon->initial_retry_timeout = *tv;
2513 evutil_timerclear(&evcon->initial_retry_timeout);
2514 evcon->initial_retry_timeout.tv_sec = 2;
2519 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2522 evcon->retry_max = retry_max;
2526 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2527 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2529 evcon->closecb = cb;
2530 evcon->closecb_arg = cbarg;
2534 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2535 char **address, ev_uint16_t *port)
2537 *address = evcon->address;
2538 *port = evcon->port;
2541 const struct sockaddr*
2542 evhttp_connection_get_addr(struct evhttp_connection *evcon)
2544 return bufferevent_socket_get_conn_address_(evcon->bufev);
2548 evhttp_connection_connect_(struct evhttp_connection *evcon)
2550 int old_state = evcon->state;
2551 const char *address = evcon->address;
2552 const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
2555 if (evcon->state == EVCON_CONNECTING)
2558 evhttp_connection_reset_(evcon);
2560 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2561 evcon->flags |= EVHTTP_CON_OUTGOING;
2563 if (evcon->bind_address || evcon->bind_port) {
2564 evcon->fd = bind_socket(
2565 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2566 if (evcon->fd == -1) {
2567 event_debug(("%s: failed to bind to \"%s\"",
2568 __func__, evcon->bind_address));
2572 if (bufferevent_setfd(evcon->bufev, evcon->fd))
2575 if (bufferevent_setfd(evcon->bufev, -1))
2579 /* Set up a callback for successful connection setup */
2580 bufferevent_setcb(evcon->bufev,
2581 NULL /* evhttp_read_cb */,
2582 NULL /* evhttp_write_cb */,
2583 evhttp_connection_cb,
2585 if (!evutil_timerisset(&evcon->timeout)) {
2586 const struct timeval conn_tv = { HTTP_CONNECT_TIMEOUT, 0 };
2587 bufferevent_set_timeouts(evcon->bufev, &conn_tv, &conn_tv);
2589 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
2591 /* make sure that we get a write callback */
2592 if (bufferevent_enable(evcon->bufev, EV_WRITE))
2595 evcon->state = EVCON_CONNECTING;
2597 if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
2599 (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
2600 int socklen = sizeof(struct sockaddr_in);
2601 if (sa->sa_family == AF_INET6) {
2602 socklen = sizeof(struct sockaddr_in6);
2604 ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
2606 ret = bufferevent_socket_connect_hostname(evcon->bufev,
2607 evcon->dns_base, evcon->ai_family, address, evcon->port);
2611 evcon->state = old_state;
2612 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2613 __func__, evcon->address);
2614 /* some operating systems return ECONNREFUSED immediately
2615 * when connecting to a local address. the cleanup is going
2616 * to reschedule this function call.
2618 evhttp_connection_cb_cleanup(evcon);
2626 * Starts an HTTP request on the provided evhttp_connection object.
2627 * If the connection object is not connected to the web server already,
2628 * this will start the connection.
2632 evhttp_make_request(struct evhttp_connection *evcon,
2633 struct evhttp_request *req,
2634 enum evhttp_cmd_type type, const char *uri)
2636 /* We are making a request */
2637 req->kind = EVHTTP_REQUEST;
2639 if (req->uri != NULL)
2641 if ((req->uri = mm_strdup(uri)) == NULL) {
2642 event_warn("%s: strdup", __func__);
2643 evhttp_request_free_auto(req);
2647 /* Set the protocol version if it is not supplied */
2648 if (!req->major && !req->minor) {
2653 EVUTIL_ASSERT(req->evcon == NULL);
2655 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2657 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2659 /* We do not want to conflict with retry_ev */
2660 if (evcon->retry_cnt)
2663 /* If the connection object is not connected; make it so */
2664 if (!evhttp_connected(evcon)) {
2665 int res = evhttp_connection_connect_(evcon);
2666 /* evhttp_connection_fail_(), which is called through
2667 * evhttp_connection_connect_(), assumes that req lies in
2668 * evcon->requests. Thus, enqueue the request in advance and
2669 * remove it in the error case. */
2671 TAILQ_REMOVE(&evcon->requests, req, next);
2677 * If it's connected already and we are the first in the queue,
2678 * then we can dispatch this request immediately. Otherwise, it
2679 * will be dispatched once the pending requests are completed.
2681 if (TAILQ_FIRST(&evcon->requests) == req)
2682 evhttp_request_dispatch(evcon);
2688 evhttp_cancel_request(struct evhttp_request *req)
2690 struct evhttp_connection *evcon = req->evcon;
2691 if (evcon != NULL) {
2692 /* We need to remove it from the connection */
2693 if (TAILQ_FIRST(&evcon->requests) == req) {
2694 /* it's currently being worked on, so reset
2697 evhttp_connection_fail_(evcon,
2698 EVREQ_HTTP_REQUEST_CANCEL);
2700 /* connection fail freed the request */
2703 /* otherwise, we can just remove it from the
2706 TAILQ_REMOVE(&evcon->requests, req, next);
2710 evhttp_request_free_auto(req);
2714 * Reads data from file descriptor into request structure
2715 * Request structure needs to be set up correctly.
2719 evhttp_start_read_(struct evhttp_connection *evcon)
2721 bufferevent_disable(evcon->bufev, EV_WRITE);
2722 bufferevent_enable(evcon->bufev, EV_READ);
2724 evcon->state = EVCON_READING_FIRSTLINE;
2725 /* Reset the bufferevent callbacks */
2726 bufferevent_setcb(evcon->bufev,
2732 /* If there's still data pending, process it next time through the
2733 * loop. Don't do it now; that could get recusive. */
2734 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2735 event_deferred_cb_schedule_(get_deferred_queue(evcon),
2736 &evcon->read_more_deferred_cb);
2741 evhttp_start_write_(struct evhttp_connection *evcon)
2743 bufferevent_disable(evcon->bufev, EV_WRITE);
2744 bufferevent_enable(evcon->bufev, EV_READ);
2746 evcon->state = EVCON_WRITING;
2747 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
2751 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2754 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2755 TAILQ_REMOVE(&evcon->requests, req, next);
2757 if (req->on_complete_cb != NULL) {
2758 req->on_complete_cb(req, req->on_complete_cb_arg);
2762 (REQ_VERSION_BEFORE(req, 1, 1) &&
2763 !evhttp_is_connection_keepalive(req->input_headers)) ||
2764 evhttp_is_request_connection_close(req);
2766 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2767 evhttp_request_free(req);
2770 evhttp_connection_free(evcon);
2774 /* we have a persistent connection; try to accept another request. */
2775 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2776 evhttp_connection_free(evcon);
2781 * Returns an error page.
2785 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2788 #define ERR_FORMAT "<HTML><HEAD>\n" \
2789 "<TITLE>%d %s</TITLE>\n" \
2794 struct evbuffer *buf = evbuffer_new();
2796 /* if we cannot allocate memory; we just drop the connection */
2797 evhttp_connection_free(req->evcon);
2800 if (reason == NULL) {
2801 reason = evhttp_response_phrase_internal(error);
2804 evhttp_response_code_(req, error, reason);
2806 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2808 evhttp_send_page_(req, buf);
2814 /* Requires that headers and response code are already set up */
2817 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2819 struct evhttp_connection *evcon = req->evcon;
2821 if (evcon == NULL) {
2822 evhttp_request_free(req);
2826 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2828 /* we expect no more calls form the user on this request */
2831 /* xxx: not sure if we really should expose the data buffer this way */
2832 if (databuf != NULL)
2833 evbuffer_add_buffer(req->output_buffer, databuf);
2835 /* Adds headers to the response */
2836 evhttp_make_header(evcon, req);
2838 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2842 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2843 struct evbuffer *databuf)
2845 evhttp_response_code_(req, code, reason);
2847 evhttp_send(req, databuf);
2851 evhttp_send_reply_start(struct evhttp_request *req, int code,
2854 evhttp_response_code_(req, code, reason);
2856 if (req->evcon == NULL)
2859 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2860 REQ_VERSION_ATLEAST(req, 1, 1) &&
2861 evhttp_response_needs_body(req)) {
2863 * prefer HTTP/1.1 chunked encoding to closing the connection;
2864 * note RFC 2616 section 4.4 forbids it with Content-Length:
2865 * and it's not necessary then anyway.
2867 evhttp_add_header(req->output_headers, "Transfer-Encoding",
2873 evhttp_make_header(req->evcon, req);
2874 evhttp_write_buffer(req->evcon, NULL, NULL);
2878 evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
2879 void (*cb)(struct evhttp_connection *, void *), void *arg)
2881 struct evhttp_connection *evcon = req->evcon;
2882 struct evbuffer *output;
2887 output = bufferevent_get_output(evcon->bufev);
2889 if (evbuffer_get_length(databuf) == 0)
2891 if (!evhttp_response_needs_body(req))
2894 evbuffer_add_printf(output, "%x\r\n",
2895 (unsigned)evbuffer_get_length(databuf));
2897 evbuffer_add_buffer(output, databuf);
2899 evbuffer_add(output, "\r\n", 2);
2901 evhttp_write_buffer(evcon, cb, arg);
2905 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
2907 evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
2910 evhttp_send_reply_end(struct evhttp_request *req)
2912 struct evhttp_connection *evcon = req->evcon;
2913 struct evbuffer *output;
2915 if (evcon == NULL) {
2916 evhttp_request_free(req);
2920 output = bufferevent_get_output(evcon->bufev);
2922 /* we expect no more calls form the user on this request */
2926 evbuffer_add(output, "0\r\n\r\n", 5);
2927 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2929 } else if (evbuffer_get_length(output) == 0) {
2930 /* let the connection know that we are done with the request */
2931 evhttp_send_done(evcon, NULL);
2933 /* make the callback execute after all data has been written */
2934 evcon->cb = evhttp_send_done;
2935 evcon->cb_arg = NULL;
2939 static const char *informational_phrases[] = {
2940 /* 100 */ "Continue",
2941 /* 101 */ "Switching Protocols"
2944 static const char *success_phrases[] = {
2946 /* 201 */ "Created",
2947 /* 202 */ "Accepted",
2948 /* 203 */ "Non-Authoritative Information",
2949 /* 204 */ "No Content",
2950 /* 205 */ "Reset Content",
2951 /* 206 */ "Partial Content"
2954 static const char *redirection_phrases[] = {
2955 /* 300 */ "Multiple Choices",
2956 /* 301 */ "Moved Permanently",
2958 /* 303 */ "See Other",
2959 /* 304 */ "Not Modified",
2960 /* 305 */ "Use Proxy",
2961 /* 307 */ "Temporary Redirect"
2964 static const char *client_error_phrases[] = {
2965 /* 400 */ "Bad Request",
2966 /* 401 */ "Unauthorized",
2967 /* 402 */ "Payment Required",
2968 /* 403 */ "Forbidden",
2969 /* 404 */ "Not Found",
2970 /* 405 */ "Method Not Allowed",
2971 /* 406 */ "Not Acceptable",
2972 /* 407 */ "Proxy Authentication Required",
2973 /* 408 */ "Request Time-out",
2974 /* 409 */ "Conflict",
2976 /* 411 */ "Length Required",
2977 /* 412 */ "Precondition Failed",
2978 /* 413 */ "Request Entity Too Large",
2979 /* 414 */ "Request-URI Too Large",
2980 /* 415 */ "Unsupported Media Type",
2981 /* 416 */ "Requested range not satisfiable",
2982 /* 417 */ "Expectation Failed"
2985 static const char *server_error_phrases[] = {
2986 /* 500 */ "Internal Server Error",
2987 /* 501 */ "Not Implemented",
2988 /* 502 */ "Bad Gateway",
2989 /* 503 */ "Service Unavailable",
2990 /* 504 */ "Gateway Time-out",
2991 /* 505 */ "HTTP Version not supported"
2994 struct response_class {
2996 size_t num_responses;
2997 const char **responses;
3001 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
3004 static const struct response_class response_classes[] = {
3005 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
3006 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
3007 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
3008 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
3009 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
3013 evhttp_response_phrase_internal(int code)
3015 int klass = code / 100 - 1;
3016 int subcode = code % 100;
3018 /* Unknown class - can't do any better here */
3019 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
3020 return "Unknown Status Class";
3022 /* Unknown sub-code, return class name at least */
3023 if (subcode >= (int) response_classes[klass].num_responses)
3024 return response_classes[klass].name;
3026 return response_classes[klass].responses[subcode];
3030 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
3032 req->kind = EVHTTP_RESPONSE;
3033 req->response_code = code;
3034 if (req->response_code_line != NULL)
3035 mm_free(req->response_code_line);
3037 reason = evhttp_response_phrase_internal(code);
3038 req->response_code_line = mm_strdup(reason);
3039 if (req->response_code_line == NULL) {
3040 event_warn("%s: strdup", __func__);
3041 /* XXX what else can we do? */
3046 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
3048 if (!req->major || !req->minor) {
3053 if (req->kind != EVHTTP_RESPONSE)
3054 evhttp_response_code_(req, 200, "OK");
3056 evhttp_clear_headers(req->output_headers);
3057 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
3058 evhttp_add_header(req->output_headers, "Connection", "close");
3060 evhttp_send(req, databuf);
3063 static const char uri_chars[256] = {
3065 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3066 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3067 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
3068 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
3070 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3071 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
3072 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3073 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
3075 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3076 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3077 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3078 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3080 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3081 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3082 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3083 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3086 #define CHAR_IS_UNRESERVED(c) \
3087 (uri_chars[(unsigned char)(c)])
3090 * Helper functions to encode/decode a string for inclusion in a URI.
3091 * The returned string must be freed by the caller.
3094 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3096 struct evbuffer *buf = evbuffer_new();
3097 const char *p, *end;
3098 char *result = NULL;
3105 if (uri + len < uri) {
3111 size_t slen = strlen(uri);
3113 if (slen >= EV_SSIZE_MAX) {
3114 /* we don't want to mix signed and unsigned */
3118 if (uri + slen < uri) {
3125 for (p = uri; p < end; p++) {
3126 if (CHAR_IS_UNRESERVED(*p)) {
3127 evbuffer_add(buf, p, 1);
3128 } else if (*p == ' ' && space_as_plus) {
3129 evbuffer_add(buf, "+", 1);
3131 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3135 evbuffer_add(buf, "", 1); /* NUL-terminator. */
3136 result = mm_malloc(evbuffer_get_length(buf));
3139 evbuffer_remove(buf, result, evbuffer_get_length(buf));
3148 evhttp_encode_uri(const char *str)
3150 return evhttp_uriencode(str, -1, 0);
3154 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
3155 * If -1, when true we transform plus to space only after we've seen
3156 * a ?. -1 is deprecated.
3157 * @return the number of bytes written to 'ret'.
3160 evhttp_decode_uri_internal(
3161 const char *uri, size_t length, char *ret, int decode_plus_ctl)
3165 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3168 for (i = j = 0; i < length; i++) {
3171 if (decode_plus_ctl < 0)
3173 } else if (c == '+' && decode_plus) {
3175 } else if ((i + 2) < length && c == '%' &&
3176 EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3181 c = (char)strtol(tmp, NULL, 16);
3193 evhttp_decode_uri(const char *uri)
3197 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3198 event_warn("%s: malloc(%lu)", __func__,
3199 (unsigned long)(strlen(uri) + 1));
3203 evhttp_decode_uri_internal(uri, strlen(uri),
3204 ret, -1 /*always_decode_plus*/);
3210 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3215 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3216 event_warn("%s: malloc(%lu)", __func__,
3217 (unsigned long)(strlen(uri) + 1));
3221 n = evhttp_decode_uri_internal(uri, strlen(uri),
3222 ret, !!decode_plus/*always_decode_plus*/);
3225 EVUTIL_ASSERT(n >= 0);
3226 *size_out = (size_t)n;
3233 * Helper function to parse out arguments in a query.
3234 * The arguments are separated by key and value.
3238 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3239 int is_whole_uri, unsigned flags)
3244 const char *query_part;
3246 struct evhttp_uri *uri=NULL;
3248 TAILQ_INIT(headers);
3251 uri = evhttp_uri_parse(str);
3254 query_part = evhttp_uri_get_query(uri);
3259 /* No arguments - we are done */
3260 if (!query_part || !strlen(query_part)) {
3265 if ((line = mm_strdup(query_part)) == NULL) {
3266 event_warn("%s: strdup", __func__);
3270 p = argument = line;
3271 while (p != NULL && *p != '\0') {
3272 char *key, *value, *decoded_value;
3273 argument = strsep(&p, "&");
3276 key = strsep(&value, "=");
3277 if (flags & EVHTTP_URI_QUERY_NONCONFORMANT) {
3283 if (value == NULL || *key == '\0')
3287 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3288 event_warn("%s: mm_malloc", __func__);
3291 evhttp_decode_uri_internal(value, strlen(value),
3292 decoded_value, 1 /*always_decode_plus*/);
3293 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3294 if (flags & EVHTTP_URI_QUERY_LAST_VAL)
3295 evhttp_remove_header(headers, key);
3296 evhttp_add_header_internal(headers, key, decoded_value);
3297 mm_free(decoded_value);
3303 evhttp_clear_headers(headers);
3308 evhttp_uri_free(uri);
3313 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3315 return evhttp_parse_query_impl(uri, headers, 1, 0);
3318 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3320 return evhttp_parse_query_impl(uri, headers, 0, 0);
3323 evhttp_parse_query_str_flags(const char *uri, struct evkeyvalq *headers, unsigned flags)
3325 return evhttp_parse_query_impl(uri, headers, 0, flags);
3328 static struct evhttp_cb *
3329 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3331 struct evhttp_cb *cb;
3336 /* Test for different URLs */
3337 path = evhttp_uri_get_path(req->uri_elems);
3338 offset = strlen(path);
3339 if ((translated = mm_malloc(offset + 1)) == NULL)
3341 evhttp_decode_uri_internal(path, offset, translated,
3342 0 /* decode_plus */);
3344 TAILQ_FOREACH(cb, callbacks, next) {
3345 if (!strcmp(cb->what, translated)) {
3346 mm_free(translated);
3351 mm_free(translated);
3357 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3362 switch (c = *pattern++) {
3364 return *name == '\0';
3367 while (*name != '\0') {
3368 if (prefix_suffix_match(pattern, name,
3377 EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3387 Search the vhost hierarchy beginning with http for a server alias
3388 matching hostname. If a match is found, and outhttp is non-null,
3389 outhttp is set to the matching http object and 1 is returned.
3393 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3394 const char *hostname)
3396 struct evhttp_server_alias *alias;
3397 struct evhttp *vhost;
3399 TAILQ_FOREACH(alias, &http->aliases, next) {
3400 /* XXX Do we need to handle IP addresses? */
3401 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3408 /* XXX It might be good to avoid recursion here, but I don't
3409 see a way to do that w/o a list. */
3410 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3411 if (evhttp_find_alias(vhost, outhttp, hostname))
3419 Attempts to find the best http object to handle a request for a hostname.
3420 All aliases for the root http object and vhosts are searched for an exact
3421 match. Then, the vhost hierarchy is traversed again for a matching
3424 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3425 is set with the best matching http object. If there are no matches, the
3426 root http object is stored in outhttp and 0 is returned.
3430 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3431 const char *hostname)
3433 struct evhttp *vhost;
3434 struct evhttp *oldhttp;
3435 int match_found = 0;
3437 if (evhttp_find_alias(http, outhttp, hostname))
3442 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3443 if (prefix_suffix_match(vhost->vhost_pattern,
3444 hostname, 1 /* ignorecase */)) {
3450 } while (oldhttp != http);
3459 evhttp_handle_request(struct evhttp_request *req, void *arg)
3461 struct evhttp *http = arg;
3462 struct evhttp_cb *cb = NULL;
3463 const char *hostname;
3465 /* we have a new request on which the user needs to take action */
3468 bufferevent_disable(req->evcon->bufev, EV_READ);
3470 if (req->type == 0 || req->uri == NULL) {
3471 evhttp_send_error(req, req->response_code, NULL);
3475 if ((http->allowed_methods & req->type) == 0) {
3476 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3477 (unsigned)req->type, (unsigned)http->allowed_methods));
3478 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3482 /* handle potential virtual hosts */
3483 hostname = evhttp_request_get_host(req);
3484 if (hostname != NULL) {
3485 evhttp_find_vhost(http, &http, hostname);
3488 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3489 (*cb->cb)(req, cb->cbarg);
3493 /* Generic call back */
3495 (*http->gencb)(req, http->gencbarg);
3498 /* We need to send a 404 here */
3499 #define ERR_FORMAT "<html><head>" \
3500 "<title>404 Not Found</title>" \
3502 "<h1>Not Found</h1>" \
3503 "<p>The requested URL %s was not found on this server.</p>"\
3507 struct evbuffer *buf;
3509 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3510 evhttp_connection_free(req->evcon);
3514 if ((buf = evbuffer_new()) == NULL) {
3515 mm_free(escaped_html);
3516 evhttp_connection_free(req->evcon);
3520 evhttp_response_code_(req, HTTP_NOTFOUND, "Not Found");
3522 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3524 mm_free(escaped_html);
3526 evhttp_send_page_(req, buf);
3533 /* Listener callback when a connection arrives at a server. */
3535 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3537 struct evhttp *http = arg;
3539 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3543 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3545 struct evhttp_bound_socket *bound =
3546 evhttp_bind_socket_with_handle(http, address, port);
3552 struct evhttp_bound_socket *
3553 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3556 struct evhttp_bound_socket *bound;
3559 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3562 if (listen(fd, 128) == -1) {
3563 serrno = EVUTIL_SOCKET_ERROR();
3564 event_sock_warn(fd, "%s: listen", __func__);
3565 evutil_closesocket(fd);
3566 EVUTIL_SET_SOCKET_ERROR(serrno);
3570 bound = evhttp_accept_socket_with_handle(http, fd);
3572 if (bound != NULL) {
3573 event_debug(("Bound to port %d - Awaiting connections ... ",
3582 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3584 struct evhttp_bound_socket *bound =
3585 evhttp_accept_socket_with_handle(http, fd);
3592 evhttp_foreach_bound_socket(struct evhttp *http,
3593 evhttp_bound_socket_foreach_fn *function,
3596 struct evhttp_bound_socket *bound;
3598 TAILQ_FOREACH(bound, &http->sockets, next)
3599 function(bound, argument);
3602 struct evhttp_bound_socket *
3603 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3605 struct evhttp_bound_socket *bound;
3606 struct evconnlistener *listener;
3608 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3610 listener = evconnlistener_new(http->base, NULL, NULL,
3612 0, /* Backlog is '0' because we already said 'listen' */
3617 bound = evhttp_bind_listener(http, listener);
3619 evconnlistener_free(listener);
3625 struct evhttp_bound_socket *
3626 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3628 struct evhttp_bound_socket *bound;
3630 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3634 bound->listener = listener;
3635 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3637 evconnlistener_set_cb(listener, accept_socket_cb, http);
3642 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3644 return evconnlistener_get_fd(bound->listener);
3647 struct evconnlistener *
3648 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3650 return bound->listener;
3654 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3656 TAILQ_REMOVE(&http->sockets, bound, next);
3657 evconnlistener_free(bound->listener);
3661 static struct evhttp*
3662 evhttp_new_object(void)
3664 struct evhttp *http = NULL;
3666 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3667 event_warn("%s: calloc", __func__);
3671 evutil_timerclear(&http->timeout);
3672 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3673 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3674 evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
3675 evhttp_set_allowed_methods(http,
3682 TAILQ_INIT(&http->sockets);
3683 TAILQ_INIT(&http->callbacks);
3684 TAILQ_INIT(&http->connections);
3685 TAILQ_INIT(&http->virtualhosts);
3686 TAILQ_INIT(&http->aliases);
3692 evhttp_new(struct event_base *base)
3694 struct evhttp *http = NULL;
3696 http = evhttp_new_object();
3705 * Start a web server on the specified address and port.
3709 evhttp_start(const char *address, ev_uint16_t port)
3711 struct evhttp *http = NULL;
3713 http = evhttp_new_object();
3716 if (evhttp_bind_socket(http, address, port) == -1) {
3725 evhttp_free(struct evhttp* http)
3727 struct evhttp_cb *http_cb;
3728 struct evhttp_connection *evcon;
3729 struct evhttp_bound_socket *bound;
3730 struct evhttp* vhost;
3731 struct evhttp_server_alias *alias;
3733 /* Remove the accepting part */
3734 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3735 TAILQ_REMOVE(&http->sockets, bound, next);
3737 evconnlistener_free(bound->listener);
3742 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3743 /* evhttp_connection_free removes the connection */
3744 evhttp_connection_free(evcon);
3747 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3748 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3749 mm_free(http_cb->what);
3753 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3754 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3759 if (http->vhost_pattern != NULL)
3760 mm_free(http->vhost_pattern);
3762 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3763 TAILQ_REMOVE(&http->aliases, alias, next);
3764 mm_free(alias->alias);
3772 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3773 struct evhttp* vhost)
3775 /* a vhost can only be a vhost once and should not have bound sockets */
3776 if (vhost->vhost_pattern != NULL ||
3777 TAILQ_FIRST(&vhost->sockets) != NULL)
3780 vhost->vhost_pattern = mm_strdup(pattern);
3781 if (vhost->vhost_pattern == NULL)
3784 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3790 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3792 if (vhost->vhost_pattern == NULL)
3795 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3797 mm_free(vhost->vhost_pattern);
3798 vhost->vhost_pattern = NULL;
3804 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3806 struct evhttp_server_alias *evalias;
3808 evalias = mm_calloc(1, sizeof(*evalias));
3812 evalias->alias = mm_strdup(alias);
3813 if (!evalias->alias) {
3818 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3824 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3826 struct evhttp_server_alias *evalias;
3828 TAILQ_FOREACH(evalias, &http->aliases, next) {
3829 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3830 TAILQ_REMOVE(&http->aliases, evalias, next);
3831 mm_free(evalias->alias);
3841 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
3843 if (timeout_in_secs == -1) {
3844 evhttp_set_timeout_tv(http, NULL);
3847 tv.tv_sec = timeout_in_secs;
3849 evhttp_set_timeout_tv(http, &tv);
3854 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
3857 http->timeout = *tv;
3859 evutil_timerclear(&http->timeout);
3863 int evhttp_set_flags(struct evhttp *http, int flags)
3865 int avail_flags = 0;
3866 avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
3868 if (flags & ~avail_flags)
3870 http->flags &= ~avail_flags;
3872 http->flags |= flags;
3878 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
3880 if (max_headers_size < 0)
3881 http->default_max_headers_size = EV_SIZE_MAX;
3883 http->default_max_headers_size = max_headers_size;
3887 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
3889 if (max_body_size < 0)
3890 http->default_max_body_size = EV_UINT64_MAX;
3892 http->default_max_body_size = max_body_size;
3896 evhttp_set_default_content_type(struct evhttp *http,
3897 const char *content_type) {
3898 http->default_content_type = content_type;
3902 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
3904 http->allowed_methods = methods;
3908 evhttp_set_cb(struct evhttp *http, const char *uri,
3909 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3911 struct evhttp_cb *http_cb;
3913 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3914 if (strcmp(http_cb->what, uri) == 0)
3918 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
3919 event_warn("%s: calloc", __func__);
3923 http_cb->what = mm_strdup(uri);
3924 if (http_cb->what == NULL) {
3925 event_warn("%s: strdup", __func__);
3930 http_cb->cbarg = cbarg;
3932 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
3938 evhttp_del_cb(struct evhttp *http, const char *uri)
3940 struct evhttp_cb *http_cb;
3942 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3943 if (strcmp(http_cb->what, uri) == 0)
3946 if (http_cb == NULL)
3949 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3950 mm_free(http_cb->what);
3957 evhttp_set_gencb(struct evhttp *http,
3958 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3961 http->gencbarg = cbarg;
3965 evhttp_set_bevcb(struct evhttp *http,
3966 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
3969 http->bevcbarg = cbarg;
3973 evhttp_set_newreqcb(struct evhttp *http,
3974 int (*cb)(struct evhttp_request *, void *), void *cbarg)
3976 http->newreqcb = cb;
3977 http->newreqcbarg = cbarg;
3981 * Request related functions
3984 struct evhttp_request *
3985 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
3987 struct evhttp_request *req = NULL;
3989 /* Allocate request structure */
3990 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
3991 event_warn("%s: calloc", __func__);
3995 req->headers_size = 0;
3998 req->kind = EVHTTP_RESPONSE;
3999 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4000 if (req->input_headers == NULL) {
4001 event_warn("%s: calloc", __func__);
4004 TAILQ_INIT(req->input_headers);
4006 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4007 if (req->output_headers == NULL) {
4008 event_warn("%s: calloc", __func__);
4011 TAILQ_INIT(req->output_headers);
4013 if ((req->input_buffer = evbuffer_new()) == NULL) {
4014 event_warn("%s: evbuffer_new", __func__);
4018 if ((req->output_buffer = evbuffer_new()) == NULL) {
4019 event_warn("%s: evbuffer_new", __func__);
4030 evhttp_request_free(req);
4035 evhttp_request_free(struct evhttp_request *req)
4037 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
4038 req->flags |= EVHTTP_REQ_NEEDS_FREE;
4042 if (req->remote_host != NULL)
4043 mm_free(req->remote_host);
4044 if (req->uri != NULL)
4046 if (req->uri_elems != NULL)
4047 evhttp_uri_free(req->uri_elems);
4048 if (req->response_code_line != NULL)
4049 mm_free(req->response_code_line);
4050 if (req->host_cache != NULL)
4051 mm_free(req->host_cache);
4053 evhttp_clear_headers(req->input_headers);
4054 mm_free(req->input_headers);
4056 evhttp_clear_headers(req->output_headers);
4057 mm_free(req->output_headers);
4059 if (req->input_buffer != NULL)
4060 evbuffer_free(req->input_buffer);
4062 if (req->output_buffer != NULL)
4063 evbuffer_free(req->output_buffer);
4069 evhttp_request_own(struct evhttp_request *req)
4071 req->flags |= EVHTTP_USER_OWNED;
4075 evhttp_request_is_owned(struct evhttp_request *req)
4077 return (req->flags & EVHTTP_USER_OWNED) != 0;
4080 struct evhttp_connection *
4081 evhttp_request_get_connection(struct evhttp_request *req)
4087 evhttp_connection_get_base(struct evhttp_connection *conn)
4093 evhttp_request_set_chunked_cb(struct evhttp_request *req,
4094 void (*cb)(struct evhttp_request *, void *))
4100 evhttp_request_set_header_cb(struct evhttp_request *req,
4101 int (*cb)(struct evhttp_request *, void *))
4103 req->header_cb = cb;
4107 evhttp_request_set_error_cb(struct evhttp_request *req,
4108 void (*cb)(enum evhttp_request_error, void *))
4114 evhttp_request_set_on_complete_cb(struct evhttp_request *req,
4115 void (*cb)(struct evhttp_request *, void *), void *cb_arg)
4117 req->on_complete_cb = cb;
4118 req->on_complete_cb_arg = cb_arg;
4122 * Allows for inspection of the request URI
4126 evhttp_request_get_uri(const struct evhttp_request *req) {
4127 if (req->uri == NULL)
4128 event_debug(("%s: request %p has no uri\n", __func__, req));
4132 const struct evhttp_uri *
4133 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4134 if (req->uri_elems == NULL)
4135 event_debug(("%s: request %p has no uri elems\n",
4137 return (req->uri_elems);
4141 evhttp_request_get_host(struct evhttp_request *req)
4143 const char *host = NULL;
4145 if (req->host_cache)
4146 return req->host_cache;
4149 host = evhttp_uri_get_host(req->uri_elems);
4150 if (!host && req->input_headers) {
4154 host = evhttp_find_header(req->input_headers, "Host");
4155 /* The Host: header may include a port. Remove it here
4156 to be consistent with uri_elems case above. */
4158 p = host + strlen(host) - 1;
4159 while (p > host && EVUTIL_ISDIGIT_(*p))
4161 if (p > host && *p == ':') {
4163 req->host_cache = mm_malloc(len + 1);
4164 if (!req->host_cache) {
4165 event_warn("%s: malloc", __func__);
4168 memcpy(req->host_cache, host, len);
4169 req->host_cache[len] = '\0';
4170 host = req->host_cache;
4178 enum evhttp_cmd_type
4179 evhttp_request_get_command(const struct evhttp_request *req) {
4184 evhttp_request_get_response_code(const struct evhttp_request *req)
4186 return req->response_code;
4190 evhttp_request_get_response_code_line(const struct evhttp_request *req)
4192 return req->response_code_line;
4195 /** Returns the input headers */
4196 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4198 return (req->input_headers);
4201 /** Returns the output headers */
4202 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4204 return (req->output_headers);
4207 /** Returns the input buffer */
4208 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4210 return (req->input_buffer);
4213 /** Returns the output buffer */
4214 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4216 return (req->output_buffer);
4221 * Takes a file descriptor to read a request from.
4222 * The callback is executed once the whole request has been read.
4225 static struct evhttp_connection*
4226 evhttp_get_request_connection(
4227 struct evhttp* http,
4228 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
4230 struct evhttp_connection *evcon;
4231 char *hostname = NULL, *portname = NULL;
4232 struct bufferevent* bev = NULL;
4234 name_from_addr(sa, salen, &hostname, &portname);
4235 if (hostname == NULL || portname == NULL) {
4236 if (hostname) mm_free(hostname);
4237 if (portname) mm_free(portname);
4241 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4242 __func__, hostname, portname, EV_SOCK_ARG(fd)));
4244 /* we need a connection object to put the http request on */
4245 if (http->bevcb != NULL) {
4246 bev = (*http->bevcb)(http->base, http->bevcbarg);
4248 evcon = evhttp_connection_base_bufferevent_new(
4249 http->base, NULL, bev, hostname, atoi(portname));
4255 evcon->max_headers_size = http->default_max_headers_size;
4256 evcon->max_body_size = http->default_max_body_size;
4257 if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4258 evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4260 evcon->flags |= EVHTTP_CON_INCOMING;
4261 evcon->state = EVCON_READING_FIRSTLINE;
4265 if (bufferevent_setfd(evcon->bufev, fd))
4267 if (bufferevent_enable(evcon->bufev, EV_READ))
4269 if (bufferevent_disable(evcon->bufev, EV_WRITE))
4271 bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
4276 evhttp_connection_free(evcon);
4281 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4283 struct evhttp *http = evcon->http_server;
4284 struct evhttp_request *req;
4285 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4288 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4289 event_warn("%s: strdup", __func__);
4290 evhttp_request_free(req);
4293 req->remote_port = evcon->port;
4295 req->evcon = evcon; /* the request ends up owning the connection */
4296 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4298 /* We did not present the request to the user yet, so treat it
4299 * as if the user was done with the request. This allows us
4300 * to free the request on a persistent connection if the
4301 * client drops it without sending a request.
4304 req->kind = EVHTTP_REQUEST;
4306 if (http->newreqcb && http->newreqcb(req, http->newreqcbarg) == -1) {
4307 evhttp_request_free(req);
4311 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4313 evhttp_start_read_(evcon);
4319 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4320 struct sockaddr *sa, ev_socklen_t salen)
4322 struct evhttp_connection *evcon;
4324 evcon = evhttp_get_request_connection(http, fd, sa, salen);
4325 if (evcon == NULL) {
4326 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4327 __func__, EV_SOCK_ARG(fd));
4328 evutil_closesocket(fd);
4332 /* the timeout can be used by the server to close idle connections */
4333 if (evutil_timerisset(&http->timeout))
4334 evhttp_connection_set_timeout_tv(evcon, &http->timeout);
4337 * if we want to accept more than one request on a connection,
4338 * we need to know which http server it belongs to.
4340 evcon->http_server = http;
4341 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4343 if (evhttp_associate_new_request_with_connection(evcon) == -1)
4344 evhttp_connection_free(evcon);
4349 * Network helper functions that we do not want to export to the rest of
4354 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4355 char **phost, char **pport)
4357 char ntop[NI_MAXHOST];
4358 char strport[NI_MAXSERV];
4361 #ifdef EVENT__HAVE_GETNAMEINFO
4362 ni_result = getnameinfo(sa, salen,
4363 ntop, sizeof(ntop), strport, sizeof(strport),
4364 NI_NUMERICHOST|NI_NUMERICSERV);
4366 if (ni_result != 0) {
4368 /* Windows doesn't have an EAI_SYSTEM. */
4369 if (ni_result == EAI_SYSTEM)
4370 event_err(1, "getnameinfo failed");
4373 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4377 ni_result = fake_getnameinfo(sa, salen,
4378 ntop, sizeof(ntop), strport, sizeof(strport),
4379 NI_NUMERICHOST|NI_NUMERICSERV);
4384 *phost = mm_strdup(ntop);
4385 *pport = mm_strdup(strport);
4388 /* Create a non-blocking socket and bind it */
4389 /* todo: rename this function */
4390 static evutil_socket_t
4391 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
4398 /* Create listen socket */
4399 fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
4400 SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
4402 event_sock_warn(-1, "socket");
4406 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
4409 if (evutil_make_listen_socket_reuseable(fd) < 0)
4414 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
4422 serrno = EVUTIL_SOCKET_ERROR();
4423 evutil_closesocket(fd);
4424 EVUTIL_SET_SOCKET_ERROR(serrno);
4428 static struct evutil_addrinfo *
4429 make_addrinfo(const char *address, ev_uint16_t port)
4431 struct evutil_addrinfo *ai = NULL;
4433 struct evutil_addrinfo hints;
4434 char strport[NI_MAXSERV];
4437 memset(&hints, 0, sizeof(hints));
4438 hints.ai_family = AF_UNSPEC;
4439 hints.ai_socktype = SOCK_STREAM;
4440 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
4441 * types we don't have an interface to connect to. */
4442 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
4443 evutil_snprintf(strport, sizeof(strport), "%d", port);
4444 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
4446 if (ai_result == EVUTIL_EAI_SYSTEM)
4447 event_warn("getaddrinfo");
4449 event_warnx("getaddrinfo: %s",
4450 evutil_gai_strerror(ai_result));
4457 static evutil_socket_t
4458 bind_socket(const char *address, ev_uint16_t port, int reuse)
4461 struct evutil_addrinfo *aitop = NULL;
4463 /* just create an unbound socket */
4464 if (address == NULL && port == 0)
4465 return bind_socket_ai(NULL, 0);
4467 aitop = make_addrinfo(address, port);
4472 fd = bind_socket_ai(aitop, reuse);
4474 evutil_freeaddrinfo(aitop);
4481 char *scheme; /* scheme; e.g http, ftp etc */
4482 char *userinfo; /* userinfo (typically username:pass), or NULL */
4483 char *host; /* hostname, IP address, or NULL */
4484 int port; /* port, or zero */
4485 char *path; /* path, or "". */
4486 char *query; /* query, or NULL */
4487 char *fragment; /* fragment or NULL */
4491 evhttp_uri_new(void)
4493 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
4500 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
4505 /* Return true if the string starting at s and ending immediately before eos
4506 * is a valid URI scheme according to RFC3986
4509 scheme_ok(const char *s, const char *eos)
4511 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4512 EVUTIL_ASSERT(eos >= s);
4515 if (!EVUTIL_ISALPHA_(*s))
4518 if (! EVUTIL_ISALNUM_(*s) &&
4519 *s != '+' && *s != '-' && *s != '.')
4525 #define SUBDELIMS "!$&'()*+,;="
4527 /* Return true iff [s..eos) is a valid userinfo */
4529 userinfo_ok(const char *s, const char *eos)
4532 if (CHAR_IS_UNRESERVED(*s) ||
4533 strchr(SUBDELIMS, *s) ||
4536 else if (*s == '%' && s+2 < eos &&
4537 EVUTIL_ISXDIGIT_(s[1]) &&
4538 EVUTIL_ISXDIGIT_(s[2]))
4547 regname_ok(const char *s, const char *eos)
4549 while (s && s<eos) {
4550 if (CHAR_IS_UNRESERVED(*s) ||
4551 strchr(SUBDELIMS, *s))
4553 else if (*s == '%' &&
4554 EVUTIL_ISXDIGIT_(s[1]) &&
4555 EVUTIL_ISXDIGIT_(s[2]))
4564 parse_port(const char *s, const char *eos)
4568 if (! EVUTIL_ISDIGIT_(*s))
4570 portnum = (portnum * 10) + (*s - '0');
4573 if (portnum > 65535)
4580 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4582 bracket_addr_ok(const char *s, const char *eos)
4584 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4587 /* IPvFuture, or junk.
4588 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4590 s += 2; /* skip [v */
4592 if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
4594 while (s < eos && *s != '.') {
4595 if (EVUTIL_ISXDIGIT_(*s))
4604 if (CHAR_IS_UNRESERVED(*s) ||
4605 strchr(SUBDELIMS, *s) ||
4615 ev_ssize_t n_chars = eos-s-2;
4616 struct in6_addr in6;
4617 if (n_chars >= 64) /* way too long */
4619 memcpy(buf, s+1, n_chars);
4621 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4626 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4631 uri->host = mm_strdup("");
4632 if (uri->host == NULL) {
4633 event_warn("%s: strdup", __func__);
4639 /* Optionally, we start with "userinfo@" */
4641 cp = strchr(s, '@');
4642 if (cp && cp < eos) {
4643 if (! userinfo_ok(s,cp))
4646 uri->userinfo = mm_strdup(s);
4647 if (uri->userinfo == NULL) {
4648 event_warn("%s: strdup", __func__);
4654 /* Optionally, we end with ":port" */
4655 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
4657 if (port >= cp && *port == ':') {
4658 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4661 else if ((uri->port = parse_port(port+1, eos))<0)
4665 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4666 * an IP-Literal, or a reg-name */
4667 EVUTIL_ASSERT(eos >= cp);
4668 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4669 /* IPv6address, IP-Literal, or junk. */
4670 if (! bracket_addr_ok(cp, eos))
4673 /* Make sure the host part is ok. */
4674 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4677 uri->host = mm_malloc(eos-cp+1);
4678 if (uri->host == NULL) {
4679 event_warn("%s: malloc", __func__);
4682 memcpy(uri->host, cp, eos-cp);
4683 uri->host[eos-cp] = '\0';
4689 end_of_authority(char *cp)
4692 if (*cp == '?' || *cp == '#' || *cp == '/')
4705 /* Return the character after the longest prefix of 'cp' that matches...
4706 * *pchar / "/" if allow_qchars is false, or
4707 * *(pchar / "/" / "?") if allow_qchars is true.
4710 end_of_path(char *cp, enum uri_part part, unsigned flags)
4712 if (flags & EVHTTP_URI_NONCONFORMANT) {
4713 /* If NONCONFORMANT:
4714 * Path is everything up to a # or ? or nul.
4715 * Query is everything up a # or nul
4716 * Fragment is everything up to a nul.
4720 while (*cp && *cp != '#' && *cp != '?')
4724 while (*cp && *cp != '#')
4735 if (CHAR_IS_UNRESERVED(*cp) ||
4736 strchr(SUBDELIMS, *cp) ||
4737 *cp == ':' || *cp == '@' || *cp == '/')
4739 else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
4740 EVUTIL_ISXDIGIT_(cp[2]))
4742 else if (*cp == '?' && part != PART_PATH)
4751 path_matches_noscheme(const char *cp)
4756 else if (*cp == '/')
4764 evhttp_uri_parse(const char *source_uri)
4766 return evhttp_uri_parse_with_flags(source_uri, 0);
4770 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4772 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4773 char *path = NULL, *fragment = NULL;
4774 int got_authority = 0;
4776 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4778 event_warn("%s: calloc", __func__);
4784 readbuf = mm_strdup(source_uri);
4785 if (readbuf == NULL) {
4786 event_warn("%s: strdup", __func__);
4793 /* We try to follow RFC3986 here as much as we can, and match
4796 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4798 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
4802 token = strchr(readp, ':');
4803 if (token && scheme_ok(readp,token)) {
4805 uri->scheme = mm_strdup(readp);
4806 if (uri->scheme == NULL) {
4807 event_warn("%s: strdup", __func__);
4810 readp = token+1; /* eat : */
4813 /* 2. Optionally, "//" then an 'authority' part. */
4814 if (readp[0]=='/' && readp[1] == '/') {
4818 path = end_of_authority(readp);
4819 if (parse_authority(uri, authority, path) < 0)
4825 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4828 readp = end_of_path(path, PART_PATH, flags);
4831 if (*readp == '?') {
4835 readp = end_of_path(readp, PART_QUERY, flags);
4838 if (*readp == '#') {
4842 readp = end_of_path(readp, PART_FRAGMENT, flags);
4844 if (*readp != '\0') {
4848 /* These next two cases may be unreachable; I'm leaving them
4849 * in to be defensive. */
4850 /* If you didn't get an authority, the path can't begin with "//" */
4851 if (!got_authority && path[0]=='/' && path[1]=='/')
4853 /* If you did get an authority, the path must begin with "/" or be
4855 if (got_authority && path[0] != '/' && path[0] != '\0')
4857 /* (End of maybe-unreachable cases) */
4859 /* If there was no scheme, the first part of the path (if any) must
4860 * have no colon in it. */
4861 if (! uri->scheme && !path_matches_noscheme(path))
4864 EVUTIL_ASSERT(path);
4865 uri->path = mm_strdup(path);
4866 if (uri->path == NULL) {
4867 event_warn("%s: strdup", __func__);
4872 uri->query = mm_strdup(query);
4873 if (uri->query == NULL) {
4874 event_warn("%s: strdup", __func__);
4879 uri->fragment = mm_strdup(fragment);
4880 if (uri->fragment == NULL) {
4881 event_warn("%s: strdup", __func__);
4891 evhttp_uri_free(uri);
4897 static struct evhttp_uri *
4898 evhttp_uri_parse_authority(char *source_uri)
4900 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4904 event_warn("%s: calloc", __func__);
4910 end = end_of_authority(source_uri);
4911 if (parse_authority(uri, source_uri, end) < 0)
4914 uri->path = mm_strdup("");
4915 if (uri->path == NULL) {
4916 event_warn("%s: strdup", __func__);
4923 evhttp_uri_free(uri);
4928 evhttp_uri_free(struct evhttp_uri *uri)
4930 #define URI_FREE_STR_(f) \
4935 URI_FREE_STR_(scheme);
4936 URI_FREE_STR_(userinfo);
4937 URI_FREE_STR_(host);
4938 URI_FREE_STR_(path);
4939 URI_FREE_STR_(query);
4940 URI_FREE_STR_(fragment);
4943 #undef URI_FREE_STR_
4947 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
4949 struct evbuffer *tmp = 0;
4950 size_t joined_size = 0;
4951 char *output = NULL;
4953 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
4955 if (!uri || !buf || !limit)
4958 tmp = evbuffer_new();
4964 evbuffer_add(tmp, ":", 1);
4967 evbuffer_add(tmp, "//", 2);
4969 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
4972 evbuffer_add_printf(tmp,":%d", uri->port);
4974 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
4982 evbuffer_add(tmp, "?", 1);
4986 if (uri->fragment) {
4987 evbuffer_add(tmp, "#", 1);
4991 evbuffer_add(tmp, "\0", 1); /* NUL */
4993 joined_size = evbuffer_get_length(tmp);
4995 if (joined_size > limit) {
4996 /* It doesn't fit. */
5000 evbuffer_remove(tmp, buf, joined_size);
5011 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
5016 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
5018 return uri->userinfo;
5021 evhttp_uri_get_host(const struct evhttp_uri *uri)
5026 evhttp_uri_get_port(const struct evhttp_uri *uri)
5031 evhttp_uri_get_path(const struct evhttp_uri *uri)
5036 evhttp_uri_get_query(const struct evhttp_uri *uri)
5041 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
5043 return uri->fragment;
5046 #define URI_SET_STR_(f) do { \
5050 if ((uri->f = mm_strdup(f)) == NULL) { \
5051 event_warn("%s: strdup()", __func__); \
5060 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
5062 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
5065 URI_SET_STR_(scheme);
5069 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
5071 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
5073 URI_SET_STR_(userinfo);
5077 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
5080 if (host[0] == '[') {
5081 if (! bracket_addr_ok(host, host+strlen(host)))
5084 if (! regname_ok(host, host+strlen(host)))
5093 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
5100 #define end_of_cpath(cp,p,f) \
5101 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
5104 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
5106 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
5113 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
5115 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
5117 URI_SET_STR_(query);
5121 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
5123 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
5125 URI_SET_STR_(fragment);