2 * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
3 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "event2/event-config.h"
29 #include "evconfig-private.h"
31 #ifdef EVENT__HAVE_SYS_PARAM_H
32 #include <sys/param.h>
34 #ifdef EVENT__HAVE_SYS_TYPES_H
35 #include <sys/types.h>
38 #ifdef HAVE_SYS_IOCCOM_H
39 #include <sys/ioccom.h>
41 #ifdef EVENT__HAVE_SYS_RESOURCE_H
42 #include <sys/resource.h>
44 #ifdef EVENT__HAVE_SYS_TIME_H
47 #ifdef EVENT__HAVE_SYS_WAIT_H
52 #include <sys/socket.h>
59 #ifdef EVENT__HAVE_SYS_UN_H
62 #ifdef EVENT__HAVE_AFUNIX_H
66 #include <sys/queue.h>
68 #ifdef EVENT__HAVE_NETINET_IN_H
69 #include <netinet/in.h>
71 #ifdef EVENT__HAVE_ARPA_INET_H
72 #include <arpa/inet.h>
74 #ifdef EVENT__HAVE_NETDB_H
90 #ifdef EVENT__HAVE_UNISTD_H
93 #ifdef EVENT__HAVE_FCNTL_H
97 #undef timeout_pending
98 #undef timeout_initialized
100 #include "strlcpy-internal.h"
101 #include "event2/http.h"
102 #include "event2/event.h"
103 #include "event2/buffer.h"
104 #include "event2/bufferevent.h"
105 #include "event2/http_struct.h"
106 #include "event2/http_compat.h"
107 #include "event2/util.h"
108 #include "event2/listener.h"
109 #include "log-internal.h"
110 #include "util-internal.h"
111 #include "http-internal.h"
112 #include "mm-internal.h"
113 #include "bufferevent-internal.h"
115 #ifndef EVENT__HAVE_GETNAMEINFO
116 #define NI_MAXSERV 32
117 #define NI_MAXHOST 1025
119 #ifndef NI_NUMERICHOST
120 #define NI_NUMERICHOST 1
123 #ifndef NI_NUMERICSERV
124 #define NI_NUMERICSERV 2
128 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
129 size_t hostlen, char *serv, size_t servlen, int flags)
131 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
135 evutil_snprintf(tmpserv, sizeof(tmpserv),
136 "%d", ntohs(sin->sin_port));
137 if (strlcpy(serv, tmpserv, servlen) >= servlen)
142 if (flags & NI_NUMERICHOST) {
143 if (strlcpy(host, inet_ntoa(sin->sin_addr),
150 hp = gethostbyaddr((char *)&sin->sin_addr,
151 sizeof(struct in_addr), AF_INET);
155 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
166 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \
167 ((req)->major < (major_v) || \
168 ((req)->major == (major_v) && (req)->minor < (minor_v)))
170 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \
171 ((req)->major > (major_v) || \
172 ((req)->major == (major_v) && (req)->minor >= (minor_v)))
175 #define MIN(a,b) (((a)<(b))?(a):(b))
180 static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse);
181 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
182 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
183 static struct evhttp_uri *evhttp_uri_parse_authority(char *source_uri);
184 static int evhttp_associate_new_request_with_connection(
185 struct evhttp_connection *evcon);
186 static void evhttp_connection_start_detectclose(
187 struct evhttp_connection *evcon);
188 static void evhttp_connection_stop_detectclose(
189 struct evhttp_connection *evcon);
190 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
191 static void evhttp_read_firstline(struct evhttp_connection *evcon,
192 struct evhttp_request *req);
193 static void evhttp_read_header(struct evhttp_connection *evcon,
194 struct evhttp_request *req);
195 static int evhttp_add_header_internal(struct evkeyvalq *headers,
196 const char *key, const char *value);
197 static const char *evhttp_response_phrase_internal(int code);
198 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t);
199 static void evhttp_write_buffer(struct evhttp_connection *,
200 void (*)(struct evhttp_connection *, void *), void *);
201 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
203 /* callbacks for bufferevent */
204 static void evhttp_read_cb(struct bufferevent *, void *);
205 static void evhttp_write_cb(struct bufferevent *, void *);
206 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
207 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
208 const char *hostname);
210 #ifndef EVENT__HAVE_STRSEP
211 /* strsep replacement for platforms that lack it. Only works if
212 * del is one character long. */
214 strsep(char **s, const char *del)
217 EVUTIL_ASSERT(strlen(del) == 1);
221 d = strstr(tok, del);
232 html_replace(const char ch, const char **escaped)
258 * Replaces <, >, ", ' and & with <, >, ",
259 * ' and & correspondingly.
261 * The returned string needs to be freed by the caller.
265 evhttp_htmlescape(const char *html)
268 size_t new_size = 0, old_size = 0;
269 char *escaped_html, *p;
274 old_size = strlen(html);
275 for (i = 0; i < old_size; ++i) {
276 const char *replaced = NULL;
277 const size_t replace_size = html_replace(html[i], &replaced);
278 if (replace_size > EV_SIZE_MAX - new_size) {
279 event_warn("%s: html_replace overflow", __func__);
282 new_size += replace_size;
285 if (new_size == EV_SIZE_MAX)
287 p = escaped_html = mm_malloc(new_size + 1);
288 if (escaped_html == NULL) {
289 event_warn("%s: malloc(%lu)", __func__,
290 (unsigned long)(new_size + 1));
293 for (i = 0; i < old_size; ++i) {
294 const char *replaced = &html[i];
295 const size_t len = html_replace(html[i], &replaced);
296 memcpy(p, replaced, len);
302 return (escaped_html);
305 /** Given an evhttp_cmd_type, returns a constant string containing the
306 * equivalent HTTP command, or NULL if the evhttp_command_type is
309 evhttp_method(enum evhttp_cmd_type type)
317 case EVHTTP_REQ_POST:
320 case EVHTTP_REQ_HEAD:
326 case EVHTTP_REQ_DELETE:
329 case EVHTTP_REQ_OPTIONS:
332 case EVHTTP_REQ_TRACE:
335 case EVHTTP_REQ_CONNECT:
338 case EVHTTP_REQ_PATCH:
350 * Determines if a response should have a body.
351 * Follows the rules in RFC 2616 section 4.3.
352 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
356 evhttp_response_needs_body(struct evhttp_request *req)
358 return (req->response_code != HTTP_NOCONTENT &&
359 req->response_code != HTTP_NOTMODIFIED &&
360 (req->response_code < 100 || req->response_code >= 200) &&
361 req->type != EVHTTP_REQ_HEAD);
364 /** Helper: called after we've added some data to an evcon's bufferevent's
365 * output buffer. Sets the evconn's writing-is-done callback, and puts
366 * the bufferevent into writing mode.
369 evhttp_write_buffer(struct evhttp_connection *evcon,
370 void (*cb)(struct evhttp_connection *, void *), void *arg)
372 event_debug(("%s: preparing to write buffer\n", __func__));
378 /* Disable the read callback: we don't actually care about data;
379 * we only care about close detection. (We don't disable reading --
380 * EV_READ, since we *do* want to learn about any close events.) */
381 bufferevent_setcb(evcon->bufev,
387 bufferevent_enable(evcon->bufev, EV_READ|EV_WRITE);
391 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
393 bufferevent_disable(evcon->bufev, EV_WRITE);
397 evhttp_send_continue(struct evhttp_connection *evcon,
398 struct evhttp_request *req)
400 bufferevent_enable(evcon->bufev, EV_WRITE);
401 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
402 "HTTP/%d.%d 100 Continue\r\n\r\n",
403 req->major, req->minor);
404 evcon->cb = evhttp_send_continue_done;
405 evcon->cb_arg = NULL;
406 bufferevent_setcb(evcon->bufev,
413 /** Helper: returns true iff evconn is in any connected state. */
415 evhttp_connected(struct evhttp_connection *evcon)
417 switch (evcon->state) {
418 case EVCON_DISCONNECTED:
419 case EVCON_CONNECTING:
422 case EVCON_READING_FIRSTLINE:
423 case EVCON_READING_HEADERS:
424 case EVCON_READING_BODY:
425 case EVCON_READING_TRAILER:
432 /* Create the headers needed for an outgoing HTTP request, adds them to
433 * the request's header list, and writes the request line to the
434 * connection's output buffer.
437 evhttp_make_header_request(struct evhttp_connection *evcon,
438 struct evhttp_request *req)
442 evhttp_remove_header(req->output_headers, "Proxy-Connection");
444 /* Generate request line */
445 if (!(method = evhttp_method(req->type))) {
449 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
450 "%s %s HTTP/%d.%d\r\n",
451 method, req->uri, req->major, req->minor);
453 /* Add the content length on a post or put request if missing */
454 if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
455 evhttp_find_header(req->output_headers, "Content-Length") == NULL){
457 evutil_snprintf(size, sizeof(size), EV_SIZE_FMT,
458 EV_SIZE_ARG(evbuffer_get_length(req->output_buffer)));
459 evhttp_add_header(req->output_headers, "Content-Length", size);
463 /** Return true if the list of headers in 'headers', intepreted with respect
464 * to flags, means that we should send a "connection: close" when the request
467 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
469 if (flags & EVHTTP_PROXY_REQUEST) {
470 /* proxy connection */
471 const char *connection = evhttp_find_header(headers, "Proxy-Connection");
472 return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
474 const char *connection = evhttp_find_header(headers, "Connection");
475 return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
479 evhttp_is_request_connection_close(struct evhttp_request *req)
482 evhttp_is_connection_close(req->flags, req->input_headers) ||
483 evhttp_is_connection_close(req->flags, req->output_headers);
486 /* Return true iff 'headers' contains 'Connection: keep-alive' */
488 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
490 const char *connection = evhttp_find_header(headers, "Connection");
491 return (connection != NULL
492 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
495 /* Add a correct "Date" header to headers, unless it already has one. */
497 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
499 if (evhttp_find_header(headers, "Date") == NULL) {
501 if (sizeof(date) - evutil_date_rfc1123(date, sizeof(date), NULL) > 0) {
502 evhttp_add_header(headers, "Date", date);
507 /* Add a "Content-Length" header with value 'content_length' to headers,
508 * unless it already has a content-length or transfer-encoding header. */
510 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
511 size_t content_length)
513 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
514 evhttp_find_header(headers, "Content-Length") == NULL) {
516 evutil_snprintf(len, sizeof(len), EV_SIZE_FMT,
517 EV_SIZE_ARG(content_length));
518 evhttp_add_header(headers, "Content-Length", len);
523 * Create the headers needed for an HTTP reply in req->output_headers,
524 * and write the first HTTP response for req line to evcon.
527 evhttp_make_header_response(struct evhttp_connection *evcon,
528 struct evhttp_request *req)
530 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
531 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
532 "HTTP/%d.%d %d %s\r\n",
533 req->major, req->minor, req->response_code,
534 req->response_code_line);
536 if (req->major == 1) {
538 evhttp_maybe_add_date_header(req->output_headers);
541 * if the protocol is 1.0; and the connection was keep-alive
542 * we need to add a keep-alive header, too.
544 if (req->minor == 0 && is_keepalive)
545 evhttp_add_header(req->output_headers,
546 "Connection", "keep-alive");
548 if ((req->minor >= 1 || is_keepalive) &&
549 evhttp_response_needs_body(req)) {
551 * we need to add the content length if the
552 * user did not give it, this is required for
553 * persistent connections to work.
555 evhttp_maybe_add_content_length_header(
557 evbuffer_get_length(req->output_buffer));
561 /* Potentially add headers for unidentified content. */
562 if (evhttp_response_needs_body(req)) {
563 if (evhttp_find_header(req->output_headers,
564 "Content-Type") == NULL
565 && evcon->http_server->default_content_type) {
566 evhttp_add_header(req->output_headers,
568 evcon->http_server->default_content_type);
572 /* if the request asked for a close, we send a close, too */
573 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
574 evhttp_remove_header(req->output_headers, "Connection");
575 if (!(req->flags & EVHTTP_PROXY_REQUEST))
576 evhttp_add_header(req->output_headers, "Connection", "close");
577 evhttp_remove_header(req->output_headers, "Proxy-Connection");
581 enum expect { NO, CONTINUE, OTHER };
582 static enum expect evhttp_have_expect(struct evhttp_request *req, int input)
585 struct evkeyvalq *h = input ? req->input_headers : req->output_headers;
587 if (!(req->kind == EVHTTP_REQUEST) || !REQ_VERSION_ATLEAST(req, 1, 1))
590 expect = evhttp_find_header(h, "Expect");
594 return !evutil_ascii_strcasecmp(expect, "100-continue") ? CONTINUE : OTHER;
598 /** Generate all headers appropriate for sending the http request in req (or
599 * the response, if we're sending a response), and write them to evcon's
600 * bufferevent. Also writes all data from req->output_buffer */
602 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
604 struct evkeyval *header;
605 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
608 * Depending if this is a HTTP request or response, we might need to
609 * add some new headers or remove existing headers.
611 if (req->kind == EVHTTP_REQUEST) {
612 evhttp_make_header_request(evcon, req);
614 evhttp_make_header_response(evcon, req);
617 TAILQ_FOREACH(header, req->output_headers, next) {
618 evbuffer_add_printf(output, "%s: %s\r\n",
619 header->key, header->value);
621 evbuffer_add(output, "\r\n", 2);
623 if (evhttp_have_expect(req, 0) != CONTINUE &&
624 evbuffer_get_length(req->output_buffer)) {
626 * For a request, we add the POST data, for a reply, this
627 * is the regular data.
629 evbuffer_add_buffer(output, req->output_buffer);
634 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
635 ev_ssize_t new_max_headers_size)
637 if (new_max_headers_size<0)
638 evcon->max_headers_size = EV_SIZE_MAX;
640 evcon->max_headers_size = new_max_headers_size;
643 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
644 ev_ssize_t new_max_body_size)
646 if (new_max_body_size<0)
647 evcon->max_body_size = EV_UINT64_MAX;
649 evcon->max_body_size = new_max_body_size;
653 evhttp_connection_incoming_fail(struct evhttp_request *req,
654 enum evhttp_request_error error)
657 case EVREQ_HTTP_DATA_TOO_LONG:
658 req->response_code = HTTP_ENTITYTOOLARGE;
661 req->response_code = HTTP_BADREQUEST;
665 case EVREQ_HTTP_TIMEOUT:
668 * these are cases in which we probably should just
669 * close the connection and not send a reply. this
670 * case may happen when a browser keeps a persistent
671 * connection open and we timeout on the read. when
672 * the request is still being used for sending, we
673 * need to disassociated it from the connection here.
675 if (!req->userdone) {
676 /* remove it so that it will not be freed */
677 TAILQ_REMOVE(&req->evcon->requests, req, next);
678 /* indicate that this request no longer has a
684 case EVREQ_HTTP_INVALID_HEADER:
685 case EVREQ_HTTP_BUFFER_ERROR:
686 case EVREQ_HTTP_REQUEST_CANCEL:
687 case EVREQ_HTTP_DATA_TOO_LONG:
688 default: /* xxx: probably should just error on default */
689 /* the callback looks at the uri to determine errors */
694 if (req->uri_elems) {
695 evhttp_uri_free(req->uri_elems);
696 req->uri_elems = NULL;
700 * the callback needs to send a reply, once the reply has
701 * been send, the connection should get freed.
703 (*req->cb)(req, req->cb_arg);
709 /* Free connection ownership of which can be acquired by user using
710 * evhttp_request_own(). */
712 evhttp_request_free_auto(struct evhttp_request *req)
714 if (!(req->flags & EVHTTP_USER_OWNED))
715 evhttp_request_free(req);
719 evhttp_request_free_(struct evhttp_connection *evcon, struct evhttp_request *req)
721 TAILQ_REMOVE(&evcon->requests, req, next);
722 evhttp_request_free_auto(req);
725 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
726 * given in error. If it's an outgoing connection, reset the connection,
727 * retry any pending requests, and inform the user. If it's incoming,
728 * delegates to evhttp_connection_incoming_fail(). */
730 evhttp_connection_fail_(struct evhttp_connection *evcon,
731 enum evhttp_request_error error)
733 const int errsave = EVUTIL_SOCKET_ERROR();
734 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
735 void (*cb)(struct evhttp_request *, void *);
737 void (*error_cb)(enum evhttp_request_error, void *);
739 EVUTIL_ASSERT(req != NULL);
741 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
743 if (evcon->flags & EVHTTP_CON_INCOMING) {
745 * for incoming requests, there are two different
746 * failure cases. it's either a network level error
747 * or an http layer error. for problems on the network
748 * layer like timeouts we just drop the connections.
749 * For HTTP problems, we might have to send back a
750 * reply before the connection can be freed.
752 if (evhttp_connection_incoming_fail(req, error) == -1)
753 evhttp_connection_free(evcon);
757 error_cb = req->error_cb;
758 error_cb_arg = req->cb_arg;
759 /* when the request was canceled, the callback is not executed */
760 if (error != EVREQ_HTTP_REQUEST_CANCEL) {
761 /* save the callback for later; the cb might free our object */
763 cb_arg = req->cb_arg;
769 /* do not fail all requests; the next request is going to get
770 * send over a new connection. when a user cancels a request,
771 * all other pending requests should be processed as normal
773 evhttp_request_free_(evcon, req);
775 /* reset the connection */
776 evhttp_connection_reset_(evcon);
778 /* We are trying the next request that was queued on us */
779 if (TAILQ_FIRST(&evcon->requests) != NULL)
780 evhttp_connection_connect_(evcon);
782 /* The call to evhttp_connection_reset_ overwrote errno.
783 * Let's restore the original errno, so that the user's
784 * callback can have a better idea of what the error was.
786 EVUTIL_SET_SOCKET_ERROR(errsave);
788 /* inform the user */
789 if (error_cb != NULL)
790 error_cb(error, error_cb_arg);
795 /* Bufferevent callback: invoked when any data has been written from an
796 * http connection's bufferevent */
798 evhttp_write_cb(struct bufferevent *bufev, void *arg)
800 struct evhttp_connection *evcon = arg;
802 /* Activate our call back */
803 if (evcon->cb != NULL)
804 (*evcon->cb)(evcon, evcon->cb_arg);
808 * Advance the connection state.
809 * - If this is an outgoing connection, we've just processed the response;
810 * idle or close the connection.
811 * - If this is an incoming connection, we've just processed the request;
815 evhttp_connection_done(struct evhttp_connection *evcon)
817 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
818 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
822 /* idle or close the connection */
823 int need_close = evhttp_is_request_connection_close(req);
824 TAILQ_REMOVE(&evcon->requests, req, next);
827 evcon->state = EVCON_IDLE;
829 /* check if we got asked to close the connection */
831 evhttp_connection_reset_(evcon);
833 if (TAILQ_FIRST(&evcon->requests) != NULL) {
835 * We have more requests; reset the connection
836 * and deal with the next request.
838 if (!evhttp_connected(evcon))
839 evhttp_connection_connect_(evcon);
841 evhttp_request_dispatch(evcon);
842 } else if (!need_close) {
844 * The connection is going to be persistent, but we
845 * need to detect if the other side closes it.
847 evhttp_connection_start_detectclose(evcon);
848 } else if ((evcon->flags & EVHTTP_CON_AUTOFREE)) {
850 * If we have no more requests that need completion
851 * and we're not waiting for the connection to close
857 * incoming connection - we need to leave the request on the
858 * connection so that we can reply to it.
860 evcon->state = EVCON_WRITING;
863 /* notify the user of the request */
864 (*req->cb)(req, req->cb_arg);
866 /* if this was an outgoing request, we own and it's done. so free it. */
868 evhttp_request_free_auto(req);
871 /* If this was the last request of an outgoing connection and we're
872 * not waiting to receive a connection close event and we want to
873 * automatically free the connection. We check to ensure our request
874 * list is empty one last time just in case our callback added a
877 if (free_evcon && TAILQ_FIRST(&evcon->requests) == NULL) {
878 evhttp_connection_free(evcon);
883 * Handles reading from a chunked request.
884 * return ALL_DATA_READ:
885 * all data has been read
886 * return MORE_DATA_EXPECTED:
887 * more data is expected
888 * return DATA_CORRUPTED:
890 * return REQUEST_CANCELED:
891 * request was canceled by the user calling evhttp_cancel_request
892 * return DATA_TOO_LONG:
893 * ran over the maximum limit
896 static enum message_read_status
897 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
899 if (req == NULL || buf == NULL) {
900 return DATA_CORRUPTED;
906 if ((buflen = evbuffer_get_length(buf)) == 0) {
910 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
911 * check for overflow conditions */
912 if (buflen > EV_SSIZE_MAX) {
913 return DATA_CORRUPTED;
916 if (req->ntoread < 0) {
917 /* Read chunk size */
919 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
924 /* the last chunk is on a new line? */
925 if (strlen(p) == 0) {
929 ntoread = evutil_strtoll(p, &endp, 16);
930 error = (*p == '\0' ||
931 (*endp != '\0' && *endp != ' ') ||
935 /* could not get chunk size */
936 return (DATA_CORRUPTED);
939 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
940 if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
941 return DATA_CORRUPTED;
944 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
945 /* failed body length test */
946 event_debug(("Request body is too long"));
947 return (DATA_TOO_LONG);
950 req->body_size += (size_t)ntoread;
951 req->ntoread = ntoread;
952 if (req->ntoread == 0) {
954 return (ALL_DATA_READ);
959 /* req->ntoread is signed int64, len is ssize_t, based on arch,
960 * ssize_t could only be 32b, check for these conditions */
961 if (req->ntoread > EV_SSIZE_MAX) {
962 return DATA_CORRUPTED;
965 /* don't have enough to complete a chunk; wait for more */
966 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
967 return (MORE_DATA_EXPECTED);
969 /* Completed chunk */
970 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
972 if (req->chunk_cb != NULL) {
973 req->flags |= EVHTTP_REQ_DEFER_FREE;
974 (*req->chunk_cb)(req, req->cb_arg);
975 evbuffer_drain(req->input_buffer,
976 evbuffer_get_length(req->input_buffer));
977 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
978 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
979 return (REQUEST_CANCELED);
984 return (MORE_DATA_EXPECTED);
988 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
990 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
992 switch (evhttp_parse_headers_(req, buf)) {
995 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
998 bufferevent_disable(evcon->bufev, EV_READ);
999 evhttp_connection_done(evcon);
1001 case MORE_DATA_EXPECTED:
1002 case REQUEST_CANCELED: /* ??? */
1009 evhttp_lingering_close(struct evhttp_connection *evcon,
1010 struct evhttp_request *req)
1012 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1014 size_t n = evbuffer_get_length(buf);
1015 if (n > (size_t) req->ntoread)
1016 n = (size_t) req->ntoread;
1018 req->body_size += n;
1020 event_debug(("Request body is too long, left " EV_I64_FMT,
1021 EV_I64_ARG(req->ntoread)));
1023 evbuffer_drain(buf, n);
1025 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1028 evhttp_lingering_fail(struct evhttp_connection *evcon,
1029 struct evhttp_request *req)
1031 if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE)
1032 evhttp_lingering_close(evcon, req);
1034 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1038 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1040 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1043 switch (evhttp_handle_chunked_read(req, buf)) {
1045 /* finished last chunk */
1046 evcon->state = EVCON_READING_TRAILER;
1047 evhttp_read_trailer(evcon, req);
1049 case DATA_CORRUPTED:
1051 /* corrupted data */
1052 evhttp_connection_fail_(evcon,
1053 EVREQ_HTTP_DATA_TOO_LONG);
1055 case REQUEST_CANCELED:
1056 /* request canceled */
1057 evhttp_request_free_auto(req);
1059 case MORE_DATA_EXPECTED:
1063 } else if (req->ntoread < 0) {
1064 /* Read until connection close. */
1065 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
1066 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
1070 req->body_size += evbuffer_get_length(buf);
1071 evbuffer_add_buffer(req->input_buffer, buf);
1072 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
1073 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
1074 /* We've postponed moving the data until now, but we're
1075 * about to use it. */
1076 size_t n = evbuffer_get_length(buf);
1078 if (n > (size_t) req->ntoread)
1079 n = (size_t) req->ntoread;
1081 req->body_size += n;
1082 evbuffer_remove_buffer(buf, req->input_buffer, n);
1085 if (req->body_size > req->evcon->max_body_size ||
1086 (!req->chunked && req->ntoread >= 0 &&
1087 (size_t)req->ntoread > req->evcon->max_body_size)) {
1088 /* XXX: The above casted comparison must checked for overflow */
1089 /* failed body length test */
1091 evhttp_lingering_fail(evcon, req);
1095 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1096 req->flags |= EVHTTP_REQ_DEFER_FREE;
1097 (*req->chunk_cb)(req, req->cb_arg);
1098 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1099 evbuffer_drain(req->input_buffer,
1100 evbuffer_get_length(req->input_buffer));
1101 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1102 evhttp_request_free_auto(req);
1107 if (!req->ntoread) {
1108 bufferevent_disable(evcon->bufev, EV_READ);
1109 /* Completed content length */
1110 evhttp_connection_done(evcon);
1115 #define get_deferred_queue(evcon) \
1119 * Gets called when more data becomes available
1123 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1125 struct evhttp_connection *evcon = arg;
1126 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1128 /* Cancel if it's pending. */
1129 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1130 &evcon->read_more_deferred_cb);
1132 switch (evcon->state) {
1133 case EVCON_READING_FIRSTLINE:
1134 evhttp_read_firstline(evcon, req);
1135 /* note the request may have been freed in
1136 * evhttp_read_body */
1138 case EVCON_READING_HEADERS:
1139 evhttp_read_header(evcon, req);
1140 /* note the request may have been freed in
1141 * evhttp_read_body */
1143 case EVCON_READING_BODY:
1144 evhttp_read_body(evcon, req);
1145 /* note the request may have been freed in
1146 * evhttp_read_body */
1148 case EVCON_READING_TRAILER:
1149 evhttp_read_trailer(evcon, req);
1154 struct evbuffer *input;
1157 input = bufferevent_get_input(evcon->bufev);
1158 total_len = evbuffer_get_length(input);
1159 event_debug(("%s: read "EV_SIZE_FMT
1160 " bytes in EVCON_IDLE state,"
1161 " resetting connection",
1162 __func__, EV_SIZE_ARG(total_len)));
1165 evhttp_connection_reset_(evcon);
1168 case EVCON_DISCONNECTED:
1169 case EVCON_CONNECTING:
1172 event_errx(1, "%s: illegal connection state %d",
1173 __func__, evcon->state);
1178 evhttp_deferred_read_cb(struct event_callback *cb, void *data)
1180 struct evhttp_connection *evcon = data;
1181 struct bufferevent *bev = evcon->bufev;
1183 (bev->readcb)(evcon->bufev, evcon);
1187 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1189 /* This is after writing the request to the server */
1190 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1191 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
1192 EVUTIL_ASSERT(req != NULL);
1194 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1196 /* We need to wait until we've written all of our output data before we can
1198 if (evbuffer_get_length(output) > 0)
1201 /* We are done writing our header and are now expecting the response */
1202 req->kind = EVHTTP_RESPONSE;
1204 evhttp_start_read_(evcon);
1208 * Clean up a connection object
1212 evhttp_connection_free(struct evhttp_connection *evcon)
1214 struct evhttp_request *req;
1217 /* notify interested parties that this connection is going down */
1218 if (evcon->fd != -1) {
1219 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1220 (*evcon->closecb)(evcon, evcon->closecb_arg);
1223 /* remove all requests that might be queued on this
1224 * connection. for server connections, this should be empty.
1225 * because it gets dequeued either in evhttp_connection_done or
1226 * evhttp_connection_fail_.
1228 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1229 evhttp_request_free_(evcon, req);
1232 if (evcon->http_server != NULL) {
1233 struct evhttp *http = evcon->http_server;
1234 TAILQ_REMOVE(&http->connections, evcon, next);
1237 if (event_initialized(&evcon->retry_ev)) {
1238 event_del(&evcon->retry_ev);
1239 event_debug_unassign(&evcon->retry_ev);
1242 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1243 &evcon->read_more_deferred_cb);
1245 if (evcon->bufev != NULL) {
1247 !(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE);
1248 if (evcon->fd == -1)
1249 evcon->fd = bufferevent_getfd(evcon->bufev);
1251 bufferevent_free(evcon->bufev);
1254 if (evcon->fd != -1) {
1255 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1257 evutil_closesocket(evcon->fd);
1260 if (evcon->bind_address != NULL)
1261 mm_free(evcon->bind_address);
1263 if (evcon->address != NULL)
1264 mm_free(evcon->address);
1270 evhttp_connection_free_on_completion(struct evhttp_connection *evcon) {
1271 evcon->flags |= EVHTTP_CON_AUTOFREE;
1275 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1276 const char *address)
1278 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1279 if (evcon->bind_address)
1280 mm_free(evcon->bind_address);
1281 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1282 event_warn("%s: strdup", __func__);
1286 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1289 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1290 evcon->bind_port = port;
1294 evhttp_request_dispatch(struct evhttp_connection* evcon)
1296 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1298 /* this should not usually happy but it's possible */
1302 EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST);
1304 /* delete possible close detection events */
1305 evhttp_connection_stop_detectclose(evcon);
1307 /* we assume that the connection is connected already */
1308 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1310 evcon->state = EVCON_WRITING;
1312 /* Create the header from the store arguments */
1313 evhttp_make_header(evcon, req);
1315 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1318 /* Reset our connection state: disables reading/writing, closes our fd (if
1319 * any), clears out buffers, and puts us in state DISCONNECTED. */
1321 evhttp_connection_reset_(struct evhttp_connection *evcon)
1323 struct evbuffer *tmp;
1326 bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL);
1328 /* XXXX This is not actually an optimal fix. Instead we ought to have
1329 an API for "stop connecting", or use bufferevent_setfd to turn off
1330 connecting. But for Libevent 2.0, this seems like a minimal change
1331 least likely to disrupt the rest of the bufferevent and http code.
1333 Why is this here? If the fd is set in the bufferevent, and the
1334 bufferevent is connecting, then you can't actually stop the
1335 bufferevent from trying to connect with bufferevent_disable(). The
1336 connect will never trigger, since we close the fd, but the timeout
1337 might. That caused an assertion failure in evhttp_connection_fail_.
1339 bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE);
1341 if (evcon->fd == -1)
1342 evcon->fd = bufferevent_getfd(evcon->bufev);
1344 if (evcon->fd != -1) {
1345 /* inform interested parties about connection close */
1346 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1347 (*evcon->closecb)(evcon, evcon->closecb_arg);
1349 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1350 evutil_closesocket(evcon->fd);
1353 err = bufferevent_setfd(evcon->bufev, -1);
1354 EVUTIL_ASSERT(!err && "setfd");
1356 /* we need to clean up any buffered data */
1357 tmp = bufferevent_get_output(evcon->bufev);
1358 err = evbuffer_drain(tmp, -1);
1359 EVUTIL_ASSERT(!err && "drain output");
1360 tmp = bufferevent_get_input(evcon->bufev);
1361 err = evbuffer_drain(tmp, -1);
1362 EVUTIL_ASSERT(!err && "drain input");
1364 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1366 evcon->state = EVCON_DISCONNECTED;
1370 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1372 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1373 bufferevent_enable(evcon->bufev, EV_READ);
1377 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1379 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1380 bufferevent_disable(evcon->bufev, EV_READ);
1384 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1386 struct evhttp_connection *evcon = arg;
1388 evcon->state = EVCON_DISCONNECTED;
1389 evhttp_connection_connect_(evcon);
1393 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1395 struct evcon_requestq requests;
1397 evhttp_connection_reset_(evcon);
1398 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1399 struct timeval tv_retry = evcon->initial_retry_timeout;
1401 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1402 /* XXXX handle failure from evhttp_add_event */
1403 for (i=0; i < evcon->retry_cnt; ++i) {
1404 tv_retry.tv_usec *= 2;
1405 if (tv_retry.tv_usec > 1000000) {
1406 tv_retry.tv_usec -= 1000000;
1407 tv_retry.tv_sec += 1;
1409 tv_retry.tv_sec *= 2;
1410 if (tv_retry.tv_sec > 3600) {
1411 tv_retry.tv_sec = 3600;
1412 tv_retry.tv_usec = 0;
1415 event_add(&evcon->retry_ev, &tv_retry);
1421 * User callback can do evhttp_make_request() on the same
1422 * evcon so new request will be added to evcon->requests. To
1423 * avoid freeing it prematurely we iterate over the copy of
1426 TAILQ_INIT(&requests);
1427 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1428 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1429 TAILQ_REMOVE(&evcon->requests, request, next);
1430 TAILQ_INSERT_TAIL(&requests, request, next);
1433 /* for now, we just signal all requests by executing their callbacks */
1434 while (TAILQ_FIRST(&requests) != NULL) {
1435 struct evhttp_request *request = TAILQ_FIRST(&requests);
1436 TAILQ_REMOVE(&requests, request, next);
1437 request->evcon = NULL;
1439 /* we might want to set an error here */
1440 request->cb(request, request->cb_arg);
1441 evhttp_request_free_auto(request);
1446 evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
1447 struct evhttp_request *req)
1449 struct evbuffer *buf;
1451 /** Second time, we can't read anything */
1452 if (evcon->flags & EVHTTP_CON_READING_ERROR) {
1453 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1454 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1458 req->kind = EVHTTP_RESPONSE;
1460 buf = bufferevent_get_output(evcon->bufev);
1461 evbuffer_unfreeze(buf, 1);
1462 evbuffer_drain(buf, evbuffer_get_length(buf));
1463 evbuffer_freeze(buf, 1);
1465 evhttp_start_read_(evcon);
1466 evcon->flags |= EVHTTP_CON_READING_ERROR;
1470 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1472 struct evhttp_connection *evcon = arg;
1473 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1475 if (evcon->fd == -1)
1476 evcon->fd = bufferevent_getfd(bufev);
1478 switch (evcon->state) {
1479 case EVCON_CONNECTING:
1480 if (what & BEV_EVENT_TIMEOUT) {
1481 event_debug(("%s: connection timeout for \"%s:%d\" on "
1483 __func__, evcon->address, evcon->port,
1484 EV_SOCK_ARG(evcon->fd)));
1485 evhttp_connection_cb_cleanup(evcon);
1490 case EVCON_READING_BODY:
1491 if (!req->chunked && req->ntoread < 0
1492 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1493 /* EOF on read can be benign */
1494 evhttp_connection_done(evcon);
1499 case EVCON_DISCONNECTED:
1501 case EVCON_READING_FIRSTLINE:
1502 case EVCON_READING_HEADERS:
1503 case EVCON_READING_TRAILER:
1509 /* when we are in close detect mode, a read error means that
1510 * the other side closed their connection.
1512 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1513 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1514 EVUTIL_ASSERT(evcon->http_server == NULL);
1515 /* For connections from the client, we just
1516 * reset the connection so that it becomes
1519 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1520 evhttp_connection_reset_(evcon);
1523 * If we have no more requests that need completion
1524 * and we want to auto-free the connection when all
1525 * requests have been completed.
1527 if (TAILQ_FIRST(&evcon->requests) == NULL
1528 && (evcon->flags & EVHTTP_CON_OUTGOING)
1529 && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1530 evhttp_connection_free(evcon);
1535 if (what & BEV_EVENT_TIMEOUT) {
1536 evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
1537 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1538 if (what & BEV_EVENT_WRITING &&
1539 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR) {
1540 evhttp_connection_read_on_write_error(evcon, req);
1544 if (what & BEV_EVENT_READING &&
1545 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR &&
1546 evbuffer_get_length(bufferevent_get_input(bufev))) {
1547 event_deferred_cb_schedule_(get_deferred_queue(evcon),
1548 &evcon->read_more_deferred_cb);
1552 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1553 } else if (what == BEV_EVENT_CONNECTED) {
1555 evhttp_connection_fail_(evcon, EVREQ_HTTP_BUFFER_ERROR);
1560 * Event callback for asynchronous connection attempt.
1563 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1565 struct evhttp_connection *evcon = arg;
1567 ev_socklen_t errsz = sizeof(error);
1569 if (evcon->fd == -1)
1570 evcon->fd = bufferevent_getfd(bufev);
1572 if (!(what & BEV_EVENT_CONNECTED)) {
1573 /* some operating systems return ECONNREFUSED immediately
1574 * when connecting to a local address. the cleanup is going
1575 * to reschedule this function call.
1578 if (errno == ECONNREFUSED)
1581 evhttp_error_cb(bufev, what, arg);
1585 if (evcon->fd == -1) {
1586 event_debug(("%s: bufferevent_getfd returned -1",
1591 /* Check if the connection completed */
1592 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1594 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT,
1595 __func__, evcon->address, evcon->port,
1596 EV_SOCK_ARG(evcon->fd)));
1601 event_debug(("%s: connect failed for \"%s:%d\" on "
1603 __func__, evcon->address, evcon->port,
1604 EV_SOCK_ARG(evcon->fd),
1605 evutil_socket_error_to_string(error)));
1609 /* We are connected to the server now */
1610 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1611 __func__, evcon->address, evcon->port,
1612 EV_SOCK_ARG(evcon->fd)));
1614 /* Reset the retry count as we were successful in connecting */
1615 evcon->retry_cnt = 0;
1616 evcon->state = EVCON_IDLE;
1618 /* reset the bufferevent cbs */
1619 bufferevent_setcb(evcon->bufev,
1625 if (!evutil_timerisset(&evcon->timeout)) {
1626 const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 };
1627 const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 };
1628 bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv);
1630 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
1633 /* try to start requests that have queued up on this connection */
1634 evhttp_request_dispatch(evcon);
1638 evhttp_connection_cb_cleanup(evcon);
1642 * Check if we got a valid response code.
1646 evhttp_valid_response_code(int code)
1655 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1659 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1660 if (n != 2 || major > 1) {
1661 event_debug(("%s: bad version %s on message %p from %s",
1662 __func__, version, req, req->remote_host));
1670 /* Parses the status line of a web server */
1673 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1677 const char *readable = "";
1679 protocol = strsep(&line, " ");
1682 number = strsep(&line, " ");
1686 if (evhttp_parse_http_version(protocol, req) < 0)
1689 req->response_code = atoi(number);
1690 if (!evhttp_valid_response_code(req->response_code)) {
1691 event_debug(("%s: bad response code \"%s\"",
1696 if (req->response_code_line != NULL)
1697 mm_free(req->response_code_line);
1698 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1699 event_warn("%s: strdup", __func__);
1706 /* Parse the first line of a HTTP request */
1709 evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len)
1711 char *eos = line + len;
1715 const char *hostname;
1718 enum evhttp_cmd_type type;
1720 while (eos > line && *(eos-1) == ' ') {
1725 if (len < strlen("GET / HTTP/1.0"))
1728 /* Parse the request line */
1729 method = strsep(&line, " ");
1733 version = strrchr(uri, ' ');
1734 if (!version || uri == version)
1739 method_len = (uri - method) - 1;
1740 type = EVHTTP_REQ_UNKNOWN_;
1743 switch (method_len) {
1745 /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1747 /* Since both GET and PUT share the same character 'T' at the end,
1748 * if the string doesn't have 'T', we can immediately determine this
1749 * is an invalid HTTP method */
1751 if (method[2] != 'T') {
1757 /* This first byte is 'G', so make sure the next byte is
1758 * 'E', if it isn't then this isn't a valid method */
1760 if (method[1] == 'E') {
1761 type = EVHTTP_REQ_GET;
1766 /* First byte is P, check second byte for 'U', if not,
1767 * we know it's an invalid method */
1768 if (method[1] == 'U') {
1769 type = EVHTTP_REQ_PUT;
1777 /* The method length is 4 bytes, leaving only the methods "POST" and "HEAD" */
1780 if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') {
1781 type = EVHTTP_REQ_POST;
1785 if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') {
1786 type = EVHTTP_REQ_HEAD;
1794 /* Method length is 5 bytes, which can only encompass PATCH and TRACE */
1797 if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') {
1798 type = EVHTTP_REQ_PATCH;
1802 if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') {
1803 type = EVHTTP_REQ_TRACE;
1812 /* Method length is 6, only valid method 6 bytes in length is DELEte */
1814 /* If the first byte isn't 'D' then it's invalid */
1815 if (*method != 'D') {
1819 if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' && method[2] == 'L' && method[1] == 'E') {
1820 type = EVHTTP_REQ_DELETE;
1825 /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1828 if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' &&
1829 method[3] == 'I' && method[2] == 'T' && method[1] == 'P') {
1830 type = EVHTTP_REQ_OPTIONS;
1835 if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' &&
1836 method[3] == 'N' && method[2] == 'N' && method[1] == 'O') {
1837 type = EVHTTP_REQ_CONNECT;
1847 if ((int)type == EVHTTP_REQ_UNKNOWN_) {
1848 event_debug(("%s: bad method %s on request %p from %s",
1849 __func__, method, req, req->remote_host));
1850 /* No error yet; we'll give a better error later when
1851 * we see that req->type is unsupported. */
1856 if (evhttp_parse_http_version(version, req) < 0)
1859 if ((req->uri = mm_strdup(uri)) == NULL) {
1860 event_debug(("%s: mm_strdup", __func__));
1864 if (type == EVHTTP_REQ_CONNECT) {
1865 if ((req->uri_elems = evhttp_uri_parse_authority(req->uri)) == NULL) {
1869 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
1870 EVHTTP_URI_NONCONFORMANT)) == NULL) {
1875 /* If we have an absolute-URI, check to see if it is an http request
1876 for a known vhost or server alias. If we don't know about this
1877 host, we consider it a proxy request. */
1878 scheme = evhttp_uri_get_scheme(req->uri_elems);
1879 hostname = evhttp_uri_get_host(req->uri_elems);
1880 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1881 !evutil_ascii_strcasecmp(scheme, "https")) &&
1883 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1884 req->flags |= EVHTTP_PROXY_REQUEST;
1890 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1892 struct evkeyval *header;
1894 TAILQ_FOREACH(header, headers, next) {
1895 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1896 return (header->value);
1903 evhttp_clear_headers(struct evkeyvalq *headers)
1905 struct evkeyval *header;
1907 for (header = TAILQ_FIRST(headers);
1909 header = TAILQ_FIRST(headers)) {
1910 TAILQ_REMOVE(headers, header, next);
1911 mm_free(header->key);
1912 mm_free(header->value);
1918 * Returns 0, if the header was successfully removed.
1919 * Returns -1, if the header could not be found.
1923 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1925 struct evkeyval *header;
1927 TAILQ_FOREACH(header, headers, next) {
1928 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1935 /* Free and remove the header that we found */
1936 TAILQ_REMOVE(headers, header, next);
1937 mm_free(header->key);
1938 mm_free(header->value);
1945 evhttp_header_is_valid_value(const char *value)
1947 const char *p = value;
1949 while ((p = strpbrk(p, "\r\n")) != NULL) {
1950 /* we really expect only one new line */
1951 p += strspn(p, "\r\n");
1952 /* we expect a space or tab for continuation */
1953 if (*p != ' ' && *p != '\t')
1960 evhttp_add_header(struct evkeyvalq *headers,
1961 const char *key, const char *value)
1963 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1965 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1966 /* drop illegal headers */
1967 event_debug(("%s: dropping illegal header key\n", __func__));
1971 if (!evhttp_header_is_valid_value(value)) {
1972 event_debug(("%s: dropping illegal header value\n", __func__));
1976 return (evhttp_add_header_internal(headers, key, value));
1980 evhttp_add_header_internal(struct evkeyvalq *headers,
1981 const char *key, const char *value)
1983 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
1984 if (header == NULL) {
1985 event_warn("%s: calloc", __func__);
1988 if ((header->key = mm_strdup(key)) == NULL) {
1990 event_warn("%s: strdup", __func__);
1993 if ((header->value = mm_strdup(value)) == NULL) {
1994 mm_free(header->key);
1996 event_warn("%s: strdup", __func__);
2000 TAILQ_INSERT_TAIL(headers, header, next);
2006 * Parses header lines from a request or a response into the specified
2007 * request object given an event buffer.
2010 * DATA_CORRUPTED on error
2011 * MORE_DATA_EXPECTED when we need to read more headers
2012 * ALL_DATA_READ when all headers have been read.
2015 enum message_read_status
2016 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
2019 enum message_read_status status = ALL_DATA_READ;
2023 line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
2025 if (req->evcon != NULL &&
2026 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2027 return (DATA_TOO_LONG);
2029 return (MORE_DATA_EXPECTED);
2032 if (req->evcon != NULL && len > req->evcon->max_headers_size) {
2034 return (DATA_TOO_LONG);
2037 req->headers_size = len;
2039 switch (req->kind) {
2040 case EVHTTP_REQUEST:
2041 if (evhttp_parse_request_line(req, line, len) == -1)
2042 status = DATA_CORRUPTED;
2044 case EVHTTP_RESPONSE:
2045 if (evhttp_parse_response_line(req, line) == -1)
2046 status = DATA_CORRUPTED;
2049 status = DATA_CORRUPTED;
2057 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
2059 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
2061 size_t old_len, line_len;
2066 old_len = strlen(header->value);
2068 /* Strip space from start and end of line. */
2069 while (*line == ' ' || *line == '\t')
2071 evutil_rtrim_lws_(line);
2073 line_len = strlen(line);
2075 newval = mm_realloc(header->value, old_len + line_len + 2);
2079 newval[old_len] = ' ';
2080 memcpy(newval + old_len + 1, line, line_len + 1);
2081 header->value = newval;
2086 enum message_read_status
2087 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
2089 enum message_read_status errcode = DATA_CORRUPTED;
2091 enum message_read_status status = MORE_DATA_EXPECTED;
2093 struct evkeyvalq* headers = req->input_headers;
2095 while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
2097 char *skey, *svalue;
2099 req->headers_size += len;
2101 if (req->evcon != NULL &&
2102 req->headers_size > req->evcon->max_headers_size) {
2103 errcode = DATA_TOO_LONG;
2107 if (*line == '\0') { /* Last header - Done */
2108 status = ALL_DATA_READ;
2113 /* Check if this is a continuation line */
2114 if (*line == ' ' || *line == '\t') {
2115 if (evhttp_append_to_last_header(headers, line) == -1)
2121 /* Processing of header lines */
2123 skey = strsep(&svalue, ":");
2127 svalue += strspn(svalue, " ");
2128 evutil_rtrim_lws_(svalue);
2130 if (evhttp_add_header(headers, skey, svalue) == -1)
2136 if (status == MORE_DATA_EXPECTED) {
2137 if (req->evcon != NULL &&
2138 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2139 return (DATA_TOO_LONG);
2150 evhttp_get_body_length(struct evhttp_request *req)
2152 struct evkeyvalq *headers = req->input_headers;
2153 const char *content_length;
2154 const char *connection;
2156 content_length = evhttp_find_header(headers, "Content-Length");
2157 connection = evhttp_find_header(headers, "Connection");
2159 if (content_length == NULL && connection == NULL)
2161 else if (content_length == NULL &&
2162 evutil_ascii_strcasecmp(connection, "Close") != 0) {
2164 } else if (content_length == NULL) {
2168 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2169 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2170 event_debug(("%s: illegal content length: %s",
2171 __func__, content_length));
2174 req->ntoread = ntoread;
2177 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2178 __func__, EV_I64_ARG(req->ntoread),
2179 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2185 evhttp_method_may_have_body(enum evhttp_cmd_type type)
2188 case EVHTTP_REQ_POST:
2189 case EVHTTP_REQ_PUT:
2190 case EVHTTP_REQ_PATCH:
2192 case EVHTTP_REQ_GET:
2193 case EVHTTP_REQ_DELETE:
2194 case EVHTTP_REQ_OPTIONS:
2195 case EVHTTP_REQ_CONNECT:
2198 case EVHTTP_REQ_TRACE:
2199 case EVHTTP_REQ_HEAD:
2206 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2208 const char *xfer_enc;
2210 /* If this is a request without a body, then we are done */
2211 if (req->kind == EVHTTP_REQUEST &&
2212 !evhttp_method_may_have_body(req->type)) {
2213 evhttp_connection_done(evcon);
2216 evcon->state = EVCON_READING_BODY;
2217 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
2218 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
2222 if (evhttp_get_body_length(req) == -1) {
2223 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2226 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2227 /* An incoming request with no content-length and no
2228 * transfer-encoding has no body. */
2229 evhttp_connection_done(evcon);
2234 /* Should we send a 100 Continue status line? */
2235 switch (evhttp_have_expect(req, 1)) {
2237 /* XXX It would be nice to do some sanity
2238 checking here. Does the resource exist?
2239 Should the resource accept post requests? If
2240 no, we should respond with an error. For
2241 now, just optimistically tell the client to
2242 send their message body. */
2243 if (req->ntoread > 0) {
2244 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2245 if ((req->evcon->max_body_size <= EV_INT64_MAX) &&
2246 (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2247 evhttp_lingering_fail(evcon, req);
2251 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2252 evhttp_send_continue(evcon, req);
2255 evhttp_send_error(req, HTTP_EXPECTATIONFAILED, NULL);
2260 evhttp_read_body(evcon, req);
2261 /* note the request may have been freed in evhttp_read_body */
2265 evhttp_read_firstline(struct evhttp_connection *evcon,
2266 struct evhttp_request *req)
2268 enum message_read_status res;
2270 res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2271 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2272 /* Error while reading, terminate */
2273 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2274 __func__, EV_SOCK_ARG(evcon->fd)));
2275 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2277 } else if (res == MORE_DATA_EXPECTED) {
2278 /* Need more header lines */
2282 evcon->state = EVCON_READING_HEADERS;
2283 evhttp_read_header(evcon, req);
2287 evhttp_read_header(struct evhttp_connection *evcon,
2288 struct evhttp_request *req)
2290 enum message_read_status res;
2291 evutil_socket_t fd = evcon->fd;
2293 res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2294 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2295 /* Error while reading, terminate */
2296 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2297 __func__, EV_SOCK_ARG(fd)));
2298 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2300 } else if (res == MORE_DATA_EXPECTED) {
2301 /* Need more header lines */
2305 /* Callback can shut down connection with negative return value */
2306 if (req->header_cb != NULL) {
2307 if ((*req->header_cb)(req, req->cb_arg) < 0) {
2308 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2313 /* Done reading headers, do the real work */
2314 switch (req->kind) {
2315 case EVHTTP_REQUEST:
2316 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2317 __func__, EV_SOCK_ARG(fd)));
2318 evhttp_get_body(evcon, req);
2319 /* note the request may have been freed in evhttp_get_body */
2322 case EVHTTP_RESPONSE:
2323 /* Start over if we got a 100 Continue response. */
2324 if (req->response_code == 100) {
2325 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
2326 evbuffer_add_buffer(output, req->output_buffer);
2327 evhttp_start_write_(evcon);
2330 if (!evhttp_response_needs_body(req)) {
2331 event_debug(("%s: skipping body for code %d\n",
2332 __func__, req->response_code));
2333 evhttp_connection_done(evcon);
2335 event_debug(("%s: start of read body for %s on "
2337 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2338 evhttp_get_body(evcon, req);
2339 /* note the request may have been freed in
2340 * evhttp_get_body */
2345 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2347 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2350 /* request may have been freed above */
2354 * Creates a TCP connection to the specified port and executes a callback
2355 * when finished. Failure or success is indicate by the passed connection
2358 * Although this interface accepts a hostname, it is intended to take
2359 * only numeric hostnames so that non-blocking DNS resolution can
2363 struct evhttp_connection *
2364 evhttp_connection_new(const char *address, ev_uint16_t port)
2366 return (evhttp_connection_base_new(NULL, NULL, address, port));
2369 struct evhttp_connection *
2370 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2371 const char *address, ev_uint16_t port)
2373 struct evhttp_connection *evcon = NULL;
2375 event_debug(("Attempting connection to %s:%d\n", address, port));
2377 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2378 event_warn("%s: calloc failed", __func__);
2385 evcon->max_headers_size = EV_SIZE_MAX;
2386 evcon->max_body_size = EV_SIZE_MAX;
2388 evutil_timerclear(&evcon->timeout);
2389 evcon->retry_cnt = evcon->retry_max = 0;
2391 if ((evcon->address = mm_strdup(address)) == NULL) {
2392 event_warn("%s: strdup failed", __func__);
2397 if (!(bev = bufferevent_socket_new(base, -1, 0))) {
2398 event_warn("%s: bufferevent_socket_new failed", __func__);
2403 bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2406 evcon->state = EVCON_DISCONNECTED;
2407 TAILQ_INIT(&evcon->requests);
2409 evcon->initial_retry_timeout.tv_sec = 2;
2410 evcon->initial_retry_timeout.tv_usec = 0;
2414 if (bufferevent_get_base(bev) != base)
2415 bufferevent_base_set(base, evcon->bufev);
2418 event_deferred_cb_init_(
2419 &evcon->read_more_deferred_cb,
2420 bufferevent_get_priority(bev),
2421 evhttp_deferred_read_cb, evcon);
2423 evcon->dns_base = dnsbase;
2424 evcon->ai_family = AF_UNSPEC;
2430 evhttp_connection_free(evcon);
2434 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2436 return evcon->bufev;
2440 evhttp_connection_get_server(struct evhttp_connection *evcon)
2442 return evcon->http_server;
2445 struct evhttp_connection *
2446 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2447 const char *address, ev_uint16_t port)
2449 return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2452 void evhttp_connection_set_family(struct evhttp_connection *evcon,
2455 evcon->ai_family = family;
2458 int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2461 int avail_flags = 0;
2462 avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2463 avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2465 if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2467 evcon->flags &= ~avail_flags;
2469 evcon->flags |= flags;
2475 evhttp_connection_set_base(struct evhttp_connection *evcon,
2476 struct event_base *base)
2478 EVUTIL_ASSERT(evcon->base == NULL);
2479 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2481 bufferevent_base_set(base, evcon->bufev);
2485 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2486 int timeout_in_secs)
2488 if (timeout_in_secs == -1)
2489 evhttp_connection_set_timeout_tv(evcon, NULL);
2492 tv.tv_sec = timeout_in_secs;
2494 evhttp_connection_set_timeout_tv(evcon, &tv);
2499 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2500 const struct timeval* tv)
2503 evcon->timeout = *tv;
2504 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
2506 const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 };
2507 const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 };
2508 evutil_timerclear(&evcon->timeout);
2509 bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv);
2514 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2515 const struct timeval *tv)
2518 evcon->initial_retry_timeout = *tv;
2520 evutil_timerclear(&evcon->initial_retry_timeout);
2521 evcon->initial_retry_timeout.tv_sec = 2;
2526 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2529 evcon->retry_max = retry_max;
2533 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2534 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2536 evcon->closecb = cb;
2537 evcon->closecb_arg = cbarg;
2541 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2542 char **address, ev_uint16_t *port)
2544 *address = evcon->address;
2545 *port = evcon->port;
2548 const struct sockaddr*
2549 evhttp_connection_get_addr(struct evhttp_connection *evcon)
2551 return bufferevent_socket_get_conn_address_(evcon->bufev);
2555 evhttp_connection_connect_(struct evhttp_connection *evcon)
2557 int old_state = evcon->state;
2558 const char *address = evcon->address;
2559 const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
2562 if (evcon->state == EVCON_CONNECTING)
2565 evhttp_connection_reset_(evcon);
2567 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2568 evcon->flags |= EVHTTP_CON_OUTGOING;
2570 if (evcon->bind_address || evcon->bind_port) {
2571 evcon->fd = bind_socket(
2572 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2573 if (evcon->fd == -1) {
2574 event_debug(("%s: failed to bind to \"%s\"",
2575 __func__, evcon->bind_address));
2579 if (bufferevent_setfd(evcon->bufev, evcon->fd))
2582 if (bufferevent_setfd(evcon->bufev, -1))
2586 /* Set up a callback for successful connection setup */
2587 bufferevent_setcb(evcon->bufev,
2588 NULL /* evhttp_read_cb */,
2589 NULL /* evhttp_write_cb */,
2590 evhttp_connection_cb,
2592 if (!evutil_timerisset(&evcon->timeout)) {
2593 const struct timeval conn_tv = { HTTP_CONNECT_TIMEOUT, 0 };
2594 bufferevent_set_timeouts(evcon->bufev, &conn_tv, &conn_tv);
2596 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
2598 /* make sure that we get a write callback */
2599 if (bufferevent_enable(evcon->bufev, EV_WRITE))
2602 evcon->state = EVCON_CONNECTING;
2604 if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
2606 (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
2607 int socklen = sizeof(struct sockaddr_in);
2608 if (sa->sa_family == AF_INET6) {
2609 socklen = sizeof(struct sockaddr_in6);
2611 ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
2613 ret = bufferevent_socket_connect_hostname(evcon->bufev,
2614 evcon->dns_base, evcon->ai_family, address, evcon->port);
2618 evcon->state = old_state;
2619 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2620 __func__, evcon->address);
2621 /* some operating systems return ECONNREFUSED immediately
2622 * when connecting to a local address. the cleanup is going
2623 * to reschedule this function call.
2625 evhttp_connection_cb_cleanup(evcon);
2633 * Starts an HTTP request on the provided evhttp_connection object.
2634 * If the connection object is not connected to the web server already,
2635 * this will start the connection.
2639 evhttp_make_request(struct evhttp_connection *evcon,
2640 struct evhttp_request *req,
2641 enum evhttp_cmd_type type, const char *uri)
2643 /* We are making a request */
2644 req->kind = EVHTTP_REQUEST;
2646 if (req->uri != NULL)
2648 if ((req->uri = mm_strdup(uri)) == NULL) {
2649 event_warn("%s: strdup", __func__);
2650 evhttp_request_free_auto(req);
2654 /* Set the protocol version if it is not supplied */
2655 if (!req->major && !req->minor) {
2660 EVUTIL_ASSERT(req->evcon == NULL);
2662 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2664 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2666 /* We do not want to conflict with retry_ev */
2667 if (evcon->retry_cnt)
2670 /* If the connection object is not connected; make it so */
2671 if (!evhttp_connected(evcon)) {
2672 int res = evhttp_connection_connect_(evcon);
2673 /* evhttp_connection_fail_(), which is called through
2674 * evhttp_connection_connect_(), assumes that req lies in
2675 * evcon->requests. Thus, enqueue the request in advance and
2676 * remove it in the error case. */
2678 TAILQ_REMOVE(&evcon->requests, req, next);
2684 * If it's connected already and we are the first in the queue,
2685 * then we can dispatch this request immediately. Otherwise, it
2686 * will be dispatched once the pending requests are completed.
2688 if (TAILQ_FIRST(&evcon->requests) == req)
2689 evhttp_request_dispatch(evcon);
2695 evhttp_cancel_request(struct evhttp_request *req)
2697 struct evhttp_connection *evcon = req->evcon;
2698 if (evcon != NULL) {
2699 /* We need to remove it from the connection */
2700 if (TAILQ_FIRST(&evcon->requests) == req) {
2701 /* it's currently being worked on, so reset
2704 evhttp_connection_fail_(evcon,
2705 EVREQ_HTTP_REQUEST_CANCEL);
2707 /* connection fail freed the request */
2710 /* otherwise, we can just remove it from the
2713 TAILQ_REMOVE(&evcon->requests, req, next);
2717 evhttp_request_free_auto(req);
2721 * Reads data from file descriptor into request structure
2722 * Request structure needs to be set up correctly.
2726 evhttp_start_read_(struct evhttp_connection *evcon)
2728 bufferevent_disable(evcon->bufev, EV_WRITE);
2729 bufferevent_enable(evcon->bufev, EV_READ);
2731 evcon->state = EVCON_READING_FIRSTLINE;
2732 /* Reset the bufferevent callbacks */
2733 bufferevent_setcb(evcon->bufev,
2739 /* If there's still data pending, process it next time through the
2740 * loop. Don't do it now; that could get recusive. */
2741 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2742 event_deferred_cb_schedule_(get_deferred_queue(evcon),
2743 &evcon->read_more_deferred_cb);
2748 evhttp_start_write_(struct evhttp_connection *evcon)
2750 bufferevent_disable(evcon->bufev, EV_WRITE);
2751 bufferevent_enable(evcon->bufev, EV_READ);
2753 evcon->state = EVCON_WRITING;
2754 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
2758 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2761 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2762 TAILQ_REMOVE(&evcon->requests, req, next);
2764 if (req->on_complete_cb != NULL) {
2765 req->on_complete_cb(req, req->on_complete_cb_arg);
2769 (REQ_VERSION_BEFORE(req, 1, 1) &&
2770 !evhttp_is_connection_keepalive(req->input_headers)) ||
2771 evhttp_is_request_connection_close(req);
2773 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2774 evhttp_request_free(req);
2777 evhttp_connection_free(evcon);
2781 /* we have a persistent connection; try to accept another request. */
2782 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2783 evhttp_connection_free(evcon);
2788 * Returns an error page.
2792 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2795 #define ERR_FORMAT "<HTML><HEAD>\n" \
2796 "<TITLE>%d %s</TITLE>\n" \
2801 struct evbuffer *buf = evbuffer_new();
2803 /* if we cannot allocate memory; we just drop the connection */
2804 evhttp_connection_free(req->evcon);
2807 if (reason == NULL) {
2808 reason = evhttp_response_phrase_internal(error);
2811 evhttp_response_code_(req, error, reason);
2813 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2815 evhttp_send_page_(req, buf);
2821 /* Requires that headers and response code are already set up */
2824 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2826 struct evhttp_connection *evcon = req->evcon;
2828 if (evcon == NULL) {
2829 evhttp_request_free(req);
2833 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2835 /* we expect no more calls form the user on this request */
2838 /* xxx: not sure if we really should expose the data buffer this way */
2839 if (databuf != NULL)
2840 evbuffer_add_buffer(req->output_buffer, databuf);
2842 /* Adds headers to the response */
2843 evhttp_make_header(evcon, req);
2845 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2849 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2850 struct evbuffer *databuf)
2852 evhttp_response_code_(req, code, reason);
2854 evhttp_send(req, databuf);
2858 evhttp_send_reply_start(struct evhttp_request *req, int code,
2861 evhttp_response_code_(req, code, reason);
2863 if (req->evcon == NULL)
2866 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2867 REQ_VERSION_ATLEAST(req, 1, 1) &&
2868 evhttp_response_needs_body(req)) {
2870 * prefer HTTP/1.1 chunked encoding to closing the connection;
2871 * note RFC 2616 section 4.4 forbids it with Content-Length:
2872 * and it's not necessary then anyway.
2874 evhttp_add_header(req->output_headers, "Transfer-Encoding",
2880 evhttp_make_header(req->evcon, req);
2881 evhttp_write_buffer(req->evcon, NULL, NULL);
2885 evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
2886 void (*cb)(struct evhttp_connection *, void *), void *arg)
2888 struct evhttp_connection *evcon = req->evcon;
2889 struct evbuffer *output;
2894 output = bufferevent_get_output(evcon->bufev);
2896 if (evbuffer_get_length(databuf) == 0)
2898 if (!evhttp_response_needs_body(req))
2901 evbuffer_add_printf(output, "%x\r\n",
2902 (unsigned)evbuffer_get_length(databuf));
2904 evbuffer_add_buffer(output, databuf);
2906 evbuffer_add(output, "\r\n", 2);
2908 evhttp_write_buffer(evcon, cb, arg);
2912 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
2914 evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
2917 evhttp_send_reply_end(struct evhttp_request *req)
2919 struct evhttp_connection *evcon = req->evcon;
2920 struct evbuffer *output;
2922 if (evcon == NULL) {
2923 evhttp_request_free(req);
2927 output = bufferevent_get_output(evcon->bufev);
2929 /* we expect no more calls form the user on this request */
2933 evbuffer_add(output, "0\r\n\r\n", 5);
2934 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2936 } else if (evbuffer_get_length(output) == 0) {
2937 /* let the connection know that we are done with the request */
2938 evhttp_send_done(evcon, NULL);
2940 /* make the callback execute after all data has been written */
2941 evcon->cb = evhttp_send_done;
2942 evcon->cb_arg = NULL;
2946 static const char *informational_phrases[] = {
2947 /* 100 */ "Continue",
2948 /* 101 */ "Switching Protocols"
2951 static const char *success_phrases[] = {
2953 /* 201 */ "Created",
2954 /* 202 */ "Accepted",
2955 /* 203 */ "Non-Authoritative Information",
2956 /* 204 */ "No Content",
2957 /* 205 */ "Reset Content",
2958 /* 206 */ "Partial Content"
2961 static const char *redirection_phrases[] = {
2962 /* 300 */ "Multiple Choices",
2963 /* 301 */ "Moved Permanently",
2965 /* 303 */ "See Other",
2966 /* 304 */ "Not Modified",
2967 /* 305 */ "Use Proxy",
2968 /* 307 */ "Temporary Redirect"
2971 static const char *client_error_phrases[] = {
2972 /* 400 */ "Bad Request",
2973 /* 401 */ "Unauthorized",
2974 /* 402 */ "Payment Required",
2975 /* 403 */ "Forbidden",
2976 /* 404 */ "Not Found",
2977 /* 405 */ "Method Not Allowed",
2978 /* 406 */ "Not Acceptable",
2979 /* 407 */ "Proxy Authentication Required",
2980 /* 408 */ "Request Time-out",
2981 /* 409 */ "Conflict",
2983 /* 411 */ "Length Required",
2984 /* 412 */ "Precondition Failed",
2985 /* 413 */ "Request Entity Too Large",
2986 /* 414 */ "Request-URI Too Large",
2987 /* 415 */ "Unsupported Media Type",
2988 /* 416 */ "Requested range not satisfiable",
2989 /* 417 */ "Expectation Failed"
2992 static const char *server_error_phrases[] = {
2993 /* 500 */ "Internal Server Error",
2994 /* 501 */ "Not Implemented",
2995 /* 502 */ "Bad Gateway",
2996 /* 503 */ "Service Unavailable",
2997 /* 504 */ "Gateway Time-out",
2998 /* 505 */ "HTTP Version not supported"
3001 struct response_class {
3003 size_t num_responses;
3004 const char **responses;
3008 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
3011 static const struct response_class response_classes[] = {
3012 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
3013 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
3014 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
3015 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
3016 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
3020 evhttp_response_phrase_internal(int code)
3022 int klass = code / 100 - 1;
3023 int subcode = code % 100;
3025 /* Unknown class - can't do any better here */
3026 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
3027 return "Unknown Status Class";
3029 /* Unknown sub-code, return class name at least */
3030 if (subcode >= (int) response_classes[klass].num_responses)
3031 return response_classes[klass].name;
3033 return response_classes[klass].responses[subcode];
3037 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
3039 req->kind = EVHTTP_RESPONSE;
3040 req->response_code = code;
3041 if (req->response_code_line != NULL)
3042 mm_free(req->response_code_line);
3044 reason = evhttp_response_phrase_internal(code);
3045 req->response_code_line = mm_strdup(reason);
3046 if (req->response_code_line == NULL) {
3047 event_warn("%s: strdup", __func__);
3048 /* XXX what else can we do? */
3053 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
3055 if (!req->major || !req->minor) {
3060 if (req->kind != EVHTTP_RESPONSE)
3061 evhttp_response_code_(req, 200, "OK");
3063 evhttp_clear_headers(req->output_headers);
3064 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
3065 evhttp_add_header(req->output_headers, "Connection", "close");
3067 evhttp_send(req, databuf);
3070 static const char uri_chars[256] = {
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,
3074 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
3075 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
3077 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3078 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
3079 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3080 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
3082 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3083 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3084 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3085 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3087 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3088 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3089 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3090 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3093 #define CHAR_IS_UNRESERVED(c) \
3094 (uri_chars[(unsigned char)(c)])
3097 * Helper functions to encode/decode a string for inclusion in a URI.
3098 * The returned string must be freed by the caller.
3101 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3103 struct evbuffer *buf = evbuffer_new();
3104 const char *p, *end;
3105 char *result = NULL;
3112 if (uri + len < uri) {
3118 size_t slen = strlen(uri);
3120 if (slen >= EV_SSIZE_MAX) {
3121 /* we don't want to mix signed and unsigned */
3125 if (uri + slen < uri) {
3132 for (p = uri; p < end; p++) {
3133 if (CHAR_IS_UNRESERVED(*p)) {
3134 evbuffer_add(buf, p, 1);
3135 } else if (*p == ' ' && space_as_plus) {
3136 evbuffer_add(buf, "+", 1);
3138 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3142 evbuffer_add(buf, "", 1); /* NUL-terminator. */
3143 result = mm_malloc(evbuffer_get_length(buf));
3146 evbuffer_remove(buf, result, evbuffer_get_length(buf));
3155 evhttp_encode_uri(const char *str)
3157 return evhttp_uriencode(str, -1, 0);
3161 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
3162 * If -1, when true we transform plus to space only after we've seen
3163 * a ?. -1 is deprecated.
3164 * @return the number of bytes written to 'ret'.
3167 evhttp_decode_uri_internal(
3168 const char *uri, size_t length, char *ret, int decode_plus_ctl)
3172 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3175 for (i = j = 0; i < length; i++) {
3178 if (decode_plus_ctl < 0)
3180 } else if (c == '+' && decode_plus) {
3182 } else if ((i + 2) < length && c == '%' &&
3183 EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3188 c = (char)strtol(tmp, NULL, 16);
3200 evhttp_decode_uri(const char *uri)
3204 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3205 event_warn("%s: malloc(%lu)", __func__,
3206 (unsigned long)(strlen(uri) + 1));
3210 evhttp_decode_uri_internal(uri, strlen(uri),
3211 ret, -1 /*always_decode_plus*/);
3217 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3222 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3223 event_warn("%s: malloc(%lu)", __func__,
3224 (unsigned long)(strlen(uri) + 1));
3228 n = evhttp_decode_uri_internal(uri, strlen(uri),
3229 ret, !!decode_plus/*always_decode_plus*/);
3232 EVUTIL_ASSERT(n >= 0);
3233 *size_out = (size_t)n;
3240 * Helper function to parse out arguments in a query.
3241 * The arguments are separated by key and value.
3245 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3251 const char *query_part;
3253 struct evhttp_uri *uri=NULL;
3255 TAILQ_INIT(headers);
3258 uri = evhttp_uri_parse(str);
3261 query_part = evhttp_uri_get_query(uri);
3266 /* No arguments - we are done */
3267 if (!query_part || !strlen(query_part)) {
3272 if ((line = mm_strdup(query_part)) == NULL) {
3273 event_warn("%s: strdup", __func__);
3277 p = argument = line;
3278 while (p != NULL && *p != '\0') {
3279 char *key, *value, *decoded_value;
3280 argument = strsep(&p, "&");
3283 key = strsep(&value, "=");
3284 if (value == NULL || *key == '\0') {
3288 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3289 event_warn("%s: mm_malloc", __func__);
3292 evhttp_decode_uri_internal(value, strlen(value),
3293 decoded_value, 1 /*always_decode_plus*/);
3294 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3295 evhttp_add_header_internal(headers, key, decoded_value);
3296 mm_free(decoded_value);
3302 evhttp_clear_headers(headers);
3307 evhttp_uri_free(uri);
3312 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3314 return evhttp_parse_query_impl(uri, headers, 1);
3317 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3319 return evhttp_parse_query_impl(uri, headers, 0);
3322 static struct evhttp_cb *
3323 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3325 struct evhttp_cb *cb;
3330 /* Test for different URLs */
3331 path = evhttp_uri_get_path(req->uri_elems);
3332 offset = strlen(path);
3333 if ((translated = mm_malloc(offset + 1)) == NULL)
3335 evhttp_decode_uri_internal(path, offset, translated,
3336 0 /* decode_plus */);
3338 TAILQ_FOREACH(cb, callbacks, next) {
3339 if (!strcmp(cb->what, translated)) {
3340 mm_free(translated);
3345 mm_free(translated);
3351 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3356 switch (c = *pattern++) {
3358 return *name == '\0';
3361 while (*name != '\0') {
3362 if (prefix_suffix_match(pattern, name,
3371 EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3381 Search the vhost hierarchy beginning with http for a server alias
3382 matching hostname. If a match is found, and outhttp is non-null,
3383 outhttp is set to the matching http object and 1 is returned.
3387 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3388 const char *hostname)
3390 struct evhttp_server_alias *alias;
3391 struct evhttp *vhost;
3393 TAILQ_FOREACH(alias, &http->aliases, next) {
3394 /* XXX Do we need to handle IP addresses? */
3395 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3402 /* XXX It might be good to avoid recursion here, but I don't
3403 see a way to do that w/o a list. */
3404 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3405 if (evhttp_find_alias(vhost, outhttp, hostname))
3413 Attempts to find the best http object to handle a request for a hostname.
3414 All aliases for the root http object and vhosts are searched for an exact
3415 match. Then, the vhost hierarchy is traversed again for a matching
3418 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3419 is set with the best matching http object. If there are no matches, the
3420 root http object is stored in outhttp and 0 is returned.
3424 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3425 const char *hostname)
3427 struct evhttp *vhost;
3428 struct evhttp *oldhttp;
3429 int match_found = 0;
3431 if (evhttp_find_alias(http, outhttp, hostname))
3436 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3437 if (prefix_suffix_match(vhost->vhost_pattern,
3438 hostname, 1 /* ignorecase */)) {
3444 } while (oldhttp != http);
3453 evhttp_handle_request(struct evhttp_request *req, void *arg)
3455 struct evhttp *http = arg;
3456 struct evhttp_cb *cb = NULL;
3457 const char *hostname;
3459 /* we have a new request on which the user needs to take action */
3462 bufferevent_disable(req->evcon->bufev, EV_READ);
3464 if (req->type == 0 || req->uri == NULL) {
3465 evhttp_send_error(req, req->response_code, NULL);
3469 if ((http->allowed_methods & req->type) == 0) {
3470 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3471 (unsigned)req->type, (unsigned)http->allowed_methods));
3472 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3476 /* handle potential virtual hosts */
3477 hostname = evhttp_request_get_host(req);
3478 if (hostname != NULL) {
3479 evhttp_find_vhost(http, &http, hostname);
3482 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3483 (*cb->cb)(req, cb->cbarg);
3487 /* Generic call back */
3489 (*http->gencb)(req, http->gencbarg);
3492 /* We need to send a 404 here */
3493 #define ERR_FORMAT "<html><head>" \
3494 "<title>404 Not Found</title>" \
3496 "<h1>Not Found</h1>" \
3497 "<p>The requested URL %s was not found on this server.</p>"\
3501 struct evbuffer *buf;
3503 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3504 evhttp_connection_free(req->evcon);
3508 if ((buf = evbuffer_new()) == NULL) {
3509 mm_free(escaped_html);
3510 evhttp_connection_free(req->evcon);
3514 evhttp_response_code_(req, HTTP_NOTFOUND, "Not Found");
3516 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3518 mm_free(escaped_html);
3520 evhttp_send_page_(req, buf);
3527 /* Listener callback when a connection arrives at a server. */
3529 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3531 struct evhttp *http = arg;
3533 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3537 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3539 struct evhttp_bound_socket *bound =
3540 evhttp_bind_socket_with_handle(http, address, port);
3546 struct evhttp_bound_socket *
3547 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3550 struct evhttp_bound_socket *bound;
3553 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3556 if (listen(fd, 128) == -1) {
3557 serrno = EVUTIL_SOCKET_ERROR();
3558 event_sock_warn(fd, "%s: listen", __func__);
3559 evutil_closesocket(fd);
3560 EVUTIL_SET_SOCKET_ERROR(serrno);
3564 bound = evhttp_accept_socket_with_handle(http, fd);
3566 if (bound != NULL) {
3567 event_debug(("Bound to port %d - Awaiting connections ... ",
3576 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3578 struct evhttp_bound_socket *bound =
3579 evhttp_accept_socket_with_handle(http, fd);
3586 evhttp_foreach_bound_socket(struct evhttp *http,
3587 evhttp_bound_socket_foreach_fn *function,
3590 struct evhttp_bound_socket *bound;
3592 TAILQ_FOREACH(bound, &http->sockets, next)
3593 function(bound, argument);
3596 struct evhttp_bound_socket *
3597 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3599 struct evhttp_bound_socket *bound;
3600 struct evconnlistener *listener;
3602 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3604 listener = evconnlistener_new(http->base, NULL, NULL,
3606 0, /* Backlog is '0' because we already said 'listen' */
3611 bound = evhttp_bind_listener(http, listener);
3613 evconnlistener_free(listener);
3619 struct evhttp_bound_socket *
3620 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3622 struct evhttp_bound_socket *bound;
3624 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3628 bound->listener = listener;
3629 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3631 evconnlistener_set_cb(listener, accept_socket_cb, http);
3636 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3638 return evconnlistener_get_fd(bound->listener);
3641 struct evconnlistener *
3642 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3644 return bound->listener;
3648 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3650 TAILQ_REMOVE(&http->sockets, bound, next);
3651 evconnlistener_free(bound->listener);
3655 static struct evhttp*
3656 evhttp_new_object(void)
3658 struct evhttp *http = NULL;
3660 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3661 event_warn("%s: calloc", __func__);
3665 evutil_timerclear(&http->timeout);
3666 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3667 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3668 evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
3669 evhttp_set_allowed_methods(http,
3676 TAILQ_INIT(&http->sockets);
3677 TAILQ_INIT(&http->callbacks);
3678 TAILQ_INIT(&http->connections);
3679 TAILQ_INIT(&http->virtualhosts);
3680 TAILQ_INIT(&http->aliases);
3686 evhttp_new(struct event_base *base)
3688 struct evhttp *http = NULL;
3690 http = evhttp_new_object();
3699 * Start a web server on the specified address and port.
3703 evhttp_start(const char *address, ev_uint16_t port)
3705 struct evhttp *http = NULL;
3707 http = evhttp_new_object();
3710 if (evhttp_bind_socket(http, address, port) == -1) {
3719 evhttp_free(struct evhttp* http)
3721 struct evhttp_cb *http_cb;
3722 struct evhttp_connection *evcon;
3723 struct evhttp_bound_socket *bound;
3724 struct evhttp* vhost;
3725 struct evhttp_server_alias *alias;
3727 /* Remove the accepting part */
3728 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3729 TAILQ_REMOVE(&http->sockets, bound, next);
3731 evconnlistener_free(bound->listener);
3736 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3737 /* evhttp_connection_free removes the connection */
3738 evhttp_connection_free(evcon);
3741 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3742 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3743 mm_free(http_cb->what);
3747 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3748 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3753 if (http->vhost_pattern != NULL)
3754 mm_free(http->vhost_pattern);
3756 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3757 TAILQ_REMOVE(&http->aliases, alias, next);
3758 mm_free(alias->alias);
3766 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3767 struct evhttp* vhost)
3769 /* a vhost can only be a vhost once and should not have bound sockets */
3770 if (vhost->vhost_pattern != NULL ||
3771 TAILQ_FIRST(&vhost->sockets) != NULL)
3774 vhost->vhost_pattern = mm_strdup(pattern);
3775 if (vhost->vhost_pattern == NULL)
3778 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3784 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3786 if (vhost->vhost_pattern == NULL)
3789 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3791 mm_free(vhost->vhost_pattern);
3792 vhost->vhost_pattern = NULL;
3798 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3800 struct evhttp_server_alias *evalias;
3802 evalias = mm_calloc(1, sizeof(*evalias));
3806 evalias->alias = mm_strdup(alias);
3807 if (!evalias->alias) {
3812 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3818 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3820 struct evhttp_server_alias *evalias;
3822 TAILQ_FOREACH(evalias, &http->aliases, next) {
3823 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3824 TAILQ_REMOVE(&http->aliases, evalias, next);
3825 mm_free(evalias->alias);
3835 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
3837 if (timeout_in_secs == -1) {
3838 evhttp_set_timeout_tv(http, NULL);
3841 tv.tv_sec = timeout_in_secs;
3843 evhttp_set_timeout_tv(http, &tv);
3848 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
3851 http->timeout = *tv;
3853 evutil_timerclear(&http->timeout);
3857 int evhttp_set_flags(struct evhttp *http, int flags)
3859 int avail_flags = 0;
3860 avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
3862 if (flags & ~avail_flags)
3864 http->flags &= ~avail_flags;
3866 http->flags |= flags;
3872 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
3874 if (max_headers_size < 0)
3875 http->default_max_headers_size = EV_SIZE_MAX;
3877 http->default_max_headers_size = max_headers_size;
3881 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
3883 if (max_body_size < 0)
3884 http->default_max_body_size = EV_UINT64_MAX;
3886 http->default_max_body_size = max_body_size;
3890 evhttp_set_default_content_type(struct evhttp *http,
3891 const char *content_type) {
3892 http->default_content_type = content_type;
3896 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
3898 http->allowed_methods = methods;
3902 evhttp_set_cb(struct evhttp *http, const char *uri,
3903 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3905 struct evhttp_cb *http_cb;
3907 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3908 if (strcmp(http_cb->what, uri) == 0)
3912 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
3913 event_warn("%s: calloc", __func__);
3917 http_cb->what = mm_strdup(uri);
3918 if (http_cb->what == NULL) {
3919 event_warn("%s: strdup", __func__);
3924 http_cb->cbarg = cbarg;
3926 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
3932 evhttp_del_cb(struct evhttp *http, const char *uri)
3934 struct evhttp_cb *http_cb;
3936 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3937 if (strcmp(http_cb->what, uri) == 0)
3940 if (http_cb == NULL)
3943 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3944 mm_free(http_cb->what);
3951 evhttp_set_gencb(struct evhttp *http,
3952 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3955 http->gencbarg = cbarg;
3959 evhttp_set_bevcb(struct evhttp *http,
3960 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
3963 http->bevcbarg = cbarg;
3967 * Request related functions
3970 struct evhttp_request *
3971 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
3973 struct evhttp_request *req = NULL;
3975 /* Allocate request structure */
3976 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
3977 event_warn("%s: calloc", __func__);
3981 req->headers_size = 0;
3984 req->kind = EVHTTP_RESPONSE;
3985 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3986 if (req->input_headers == NULL) {
3987 event_warn("%s: calloc", __func__);
3990 TAILQ_INIT(req->input_headers);
3992 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3993 if (req->output_headers == NULL) {
3994 event_warn("%s: calloc", __func__);
3997 TAILQ_INIT(req->output_headers);
3999 if ((req->input_buffer = evbuffer_new()) == NULL) {
4000 event_warn("%s: evbuffer_new", __func__);
4004 if ((req->output_buffer = evbuffer_new()) == NULL) {
4005 event_warn("%s: evbuffer_new", __func__);
4016 evhttp_request_free(req);
4021 evhttp_request_free(struct evhttp_request *req)
4023 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
4024 req->flags |= EVHTTP_REQ_NEEDS_FREE;
4028 if (req->remote_host != NULL)
4029 mm_free(req->remote_host);
4030 if (req->uri != NULL)
4032 if (req->uri_elems != NULL)
4033 evhttp_uri_free(req->uri_elems);
4034 if (req->response_code_line != NULL)
4035 mm_free(req->response_code_line);
4036 if (req->host_cache != NULL)
4037 mm_free(req->host_cache);
4039 evhttp_clear_headers(req->input_headers);
4040 mm_free(req->input_headers);
4042 evhttp_clear_headers(req->output_headers);
4043 mm_free(req->output_headers);
4045 if (req->input_buffer != NULL)
4046 evbuffer_free(req->input_buffer);
4048 if (req->output_buffer != NULL)
4049 evbuffer_free(req->output_buffer);
4055 evhttp_request_own(struct evhttp_request *req)
4057 req->flags |= EVHTTP_USER_OWNED;
4061 evhttp_request_is_owned(struct evhttp_request *req)
4063 return (req->flags & EVHTTP_USER_OWNED) != 0;
4066 struct evhttp_connection *
4067 evhttp_request_get_connection(struct evhttp_request *req)
4073 evhttp_connection_get_base(struct evhttp_connection *conn)
4079 evhttp_request_set_chunked_cb(struct evhttp_request *req,
4080 void (*cb)(struct evhttp_request *, void *))
4086 evhttp_request_set_header_cb(struct evhttp_request *req,
4087 int (*cb)(struct evhttp_request *, void *))
4089 req->header_cb = cb;
4093 evhttp_request_set_error_cb(struct evhttp_request *req,
4094 void (*cb)(enum evhttp_request_error, void *))
4100 evhttp_request_set_on_complete_cb(struct evhttp_request *req,
4101 void (*cb)(struct evhttp_request *, void *), void *cb_arg)
4103 req->on_complete_cb = cb;
4104 req->on_complete_cb_arg = cb_arg;
4108 * Allows for inspection of the request URI
4112 evhttp_request_get_uri(const struct evhttp_request *req) {
4113 if (req->uri == NULL)
4114 event_debug(("%s: request %p has no uri\n", __func__, req));
4118 const struct evhttp_uri *
4119 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4120 if (req->uri_elems == NULL)
4121 event_debug(("%s: request %p has no uri elems\n",
4123 return (req->uri_elems);
4127 evhttp_request_get_host(struct evhttp_request *req)
4129 const char *host = NULL;
4131 if (req->host_cache)
4132 return req->host_cache;
4135 host = evhttp_uri_get_host(req->uri_elems);
4136 if (!host && req->input_headers) {
4140 host = evhttp_find_header(req->input_headers, "Host");
4141 /* The Host: header may include a port. Remove it here
4142 to be consistent with uri_elems case above. */
4144 p = host + strlen(host) - 1;
4145 while (p > host && EVUTIL_ISDIGIT_(*p))
4147 if (p > host && *p == ':') {
4149 req->host_cache = mm_malloc(len + 1);
4150 if (!req->host_cache) {
4151 event_warn("%s: malloc", __func__);
4154 memcpy(req->host_cache, host, len);
4155 req->host_cache[len] = '\0';
4156 host = req->host_cache;
4164 enum evhttp_cmd_type
4165 evhttp_request_get_command(const struct evhttp_request *req) {
4170 evhttp_request_get_response_code(const struct evhttp_request *req)
4172 return req->response_code;
4176 evhttp_request_get_response_code_line(const struct evhttp_request *req)
4178 return req->response_code_line;
4181 /** Returns the input headers */
4182 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4184 return (req->input_headers);
4187 /** Returns the output headers */
4188 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4190 return (req->output_headers);
4193 /** Returns the input buffer */
4194 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4196 return (req->input_buffer);
4199 /** Returns the output buffer */
4200 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4202 return (req->output_buffer);
4207 * Takes a file descriptor to read a request from.
4208 * The callback is executed once the whole request has been read.
4211 static struct evhttp_connection*
4212 evhttp_get_request_connection(
4213 struct evhttp* http,
4214 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
4216 struct evhttp_connection *evcon;
4217 char *hostname = NULL, *portname = NULL;
4218 struct bufferevent* bev = NULL;
4220 #ifdef EVENT__HAVE_STRUCT_SOCKADDR_UN
4221 if (sa->sa_family == AF_UNIX) {
4222 struct sockaddr_un *sa_un = (struct sockaddr_un *)sa;
4223 sa_un->sun_path[0] = '\0';
4227 name_from_addr(sa, salen, &hostname, &portname);
4228 if (hostname == NULL || portname == NULL) {
4229 if (hostname) mm_free(hostname);
4230 if (portname) mm_free(portname);
4234 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4235 __func__, hostname, portname, EV_SOCK_ARG(fd)));
4237 /* we need a connection object to put the http request on */
4238 if (http->bevcb != NULL) {
4239 bev = (*http->bevcb)(http->base, http->bevcbarg);
4241 evcon = evhttp_connection_base_bufferevent_new(
4242 http->base, NULL, bev, hostname, atoi(portname));
4248 evcon->max_headers_size = http->default_max_headers_size;
4249 evcon->max_body_size = http->default_max_body_size;
4250 if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4251 evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4253 evcon->flags |= EVHTTP_CON_INCOMING;
4254 evcon->state = EVCON_READING_FIRSTLINE;
4258 if (bufferevent_setfd(evcon->bufev, fd))
4260 if (bufferevent_enable(evcon->bufev, EV_READ))
4262 if (bufferevent_disable(evcon->bufev, EV_WRITE))
4264 bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
4269 evhttp_connection_free(evcon);
4274 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4276 struct evhttp *http = evcon->http_server;
4277 struct evhttp_request *req;
4278 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4281 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4282 event_warn("%s: strdup", __func__);
4283 evhttp_request_free(req);
4286 req->remote_port = evcon->port;
4288 req->evcon = evcon; /* the request ends up owning the connection */
4289 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4291 /* We did not present the request to the user user yet, so treat it as
4292 * if the user was done with the request. This allows us to free the
4293 * request on a persistent connection if the client drops it without
4294 * sending a request.
4298 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4300 req->kind = EVHTTP_REQUEST;
4303 evhttp_start_read_(evcon);
4309 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4310 struct sockaddr *sa, ev_socklen_t salen)
4312 struct evhttp_connection *evcon;
4314 evcon = evhttp_get_request_connection(http, fd, sa, salen);
4315 if (evcon == NULL) {
4316 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4317 __func__, EV_SOCK_ARG(fd));
4318 evutil_closesocket(fd);
4322 /* the timeout can be used by the server to close idle connections */
4323 if (evutil_timerisset(&http->timeout))
4324 evhttp_connection_set_timeout_tv(evcon, &http->timeout);
4327 * if we want to accept more than one request on a connection,
4328 * we need to know which http server it belongs to.
4330 evcon->http_server = http;
4331 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4333 if (evhttp_associate_new_request_with_connection(evcon) == -1)
4334 evhttp_connection_free(evcon);
4339 * Network helper functions that we do not want to export to the rest of
4344 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4345 char **phost, char **pport)
4347 char ntop[NI_MAXHOST];
4348 char strport[NI_MAXSERV];
4351 #ifdef EVENT__HAVE_GETNAMEINFO
4352 ni_result = getnameinfo(sa, salen,
4353 ntop, sizeof(ntop), strport, sizeof(strport),
4354 NI_NUMERICHOST|NI_NUMERICSERV);
4356 if (ni_result != 0) {
4358 /* Windows doesn't have an EAI_SYSTEM. */
4359 if (ni_result == EAI_SYSTEM)
4360 event_err(1, "getnameinfo failed");
4363 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4367 ni_result = fake_getnameinfo(sa, salen,
4368 ntop, sizeof(ntop), strport, sizeof(strport),
4369 NI_NUMERICHOST|NI_NUMERICSERV);
4374 *phost = mm_strdup(ntop);
4375 *pport = mm_strdup(strport);
4378 /* Create a non-blocking socket and bind it */
4379 /* todo: rename this function */
4380 static evutil_socket_t
4381 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
4388 /* Create listen socket */
4389 fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
4390 SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
4392 event_sock_warn(-1, "socket");
4396 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
4399 if (evutil_make_listen_socket_reuseable(fd) < 0)
4404 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
4412 serrno = EVUTIL_SOCKET_ERROR();
4413 evutil_closesocket(fd);
4414 EVUTIL_SET_SOCKET_ERROR(serrno);
4418 static struct evutil_addrinfo *
4419 make_addrinfo(const char *address, ev_uint16_t port)
4421 struct evutil_addrinfo *ai = NULL;
4423 struct evutil_addrinfo hints;
4424 char strport[NI_MAXSERV];
4427 memset(&hints, 0, sizeof(hints));
4428 hints.ai_family = AF_UNSPEC;
4429 hints.ai_socktype = SOCK_STREAM;
4430 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
4431 * types we don't have an interface to connect to. */
4432 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
4433 evutil_snprintf(strport, sizeof(strport), "%d", port);
4434 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
4436 if (ai_result == EVUTIL_EAI_SYSTEM)
4437 event_warn("getaddrinfo");
4439 event_warnx("getaddrinfo: %s",
4440 evutil_gai_strerror(ai_result));
4447 static evutil_socket_t
4448 bind_socket(const char *address, ev_uint16_t port, int reuse)
4451 struct evutil_addrinfo *aitop = NULL;
4453 /* just create an unbound socket */
4454 if (address == NULL && port == 0)
4455 return bind_socket_ai(NULL, 0);
4457 aitop = make_addrinfo(address, port);
4462 fd = bind_socket_ai(aitop, reuse);
4464 evutil_freeaddrinfo(aitop);
4471 char *scheme; /* scheme; e.g http, ftp etc */
4472 char *userinfo; /* userinfo (typically username:pass), or NULL */
4473 char *host; /* hostname, IP address, or NULL */
4474 int port; /* port, or zero */
4475 char *path; /* path, or "". */
4476 char *query; /* query, or NULL */
4477 char *fragment; /* fragment or NULL */
4481 evhttp_uri_new(void)
4483 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
4490 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
4495 /* Return true if the string starting at s and ending immediately before eos
4496 * is a valid URI scheme according to RFC3986
4499 scheme_ok(const char *s, const char *eos)
4501 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4502 EVUTIL_ASSERT(eos >= s);
4505 if (!EVUTIL_ISALPHA_(*s))
4508 if (! EVUTIL_ISALNUM_(*s) &&
4509 *s != '+' && *s != '-' && *s != '.')
4515 #define SUBDELIMS "!$&'()*+,;="
4517 /* Return true iff [s..eos) is a valid userinfo */
4519 userinfo_ok(const char *s, const char *eos)
4522 if (CHAR_IS_UNRESERVED(*s) ||
4523 strchr(SUBDELIMS, *s) ||
4526 else if (*s == '%' && s+2 < eos &&
4527 EVUTIL_ISXDIGIT_(s[1]) &&
4528 EVUTIL_ISXDIGIT_(s[2]))
4537 regname_ok(const char *s, const char *eos)
4539 while (s && s<eos) {
4540 if (CHAR_IS_UNRESERVED(*s) ||
4541 strchr(SUBDELIMS, *s))
4543 else if (*s == '%' &&
4544 EVUTIL_ISXDIGIT_(s[1]) &&
4545 EVUTIL_ISXDIGIT_(s[2]))
4554 parse_port(const char *s, const char *eos)
4558 if (! EVUTIL_ISDIGIT_(*s))
4560 portnum = (portnum * 10) + (*s - '0');
4563 if (portnum > 65535)
4570 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4572 bracket_addr_ok(const char *s, const char *eos)
4574 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4577 /* IPvFuture, or junk.
4578 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4580 s += 2; /* skip [v */
4582 if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
4584 while (s < eos && *s != '.') {
4585 if (EVUTIL_ISXDIGIT_(*s))
4594 if (CHAR_IS_UNRESERVED(*s) ||
4595 strchr(SUBDELIMS, *s) ||
4605 ev_ssize_t n_chars = eos-s-2;
4606 struct in6_addr in6;
4607 if (n_chars >= 64) /* way too long */
4609 memcpy(buf, s+1, n_chars);
4611 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4616 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4621 uri->host = mm_strdup("");
4622 if (uri->host == NULL) {
4623 event_warn("%s: strdup", __func__);
4629 /* Optionally, we start with "userinfo@" */
4631 cp = strchr(s, '@');
4632 if (cp && cp < eos) {
4633 if (! userinfo_ok(s,cp))
4636 uri->userinfo = mm_strdup(s);
4637 if (uri->userinfo == NULL) {
4638 event_warn("%s: strdup", __func__);
4644 /* Optionally, we end with ":port" */
4645 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
4647 if (port >= cp && *port == ':') {
4648 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4651 else if ((uri->port = parse_port(port+1, eos))<0)
4655 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4656 * an IP-Literal, or a reg-name */
4657 EVUTIL_ASSERT(eos >= cp);
4658 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4659 /* IPv6address, IP-Literal, or junk. */
4660 if (! bracket_addr_ok(cp, eos))
4663 /* Make sure the host part is ok. */
4664 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4667 uri->host = mm_malloc(eos-cp+1);
4668 if (uri->host == NULL) {
4669 event_warn("%s: malloc", __func__);
4672 memcpy(uri->host, cp, eos-cp);
4673 uri->host[eos-cp] = '\0';
4679 end_of_authority(char *cp)
4682 if (*cp == '?' || *cp == '#' || *cp == '/')
4695 /* Return the character after the longest prefix of 'cp' that matches...
4696 * *pchar / "/" if allow_qchars is false, or
4697 * *(pchar / "/" / "?") if allow_qchars is true.
4700 end_of_path(char *cp, enum uri_part part, unsigned flags)
4702 if (flags & EVHTTP_URI_NONCONFORMANT) {
4703 /* If NONCONFORMANT:
4704 * Path is everything up to a # or ? or nul.
4705 * Query is everything up a # or nul
4706 * Fragment is everything up to a nul.
4710 while (*cp && *cp != '#' && *cp != '?')
4714 while (*cp && *cp != '#')
4725 if (CHAR_IS_UNRESERVED(*cp) ||
4726 strchr(SUBDELIMS, *cp) ||
4727 *cp == ':' || *cp == '@' || *cp == '/')
4729 else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
4730 EVUTIL_ISXDIGIT_(cp[2]))
4732 else if (*cp == '?' && part != PART_PATH)
4741 path_matches_noscheme(const char *cp)
4746 else if (*cp == '/')
4754 evhttp_uri_parse(const char *source_uri)
4756 return evhttp_uri_parse_with_flags(source_uri, 0);
4760 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4762 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4763 char *path = NULL, *fragment = NULL;
4764 int got_authority = 0;
4766 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4768 event_warn("%s: calloc", __func__);
4774 readbuf = mm_strdup(source_uri);
4775 if (readbuf == NULL) {
4776 event_warn("%s: strdup", __func__);
4783 /* We try to follow RFC3986 here as much as we can, and match
4786 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4788 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
4792 token = strchr(readp, ':');
4793 if (token && scheme_ok(readp,token)) {
4795 uri->scheme = mm_strdup(readp);
4796 if (uri->scheme == NULL) {
4797 event_warn("%s: strdup", __func__);
4800 readp = token+1; /* eat : */
4803 /* 2. Optionally, "//" then an 'authority' part. */
4804 if (readp[0]=='/' && readp[1] == '/') {
4808 path = end_of_authority(readp);
4809 if (parse_authority(uri, authority, path) < 0)
4815 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4818 readp = end_of_path(path, PART_PATH, flags);
4821 if (*readp == '?') {
4825 readp = end_of_path(readp, PART_QUERY, flags);
4828 if (*readp == '#') {
4832 readp = end_of_path(readp, PART_FRAGMENT, flags);
4834 if (*readp != '\0') {
4838 /* These next two cases may be unreachable; I'm leaving them
4839 * in to be defensive. */
4840 /* If you didn't get an authority, the path can't begin with "//" */
4841 if (!got_authority && path[0]=='/' && path[1]=='/')
4843 /* If you did get an authority, the path must begin with "/" or be
4845 if (got_authority && path[0] != '/' && path[0] != '\0')
4847 /* (End of maybe-unreachable cases) */
4849 /* If there was no scheme, the first part of the path (if any) must
4850 * have no colon in it. */
4851 if (! uri->scheme && !path_matches_noscheme(path))
4854 EVUTIL_ASSERT(path);
4855 uri->path = mm_strdup(path);
4856 if (uri->path == NULL) {
4857 event_warn("%s: strdup", __func__);
4862 uri->query = mm_strdup(query);
4863 if (uri->query == NULL) {
4864 event_warn("%s: strdup", __func__);
4869 uri->fragment = mm_strdup(fragment);
4870 if (uri->fragment == NULL) {
4871 event_warn("%s: strdup", __func__);
4881 evhttp_uri_free(uri);
4887 static struct evhttp_uri *
4888 evhttp_uri_parse_authority(char *source_uri)
4890 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4894 event_warn("%s: calloc", __func__);
4900 end = end_of_authority(source_uri);
4901 if (parse_authority(uri, source_uri, end) < 0)
4904 uri->path = mm_strdup("");
4905 if (uri->path == NULL) {
4906 event_warn("%s: strdup", __func__);
4913 evhttp_uri_free(uri);
4918 evhttp_uri_free(struct evhttp_uri *uri)
4920 #define URI_FREE_STR_(f) \
4925 URI_FREE_STR_(scheme);
4926 URI_FREE_STR_(userinfo);
4927 URI_FREE_STR_(host);
4928 URI_FREE_STR_(path);
4929 URI_FREE_STR_(query);
4930 URI_FREE_STR_(fragment);
4933 #undef URI_FREE_STR_
4937 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
4939 struct evbuffer *tmp = 0;
4940 size_t joined_size = 0;
4941 char *output = NULL;
4943 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
4945 if (!uri || !buf || !limit)
4948 tmp = evbuffer_new();
4954 evbuffer_add(tmp, ":", 1);
4957 evbuffer_add(tmp, "//", 2);
4959 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
4962 evbuffer_add_printf(tmp,":%d", uri->port);
4964 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
4972 evbuffer_add(tmp, "?", 1);
4976 if (uri->fragment) {
4977 evbuffer_add(tmp, "#", 1);
4981 evbuffer_add(tmp, "\0", 1); /* NUL */
4983 joined_size = evbuffer_get_length(tmp);
4985 if (joined_size > limit) {
4986 /* It doesn't fit. */
4990 evbuffer_remove(tmp, buf, joined_size);
5001 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
5006 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
5008 return uri->userinfo;
5011 evhttp_uri_get_host(const struct evhttp_uri *uri)
5016 evhttp_uri_get_port(const struct evhttp_uri *uri)
5021 evhttp_uri_get_path(const struct evhttp_uri *uri)
5026 evhttp_uri_get_query(const struct evhttp_uri *uri)
5031 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
5033 return uri->fragment;
5036 #define URI_SET_STR_(f) do { \
5040 if ((uri->f = mm_strdup(f)) == NULL) { \
5041 event_warn("%s: strdup()", __func__); \
5050 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
5052 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
5055 URI_SET_STR_(scheme);
5059 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
5061 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
5063 URI_SET_STR_(userinfo);
5067 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
5070 if (host[0] == '[') {
5071 if (! bracket_addr_ok(host, host+strlen(host)))
5074 if (! regname_ok(host, host+strlen(host)))
5083 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
5090 #define end_of_cpath(cp,p,f) \
5091 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
5094 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
5096 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
5103 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
5105 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
5107 URI_SET_STR_(query);
5111 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
5113 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
5115 URI_SET_STR_(fragment);