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 evhttp_read_cb(evcon->bufev, evcon);
1178 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1180 /* This is after writing the request to the server */
1181 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1182 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
1183 EVUTIL_ASSERT(req != NULL);
1185 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1187 /* We need to wait until we've written all of our output data before we can
1189 if (evbuffer_get_length(output) > 0)
1192 /* We are done writing our header and are now expecting the response */
1193 req->kind = EVHTTP_RESPONSE;
1195 evhttp_start_read_(evcon);
1199 * Clean up a connection object
1203 evhttp_connection_free(struct evhttp_connection *evcon)
1205 struct evhttp_request *req;
1208 /* notify interested parties that this connection is going down */
1209 if (evcon->fd != -1) {
1210 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1211 (*evcon->closecb)(evcon, evcon->closecb_arg);
1214 /* remove all requests that might be queued on this
1215 * connection. for server connections, this should be empty.
1216 * because it gets dequeued either in evhttp_connection_done or
1217 * evhttp_connection_fail_.
1219 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1220 evhttp_request_free_(evcon, req);
1223 if (evcon->http_server != NULL) {
1224 struct evhttp *http = evcon->http_server;
1225 TAILQ_REMOVE(&http->connections, evcon, next);
1228 if (event_initialized(&evcon->retry_ev)) {
1229 event_del(&evcon->retry_ev);
1230 event_debug_unassign(&evcon->retry_ev);
1233 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1234 &evcon->read_more_deferred_cb);
1236 if (evcon->bufev != NULL) {
1238 !(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE);
1239 if (evcon->fd == -1)
1240 evcon->fd = bufferevent_getfd(evcon->bufev);
1242 bufferevent_free(evcon->bufev);
1245 if (evcon->fd != -1) {
1246 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1248 evutil_closesocket(evcon->fd);
1251 if (evcon->bind_address != NULL)
1252 mm_free(evcon->bind_address);
1254 if (evcon->address != NULL)
1255 mm_free(evcon->address);
1261 evhttp_connection_free_on_completion(struct evhttp_connection *evcon) {
1262 evcon->flags |= EVHTTP_CON_AUTOFREE;
1266 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1267 const char *address)
1269 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1270 if (evcon->bind_address)
1271 mm_free(evcon->bind_address);
1272 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1273 event_warn("%s: strdup", __func__);
1277 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1280 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1281 evcon->bind_port = port;
1285 evhttp_request_dispatch(struct evhttp_connection* evcon)
1287 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1289 /* this should not usually happy but it's possible */
1293 EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST);
1295 /* delete possible close detection events */
1296 evhttp_connection_stop_detectclose(evcon);
1298 /* we assume that the connection is connected already */
1299 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1301 evcon->state = EVCON_WRITING;
1303 /* Create the header from the store arguments */
1304 evhttp_make_header(evcon, req);
1306 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1309 /* Reset our connection state: disables reading/writing, closes our fd (if
1310 * any), clears out buffers, and puts us in state DISCONNECTED. */
1312 evhttp_connection_reset_(struct evhttp_connection *evcon)
1314 struct evbuffer *tmp;
1317 bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL);
1319 /* XXXX This is not actually an optimal fix. Instead we ought to have
1320 an API for "stop connecting", or use bufferevent_setfd to turn off
1321 connecting. But for Libevent 2.0, this seems like a minimal change
1322 least likely to disrupt the rest of the bufferevent and http code.
1324 Why is this here? If the fd is set in the bufferevent, and the
1325 bufferevent is connecting, then you can't actually stop the
1326 bufferevent from trying to connect with bufferevent_disable(). The
1327 connect will never trigger, since we close the fd, but the timeout
1328 might. That caused an assertion failure in evhttp_connection_fail_.
1330 bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE);
1332 if (evcon->fd == -1)
1333 evcon->fd = bufferevent_getfd(evcon->bufev);
1335 if (evcon->fd != -1) {
1336 /* inform interested parties about connection close */
1337 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1338 (*evcon->closecb)(evcon, evcon->closecb_arg);
1340 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1341 evutil_closesocket(evcon->fd);
1344 err = bufferevent_setfd(evcon->bufev, -1);
1345 EVUTIL_ASSERT(!err && "setfd");
1347 /* we need to clean up any buffered data */
1348 tmp = bufferevent_get_output(evcon->bufev);
1349 err = evbuffer_drain(tmp, -1);
1350 EVUTIL_ASSERT(!err && "drain output");
1351 tmp = bufferevent_get_input(evcon->bufev);
1352 err = evbuffer_drain(tmp, -1);
1353 EVUTIL_ASSERT(!err && "drain input");
1355 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1357 evcon->state = EVCON_DISCONNECTED;
1361 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1363 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1364 bufferevent_enable(evcon->bufev, EV_READ);
1368 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1370 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1371 bufferevent_disable(evcon->bufev, EV_READ);
1375 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1377 struct evhttp_connection *evcon = arg;
1379 evcon->state = EVCON_DISCONNECTED;
1380 evhttp_connection_connect_(evcon);
1384 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1386 struct evcon_requestq requests;
1388 evhttp_connection_reset_(evcon);
1389 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1390 struct timeval tv_retry = evcon->initial_retry_timeout;
1392 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1393 /* XXXX handle failure from evhttp_add_event */
1394 for (i=0; i < evcon->retry_cnt; ++i) {
1395 tv_retry.tv_usec *= 2;
1396 if (tv_retry.tv_usec > 1000000) {
1397 tv_retry.tv_usec -= 1000000;
1398 tv_retry.tv_sec += 1;
1400 tv_retry.tv_sec *= 2;
1401 if (tv_retry.tv_sec > 3600) {
1402 tv_retry.tv_sec = 3600;
1403 tv_retry.tv_usec = 0;
1406 event_add(&evcon->retry_ev, &tv_retry);
1412 * User callback can do evhttp_make_request() on the same
1413 * evcon so new request will be added to evcon->requests. To
1414 * avoid freeing it prematurely we iterate over the copy of
1417 TAILQ_INIT(&requests);
1418 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1419 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1420 TAILQ_REMOVE(&evcon->requests, request, next);
1421 TAILQ_INSERT_TAIL(&requests, request, next);
1424 /* for now, we just signal all requests by executing their callbacks */
1425 while (TAILQ_FIRST(&requests) != NULL) {
1426 struct evhttp_request *request = TAILQ_FIRST(&requests);
1427 TAILQ_REMOVE(&requests, request, next);
1428 request->evcon = NULL;
1430 /* we might want to set an error here */
1431 request->cb(request, request->cb_arg);
1432 evhttp_request_free_auto(request);
1437 evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
1438 struct evhttp_request *req)
1440 struct evbuffer *buf;
1442 /** Second time, we can't read anything */
1443 if (evcon->flags & EVHTTP_CON_READING_ERROR) {
1444 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1445 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1449 req->kind = EVHTTP_RESPONSE;
1451 buf = bufferevent_get_output(evcon->bufev);
1452 evbuffer_unfreeze(buf, 1);
1453 evbuffer_drain(buf, evbuffer_get_length(buf));
1454 evbuffer_freeze(buf, 1);
1456 evhttp_start_read_(evcon);
1457 evcon->flags |= EVHTTP_CON_READING_ERROR;
1461 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1463 struct evhttp_connection *evcon = arg;
1464 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1466 if (evcon->fd == -1)
1467 evcon->fd = bufferevent_getfd(bufev);
1469 switch (evcon->state) {
1470 case EVCON_CONNECTING:
1471 if (what & BEV_EVENT_TIMEOUT) {
1472 event_debug(("%s: connection timeout for \"%s:%d\" on "
1474 __func__, evcon->address, evcon->port,
1475 EV_SOCK_ARG(evcon->fd)));
1476 evhttp_connection_cb_cleanup(evcon);
1481 case EVCON_READING_BODY:
1482 if (!req->chunked && req->ntoread < 0
1483 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1484 /* EOF on read can be benign */
1485 evhttp_connection_done(evcon);
1490 case EVCON_DISCONNECTED:
1492 case EVCON_READING_FIRSTLINE:
1493 case EVCON_READING_HEADERS:
1494 case EVCON_READING_TRAILER:
1500 /* when we are in close detect mode, a read error means that
1501 * the other side closed their connection.
1503 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1504 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1505 EVUTIL_ASSERT(evcon->http_server == NULL);
1506 /* For connections from the client, we just
1507 * reset the connection so that it becomes
1510 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1511 evhttp_connection_reset_(evcon);
1514 * If we have no more requests that need completion
1515 * and we want to auto-free the connection when all
1516 * requests have been completed.
1518 if (TAILQ_FIRST(&evcon->requests) == NULL
1519 && (evcon->flags & EVHTTP_CON_OUTGOING)
1520 && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1521 evhttp_connection_free(evcon);
1526 if (what & BEV_EVENT_TIMEOUT) {
1527 evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
1528 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1529 if (what & BEV_EVENT_WRITING &&
1530 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR) {
1531 evhttp_connection_read_on_write_error(evcon, req);
1535 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1536 } else if (what == BEV_EVENT_CONNECTED) {
1538 evhttp_connection_fail_(evcon, EVREQ_HTTP_BUFFER_ERROR);
1543 * Event callback for asynchronous connection attempt.
1546 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1548 struct evhttp_connection *evcon = arg;
1550 ev_socklen_t errsz = sizeof(error);
1552 if (evcon->fd == -1)
1553 evcon->fd = bufferevent_getfd(bufev);
1555 if (!(what & BEV_EVENT_CONNECTED)) {
1556 /* some operating systems return ECONNREFUSED immediately
1557 * when connecting to a local address. the cleanup is going
1558 * to reschedule this function call.
1561 if (errno == ECONNREFUSED)
1564 evhttp_error_cb(bufev, what, arg);
1568 if (evcon->fd == -1) {
1569 event_debug(("%s: bufferevent_getfd returned -1",
1574 /* Check if the connection completed */
1575 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1577 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT,
1578 __func__, evcon->address, evcon->port,
1579 EV_SOCK_ARG(evcon->fd)));
1584 event_debug(("%s: connect failed for \"%s:%d\" on "
1586 __func__, evcon->address, evcon->port,
1587 EV_SOCK_ARG(evcon->fd),
1588 evutil_socket_error_to_string(error)));
1592 /* We are connected to the server now */
1593 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1594 __func__, evcon->address, evcon->port,
1595 EV_SOCK_ARG(evcon->fd)));
1597 /* Reset the retry count as we were successful in connecting */
1598 evcon->retry_cnt = 0;
1599 evcon->state = EVCON_IDLE;
1601 /* reset the bufferevent cbs */
1602 bufferevent_setcb(evcon->bufev,
1608 if (!evutil_timerisset(&evcon->timeout)) {
1609 const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 };
1610 const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 };
1611 bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv);
1613 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
1616 /* try to start requests that have queued up on this connection */
1617 evhttp_request_dispatch(evcon);
1621 evhttp_connection_cb_cleanup(evcon);
1625 * Check if we got a valid response code.
1629 evhttp_valid_response_code(int code)
1638 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1642 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1643 if (n != 2 || major > 1) {
1644 event_debug(("%s: bad version %s on message %p from %s",
1645 __func__, version, req, req->remote_host));
1653 /* Parses the status line of a web server */
1656 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1660 const char *readable = "";
1662 protocol = strsep(&line, " ");
1665 number = strsep(&line, " ");
1669 if (evhttp_parse_http_version(protocol, req) < 0)
1672 req->response_code = atoi(number);
1673 if (!evhttp_valid_response_code(req->response_code)) {
1674 event_debug(("%s: bad response code \"%s\"",
1679 if (req->response_code_line != NULL)
1680 mm_free(req->response_code_line);
1681 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1682 event_warn("%s: strdup", __func__);
1689 /* Parse the first line of a HTTP request */
1692 evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len)
1694 char *eos = line + len;
1698 const char *hostname;
1701 enum evhttp_cmd_type type;
1703 while (eos > line && *(eos-1) == ' ') {
1708 if (len < strlen("GET / HTTP/1.0"))
1711 /* Parse the request line */
1712 method = strsep(&line, " ");
1716 version = strrchr(uri, ' ');
1717 if (!version || uri == version)
1722 method_len = (uri - method) - 1;
1723 type = EVHTTP_REQ_UNKNOWN_;
1726 switch (method_len) {
1728 /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1730 /* Since both GET and PUT share the same character 'T' at the end,
1731 * if the string doesn't have 'T', we can immediately determine this
1732 * is an invalid HTTP method */
1734 if (method[2] != 'T') {
1740 /* This first byte is 'G', so make sure the next byte is
1741 * 'E', if it isn't then this isn't a valid method */
1743 if (method[1] == 'E') {
1744 type = EVHTTP_REQ_GET;
1749 /* First byte is P, check second byte for 'U', if not,
1750 * we know it's an invalid method */
1751 if (method[1] == 'U') {
1752 type = EVHTTP_REQ_PUT;
1760 /* The method length is 4 bytes, leaving only the methods "POST" and "HEAD" */
1763 if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') {
1764 type = EVHTTP_REQ_POST;
1768 if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') {
1769 type = EVHTTP_REQ_HEAD;
1777 /* Method length is 5 bytes, which can only encompass PATCH and TRACE */
1780 if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') {
1781 type = EVHTTP_REQ_PATCH;
1785 if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') {
1786 type = EVHTTP_REQ_TRACE;
1795 /* Method length is 6, only valid method 6 bytes in length is DELEte */
1797 /* If the first byte isn't 'D' then it's invalid */
1798 if (*method != 'D') {
1802 if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' && method[2] == 'L' && method[1] == 'E') {
1803 type = EVHTTP_REQ_DELETE;
1808 /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1811 if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' &&
1812 method[3] == 'I' && method[2] == 'T' && method[1] == 'P') {
1813 type = EVHTTP_REQ_OPTIONS;
1818 if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' &&
1819 method[3] == 'N' && method[2] == 'N' && method[1] == 'O') {
1820 type = EVHTTP_REQ_CONNECT;
1830 if ((int)type == EVHTTP_REQ_UNKNOWN_) {
1831 event_debug(("%s: bad method %s on request %p from %s",
1832 __func__, method, req, req->remote_host));
1833 /* No error yet; we'll give a better error later when
1834 * we see that req->type is unsupported. */
1839 if (evhttp_parse_http_version(version, req) < 0)
1842 if ((req->uri = mm_strdup(uri)) == NULL) {
1843 event_debug(("%s: mm_strdup", __func__));
1847 if (type == EVHTTP_REQ_CONNECT) {
1848 if ((req->uri_elems = evhttp_uri_parse_authority(req->uri)) == NULL) {
1852 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
1853 EVHTTP_URI_NONCONFORMANT)) == NULL) {
1858 /* If we have an absolute-URI, check to see if it is an http request
1859 for a known vhost or server alias. If we don't know about this
1860 host, we consider it a proxy request. */
1861 scheme = evhttp_uri_get_scheme(req->uri_elems);
1862 hostname = evhttp_uri_get_host(req->uri_elems);
1863 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1864 !evutil_ascii_strcasecmp(scheme, "https")) &&
1866 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1867 req->flags |= EVHTTP_PROXY_REQUEST;
1873 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1875 struct evkeyval *header;
1877 TAILQ_FOREACH(header, headers, next) {
1878 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1879 return (header->value);
1886 evhttp_clear_headers(struct evkeyvalq *headers)
1888 struct evkeyval *header;
1890 for (header = TAILQ_FIRST(headers);
1892 header = TAILQ_FIRST(headers)) {
1893 TAILQ_REMOVE(headers, header, next);
1894 mm_free(header->key);
1895 mm_free(header->value);
1901 * Returns 0, if the header was successfully removed.
1902 * Returns -1, if the header could not be found.
1906 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1908 struct evkeyval *header;
1910 TAILQ_FOREACH(header, headers, next) {
1911 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1918 /* Free and remove the header that we found */
1919 TAILQ_REMOVE(headers, header, next);
1920 mm_free(header->key);
1921 mm_free(header->value);
1928 evhttp_header_is_valid_value(const char *value)
1930 const char *p = value;
1932 while ((p = strpbrk(p, "\r\n")) != NULL) {
1933 /* we really expect only one new line */
1934 p += strspn(p, "\r\n");
1935 /* we expect a space or tab for continuation */
1936 if (*p != ' ' && *p != '\t')
1943 evhttp_add_header(struct evkeyvalq *headers,
1944 const char *key, const char *value)
1946 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1948 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1949 /* drop illegal headers */
1950 event_debug(("%s: dropping illegal header key\n", __func__));
1954 if (!evhttp_header_is_valid_value(value)) {
1955 event_debug(("%s: dropping illegal header value\n", __func__));
1959 return (evhttp_add_header_internal(headers, key, value));
1963 evhttp_add_header_internal(struct evkeyvalq *headers,
1964 const char *key, const char *value)
1966 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
1967 if (header == NULL) {
1968 event_warn("%s: calloc", __func__);
1971 if ((header->key = mm_strdup(key)) == NULL) {
1973 event_warn("%s: strdup", __func__);
1976 if ((header->value = mm_strdup(value)) == NULL) {
1977 mm_free(header->key);
1979 event_warn("%s: strdup", __func__);
1983 TAILQ_INSERT_TAIL(headers, header, next);
1989 * Parses header lines from a request or a response into the specified
1990 * request object given an event buffer.
1993 * DATA_CORRUPTED on error
1994 * MORE_DATA_EXPECTED when we need to read more headers
1995 * ALL_DATA_READ when all headers have been read.
1998 enum message_read_status
1999 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
2002 enum message_read_status status = ALL_DATA_READ;
2006 line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
2008 if (req->evcon != NULL &&
2009 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2010 return (DATA_TOO_LONG);
2012 return (MORE_DATA_EXPECTED);
2015 if (req->evcon != NULL && len > req->evcon->max_headers_size) {
2017 return (DATA_TOO_LONG);
2020 req->headers_size = len;
2022 switch (req->kind) {
2023 case EVHTTP_REQUEST:
2024 if (evhttp_parse_request_line(req, line, len) == -1)
2025 status = DATA_CORRUPTED;
2027 case EVHTTP_RESPONSE:
2028 if (evhttp_parse_response_line(req, line) == -1)
2029 status = DATA_CORRUPTED;
2032 status = DATA_CORRUPTED;
2040 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
2042 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
2044 size_t old_len, line_len;
2049 old_len = strlen(header->value);
2051 /* Strip space from start and end of line. */
2052 while (*line == ' ' || *line == '\t')
2054 evutil_rtrim_lws_(line);
2056 line_len = strlen(line);
2058 newval = mm_realloc(header->value, old_len + line_len + 2);
2062 newval[old_len] = ' ';
2063 memcpy(newval + old_len + 1, line, line_len + 1);
2064 header->value = newval;
2069 enum message_read_status
2070 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
2072 enum message_read_status errcode = DATA_CORRUPTED;
2074 enum message_read_status status = MORE_DATA_EXPECTED;
2076 struct evkeyvalq* headers = req->input_headers;
2078 while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
2080 char *skey, *svalue;
2082 req->headers_size += len;
2084 if (req->evcon != NULL &&
2085 req->headers_size > req->evcon->max_headers_size) {
2086 errcode = DATA_TOO_LONG;
2090 if (*line == '\0') { /* Last header - Done */
2091 status = ALL_DATA_READ;
2096 /* Check if this is a continuation line */
2097 if (*line == ' ' || *line == '\t') {
2098 if (evhttp_append_to_last_header(headers, line) == -1)
2104 /* Processing of header lines */
2106 skey = strsep(&svalue, ":");
2110 svalue += strspn(svalue, " ");
2111 evutil_rtrim_lws_(svalue);
2113 if (evhttp_add_header(headers, skey, svalue) == -1)
2119 if (status == MORE_DATA_EXPECTED) {
2120 if (req->evcon != NULL &&
2121 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2122 return (DATA_TOO_LONG);
2133 evhttp_get_body_length(struct evhttp_request *req)
2135 struct evkeyvalq *headers = req->input_headers;
2136 const char *content_length;
2137 const char *connection;
2139 content_length = evhttp_find_header(headers, "Content-Length");
2140 connection = evhttp_find_header(headers, "Connection");
2142 if (content_length == NULL && connection == NULL)
2144 else if (content_length == NULL &&
2145 evutil_ascii_strcasecmp(connection, "Close") != 0) {
2147 } else if (content_length == NULL) {
2151 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2152 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2153 event_debug(("%s: illegal content length: %s",
2154 __func__, content_length));
2157 req->ntoread = ntoread;
2160 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2161 __func__, EV_I64_ARG(req->ntoread),
2162 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2168 evhttp_method_may_have_body(enum evhttp_cmd_type type)
2171 case EVHTTP_REQ_POST:
2172 case EVHTTP_REQ_PUT:
2173 case EVHTTP_REQ_PATCH:
2175 case EVHTTP_REQ_GET:
2176 case EVHTTP_REQ_DELETE:
2177 case EVHTTP_REQ_OPTIONS:
2178 case EVHTTP_REQ_CONNECT:
2181 case EVHTTP_REQ_TRACE:
2182 case EVHTTP_REQ_HEAD:
2189 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2191 const char *xfer_enc;
2193 /* If this is a request without a body, then we are done */
2194 if (req->kind == EVHTTP_REQUEST &&
2195 !evhttp_method_may_have_body(req->type)) {
2196 evhttp_connection_done(evcon);
2199 evcon->state = EVCON_READING_BODY;
2200 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
2201 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
2205 if (evhttp_get_body_length(req) == -1) {
2206 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2209 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2210 /* An incoming request with no content-length and no
2211 * transfer-encoding has no body. */
2212 evhttp_connection_done(evcon);
2217 /* Should we send a 100 Continue status line? */
2218 switch (evhttp_have_expect(req, 1)) {
2220 /* XXX It would be nice to do some sanity
2221 checking here. Does the resource exist?
2222 Should the resource accept post requests? If
2223 no, we should respond with an error. For
2224 now, just optimistically tell the client to
2225 send their message body. */
2226 if (req->ntoread > 0) {
2227 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2228 if ((req->evcon->max_body_size <= EV_INT64_MAX) &&
2229 (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2230 evhttp_lingering_fail(evcon, req);
2234 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2235 evhttp_send_continue(evcon, req);
2238 evhttp_send_error(req, HTTP_EXPECTATIONFAILED, NULL);
2243 evhttp_read_body(evcon, req);
2244 /* note the request may have been freed in evhttp_read_body */
2248 evhttp_read_firstline(struct evhttp_connection *evcon,
2249 struct evhttp_request *req)
2251 enum message_read_status res;
2253 res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2254 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2255 /* Error while reading, terminate */
2256 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2257 __func__, EV_SOCK_ARG(evcon->fd)));
2258 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2260 } else if (res == MORE_DATA_EXPECTED) {
2261 /* Need more header lines */
2265 evcon->state = EVCON_READING_HEADERS;
2266 evhttp_read_header(evcon, req);
2270 evhttp_read_header(struct evhttp_connection *evcon,
2271 struct evhttp_request *req)
2273 enum message_read_status res;
2274 evutil_socket_t fd = evcon->fd;
2276 res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2277 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2278 /* Error while reading, terminate */
2279 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2280 __func__, EV_SOCK_ARG(fd)));
2281 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2283 } else if (res == MORE_DATA_EXPECTED) {
2284 /* Need more header lines */
2288 /* Callback can shut down connection with negative return value */
2289 if (req->header_cb != NULL) {
2290 if ((*req->header_cb)(req, req->cb_arg) < 0) {
2291 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2296 /* Done reading headers, do the real work */
2297 switch (req->kind) {
2298 case EVHTTP_REQUEST:
2299 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2300 __func__, EV_SOCK_ARG(fd)));
2301 evhttp_get_body(evcon, req);
2302 /* note the request may have been freed in evhttp_get_body */
2305 case EVHTTP_RESPONSE:
2306 /* Start over if we got a 100 Continue response. */
2307 if (req->response_code == 100) {
2308 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
2309 evbuffer_add_buffer(output, req->output_buffer);
2310 evhttp_start_write_(evcon);
2313 if (!evhttp_response_needs_body(req)) {
2314 event_debug(("%s: skipping body for code %d\n",
2315 __func__, req->response_code));
2316 evhttp_connection_done(evcon);
2318 event_debug(("%s: start of read body for %s on "
2320 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2321 evhttp_get_body(evcon, req);
2322 /* note the request may have been freed in
2323 * evhttp_get_body */
2328 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2330 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2333 /* request may have been freed above */
2337 * Creates a TCP connection to the specified port and executes a callback
2338 * when finished. Failure or success is indicate by the passed connection
2341 * Although this interface accepts a hostname, it is intended to take
2342 * only numeric hostnames so that non-blocking DNS resolution can
2346 struct evhttp_connection *
2347 evhttp_connection_new(const char *address, ev_uint16_t port)
2349 return (evhttp_connection_base_new(NULL, NULL, address, port));
2352 struct evhttp_connection *
2353 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2354 const char *address, ev_uint16_t port)
2356 struct evhttp_connection *evcon = NULL;
2358 event_debug(("Attempting connection to %s:%d\n", address, port));
2360 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2361 event_warn("%s: calloc failed", __func__);
2368 evcon->max_headers_size = EV_SIZE_MAX;
2369 evcon->max_body_size = EV_SIZE_MAX;
2371 evutil_timerclear(&evcon->timeout);
2372 evcon->retry_cnt = evcon->retry_max = 0;
2374 if ((evcon->address = mm_strdup(address)) == NULL) {
2375 event_warn("%s: strdup failed", __func__);
2380 if (!(bev = bufferevent_socket_new(base, -1, 0))) {
2381 event_warn("%s: bufferevent_socket_new failed", __func__);
2386 bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2389 evcon->state = EVCON_DISCONNECTED;
2390 TAILQ_INIT(&evcon->requests);
2392 evcon->initial_retry_timeout.tv_sec = 2;
2393 evcon->initial_retry_timeout.tv_usec = 0;
2397 if (bufferevent_get_base(bev) != base)
2398 bufferevent_base_set(base, evcon->bufev);
2401 event_deferred_cb_init_(
2402 &evcon->read_more_deferred_cb,
2403 bufferevent_get_priority(bev),
2404 evhttp_deferred_read_cb, evcon);
2406 evcon->dns_base = dnsbase;
2407 evcon->ai_family = AF_UNSPEC;
2413 evhttp_connection_free(evcon);
2417 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2419 return evcon->bufev;
2423 evhttp_connection_get_server(struct evhttp_connection *evcon)
2425 return evcon->http_server;
2428 struct evhttp_connection *
2429 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2430 const char *address, ev_uint16_t port)
2432 return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2435 void evhttp_connection_set_family(struct evhttp_connection *evcon,
2438 evcon->ai_family = family;
2441 int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2444 int avail_flags = 0;
2445 avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2446 avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2448 if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2450 evcon->flags &= ~avail_flags;
2452 evcon->flags |= flags;
2458 evhttp_connection_set_base(struct evhttp_connection *evcon,
2459 struct event_base *base)
2461 EVUTIL_ASSERT(evcon->base == NULL);
2462 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2464 bufferevent_base_set(base, evcon->bufev);
2468 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2469 int timeout_in_secs)
2471 if (timeout_in_secs == -1)
2472 evhttp_connection_set_timeout_tv(evcon, NULL);
2475 tv.tv_sec = timeout_in_secs;
2477 evhttp_connection_set_timeout_tv(evcon, &tv);
2482 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2483 const struct timeval* tv)
2486 evcon->timeout = *tv;
2487 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
2489 const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 };
2490 const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 };
2491 evutil_timerclear(&evcon->timeout);
2492 bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv);
2497 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2498 const struct timeval *tv)
2501 evcon->initial_retry_timeout = *tv;
2503 evutil_timerclear(&evcon->initial_retry_timeout);
2504 evcon->initial_retry_timeout.tv_sec = 2;
2509 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2512 evcon->retry_max = retry_max;
2516 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2517 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2519 evcon->closecb = cb;
2520 evcon->closecb_arg = cbarg;
2524 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2525 char **address, ev_uint16_t *port)
2527 *address = evcon->address;
2528 *port = evcon->port;
2531 const struct sockaddr*
2532 evhttp_connection_get_addr(struct evhttp_connection *evcon)
2534 return bufferevent_socket_get_conn_address_(evcon->bufev);
2538 evhttp_connection_connect_(struct evhttp_connection *evcon)
2540 int old_state = evcon->state;
2541 const char *address = evcon->address;
2542 const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
2545 if (evcon->state == EVCON_CONNECTING)
2548 evhttp_connection_reset_(evcon);
2550 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2551 evcon->flags |= EVHTTP_CON_OUTGOING;
2553 if (evcon->bind_address || evcon->bind_port) {
2554 evcon->fd = bind_socket(
2555 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2556 if (evcon->fd == -1) {
2557 event_debug(("%s: failed to bind to \"%s\"",
2558 __func__, evcon->bind_address));
2562 if (bufferevent_setfd(evcon->bufev, evcon->fd))
2565 if (bufferevent_setfd(evcon->bufev, -1))
2569 /* Set up a callback for successful connection setup */
2570 bufferevent_setcb(evcon->bufev,
2571 NULL /* evhttp_read_cb */,
2572 NULL /* evhttp_write_cb */,
2573 evhttp_connection_cb,
2575 if (!evutil_timerisset(&evcon->timeout)) {
2576 const struct timeval conn_tv = { HTTP_CONNECT_TIMEOUT, 0 };
2577 bufferevent_set_timeouts(evcon->bufev, &conn_tv, &conn_tv);
2579 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
2581 /* make sure that we get a write callback */
2582 if (bufferevent_enable(evcon->bufev, EV_WRITE))
2585 evcon->state = EVCON_CONNECTING;
2587 if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
2589 (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
2590 int socklen = sizeof(struct sockaddr_in);
2591 if (sa->sa_family == AF_INET6) {
2592 socklen = sizeof(struct sockaddr_in6);
2594 ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
2596 ret = bufferevent_socket_connect_hostname(evcon->bufev,
2597 evcon->dns_base, evcon->ai_family, address, evcon->port);
2601 evcon->state = old_state;
2602 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2603 __func__, evcon->address);
2604 /* some operating systems return ECONNREFUSED immediately
2605 * when connecting to a local address. the cleanup is going
2606 * to reschedule this function call.
2608 evhttp_connection_cb_cleanup(evcon);
2616 * Starts an HTTP request on the provided evhttp_connection object.
2617 * If the connection object is not connected to the web server already,
2618 * this will start the connection.
2622 evhttp_make_request(struct evhttp_connection *evcon,
2623 struct evhttp_request *req,
2624 enum evhttp_cmd_type type, const char *uri)
2626 /* We are making a request */
2627 req->kind = EVHTTP_REQUEST;
2629 if (req->uri != NULL)
2631 if ((req->uri = mm_strdup(uri)) == NULL) {
2632 event_warn("%s: strdup", __func__);
2633 evhttp_request_free_auto(req);
2637 /* Set the protocol version if it is not supplied */
2638 if (!req->major && !req->minor) {
2643 EVUTIL_ASSERT(req->evcon == NULL);
2645 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2647 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2649 /* We do not want to conflict with retry_ev */
2650 if (evcon->retry_cnt)
2653 /* If the connection object is not connected; make it so */
2654 if (!evhttp_connected(evcon)) {
2655 int res = evhttp_connection_connect_(evcon);
2656 /* evhttp_connection_fail_(), which is called through
2657 * evhttp_connection_connect_(), assumes that req lies in
2658 * evcon->requests. Thus, enqueue the request in advance and
2659 * remove it in the error case. */
2661 TAILQ_REMOVE(&evcon->requests, req, next);
2667 * If it's connected already and we are the first in the queue,
2668 * then we can dispatch this request immediately. Otherwise, it
2669 * will be dispatched once the pending requests are completed.
2671 if (TAILQ_FIRST(&evcon->requests) == req)
2672 evhttp_request_dispatch(evcon);
2678 evhttp_cancel_request(struct evhttp_request *req)
2680 struct evhttp_connection *evcon = req->evcon;
2681 if (evcon != NULL) {
2682 /* We need to remove it from the connection */
2683 if (TAILQ_FIRST(&evcon->requests) == req) {
2684 /* it's currently being worked on, so reset
2687 evhttp_connection_fail_(evcon,
2688 EVREQ_HTTP_REQUEST_CANCEL);
2690 /* connection fail freed the request */
2693 /* otherwise, we can just remove it from the
2696 TAILQ_REMOVE(&evcon->requests, req, next);
2700 evhttp_request_free_auto(req);
2704 * Reads data from file descriptor into request structure
2705 * Request structure needs to be set up correctly.
2709 evhttp_start_read_(struct evhttp_connection *evcon)
2711 bufferevent_disable(evcon->bufev, EV_WRITE);
2712 bufferevent_enable(evcon->bufev, EV_READ);
2714 evcon->state = EVCON_READING_FIRSTLINE;
2715 /* Reset the bufferevent callbacks */
2716 bufferevent_setcb(evcon->bufev,
2722 /* If there's still data pending, process it next time through the
2723 * loop. Don't do it now; that could get recusive. */
2724 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2725 event_deferred_cb_schedule_(get_deferred_queue(evcon),
2726 &evcon->read_more_deferred_cb);
2731 evhttp_start_write_(struct evhttp_connection *evcon)
2733 bufferevent_disable(evcon->bufev, EV_WRITE);
2734 bufferevent_enable(evcon->bufev, EV_READ);
2736 evcon->state = EVCON_WRITING;
2737 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
2741 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2744 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2745 TAILQ_REMOVE(&evcon->requests, req, next);
2747 if (req->on_complete_cb != NULL) {
2748 req->on_complete_cb(req, req->on_complete_cb_arg);
2752 (REQ_VERSION_BEFORE(req, 1, 1) &&
2753 !evhttp_is_connection_keepalive(req->input_headers)) ||
2754 evhttp_is_request_connection_close(req);
2756 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2757 evhttp_request_free(req);
2760 evhttp_connection_free(evcon);
2764 /* we have a persistent connection; try to accept another request. */
2765 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2766 evhttp_connection_free(evcon);
2771 * Returns an error page.
2775 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2778 #define ERR_FORMAT "<HTML><HEAD>\n" \
2779 "<TITLE>%d %s</TITLE>\n" \
2784 struct evbuffer *buf = evbuffer_new();
2786 /* if we cannot allocate memory; we just drop the connection */
2787 evhttp_connection_free(req->evcon);
2790 if (reason == NULL) {
2791 reason = evhttp_response_phrase_internal(error);
2794 evhttp_response_code_(req, error, reason);
2796 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2798 evhttp_send_page_(req, buf);
2804 /* Requires that headers and response code are already set up */
2807 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2809 struct evhttp_connection *evcon = req->evcon;
2811 if (evcon == NULL) {
2812 evhttp_request_free(req);
2816 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2818 /* we expect no more calls form the user on this request */
2821 /* xxx: not sure if we really should expose the data buffer this way */
2822 if (databuf != NULL)
2823 evbuffer_add_buffer(req->output_buffer, databuf);
2825 /* Adds headers to the response */
2826 evhttp_make_header(evcon, req);
2828 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2832 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2833 struct evbuffer *databuf)
2835 evhttp_response_code_(req, code, reason);
2837 evhttp_send(req, databuf);
2841 evhttp_send_reply_start(struct evhttp_request *req, int code,
2844 evhttp_response_code_(req, code, reason);
2846 if (req->evcon == NULL)
2849 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2850 REQ_VERSION_ATLEAST(req, 1, 1) &&
2851 evhttp_response_needs_body(req)) {
2853 * prefer HTTP/1.1 chunked encoding to closing the connection;
2854 * note RFC 2616 section 4.4 forbids it with Content-Length:
2855 * and it's not necessary then anyway.
2857 evhttp_add_header(req->output_headers, "Transfer-Encoding",
2863 evhttp_make_header(req->evcon, req);
2864 evhttp_write_buffer(req->evcon, NULL, NULL);
2868 evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
2869 void (*cb)(struct evhttp_connection *, void *), void *arg)
2871 struct evhttp_connection *evcon = req->evcon;
2872 struct evbuffer *output;
2877 output = bufferevent_get_output(evcon->bufev);
2879 if (evbuffer_get_length(databuf) == 0)
2881 if (!evhttp_response_needs_body(req))
2884 evbuffer_add_printf(output, "%x\r\n",
2885 (unsigned)evbuffer_get_length(databuf));
2887 evbuffer_add_buffer(output, databuf);
2889 evbuffer_add(output, "\r\n", 2);
2891 evhttp_write_buffer(evcon, cb, arg);
2895 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
2897 evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
2900 evhttp_send_reply_end(struct evhttp_request *req)
2902 struct evhttp_connection *evcon = req->evcon;
2903 struct evbuffer *output;
2905 if (evcon == NULL) {
2906 evhttp_request_free(req);
2910 output = bufferevent_get_output(evcon->bufev);
2912 /* we expect no more calls form the user on this request */
2916 evbuffer_add(output, "0\r\n\r\n", 5);
2917 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2919 } else if (evbuffer_get_length(output) == 0) {
2920 /* let the connection know that we are done with the request */
2921 evhttp_send_done(evcon, NULL);
2923 /* make the callback execute after all data has been written */
2924 evcon->cb = evhttp_send_done;
2925 evcon->cb_arg = NULL;
2929 static const char *informational_phrases[] = {
2930 /* 100 */ "Continue",
2931 /* 101 */ "Switching Protocols"
2934 static const char *success_phrases[] = {
2936 /* 201 */ "Created",
2937 /* 202 */ "Accepted",
2938 /* 203 */ "Non-Authoritative Information",
2939 /* 204 */ "No Content",
2940 /* 205 */ "Reset Content",
2941 /* 206 */ "Partial Content"
2944 static const char *redirection_phrases[] = {
2945 /* 300 */ "Multiple Choices",
2946 /* 301 */ "Moved Permanently",
2948 /* 303 */ "See Other",
2949 /* 304 */ "Not Modified",
2950 /* 305 */ "Use Proxy",
2951 /* 307 */ "Temporary Redirect"
2954 static const char *client_error_phrases[] = {
2955 /* 400 */ "Bad Request",
2956 /* 401 */ "Unauthorized",
2957 /* 402 */ "Payment Required",
2958 /* 403 */ "Forbidden",
2959 /* 404 */ "Not Found",
2960 /* 405 */ "Method Not Allowed",
2961 /* 406 */ "Not Acceptable",
2962 /* 407 */ "Proxy Authentication Required",
2963 /* 408 */ "Request Time-out",
2964 /* 409 */ "Conflict",
2966 /* 411 */ "Length Required",
2967 /* 412 */ "Precondition Failed",
2968 /* 413 */ "Request Entity Too Large",
2969 /* 414 */ "Request-URI Too Large",
2970 /* 415 */ "Unsupported Media Type",
2971 /* 416 */ "Requested range not satisfiable",
2972 /* 417 */ "Expectation Failed"
2975 static const char *server_error_phrases[] = {
2976 /* 500 */ "Internal Server Error",
2977 /* 501 */ "Not Implemented",
2978 /* 502 */ "Bad Gateway",
2979 /* 503 */ "Service Unavailable",
2980 /* 504 */ "Gateway Time-out",
2981 /* 505 */ "HTTP Version not supported"
2984 struct response_class {
2986 size_t num_responses;
2987 const char **responses;
2991 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
2994 static const struct response_class response_classes[] = {
2995 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
2996 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
2997 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
2998 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
2999 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
3003 evhttp_response_phrase_internal(int code)
3005 int klass = code / 100 - 1;
3006 int subcode = code % 100;
3008 /* Unknown class - can't do any better here */
3009 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
3010 return "Unknown Status Class";
3012 /* Unknown sub-code, return class name at least */
3013 if (subcode >= (int) response_classes[klass].num_responses)
3014 return response_classes[klass].name;
3016 return response_classes[klass].responses[subcode];
3020 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
3022 req->kind = EVHTTP_RESPONSE;
3023 req->response_code = code;
3024 if (req->response_code_line != NULL)
3025 mm_free(req->response_code_line);
3027 reason = evhttp_response_phrase_internal(code);
3028 req->response_code_line = mm_strdup(reason);
3029 if (req->response_code_line == NULL) {
3030 event_warn("%s: strdup", __func__);
3031 /* XXX what else can we do? */
3036 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
3038 if (!req->major || !req->minor) {
3043 if (req->kind != EVHTTP_RESPONSE)
3044 evhttp_response_code_(req, 200, "OK");
3046 evhttp_clear_headers(req->output_headers);
3047 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
3048 evhttp_add_header(req->output_headers, "Connection", "close");
3050 evhttp_send(req, databuf);
3053 static const char uri_chars[256] = {
3055 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3056 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3057 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
3058 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
3060 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3061 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
3062 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3063 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
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, 0, 0, 0,
3068 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3070 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3071 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3072 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3073 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3076 #define CHAR_IS_UNRESERVED(c) \
3077 (uri_chars[(unsigned char)(c)])
3080 * Helper functions to encode/decode a string for inclusion in a URI.
3081 * The returned string must be freed by the caller.
3084 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3086 struct evbuffer *buf = evbuffer_new();
3087 const char *p, *end;
3088 char *result = NULL;
3095 if (uri + len < uri) {
3101 size_t slen = strlen(uri);
3103 if (slen >= EV_SSIZE_MAX) {
3104 /* we don't want to mix signed and unsigned */
3108 if (uri + slen < uri) {
3115 for (p = uri; p < end; p++) {
3116 if (CHAR_IS_UNRESERVED(*p)) {
3117 evbuffer_add(buf, p, 1);
3118 } else if (*p == ' ' && space_as_plus) {
3119 evbuffer_add(buf, "+", 1);
3121 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3125 evbuffer_add(buf, "", 1); /* NUL-terminator. */
3126 result = mm_malloc(evbuffer_get_length(buf));
3129 evbuffer_remove(buf, result, evbuffer_get_length(buf));
3138 evhttp_encode_uri(const char *str)
3140 return evhttp_uriencode(str, -1, 0);
3144 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
3145 * If -1, when true we transform plus to space only after we've seen
3146 * a ?. -1 is deprecated.
3147 * @return the number of bytes written to 'ret'.
3150 evhttp_decode_uri_internal(
3151 const char *uri, size_t length, char *ret, int decode_plus_ctl)
3155 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3158 for (i = j = 0; i < length; i++) {
3161 if (decode_plus_ctl < 0)
3163 } else if (c == '+' && decode_plus) {
3165 } else if ((i + 2) < length && c == '%' &&
3166 EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3171 c = (char)strtol(tmp, NULL, 16);
3183 evhttp_decode_uri(const char *uri)
3187 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3188 event_warn("%s: malloc(%lu)", __func__,
3189 (unsigned long)(strlen(uri) + 1));
3193 evhttp_decode_uri_internal(uri, strlen(uri),
3194 ret, -1 /*always_decode_plus*/);
3200 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3205 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3206 event_warn("%s: malloc(%lu)", __func__,
3207 (unsigned long)(strlen(uri) + 1));
3211 n = evhttp_decode_uri_internal(uri, strlen(uri),
3212 ret, !!decode_plus/*always_decode_plus*/);
3215 EVUTIL_ASSERT(n >= 0);
3216 *size_out = (size_t)n;
3223 * Helper function to parse out arguments in a query.
3224 * The arguments are separated by key and value.
3228 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3229 int is_whole_uri, unsigned flags)
3234 const char *query_part;
3236 struct evhttp_uri *uri=NULL;
3238 TAILQ_INIT(headers);
3241 uri = evhttp_uri_parse(str);
3244 query_part = evhttp_uri_get_query(uri);
3249 /* No arguments - we are done */
3250 if (!query_part || !strlen(query_part)) {
3255 if ((line = mm_strdup(query_part)) == NULL) {
3256 event_warn("%s: strdup", __func__);
3260 p = argument = line;
3261 while (p != NULL && *p != '\0') {
3262 char *key, *value, *decoded_value;
3263 argument = strsep(&p, "&");
3266 key = strsep(&value, "=");
3267 if (flags & EVHTTP_URI_QUERY_NONCONFORMANT) {
3273 if (value == NULL || *key == '\0')
3277 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3278 event_warn("%s: mm_malloc", __func__);
3281 evhttp_decode_uri_internal(value, strlen(value),
3282 decoded_value, 1 /*always_decode_plus*/);
3283 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3284 if (flags & EVHTTP_URI_QUERY_LAST_VAL)
3285 evhttp_remove_header(headers, key);
3286 evhttp_add_header_internal(headers, key, decoded_value);
3287 mm_free(decoded_value);
3293 evhttp_clear_headers(headers);
3298 evhttp_uri_free(uri);
3303 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3305 return evhttp_parse_query_impl(uri, headers, 1, 0);
3308 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3310 return evhttp_parse_query_impl(uri, headers, 0, 0);
3313 evhttp_parse_query_str_flags(const char *uri, struct evkeyvalq *headers, unsigned flags)
3315 return evhttp_parse_query_impl(uri, headers, 0, flags);
3318 static struct evhttp_cb *
3319 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3321 struct evhttp_cb *cb;
3326 /* Test for different URLs */
3327 path = evhttp_uri_get_path(req->uri_elems);
3328 offset = strlen(path);
3329 if ((translated = mm_malloc(offset + 1)) == NULL)
3331 evhttp_decode_uri_internal(path, offset, translated,
3332 0 /* decode_plus */);
3334 TAILQ_FOREACH(cb, callbacks, next) {
3335 if (!strcmp(cb->what, translated)) {
3336 mm_free(translated);
3341 mm_free(translated);
3347 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3352 switch (c = *pattern++) {
3354 return *name == '\0';
3357 while (*name != '\0') {
3358 if (prefix_suffix_match(pattern, name,
3367 EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3377 Search the vhost hierarchy beginning with http for a server alias
3378 matching hostname. If a match is found, and outhttp is non-null,
3379 outhttp is set to the matching http object and 1 is returned.
3383 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3384 const char *hostname)
3386 struct evhttp_server_alias *alias;
3387 struct evhttp *vhost;
3389 TAILQ_FOREACH(alias, &http->aliases, next) {
3390 /* XXX Do we need to handle IP addresses? */
3391 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3398 /* XXX It might be good to avoid recursion here, but I don't
3399 see a way to do that w/o a list. */
3400 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3401 if (evhttp_find_alias(vhost, outhttp, hostname))
3409 Attempts to find the best http object to handle a request for a hostname.
3410 All aliases for the root http object and vhosts are searched for an exact
3411 match. Then, the vhost hierarchy is traversed again for a matching
3414 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3415 is set with the best matching http object. If there are no matches, the
3416 root http object is stored in outhttp and 0 is returned.
3420 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3421 const char *hostname)
3423 struct evhttp *vhost;
3424 struct evhttp *oldhttp;
3425 int match_found = 0;
3427 if (evhttp_find_alias(http, outhttp, hostname))
3432 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3433 if (prefix_suffix_match(vhost->vhost_pattern,
3434 hostname, 1 /* ignorecase */)) {
3440 } while (oldhttp != http);
3449 evhttp_handle_request(struct evhttp_request *req, void *arg)
3451 struct evhttp *http = arg;
3452 struct evhttp_cb *cb = NULL;
3453 const char *hostname;
3455 /* we have a new request on which the user needs to take action */
3458 bufferevent_disable(req->evcon->bufev, EV_READ);
3460 if (req->type == 0 || req->uri == NULL) {
3461 evhttp_send_error(req, req->response_code, NULL);
3465 if ((http->allowed_methods & req->type) == 0) {
3466 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3467 (unsigned)req->type, (unsigned)http->allowed_methods));
3468 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3472 /* handle potential virtual hosts */
3473 hostname = evhttp_request_get_host(req);
3474 if (hostname != NULL) {
3475 evhttp_find_vhost(http, &http, hostname);
3478 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3479 (*cb->cb)(req, cb->cbarg);
3483 /* Generic call back */
3485 (*http->gencb)(req, http->gencbarg);
3488 /* We need to send a 404 here */
3489 #define ERR_FORMAT "<html><head>" \
3490 "<title>404 Not Found</title>" \
3492 "<h1>Not Found</h1>" \
3493 "<p>The requested URL %s was not found on this server.</p>"\
3497 struct evbuffer *buf;
3499 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3500 evhttp_connection_free(req->evcon);
3504 if ((buf = evbuffer_new()) == NULL) {
3505 mm_free(escaped_html);
3506 evhttp_connection_free(req->evcon);
3510 evhttp_response_code_(req, HTTP_NOTFOUND, "Not Found");
3512 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3514 mm_free(escaped_html);
3516 evhttp_send_page_(req, buf);
3523 /* Listener callback when a connection arrives at a server. */
3525 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3527 struct evhttp *http = arg;
3529 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3533 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3535 struct evhttp_bound_socket *bound =
3536 evhttp_bind_socket_with_handle(http, address, port);
3542 struct evhttp_bound_socket *
3543 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3546 struct evhttp_bound_socket *bound;
3548 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3551 if (listen(fd, 128) == -1) {
3552 event_sock_warn(fd, "%s: listen", __func__);
3553 evutil_closesocket(fd);
3557 bound = evhttp_accept_socket_with_handle(http, fd);
3559 if (bound != NULL) {
3560 event_debug(("Bound to port %d - Awaiting connections ... ",
3569 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3571 struct evhttp_bound_socket *bound =
3572 evhttp_accept_socket_with_handle(http, fd);
3579 evhttp_foreach_bound_socket(struct evhttp *http,
3580 evhttp_bound_socket_foreach_fn *function,
3583 struct evhttp_bound_socket *bound;
3585 TAILQ_FOREACH(bound, &http->sockets, next)
3586 function(bound, argument);
3589 struct evhttp_bound_socket *
3590 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3592 struct evhttp_bound_socket *bound;
3593 struct evconnlistener *listener;
3595 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3597 listener = evconnlistener_new(http->base, NULL, NULL,
3599 0, /* Backlog is '0' because we already said 'listen' */
3604 bound = evhttp_bind_listener(http, listener);
3606 evconnlistener_free(listener);
3612 struct evhttp_bound_socket *
3613 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3615 struct evhttp_bound_socket *bound;
3617 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3621 bound->listener = listener;
3622 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3624 evconnlistener_set_cb(listener, accept_socket_cb, http);
3629 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3631 return evconnlistener_get_fd(bound->listener);
3634 struct evconnlistener *
3635 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3637 return bound->listener;
3641 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3643 TAILQ_REMOVE(&http->sockets, bound, next);
3644 evconnlistener_free(bound->listener);
3648 static struct evhttp*
3649 evhttp_new_object(void)
3651 struct evhttp *http = NULL;
3653 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3654 event_warn("%s: calloc", __func__);
3658 evutil_timerclear(&http->timeout);
3659 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3660 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3661 evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
3662 evhttp_set_allowed_methods(http,
3669 TAILQ_INIT(&http->sockets);
3670 TAILQ_INIT(&http->callbacks);
3671 TAILQ_INIT(&http->connections);
3672 TAILQ_INIT(&http->virtualhosts);
3673 TAILQ_INIT(&http->aliases);
3679 evhttp_new(struct event_base *base)
3681 struct evhttp *http = NULL;
3683 http = evhttp_new_object();
3692 * Start a web server on the specified address and port.
3696 evhttp_start(const char *address, ev_uint16_t port)
3698 struct evhttp *http = NULL;
3700 http = evhttp_new_object();
3703 if (evhttp_bind_socket(http, address, port) == -1) {
3712 evhttp_free(struct evhttp* http)
3714 struct evhttp_cb *http_cb;
3715 struct evhttp_connection *evcon;
3716 struct evhttp_bound_socket *bound;
3717 struct evhttp* vhost;
3718 struct evhttp_server_alias *alias;
3720 /* Remove the accepting part */
3721 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3722 TAILQ_REMOVE(&http->sockets, bound, next);
3724 evconnlistener_free(bound->listener);
3729 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3730 /* evhttp_connection_free removes the connection */
3731 evhttp_connection_free(evcon);
3734 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3735 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3736 mm_free(http_cb->what);
3740 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3741 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3746 if (http->vhost_pattern != NULL)
3747 mm_free(http->vhost_pattern);
3749 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3750 TAILQ_REMOVE(&http->aliases, alias, next);
3751 mm_free(alias->alias);
3759 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3760 struct evhttp* vhost)
3762 /* a vhost can only be a vhost once and should not have bound sockets */
3763 if (vhost->vhost_pattern != NULL ||
3764 TAILQ_FIRST(&vhost->sockets) != NULL)
3767 vhost->vhost_pattern = mm_strdup(pattern);
3768 if (vhost->vhost_pattern == NULL)
3771 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3777 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3779 if (vhost->vhost_pattern == NULL)
3782 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3784 mm_free(vhost->vhost_pattern);
3785 vhost->vhost_pattern = NULL;
3791 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3793 struct evhttp_server_alias *evalias;
3795 evalias = mm_calloc(1, sizeof(*evalias));
3799 evalias->alias = mm_strdup(alias);
3800 if (!evalias->alias) {
3805 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3811 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3813 struct evhttp_server_alias *evalias;
3815 TAILQ_FOREACH(evalias, &http->aliases, next) {
3816 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3817 TAILQ_REMOVE(&http->aliases, evalias, next);
3818 mm_free(evalias->alias);
3828 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
3830 if (timeout_in_secs == -1) {
3831 evhttp_set_timeout_tv(http, NULL);
3834 tv.tv_sec = timeout_in_secs;
3836 evhttp_set_timeout_tv(http, &tv);
3841 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
3844 http->timeout = *tv;
3846 evutil_timerclear(&http->timeout);
3850 int evhttp_set_flags(struct evhttp *http, int flags)
3852 int avail_flags = 0;
3853 avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
3855 if (flags & ~avail_flags)
3857 http->flags &= ~avail_flags;
3859 http->flags |= flags;
3865 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
3867 if (max_headers_size < 0)
3868 http->default_max_headers_size = EV_SIZE_MAX;
3870 http->default_max_headers_size = max_headers_size;
3874 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
3876 if (max_body_size < 0)
3877 http->default_max_body_size = EV_UINT64_MAX;
3879 http->default_max_body_size = max_body_size;
3883 evhttp_set_default_content_type(struct evhttp *http,
3884 const char *content_type) {
3885 http->default_content_type = content_type;
3889 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
3891 http->allowed_methods = methods;
3895 evhttp_set_cb(struct evhttp *http, const char *uri,
3896 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3898 struct evhttp_cb *http_cb;
3900 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3901 if (strcmp(http_cb->what, uri) == 0)
3905 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
3906 event_warn("%s: calloc", __func__);
3910 http_cb->what = mm_strdup(uri);
3911 if (http_cb->what == NULL) {
3912 event_warn("%s: strdup", __func__);
3917 http_cb->cbarg = cbarg;
3919 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
3925 evhttp_del_cb(struct evhttp *http, const char *uri)
3927 struct evhttp_cb *http_cb;
3929 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3930 if (strcmp(http_cb->what, uri) == 0)
3933 if (http_cb == NULL)
3936 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3937 mm_free(http_cb->what);
3944 evhttp_set_gencb(struct evhttp *http,
3945 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3948 http->gencbarg = cbarg;
3952 evhttp_set_bevcb(struct evhttp *http,
3953 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
3956 http->bevcbarg = cbarg;
3960 evhttp_set_newreqcb(struct evhttp *http,
3961 int (*cb)(struct evhttp_request *, void *), void *cbarg)
3963 http->newreqcb = cb;
3964 http->newreqcbarg = cbarg;
3968 * Request related functions
3971 struct evhttp_request *
3972 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
3974 struct evhttp_request *req = NULL;
3976 /* Allocate request structure */
3977 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
3978 event_warn("%s: calloc", __func__);
3982 req->headers_size = 0;
3985 req->kind = EVHTTP_RESPONSE;
3986 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3987 if (req->input_headers == NULL) {
3988 event_warn("%s: calloc", __func__);
3991 TAILQ_INIT(req->input_headers);
3993 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3994 if (req->output_headers == NULL) {
3995 event_warn("%s: calloc", __func__);
3998 TAILQ_INIT(req->output_headers);
4000 if ((req->input_buffer = evbuffer_new()) == NULL) {
4001 event_warn("%s: evbuffer_new", __func__);
4005 if ((req->output_buffer = evbuffer_new()) == NULL) {
4006 event_warn("%s: evbuffer_new", __func__);
4017 evhttp_request_free(req);
4022 evhttp_request_free(struct evhttp_request *req)
4024 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
4025 req->flags |= EVHTTP_REQ_NEEDS_FREE;
4029 if (req->remote_host != NULL)
4030 mm_free(req->remote_host);
4031 if (req->uri != NULL)
4033 if (req->uri_elems != NULL)
4034 evhttp_uri_free(req->uri_elems);
4035 if (req->response_code_line != NULL)
4036 mm_free(req->response_code_line);
4037 if (req->host_cache != NULL)
4038 mm_free(req->host_cache);
4040 evhttp_clear_headers(req->input_headers);
4041 mm_free(req->input_headers);
4043 evhttp_clear_headers(req->output_headers);
4044 mm_free(req->output_headers);
4046 if (req->input_buffer != NULL)
4047 evbuffer_free(req->input_buffer);
4049 if (req->output_buffer != NULL)
4050 evbuffer_free(req->output_buffer);
4056 evhttp_request_own(struct evhttp_request *req)
4058 req->flags |= EVHTTP_USER_OWNED;
4062 evhttp_request_is_owned(struct evhttp_request *req)
4064 return (req->flags & EVHTTP_USER_OWNED) != 0;
4067 struct evhttp_connection *
4068 evhttp_request_get_connection(struct evhttp_request *req)
4074 evhttp_connection_get_base(struct evhttp_connection *conn)
4080 evhttp_request_set_chunked_cb(struct evhttp_request *req,
4081 void (*cb)(struct evhttp_request *, void *))
4087 evhttp_request_set_header_cb(struct evhttp_request *req,
4088 int (*cb)(struct evhttp_request *, void *))
4090 req->header_cb = cb;
4094 evhttp_request_set_error_cb(struct evhttp_request *req,
4095 void (*cb)(enum evhttp_request_error, void *))
4101 evhttp_request_set_on_complete_cb(struct evhttp_request *req,
4102 void (*cb)(struct evhttp_request *, void *), void *cb_arg)
4104 req->on_complete_cb = cb;
4105 req->on_complete_cb_arg = cb_arg;
4109 * Allows for inspection of the request URI
4113 evhttp_request_get_uri(const struct evhttp_request *req) {
4114 if (req->uri == NULL)
4115 event_debug(("%s: request %p has no uri\n", __func__, req));
4119 const struct evhttp_uri *
4120 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4121 if (req->uri_elems == NULL)
4122 event_debug(("%s: request %p has no uri elems\n",
4124 return (req->uri_elems);
4128 evhttp_request_get_host(struct evhttp_request *req)
4130 const char *host = NULL;
4132 if (req->host_cache)
4133 return req->host_cache;
4136 host = evhttp_uri_get_host(req->uri_elems);
4137 if (!host && req->input_headers) {
4141 host = evhttp_find_header(req->input_headers, "Host");
4142 /* The Host: header may include a port. Remove it here
4143 to be consistent with uri_elems case above. */
4145 p = host + strlen(host) - 1;
4146 while (p > host && EVUTIL_ISDIGIT_(*p))
4148 if (p > host && *p == ':') {
4150 req->host_cache = mm_malloc(len + 1);
4151 if (!req->host_cache) {
4152 event_warn("%s: malloc", __func__);
4155 memcpy(req->host_cache, host, len);
4156 req->host_cache[len] = '\0';
4157 host = req->host_cache;
4165 enum evhttp_cmd_type
4166 evhttp_request_get_command(const struct evhttp_request *req) {
4171 evhttp_request_get_response_code(const struct evhttp_request *req)
4173 return req->response_code;
4177 evhttp_request_get_response_code_line(const struct evhttp_request *req)
4179 return req->response_code_line;
4182 /** Returns the input headers */
4183 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4185 return (req->input_headers);
4188 /** Returns the output headers */
4189 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4191 return (req->output_headers);
4194 /** Returns the input buffer */
4195 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4197 return (req->input_buffer);
4200 /** Returns the output buffer */
4201 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4203 return (req->output_buffer);
4208 * Takes a file descriptor to read a request from.
4209 * The callback is executed once the whole request has been read.
4212 static struct evhttp_connection*
4213 evhttp_get_request_connection(
4214 struct evhttp* http,
4215 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
4217 struct evhttp_connection *evcon;
4218 char *hostname = NULL, *portname = NULL;
4219 struct bufferevent* bev = NULL;
4221 name_from_addr(sa, salen, &hostname, &portname);
4222 if (hostname == NULL || portname == NULL) {
4223 if (hostname) mm_free(hostname);
4224 if (portname) mm_free(portname);
4228 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4229 __func__, hostname, portname, EV_SOCK_ARG(fd)));
4231 /* we need a connection object to put the http request on */
4232 if (http->bevcb != NULL) {
4233 bev = (*http->bevcb)(http->base, http->bevcbarg);
4235 evcon = evhttp_connection_base_bufferevent_new(
4236 http->base, NULL, bev, hostname, atoi(portname));
4242 evcon->max_headers_size = http->default_max_headers_size;
4243 evcon->max_body_size = http->default_max_body_size;
4244 if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4245 evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4247 evcon->flags |= EVHTTP_CON_INCOMING;
4248 evcon->state = EVCON_READING_FIRSTLINE;
4252 if (bufferevent_setfd(evcon->bufev, fd))
4254 if (bufferevent_enable(evcon->bufev, EV_READ))
4256 if (bufferevent_disable(evcon->bufev, EV_WRITE))
4258 bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
4263 evhttp_connection_free(evcon);
4268 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4270 struct evhttp *http = evcon->http_server;
4271 struct evhttp_request *req;
4272 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4275 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4276 event_warn("%s: strdup", __func__);
4277 evhttp_request_free(req);
4280 req->remote_port = evcon->port;
4282 req->evcon = evcon; /* the request ends up owning the connection */
4283 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4285 /* We did not present the request to the user yet, so treat it
4286 * as if the user was done with the request. This allows us
4287 * to free the request on a persistent connection if the
4288 * client drops it without sending a request.
4291 req->kind = EVHTTP_REQUEST;
4293 if (http->newreqcb && http->newreqcb(req, http->newreqcbarg) == -1) {
4294 evhttp_request_free(req);
4298 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4300 evhttp_start_read_(evcon);
4306 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4307 struct sockaddr *sa, ev_socklen_t salen)
4309 struct evhttp_connection *evcon;
4311 evcon = evhttp_get_request_connection(http, fd, sa, salen);
4312 if (evcon == NULL) {
4313 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4314 __func__, EV_SOCK_ARG(fd));
4315 evutil_closesocket(fd);
4319 /* the timeout can be used by the server to close idle connections */
4320 if (evutil_timerisset(&http->timeout))
4321 evhttp_connection_set_timeout_tv(evcon, &http->timeout);
4324 * if we want to accept more than one request on a connection,
4325 * we need to know which http server it belongs to.
4327 evcon->http_server = http;
4328 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4330 if (evhttp_associate_new_request_with_connection(evcon) == -1)
4331 evhttp_connection_free(evcon);
4336 * Network helper functions that we do not want to export to the rest of
4341 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4342 char **phost, char **pport)
4344 char ntop[NI_MAXHOST];
4345 char strport[NI_MAXSERV];
4348 #ifdef EVENT__HAVE_GETNAMEINFO
4349 ni_result = getnameinfo(sa, salen,
4350 ntop, sizeof(ntop), strport, sizeof(strport),
4351 NI_NUMERICHOST|NI_NUMERICSERV);
4353 if (ni_result != 0) {
4355 /* Windows doesn't have an EAI_SYSTEM. */
4356 if (ni_result == EAI_SYSTEM)
4357 event_err(1, "getnameinfo failed");
4360 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4364 ni_result = fake_getnameinfo(sa, salen,
4365 ntop, sizeof(ntop), strport, sizeof(strport),
4366 NI_NUMERICHOST|NI_NUMERICSERV);
4371 *phost = mm_strdup(ntop);
4372 *pport = mm_strdup(strport);
4375 /* Create a non-blocking socket and bind it */
4376 /* todo: rename this function */
4377 static evutil_socket_t
4378 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
4385 /* Create listen socket */
4386 fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
4387 SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
4389 event_sock_warn(-1, "socket");
4393 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
4396 if (evutil_make_listen_socket_reuseable(fd) < 0)
4401 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
4409 serrno = EVUTIL_SOCKET_ERROR();
4410 evutil_closesocket(fd);
4411 EVUTIL_SET_SOCKET_ERROR(serrno);
4415 static struct evutil_addrinfo *
4416 make_addrinfo(const char *address, ev_uint16_t port)
4418 struct evutil_addrinfo *ai = NULL;
4420 struct evutil_addrinfo hints;
4421 char strport[NI_MAXSERV];
4424 memset(&hints, 0, sizeof(hints));
4425 hints.ai_family = AF_UNSPEC;
4426 hints.ai_socktype = SOCK_STREAM;
4427 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
4428 * types we don't have an interface to connect to. */
4429 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
4430 evutil_snprintf(strport, sizeof(strport), "%d", port);
4431 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
4433 if (ai_result == EVUTIL_EAI_SYSTEM)
4434 event_warn("getaddrinfo");
4436 event_warnx("getaddrinfo: %s",
4437 evutil_gai_strerror(ai_result));
4444 static evutil_socket_t
4445 bind_socket(const char *address, ev_uint16_t port, int reuse)
4448 struct evutil_addrinfo *aitop = NULL;
4450 /* just create an unbound socket */
4451 if (address == NULL && port == 0)
4452 return bind_socket_ai(NULL, 0);
4454 aitop = make_addrinfo(address, port);
4459 fd = bind_socket_ai(aitop, reuse);
4461 evutil_freeaddrinfo(aitop);
4468 char *scheme; /* scheme; e.g http, ftp etc */
4469 char *userinfo; /* userinfo (typically username:pass), or NULL */
4470 char *host; /* hostname, IP address, or NULL */
4471 int port; /* port, or zero */
4472 char *path; /* path, or "". */
4473 char *query; /* query, or NULL */
4474 char *fragment; /* fragment or NULL */
4478 evhttp_uri_new(void)
4480 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
4487 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
4492 /* Return true if the string starting at s and ending immediately before eos
4493 * is a valid URI scheme according to RFC3986
4496 scheme_ok(const char *s, const char *eos)
4498 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4499 EVUTIL_ASSERT(eos >= s);
4502 if (!EVUTIL_ISALPHA_(*s))
4505 if (! EVUTIL_ISALNUM_(*s) &&
4506 *s != '+' && *s != '-' && *s != '.')
4512 #define SUBDELIMS "!$&'()*+,;="
4514 /* Return true iff [s..eos) is a valid userinfo */
4516 userinfo_ok(const char *s, const char *eos)
4519 if (CHAR_IS_UNRESERVED(*s) ||
4520 strchr(SUBDELIMS, *s) ||
4523 else if (*s == '%' && s+2 < eos &&
4524 EVUTIL_ISXDIGIT_(s[1]) &&
4525 EVUTIL_ISXDIGIT_(s[2]))
4534 regname_ok(const char *s, const char *eos)
4536 while (s && s<eos) {
4537 if (CHAR_IS_UNRESERVED(*s) ||
4538 strchr(SUBDELIMS, *s))
4540 else if (*s == '%' &&
4541 EVUTIL_ISXDIGIT_(s[1]) &&
4542 EVUTIL_ISXDIGIT_(s[2]))
4551 parse_port(const char *s, const char *eos)
4555 if (! EVUTIL_ISDIGIT_(*s))
4557 portnum = (portnum * 10) + (*s - '0');
4560 if (portnum > 65535)
4567 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4569 bracket_addr_ok(const char *s, const char *eos)
4571 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4574 /* IPvFuture, or junk.
4575 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4577 s += 2; /* skip [v */
4579 if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
4581 while (s < eos && *s != '.') {
4582 if (EVUTIL_ISXDIGIT_(*s))
4591 if (CHAR_IS_UNRESERVED(*s) ||
4592 strchr(SUBDELIMS, *s) ||
4602 ev_ssize_t n_chars = eos-s-2;
4603 struct in6_addr in6;
4604 if (n_chars >= 64) /* way too long */
4606 memcpy(buf, s+1, n_chars);
4608 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4613 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4618 uri->host = mm_strdup("");
4619 if (uri->host == NULL) {
4620 event_warn("%s: strdup", __func__);
4626 /* Optionally, we start with "userinfo@" */
4628 cp = strchr(s, '@');
4629 if (cp && cp < eos) {
4630 if (! userinfo_ok(s,cp))
4633 uri->userinfo = mm_strdup(s);
4634 if (uri->userinfo == NULL) {
4635 event_warn("%s: strdup", __func__);
4641 /* Optionally, we end with ":port" */
4642 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
4644 if (port >= cp && *port == ':') {
4645 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4648 else if ((uri->port = parse_port(port+1, eos))<0)
4652 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4653 * an IP-Literal, or a reg-name */
4654 EVUTIL_ASSERT(eos >= cp);
4655 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4656 /* IPv6address, IP-Literal, or junk. */
4657 if (! bracket_addr_ok(cp, eos))
4660 /* Make sure the host part is ok. */
4661 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4664 uri->host = mm_malloc(eos-cp+1);
4665 if (uri->host == NULL) {
4666 event_warn("%s: malloc", __func__);
4669 memcpy(uri->host, cp, eos-cp);
4670 uri->host[eos-cp] = '\0';
4676 end_of_authority(char *cp)
4679 if (*cp == '?' || *cp == '#' || *cp == '/')
4692 /* Return the character after the longest prefix of 'cp' that matches...
4693 * *pchar / "/" if allow_qchars is false, or
4694 * *(pchar / "/" / "?") if allow_qchars is true.
4697 end_of_path(char *cp, enum uri_part part, unsigned flags)
4699 if (flags & EVHTTP_URI_NONCONFORMANT) {
4700 /* If NONCONFORMANT:
4701 * Path is everything up to a # or ? or nul.
4702 * Query is everything up a # or nul
4703 * Fragment is everything up to a nul.
4707 while (*cp && *cp != '#' && *cp != '?')
4711 while (*cp && *cp != '#')
4722 if (CHAR_IS_UNRESERVED(*cp) ||
4723 strchr(SUBDELIMS, *cp) ||
4724 *cp == ':' || *cp == '@' || *cp == '/')
4726 else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
4727 EVUTIL_ISXDIGIT_(cp[2]))
4729 else if (*cp == '?' && part != PART_PATH)
4738 path_matches_noscheme(const char *cp)
4743 else if (*cp == '/')
4751 evhttp_uri_parse(const char *source_uri)
4753 return evhttp_uri_parse_with_flags(source_uri, 0);
4757 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4759 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4760 char *path = NULL, *fragment = NULL;
4761 int got_authority = 0;
4763 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4765 event_warn("%s: calloc", __func__);
4771 readbuf = mm_strdup(source_uri);
4772 if (readbuf == NULL) {
4773 event_warn("%s: strdup", __func__);
4780 /* We try to follow RFC3986 here as much as we can, and match
4783 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4785 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
4789 token = strchr(readp, ':');
4790 if (token && scheme_ok(readp,token)) {
4792 uri->scheme = mm_strdup(readp);
4793 if (uri->scheme == NULL) {
4794 event_warn("%s: strdup", __func__);
4797 readp = token+1; /* eat : */
4800 /* 2. Optionally, "//" then an 'authority' part. */
4801 if (readp[0]=='/' && readp[1] == '/') {
4805 path = end_of_authority(readp);
4806 if (parse_authority(uri, authority, path) < 0)
4812 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4815 readp = end_of_path(path, PART_PATH, flags);
4818 if (*readp == '?') {
4822 readp = end_of_path(readp, PART_QUERY, flags);
4825 if (*readp == '#') {
4829 readp = end_of_path(readp, PART_FRAGMENT, flags);
4831 if (*readp != '\0') {
4835 /* These next two cases may be unreachable; I'm leaving them
4836 * in to be defensive. */
4837 /* If you didn't get an authority, the path can't begin with "//" */
4838 if (!got_authority && path[0]=='/' && path[1]=='/')
4840 /* If you did get an authority, the path must begin with "/" or be
4842 if (got_authority && path[0] != '/' && path[0] != '\0')
4844 /* (End of maybe-unreachable cases) */
4846 /* If there was no scheme, the first part of the path (if any) must
4847 * have no colon in it. */
4848 if (! uri->scheme && !path_matches_noscheme(path))
4851 EVUTIL_ASSERT(path);
4852 uri->path = mm_strdup(path);
4853 if (uri->path == NULL) {
4854 event_warn("%s: strdup", __func__);
4859 uri->query = mm_strdup(query);
4860 if (uri->query == NULL) {
4861 event_warn("%s: strdup", __func__);
4866 uri->fragment = mm_strdup(fragment);
4867 if (uri->fragment == NULL) {
4868 event_warn("%s: strdup", __func__);
4878 evhttp_uri_free(uri);
4884 static struct evhttp_uri *
4885 evhttp_uri_parse_authority(char *source_uri)
4887 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4891 event_warn("%s: calloc", __func__);
4897 end = end_of_authority(source_uri);
4898 if (parse_authority(uri, source_uri, end) < 0)
4901 uri->path = mm_strdup("");
4902 if (uri->path == NULL) {
4903 event_warn("%s: strdup", __func__);
4910 evhttp_uri_free(uri);
4915 evhttp_uri_free(struct evhttp_uri *uri)
4917 #define URI_FREE_STR_(f) \
4922 URI_FREE_STR_(scheme);
4923 URI_FREE_STR_(userinfo);
4924 URI_FREE_STR_(host);
4925 URI_FREE_STR_(path);
4926 URI_FREE_STR_(query);
4927 URI_FREE_STR_(fragment);
4930 #undef URI_FREE_STR_
4934 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
4936 struct evbuffer *tmp = 0;
4937 size_t joined_size = 0;
4938 char *output = NULL;
4940 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
4942 if (!uri || !buf || !limit)
4945 tmp = evbuffer_new();
4951 evbuffer_add(tmp, ":", 1);
4954 evbuffer_add(tmp, "//", 2);
4956 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
4959 evbuffer_add_printf(tmp,":%d", uri->port);
4961 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
4969 evbuffer_add(tmp, "?", 1);
4973 if (uri->fragment) {
4974 evbuffer_add(tmp, "#", 1);
4978 evbuffer_add(tmp, "\0", 1); /* NUL */
4980 joined_size = evbuffer_get_length(tmp);
4982 if (joined_size > limit) {
4983 /* It doesn't fit. */
4987 evbuffer_remove(tmp, buf, joined_size);
4998 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
5003 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
5005 return uri->userinfo;
5008 evhttp_uri_get_host(const struct evhttp_uri *uri)
5013 evhttp_uri_get_port(const struct evhttp_uri *uri)
5018 evhttp_uri_get_path(const struct evhttp_uri *uri)
5023 evhttp_uri_get_query(const struct evhttp_uri *uri)
5028 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
5030 return uri->fragment;
5033 #define URI_SET_STR_(f) do { \
5037 if ((uri->f = mm_strdup(f)) == NULL) { \
5038 event_warn("%s: strdup()", __func__); \
5047 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
5049 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
5052 URI_SET_STR_(scheme);
5056 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
5058 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
5060 URI_SET_STR_(userinfo);
5064 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
5067 if (host[0] == '[') {
5068 if (! bracket_addr_ok(host, host+strlen(host)))
5071 if (! regname_ok(host, host+strlen(host)))
5080 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
5087 #define end_of_cpath(cp,p,f) \
5088 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
5091 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
5093 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
5100 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
5102 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
5104 URI_SET_STR_(query);
5108 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
5110 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
5112 URI_SET_STR_(fragment);