2 * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
3 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "event2/event-config.h"
29 #include "evconfig-private.h"
31 #ifdef EVENT__HAVE_SYS_PARAM_H
32 #include <sys/param.h>
34 #ifdef EVENT__HAVE_SYS_TYPES_H
35 #include <sys/types.h>
38 #ifdef HAVE_SYS_IOCCOM_H
39 #include <sys/ioccom.h>
41 #ifdef EVENT__HAVE_SYS_RESOURCE_H
42 #include <sys/resource.h>
44 #ifdef EVENT__HAVE_SYS_TIME_H
47 #ifdef EVENT__HAVE_SYS_WAIT_H
52 #include <sys/socket.h>
59 #include <sys/queue.h>
61 #ifdef EVENT__HAVE_NETINET_IN_H
62 #include <netinet/in.h>
64 #ifdef EVENT__HAVE_ARPA_INET_H
65 #include <arpa/inet.h>
67 #ifdef EVENT__HAVE_NETDB_H
83 #ifdef EVENT__HAVE_UNISTD_H
86 #ifdef EVENT__HAVE_FCNTL_H
90 #undef timeout_pending
91 #undef timeout_initialized
93 #include "strlcpy-internal.h"
94 #include "event2/http.h"
95 #include "event2/event.h"
96 #include "event2/buffer.h"
97 #include "event2/bufferevent.h"
98 #include "event2/http_struct.h"
99 #include "event2/http_compat.h"
100 #include "event2/util.h"
101 #include "event2/listener.h"
102 #include "log-internal.h"
103 #include "util-internal.h"
104 #include "http-internal.h"
105 #include "mm-internal.h"
106 #include "bufferevent-internal.h"
108 #ifndef EVENT__HAVE_GETNAMEINFO
109 #define NI_MAXSERV 32
110 #define NI_MAXHOST 1025
112 #ifndef NI_NUMERICHOST
113 #define NI_NUMERICHOST 1
116 #ifndef NI_NUMERICSERV
117 #define NI_NUMERICSERV 2
121 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
122 size_t hostlen, char *serv, size_t servlen, int flags)
124 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
128 evutil_snprintf(tmpserv, sizeof(tmpserv),
129 "%d", ntohs(sin->sin_port));
130 if (strlcpy(serv, tmpserv, servlen) >= servlen)
135 if (flags & NI_NUMERICHOST) {
136 if (strlcpy(host, inet_ntoa(sin->sin_addr),
143 hp = gethostbyaddr((char *)&sin->sin_addr,
144 sizeof(struct in_addr), AF_INET);
148 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
159 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \
160 ((req)->major < (major_v) || \
161 ((req)->major == (major_v) && (req)->minor < (minor_v)))
163 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \
164 ((req)->major > (major_v) || \
165 ((req)->major == (major_v) && (req)->minor >= (minor_v)))
168 #define MIN(a,b) (((a)<(b))?(a):(b))
173 static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse);
174 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
175 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
176 static struct evhttp_uri *evhttp_uri_parse_authority(char *source_uri);
177 static int evhttp_associate_new_request_with_connection(
178 struct evhttp_connection *evcon);
179 static void evhttp_connection_start_detectclose(
180 struct evhttp_connection *evcon);
181 static void evhttp_connection_stop_detectclose(
182 struct evhttp_connection *evcon);
183 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
184 static void evhttp_read_firstline(struct evhttp_connection *evcon,
185 struct evhttp_request *req);
186 static void evhttp_read_header(struct evhttp_connection *evcon,
187 struct evhttp_request *req);
188 static int evhttp_add_header_internal(struct evkeyvalq *headers,
189 const char *key, const char *value);
190 static const char *evhttp_response_phrase_internal(int code);
191 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t);
192 static void evhttp_write_buffer(struct evhttp_connection *,
193 void (*)(struct evhttp_connection *, void *), void *);
194 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
196 /* callbacks for bufferevent */
197 static void evhttp_read_cb(struct bufferevent *, void *);
198 static void evhttp_write_cb(struct bufferevent *, void *);
199 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
200 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
201 const char *hostname);
203 #ifndef EVENT__HAVE_STRSEP
204 /* strsep replacement for platforms that lack it. Only works if
205 * del is one character long. */
207 strsep(char **s, const char *del)
210 EVUTIL_ASSERT(strlen(del) == 1);
214 d = strstr(tok, del);
225 html_replace(const char ch, const char **escaped)
251 * Replaces <, >, ", ' and & with <, >, ",
252 * ' and & correspondingly.
254 * The returned string needs to be freed by the caller.
258 evhttp_htmlescape(const char *html)
261 size_t new_size = 0, old_size = 0;
262 char *escaped_html, *p;
267 old_size = strlen(html);
268 for (i = 0; i < old_size; ++i) {
269 const char *replaced = NULL;
270 const size_t replace_size = html_replace(html[i], &replaced);
271 if (replace_size > EV_SIZE_MAX - new_size) {
272 event_warn("%s: html_replace overflow", __func__);
275 new_size += replace_size;
278 if (new_size == EV_SIZE_MAX)
280 p = escaped_html = mm_malloc(new_size + 1);
281 if (escaped_html == NULL) {
282 event_warn("%s: malloc(%lu)", __func__,
283 (unsigned long)(new_size + 1));
286 for (i = 0; i < old_size; ++i) {
287 const char *replaced = &html[i];
288 const size_t len = html_replace(html[i], &replaced);
289 memcpy(p, replaced, len);
295 return (escaped_html);
298 /** Given an evhttp_cmd_type, returns a constant string containing the
299 * equivalent HTTP command, or NULL if the evhttp_command_type is
302 evhttp_method(enum evhttp_cmd_type type)
310 case EVHTTP_REQ_POST:
313 case EVHTTP_REQ_HEAD:
319 case EVHTTP_REQ_DELETE:
322 case EVHTTP_REQ_OPTIONS:
325 case EVHTTP_REQ_TRACE:
328 case EVHTTP_REQ_CONNECT:
331 case EVHTTP_REQ_PATCH:
334 case EVHTTP_REQ_PROPFIND:
337 case EVHTTP_REQ_PROPPATCH:
338 method = "PROPPATCH";
340 case EVHTTP_REQ_MKCOL:
343 case EVHTTP_REQ_LOCK:
346 case EVHTTP_REQ_UNLOCK:
349 case EVHTTP_REQ_COPY:
352 case EVHTTP_REQ_MOVE:
364 * Determines if a response should have a body.
365 * Follows the rules in RFC 2616 section 4.3.
366 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
370 evhttp_response_needs_body(struct evhttp_request *req)
372 return (req->response_code != HTTP_NOCONTENT &&
373 req->response_code != HTTP_NOTMODIFIED &&
374 (req->response_code < 100 || req->response_code >= 200) &&
375 req->type != EVHTTP_REQ_HEAD);
378 /** Helper: called after we've added some data to an evcon's bufferevent's
379 * output buffer. Sets the evconn's writing-is-done callback, and puts
380 * the bufferevent into writing mode.
383 evhttp_write_buffer(struct evhttp_connection *evcon,
384 void (*cb)(struct evhttp_connection *, void *), void *arg)
386 event_debug(("%s: preparing to write buffer\n", __func__));
392 /* Disable the read callback: we don't actually care about data;
393 * we only care about close detection. (We don't disable reading --
394 * EV_READ, since we *do* want to learn about any close events.) */
395 bufferevent_setcb(evcon->bufev,
401 bufferevent_enable(evcon->bufev, EV_READ|EV_WRITE);
405 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
407 bufferevent_disable(evcon->bufev, EV_WRITE);
411 evhttp_send_continue(struct evhttp_connection *evcon,
412 struct evhttp_request *req)
414 bufferevent_enable(evcon->bufev, EV_WRITE);
415 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
416 "HTTP/%d.%d 100 Continue\r\n\r\n",
417 req->major, req->minor);
418 evcon->cb = evhttp_send_continue_done;
419 evcon->cb_arg = NULL;
420 bufferevent_setcb(evcon->bufev,
427 /** Helper: returns true iff evconn is in any connected state. */
429 evhttp_connected(struct evhttp_connection *evcon)
431 switch (evcon->state) {
432 case EVCON_DISCONNECTED:
433 case EVCON_CONNECTING:
436 case EVCON_READING_FIRSTLINE:
437 case EVCON_READING_HEADERS:
438 case EVCON_READING_BODY:
439 case EVCON_READING_TRAILER:
446 /* Create the headers needed for an outgoing HTTP request, adds them to
447 * the request's header list, and writes the request line to the
448 * connection's output buffer.
451 evhttp_make_header_request(struct evhttp_connection *evcon,
452 struct evhttp_request *req)
456 evhttp_remove_header(req->output_headers, "Proxy-Connection");
458 /* Generate request line */
459 if (!(method = evhttp_method(req->type))) {
463 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
464 "%s %s HTTP/%d.%d\r\n",
465 method, req->uri, req->major, req->minor);
467 /* Add the content length on a post or put request if missing */
468 if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
469 evhttp_find_header(req->output_headers, "Content-Length") == NULL){
471 evutil_snprintf(size, sizeof(size), EV_SIZE_FMT,
472 EV_SIZE_ARG(evbuffer_get_length(req->output_buffer)));
473 evhttp_add_header(req->output_headers, "Content-Length", size);
477 /** Return true if the list of headers in 'headers', intepreted with respect
478 * to flags, means that we should send a "connection: close" when the request
481 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
483 if (flags & EVHTTP_PROXY_REQUEST) {
484 /* proxy connection */
485 const char *connection = evhttp_find_header(headers, "Proxy-Connection");
486 return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
488 const char *connection = evhttp_find_header(headers, "Connection");
489 return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
493 evhttp_is_request_connection_close(struct evhttp_request *req)
496 evhttp_is_connection_close(req->flags, req->input_headers) ||
497 evhttp_is_connection_close(req->flags, req->output_headers);
500 /* Return true iff 'headers' contains 'Connection: keep-alive' */
502 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
504 const char *connection = evhttp_find_header(headers, "Connection");
505 return (connection != NULL
506 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
509 /* Add a correct "Date" header to headers, unless it already has one. */
511 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
513 if (evhttp_find_header(headers, "Date") == NULL) {
515 if (sizeof(date) - evutil_date_rfc1123(date, sizeof(date), NULL) > 0) {
516 evhttp_add_header(headers, "Date", date);
521 /* Add a "Content-Length" header with value 'content_length' to headers,
522 * unless it already has a content-length or transfer-encoding header. */
524 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
525 size_t content_length)
527 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
528 evhttp_find_header(headers, "Content-Length") == NULL) {
530 evutil_snprintf(len, sizeof(len), EV_SIZE_FMT,
531 EV_SIZE_ARG(content_length));
532 evhttp_add_header(headers, "Content-Length", len);
537 * Create the headers needed for an HTTP reply in req->output_headers,
538 * and write the first HTTP response for req line to evcon.
541 evhttp_make_header_response(struct evhttp_connection *evcon,
542 struct evhttp_request *req)
544 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
545 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
546 "HTTP/%d.%d %d %s\r\n",
547 req->major, req->minor, req->response_code,
548 req->response_code_line);
550 if (req->major == 1) {
552 evhttp_maybe_add_date_header(req->output_headers);
555 * if the protocol is 1.0; and the connection was keep-alive
556 * we need to add a keep-alive header, too.
558 if (req->minor == 0 && is_keepalive)
559 evhttp_add_header(req->output_headers,
560 "Connection", "keep-alive");
562 if ((req->minor >= 1 || is_keepalive) &&
563 evhttp_response_needs_body(req)) {
565 * we need to add the content length if the
566 * user did not give it, this is required for
567 * persistent connections to work.
569 evhttp_maybe_add_content_length_header(
571 evbuffer_get_length(req->output_buffer));
575 /* Potentially add headers for unidentified content. */
576 if (evhttp_response_needs_body(req)) {
577 if (evhttp_find_header(req->output_headers,
578 "Content-Type") == NULL
579 && evcon->http_server->default_content_type) {
580 evhttp_add_header(req->output_headers,
582 evcon->http_server->default_content_type);
586 /* if the request asked for a close, we send a close, too */
587 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
588 evhttp_remove_header(req->output_headers, "Connection");
589 if (!(req->flags & EVHTTP_PROXY_REQUEST))
590 evhttp_add_header(req->output_headers, "Connection", "close");
591 evhttp_remove_header(req->output_headers, "Proxy-Connection");
595 enum expect { NO, CONTINUE, OTHER };
596 static enum expect evhttp_have_expect(struct evhttp_request *req, int input)
599 struct evkeyvalq *h = input ? req->input_headers : req->output_headers;
601 if (!(req->kind == EVHTTP_REQUEST) || !REQ_VERSION_ATLEAST(req, 1, 1))
604 expect = evhttp_find_header(h, "Expect");
608 return !evutil_ascii_strcasecmp(expect, "100-continue") ? CONTINUE : OTHER;
612 /** Generate all headers appropriate for sending the http request in req (or
613 * the response, if we're sending a response), and write them to evcon's
614 * bufferevent. Also writes all data from req->output_buffer */
616 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
618 struct evkeyval *header;
619 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
622 * Depending if this is a HTTP request or response, we might need to
623 * add some new headers or remove existing headers.
625 if (req->kind == EVHTTP_REQUEST) {
626 evhttp_make_header_request(evcon, req);
628 evhttp_make_header_response(evcon, req);
631 TAILQ_FOREACH(header, req->output_headers, next) {
632 evbuffer_add_printf(output, "%s: %s\r\n",
633 header->key, header->value);
635 evbuffer_add(output, "\r\n", 2);
637 if (evhttp_have_expect(req, 0) != CONTINUE &&
638 evbuffer_get_length(req->output_buffer)) {
640 * For a request, we add the POST data, for a reply, this
641 * is the regular data.
643 evbuffer_add_buffer(output, req->output_buffer);
648 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
649 ev_ssize_t new_max_headers_size)
651 if (new_max_headers_size<0)
652 evcon->max_headers_size = EV_SIZE_MAX;
654 evcon->max_headers_size = new_max_headers_size;
657 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
658 ev_ssize_t new_max_body_size)
660 if (new_max_body_size<0)
661 evcon->max_body_size = EV_UINT64_MAX;
663 evcon->max_body_size = new_max_body_size;
667 evhttp_connection_incoming_fail(struct evhttp_request *req,
668 enum evhttp_request_error error)
671 case EVREQ_HTTP_DATA_TOO_LONG:
672 req->response_code = HTTP_ENTITYTOOLARGE;
675 req->response_code = HTTP_BADREQUEST;
679 case EVREQ_HTTP_TIMEOUT:
682 * these are cases in which we probably should just
683 * close the connection and not send a reply. this
684 * case may happen when a browser keeps a persistent
685 * connection open and we timeout on the read. when
686 * the request is still being used for sending, we
687 * need to disassociated it from the connection here.
689 if (!req->userdone) {
690 /* remove it so that it will not be freed */
691 TAILQ_REMOVE(&req->evcon->requests, req, next);
692 /* indicate that this request no longer has a
698 case EVREQ_HTTP_INVALID_HEADER:
699 case EVREQ_HTTP_BUFFER_ERROR:
700 case EVREQ_HTTP_REQUEST_CANCEL:
701 case EVREQ_HTTP_DATA_TOO_LONG:
702 default: /* xxx: probably should just error on default */
703 /* the callback looks at the uri to determine errors */
708 if (req->uri_elems) {
709 evhttp_uri_free(req->uri_elems);
710 req->uri_elems = NULL;
714 * the callback needs to send a reply, once the reply has
715 * been send, the connection should get freed.
717 (*req->cb)(req, req->cb_arg);
723 /* Free connection ownership of which can be acquired by user using
724 * evhttp_request_own(). */
726 evhttp_request_free_auto(struct evhttp_request *req)
728 if (!(req->flags & EVHTTP_USER_OWNED))
729 evhttp_request_free(req);
733 evhttp_request_free_(struct evhttp_connection *evcon, struct evhttp_request *req)
735 TAILQ_REMOVE(&evcon->requests, req, next);
736 evhttp_request_free_auto(req);
740 evhttp_set_timeout_tv_(struct timeval *tv, const struct timeval *timeout, int def)
742 if (timeout == NULL && def != -1) {
751 evutil_timerclear(tv);
755 evhttp_set_timeout_(struct timeval *tv, int timeout, int def)
762 evutil_timerclear(tv);
764 struct timeval timeout_tv;
765 timeout_tv.tv_sec = timeout;
766 timeout_tv.tv_usec = 0;
771 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
772 * given in error. If it's an outgoing connection, reset the connection,
773 * retry any pending requests, and inform the user. If it's incoming,
774 * delegates to evhttp_connection_incoming_fail(). */
776 evhttp_connection_fail_(struct evhttp_connection *evcon,
777 enum evhttp_request_error error)
779 const int errsave = EVUTIL_SOCKET_ERROR();
780 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
781 void (*cb)(struct evhttp_request *, void *);
783 void (*error_cb)(enum evhttp_request_error, void *);
785 EVUTIL_ASSERT(req != NULL);
787 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
789 if (evcon->flags & EVHTTP_CON_INCOMING) {
791 * for incoming requests, there are two different
792 * failure cases. it's either a network level error
793 * or an http layer error. for problems on the network
794 * layer like timeouts we just drop the connections.
795 * For HTTP problems, we might have to send back a
796 * reply before the connection can be freed.
798 if (evhttp_connection_incoming_fail(req, error) == -1)
799 evhttp_connection_free(evcon);
803 error_cb = req->error_cb;
804 error_cb_arg = req->cb_arg;
805 /* when the request was canceled, the callback is not executed */
806 if (error != EVREQ_HTTP_REQUEST_CANCEL) {
807 /* save the callback for later; the cb might free our object */
809 cb_arg = req->cb_arg;
815 /* do not fail all requests; the next request is going to get
816 * send over a new connection. when a user cancels a request,
817 * all other pending requests should be processed as normal
819 evhttp_request_free_(evcon, req);
821 /* reset the connection */
822 evhttp_connection_reset_(evcon);
824 /* We are trying the next request that was queued on us */
825 if (TAILQ_FIRST(&evcon->requests) != NULL)
826 evhttp_connection_connect_(evcon);
828 /* The call to evhttp_connection_reset_ overwrote errno.
829 * Let's restore the original errno, so that the user's
830 * callback can have a better idea of what the error was.
832 EVUTIL_SET_SOCKET_ERROR(errsave);
834 /* inform the user */
835 if (error_cb != NULL)
836 error_cb(error, error_cb_arg);
841 /* Bufferevent callback: invoked when any data has been written from an
842 * http connection's bufferevent */
844 evhttp_write_cb(struct bufferevent *bufev, void *arg)
846 struct evhttp_connection *evcon = arg;
848 /* Activate our call back */
849 if (evcon->cb != NULL)
850 (*evcon->cb)(evcon, evcon->cb_arg);
854 * Advance the connection state.
855 * - If this is an outgoing connection, we've just processed the response;
856 * idle or close the connection.
857 * - If this is an incoming connection, we've just processed the request;
861 evhttp_connection_done(struct evhttp_connection *evcon)
863 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
864 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
868 /* idle or close the connection */
869 int need_close = evhttp_is_request_connection_close(req);
870 TAILQ_REMOVE(&evcon->requests, req, next);
873 evcon->state = EVCON_IDLE;
875 /* check if we got asked to close the connection */
877 evhttp_connection_reset_(evcon);
879 if (TAILQ_FIRST(&evcon->requests) != NULL) {
881 * We have more requests; reset the connection
882 * and deal with the next request.
884 if (!evhttp_connected(evcon))
885 evhttp_connection_connect_(evcon);
887 evhttp_request_dispatch(evcon);
888 } else if (!need_close) {
890 * The connection is going to be persistent, but we
891 * need to detect if the other side closes it.
893 evhttp_connection_start_detectclose(evcon);
894 } else if ((evcon->flags & EVHTTP_CON_AUTOFREE)) {
896 * If we have no more requests that need completion
897 * and we're not waiting for the connection to close
903 * incoming connection - we need to leave the request on the
904 * connection so that we can reply to it.
906 evcon->state = EVCON_WRITING;
909 /* notify the user of the request */
910 (*req->cb)(req, req->cb_arg);
912 /* if this was an outgoing request, we own and it's done. so free it. */
914 evhttp_request_free_auto(req);
917 /* If this was the last request of an outgoing connection and we're
918 * not waiting to receive a connection close event and we want to
919 * automatically free the connection. We check to ensure our request
920 * list is empty one last time just in case our callback added a
923 if (free_evcon && TAILQ_FIRST(&evcon->requests) == NULL) {
924 evhttp_connection_free(evcon);
929 * Handles reading from a chunked request.
930 * return ALL_DATA_READ:
931 * all data has been read
932 * return MORE_DATA_EXPECTED:
933 * more data is expected
934 * return DATA_CORRUPTED:
936 * return REQUEST_CANCELED:
937 * request was canceled by the user calling evhttp_cancel_request
938 * return DATA_TOO_LONG:
939 * ran over the maximum limit
942 static enum message_read_status
943 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
945 if (req == NULL || buf == NULL) {
946 return DATA_CORRUPTED;
952 if ((buflen = evbuffer_get_length(buf)) == 0) {
956 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
957 * check for overflow conditions */
958 if (buflen > EV_SSIZE_MAX) {
959 return DATA_CORRUPTED;
962 if (req->ntoread < 0) {
963 /* Read chunk size */
965 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
970 /* the last chunk is on a new line? */
971 if (strlen(p) == 0) {
975 ntoread = evutil_strtoll(p, &endp, 16);
976 error = (*p == '\0' ||
977 (*endp != '\0' && *endp != ' ') ||
981 /* could not get chunk size */
982 return (DATA_CORRUPTED);
985 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
986 if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
987 return DATA_CORRUPTED;
990 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
991 /* failed body length test */
992 event_debug(("Request body is too long"));
993 return (DATA_TOO_LONG);
996 req->body_size += (size_t)ntoread;
997 req->ntoread = ntoread;
998 if (req->ntoread == 0) {
1000 return (ALL_DATA_READ);
1005 /* req->ntoread is signed int64, len is ssize_t, based on arch,
1006 * ssize_t could only be 32b, check for these conditions */
1007 if (req->ntoread > EV_SSIZE_MAX) {
1008 return DATA_CORRUPTED;
1011 /* don't have enough to complete a chunk; wait for more */
1012 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
1013 return (MORE_DATA_EXPECTED);
1015 /* Completed chunk */
1016 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
1018 if (req->chunk_cb != NULL) {
1019 req->flags |= EVHTTP_REQ_DEFER_FREE;
1020 (*req->chunk_cb)(req, req->cb_arg);
1021 evbuffer_drain(req->input_buffer,
1022 evbuffer_get_length(req->input_buffer));
1023 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1024 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1025 return (REQUEST_CANCELED);
1030 return (MORE_DATA_EXPECTED);
1034 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
1036 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1038 switch (evhttp_parse_headers_(req, buf)) {
1039 case DATA_CORRUPTED:
1041 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1044 bufferevent_disable(evcon->bufev, EV_READ);
1045 evhttp_connection_done(evcon);
1047 case MORE_DATA_EXPECTED:
1048 case REQUEST_CANCELED: /* ??? */
1055 evhttp_lingering_close(struct evhttp_connection *evcon,
1056 struct evhttp_request *req)
1058 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1060 size_t n = evbuffer_get_length(buf);
1061 if (n > (size_t) req->ntoread)
1062 n = (size_t) req->ntoread;
1064 req->body_size += n;
1066 event_debug(("Request body is too long, left " EV_I64_FMT,
1067 EV_I64_ARG(req->ntoread)));
1069 evbuffer_drain(buf, n);
1071 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1074 evhttp_lingering_fail(struct evhttp_connection *evcon,
1075 struct evhttp_request *req)
1077 if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE)
1078 evhttp_lingering_close(evcon, req);
1080 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1084 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1086 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1089 switch (evhttp_handle_chunked_read(req, buf)) {
1091 /* finished last chunk */
1092 evcon->state = EVCON_READING_TRAILER;
1093 evhttp_read_trailer(evcon, req);
1095 case DATA_CORRUPTED:
1097 /* corrupted data */
1098 evhttp_connection_fail_(evcon,
1099 EVREQ_HTTP_DATA_TOO_LONG);
1101 case REQUEST_CANCELED:
1102 /* request canceled */
1103 evhttp_request_free_auto(req);
1105 case MORE_DATA_EXPECTED:
1109 } else if (req->ntoread < 0) {
1110 /* Read until connection close. */
1111 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
1112 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
1116 req->body_size += evbuffer_get_length(buf);
1117 evbuffer_add_buffer(req->input_buffer, buf);
1118 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
1119 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
1120 /* We've postponed moving the data until now, but we're
1121 * about to use it. */
1122 size_t n = evbuffer_get_length(buf);
1124 if (n > (size_t) req->ntoread)
1125 n = (size_t) req->ntoread;
1127 req->body_size += n;
1128 evbuffer_remove_buffer(buf, req->input_buffer, n);
1131 if (req->body_size > req->evcon->max_body_size ||
1132 (!req->chunked && req->ntoread >= 0 &&
1133 (size_t)req->ntoread > req->evcon->max_body_size)) {
1134 /* XXX: The above casted comparison must checked for overflow */
1135 /* failed body length test */
1137 evhttp_lingering_fail(evcon, req);
1141 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1142 req->flags |= EVHTTP_REQ_DEFER_FREE;
1143 (*req->chunk_cb)(req, req->cb_arg);
1144 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1145 evbuffer_drain(req->input_buffer,
1146 evbuffer_get_length(req->input_buffer));
1147 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1148 evhttp_request_free_auto(req);
1153 if (!req->ntoread) {
1154 bufferevent_disable(evcon->bufev, EV_READ);
1155 /* Completed content length */
1156 evhttp_connection_done(evcon);
1161 #define get_deferred_queue(evcon) \
1165 * Gets called when more data becomes available
1169 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1171 struct evhttp_connection *evcon = arg;
1172 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1174 /* Cancel if it's pending. */
1175 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1176 &evcon->read_more_deferred_cb);
1178 switch (evcon->state) {
1179 case EVCON_READING_FIRSTLINE:
1180 evhttp_read_firstline(evcon, req);
1181 /* note the request may have been freed in
1182 * evhttp_read_body */
1184 case EVCON_READING_HEADERS:
1185 evhttp_read_header(evcon, req);
1186 /* note the request may have been freed in
1187 * evhttp_read_body */
1189 case EVCON_READING_BODY:
1190 evhttp_read_body(evcon, req);
1191 /* note the request may have been freed in
1192 * evhttp_read_body */
1194 case EVCON_READING_TRAILER:
1195 evhttp_read_trailer(evcon, req);
1200 struct evbuffer *input;
1203 input = bufferevent_get_input(evcon->bufev);
1204 total_len = evbuffer_get_length(input);
1205 event_debug(("%s: read "EV_SIZE_FMT
1206 " bytes in EVCON_IDLE state,"
1207 " resetting connection",
1208 __func__, EV_SIZE_ARG(total_len)));
1211 evhttp_connection_reset_(evcon);
1214 case EVCON_DISCONNECTED:
1215 case EVCON_CONNECTING:
1218 event_errx(1, "%s: illegal connection state %d",
1219 __func__, evcon->state);
1224 evhttp_deferred_read_cb(struct event_callback *cb, void *data)
1226 struct evhttp_connection *evcon = data;
1227 struct bufferevent *bev = evcon->bufev;
1229 (bev->readcb)(evcon->bufev, evcon);
1233 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1235 /* This is after writing the request to the server */
1236 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1237 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
1238 EVUTIL_ASSERT(req != NULL);
1240 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1242 /* We need to wait until we've written all of our output data before we can
1244 if (evbuffer_get_length(output) > 0)
1247 /* We are done writing our header and are now expecting the response */
1248 req->kind = EVHTTP_RESPONSE;
1250 evhttp_start_read_(evcon);
1254 * Clean up a connection object
1258 evhttp_connection_free(struct evhttp_connection *evcon)
1260 struct evhttp_request *req;
1263 /* notify interested parties that this connection is going down */
1264 if (evcon->fd != -1) {
1265 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1266 (*evcon->closecb)(evcon, evcon->closecb_arg);
1269 /* remove all requests that might be queued on this
1270 * connection. for server connections, this should be empty.
1271 * because it gets dequeued either in evhttp_connection_done or
1272 * evhttp_connection_fail_.
1274 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1275 evhttp_request_free_(evcon, req);
1278 if (evcon->http_server != NULL) {
1279 struct evhttp *http = evcon->http_server;
1280 TAILQ_REMOVE(&http->connections, evcon, next);
1283 if (event_initialized(&evcon->retry_ev)) {
1284 event_del(&evcon->retry_ev);
1285 event_debug_unassign(&evcon->retry_ev);
1288 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1289 &evcon->read_more_deferred_cb);
1291 if (evcon->bufev != NULL) {
1293 !(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE);
1294 if (evcon->fd == -1)
1295 evcon->fd = bufferevent_getfd(evcon->bufev);
1297 bufferevent_free(evcon->bufev);
1300 if (evcon->fd != -1) {
1301 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1303 evutil_closesocket(evcon->fd);
1306 if (evcon->bind_address != NULL)
1307 mm_free(evcon->bind_address);
1309 if (evcon->address != NULL)
1310 mm_free(evcon->address);
1316 evhttp_connection_free_on_completion(struct evhttp_connection *evcon) {
1317 evcon->flags |= EVHTTP_CON_AUTOFREE;
1321 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1322 const char *address)
1324 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1325 if (evcon->bind_address)
1326 mm_free(evcon->bind_address);
1327 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1328 event_warn("%s: strdup", __func__);
1332 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1335 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1336 evcon->bind_port = port;
1340 evhttp_request_dispatch(struct evhttp_connection* evcon)
1342 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1344 /* this should not usually happy but it's possible */
1348 EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST);
1350 /* delete possible close detection events */
1351 evhttp_connection_stop_detectclose(evcon);
1353 /* we assume that the connection is connected already */
1354 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1356 evcon->state = EVCON_WRITING;
1358 /* Create the header from the store arguments */
1359 evhttp_make_header(evcon, req);
1361 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1364 /* Reset our connection state: disables reading/writing, closes our fd (if
1365 * any), clears out buffers, and puts us in state DISCONNECTED. */
1367 evhttp_connection_reset_(struct evhttp_connection *evcon)
1369 struct evbuffer *tmp;
1372 bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL);
1374 /* XXXX This is not actually an optimal fix. Instead we ought to have
1375 an API for "stop connecting", or use bufferevent_setfd to turn off
1376 connecting. But for Libevent 2.0, this seems like a minimal change
1377 least likely to disrupt the rest of the bufferevent and http code.
1379 Why is this here? If the fd is set in the bufferevent, and the
1380 bufferevent is connecting, then you can't actually stop the
1381 bufferevent from trying to connect with bufferevent_disable(). The
1382 connect will never trigger, since we close the fd, but the timeout
1383 might. That caused an assertion failure in evhttp_connection_fail_.
1385 bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE);
1387 if (evcon->fd == -1)
1388 evcon->fd = bufferevent_getfd(evcon->bufev);
1390 if (evcon->fd != -1) {
1391 /* inform interested parties about connection close */
1392 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1393 (*evcon->closecb)(evcon, evcon->closecb_arg);
1395 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1396 evutil_closesocket(evcon->fd);
1399 err = bufferevent_setfd(evcon->bufev, -1);
1400 EVUTIL_ASSERT(!err && "setfd");
1402 /* we need to clean up any buffered data */
1403 tmp = bufferevent_get_output(evcon->bufev);
1404 err = evbuffer_drain(tmp, -1);
1405 EVUTIL_ASSERT(!err && "drain output");
1406 tmp = bufferevent_get_input(evcon->bufev);
1407 err = evbuffer_drain(tmp, -1);
1408 EVUTIL_ASSERT(!err && "drain input");
1410 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1412 evcon->state = EVCON_DISCONNECTED;
1416 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1418 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1419 bufferevent_enable(evcon->bufev, EV_READ);
1423 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1425 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1426 bufferevent_disable(evcon->bufev, EV_READ);
1430 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1432 struct evhttp_connection *evcon = arg;
1434 evcon->state = EVCON_DISCONNECTED;
1435 evhttp_connection_connect_(evcon);
1439 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1441 struct evcon_requestq requests;
1443 evhttp_connection_reset_(evcon);
1444 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1445 struct timeval tv_retry = evcon->initial_retry_timeout;
1447 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1448 /* XXXX handle failure from evhttp_add_event */
1449 for (i=0; i < evcon->retry_cnt; ++i) {
1450 tv_retry.tv_usec *= 2;
1451 if (tv_retry.tv_usec > 1000000) {
1452 tv_retry.tv_usec -= 1000000;
1453 tv_retry.tv_sec += 1;
1455 tv_retry.tv_sec *= 2;
1456 if (tv_retry.tv_sec > 3600) {
1457 tv_retry.tv_sec = 3600;
1458 tv_retry.tv_usec = 0;
1461 event_add(&evcon->retry_ev, &tv_retry);
1467 * User callback can do evhttp_make_request() on the same
1468 * evcon so new request will be added to evcon->requests. To
1469 * avoid freeing it prematurely we iterate over the copy of
1472 TAILQ_INIT(&requests);
1473 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1474 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1475 TAILQ_REMOVE(&evcon->requests, request, next);
1476 TAILQ_INSERT_TAIL(&requests, request, next);
1479 /* for now, we just signal all requests by executing their callbacks */
1480 while (TAILQ_FIRST(&requests) != NULL) {
1481 struct evhttp_request *request = TAILQ_FIRST(&requests);
1482 TAILQ_REMOVE(&requests, request, next);
1483 request->evcon = NULL;
1485 /* we might want to set an error here */
1486 request->cb(request, request->cb_arg);
1487 evhttp_request_free_auto(request);
1492 evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
1493 struct evhttp_request *req)
1495 struct evbuffer *buf;
1497 /** Second time, we can't read anything */
1498 if (evcon->flags & EVHTTP_CON_READING_ERROR) {
1499 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1500 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1504 req->kind = EVHTTP_RESPONSE;
1506 buf = bufferevent_get_output(evcon->bufev);
1507 evbuffer_unfreeze(buf, 1);
1508 evbuffer_drain(buf, evbuffer_get_length(buf));
1509 evbuffer_freeze(buf, 1);
1511 evhttp_start_read_(evcon);
1512 evcon->flags |= EVHTTP_CON_READING_ERROR;
1516 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1518 struct evhttp_connection *evcon = arg;
1519 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1521 if (evcon->fd == -1)
1522 evcon->fd = bufferevent_getfd(bufev);
1524 switch (evcon->state) {
1525 case EVCON_CONNECTING:
1526 if (what & BEV_EVENT_TIMEOUT) {
1527 event_debug(("%s: connection timeout for \"%s:%d\" on "
1529 __func__, evcon->address, evcon->port,
1530 EV_SOCK_ARG(evcon->fd)));
1531 evhttp_connection_cb_cleanup(evcon);
1536 case EVCON_READING_BODY:
1537 if (!req->chunked && req->ntoread < 0
1538 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1539 /* EOF on read can be benign */
1540 evhttp_connection_done(evcon);
1545 case EVCON_DISCONNECTED:
1547 case EVCON_READING_FIRSTLINE:
1548 case EVCON_READING_HEADERS:
1549 case EVCON_READING_TRAILER:
1555 /* when we are in close detect mode, a read error means that
1556 * the other side closed their connection.
1558 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1559 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1560 EVUTIL_ASSERT(evcon->http_server == NULL);
1561 /* For connections from the client, we just
1562 * reset the connection so that it becomes
1565 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1566 evhttp_connection_reset_(evcon);
1569 * If we have no more requests that need completion
1570 * and we want to auto-free the connection when all
1571 * requests have been completed.
1573 if (TAILQ_FIRST(&evcon->requests) == NULL
1574 && (evcon->flags & EVHTTP_CON_OUTGOING)
1575 && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1576 evhttp_connection_free(evcon);
1581 if (what & BEV_EVENT_TIMEOUT) {
1582 evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
1583 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1584 if (what & BEV_EVENT_WRITING &&
1585 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR) {
1586 evhttp_connection_read_on_write_error(evcon, req);
1590 if (what & BEV_EVENT_READING &&
1591 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR &&
1592 evbuffer_get_length(bufferevent_get_input(bufev))) {
1593 event_deferred_cb_schedule_(get_deferred_queue(evcon),
1594 &evcon->read_more_deferred_cb);
1598 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1599 } else if (what == BEV_EVENT_CONNECTED) {
1601 evhttp_connection_fail_(evcon, EVREQ_HTTP_BUFFER_ERROR);
1606 * Event callback for asynchronous connection attempt.
1609 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1611 struct evhttp_connection *evcon = arg;
1613 ev_socklen_t errsz = sizeof(error);
1615 if (evcon->fd == -1)
1616 evcon->fd = bufferevent_getfd(bufev);
1618 if (!(what & BEV_EVENT_CONNECTED)) {
1619 /* some operating systems return ECONNREFUSED immediately
1620 * when connecting to a local address. the cleanup is going
1621 * to reschedule this function call.
1624 if (errno == ECONNREFUSED)
1627 evhttp_error_cb(bufev, what, arg);
1631 if (evcon->fd == -1) {
1632 event_debug(("%s: bufferevent_getfd returned -1",
1637 /* Check if the connection completed */
1638 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1640 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT,
1641 __func__, evcon->address, evcon->port,
1642 EV_SOCK_ARG(evcon->fd)));
1647 event_debug(("%s: connect failed for \"%s:%d\" on "
1649 __func__, evcon->address, evcon->port,
1650 EV_SOCK_ARG(evcon->fd),
1651 evutil_socket_error_to_string(error)));
1655 /* We are connected to the server now */
1656 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1657 __func__, evcon->address, evcon->port,
1658 EV_SOCK_ARG(evcon->fd)));
1660 /* Reset the retry count as we were successful in connecting */
1661 evcon->retry_cnt = 0;
1662 evcon->state = EVCON_IDLE;
1664 /* reset the bufferevent cbs */
1665 bufferevent_setcb(evcon->bufev,
1671 bufferevent_set_timeouts(evcon->bufev,
1672 &evcon->timeout_read, &evcon->timeout_write);
1674 /* try to start requests that have queued up on this connection */
1675 evhttp_request_dispatch(evcon);
1679 evhttp_connection_cb_cleanup(evcon);
1683 * Check if we got a valid response code.
1687 evhttp_valid_response_code(int code)
1696 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1700 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1701 if (n != 2 || major > 1) {
1702 event_debug(("%s: bad version %s on message %p from %s",
1703 __func__, version, req, req->remote_host));
1711 /* Parses the status line of a web server */
1714 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1718 const char *readable = "";
1720 protocol = strsep(&line, " ");
1723 number = strsep(&line, " ");
1727 if (evhttp_parse_http_version(protocol, req) < 0)
1730 req->response_code = atoi(number);
1731 if (!evhttp_valid_response_code(req->response_code)) {
1732 event_debug(("%s: bad response code \"%s\"",
1737 if (req->response_code_line != NULL)
1738 mm_free(req->response_code_line);
1739 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1740 event_warn("%s: strdup", __func__);
1747 /* Parse the first line of a HTTP request */
1750 evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len)
1752 char *eos = line + len;
1756 const char *hostname;
1759 enum evhttp_cmd_type type;
1761 while (eos > line && *(eos-1) == ' ') {
1766 if (len < strlen("GET / HTTP/1.0"))
1769 /* Parse the request line */
1770 method = strsep(&line, " ");
1774 version = strrchr(uri, ' ');
1775 if (!version || uri == version)
1780 method_len = (uri - method) - 1;
1781 type = EVHTTP_REQ_UNKNOWN_;
1784 switch (method_len) {
1786 /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1788 /* Since both GET and PUT share the same character 'T' at the end,
1789 * if the string doesn't have 'T', we can immediately determine this
1790 * is an invalid HTTP method */
1792 if (method[2] != 'T') {
1798 /* This first byte is 'G', so make sure the next byte is
1799 * 'E', if it isn't then this isn't a valid method */
1801 if (method[1] == 'E') {
1802 type = EVHTTP_REQ_GET;
1807 /* First byte is P, check second byte for 'U', if not,
1808 * we know it's an invalid method */
1809 if (method[1] == 'U') {
1810 type = EVHTTP_REQ_PUT;
1818 /* The method length is 4 bytes, leaving only the methods POST, HEAD, LOCK, COPY and MOVE */
1821 if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') {
1822 type = EVHTTP_REQ_POST;
1826 if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') {
1827 type = EVHTTP_REQ_HEAD;
1831 if (method[3] == 'K' && method[2] == 'C' && method[1] == 'O') {
1832 type = EVHTTP_REQ_LOCK;
1836 if (method[3] == 'Y' && method[2] == 'P' && method[1] == 'O') {
1837 type = EVHTTP_REQ_COPY;
1841 if (method[3] == 'E' && method[2] == 'V' && method[1] == 'O') {
1842 type = EVHTTP_REQ_MOVE;
1850 /* Method length is 5 bytes, which can only encompass PATCH, TRACE and MKCOL */
1853 if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') {
1854 type = EVHTTP_REQ_PATCH;
1858 if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') {
1859 type = EVHTTP_REQ_TRACE;
1864 if (method[4] == 'L' && method[3] == 'O' && method[2] == 'C' && method[1] == 'K') {
1865 type = EVHTTP_REQ_MKCOL;
1873 /* Method length is 6, only valid methods 6 bytes in length is DELETE and UNLOCK */
1876 if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' &&
1877 method[2] == 'L' && method[1] == 'E') {
1878 type = EVHTTP_REQ_DELETE;
1882 if (method[5] == 'K' && method[4] == 'C' && method[3] == 'O' &&
1883 method[2] == 'L' && method[1] == 'N') {
1884 type = EVHTTP_REQ_UNLOCK;
1892 /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1895 if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' &&
1896 method[3] == 'I' && method[2] == 'T' && method[1] == 'P') {
1897 type = EVHTTP_REQ_OPTIONS;
1902 if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' &&
1903 method[3] == 'N' && method[2] == 'N' && method[1] == 'O') {
1904 type = EVHTTP_REQ_CONNECT;
1913 /* Method length is 8, only valid method 8 bytes in length is PROPFIND */
1915 /* If the first byte isn't 'P' then it's invalid */
1916 if (*method != 'P') {
1920 if (method[7] == 'D' && method[6] == 'N' && method[5] == 'I' &&
1921 method[4] == 'F' && method[3] == 'P' && method[2] == 'O' &&
1923 type = EVHTTP_REQ_PROPFIND;
1928 /* Method length is 9, only valid method 9 bytes in length is PROPPATCH */
1930 /* If the first byte isn't 'P' then it's invalid */
1931 if (*method != 'P') {
1935 if (method[8] == 'H' && method[7] == 'C' && method[6] == 'T' &&
1936 method[5] == 'A' && method[4] == 'P' && method[3] == 'P' &&
1937 method[2] == 'O' && method[1] == 'R') {
1938 type = EVHTTP_REQ_PROPPATCH;
1944 if ((int)type == EVHTTP_REQ_UNKNOWN_) {
1945 event_debug(("%s: bad method %s on request %p from %s",
1946 __func__, method, req, req->remote_host));
1947 /* No error yet; we'll give a better error later when
1948 * we see that req->type is unsupported. */
1953 if (evhttp_parse_http_version(version, req) < 0)
1956 if ((req->uri = mm_strdup(uri)) == NULL) {
1957 event_debug(("%s: mm_strdup", __func__));
1961 if (type == EVHTTP_REQ_CONNECT) {
1962 if ((req->uri_elems = evhttp_uri_parse_authority(req->uri)) == NULL) {
1966 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
1967 EVHTTP_URI_NONCONFORMANT)) == NULL) {
1972 /* If we have an absolute-URI, check to see if it is an http request
1973 for a known vhost or server alias. If we don't know about this
1974 host, we consider it a proxy request. */
1975 scheme = evhttp_uri_get_scheme(req->uri_elems);
1976 hostname = evhttp_uri_get_host(req->uri_elems);
1977 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1978 !evutil_ascii_strcasecmp(scheme, "https")) &&
1980 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1981 req->flags |= EVHTTP_PROXY_REQUEST;
1987 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1989 struct evkeyval *header;
1991 TAILQ_FOREACH(header, headers, next) {
1992 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1993 return (header->value);
2000 evhttp_clear_headers(struct evkeyvalq *headers)
2002 struct evkeyval *header;
2004 for (header = TAILQ_FIRST(headers);
2006 header = TAILQ_FIRST(headers)) {
2007 TAILQ_REMOVE(headers, header, next);
2008 mm_free(header->key);
2009 mm_free(header->value);
2015 * Returns 0, if the header was successfully removed.
2016 * Returns -1, if the header could not be found.
2020 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
2022 struct evkeyval *header;
2024 TAILQ_FOREACH(header, headers, next) {
2025 if (evutil_ascii_strcasecmp(header->key, key) == 0)
2032 /* Free and remove the header that we found */
2033 TAILQ_REMOVE(headers, header, next);
2034 mm_free(header->key);
2035 mm_free(header->value);
2042 evhttp_header_is_valid_value(const char *value)
2044 const char *p = value;
2046 while ((p = strpbrk(p, "\r\n")) != NULL) {
2047 /* we really expect only one new line */
2048 p += strspn(p, "\r\n");
2049 /* we expect a space or tab for continuation */
2050 if (*p != ' ' && *p != '\t')
2057 evhttp_add_header(struct evkeyvalq *headers,
2058 const char *key, const char *value)
2060 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
2062 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
2063 /* drop illegal headers */
2064 event_debug(("%s: dropping illegal header key\n", __func__));
2068 if (!evhttp_header_is_valid_value(value)) {
2069 event_debug(("%s: dropping illegal header value\n", __func__));
2073 return (evhttp_add_header_internal(headers, key, value));
2077 evhttp_add_header_internal(struct evkeyvalq *headers,
2078 const char *key, const char *value)
2080 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
2081 if (header == NULL) {
2082 event_warn("%s: calloc", __func__);
2085 if ((header->key = mm_strdup(key)) == NULL) {
2087 event_warn("%s: strdup", __func__);
2090 if ((header->value = mm_strdup(value)) == NULL) {
2091 mm_free(header->key);
2093 event_warn("%s: strdup", __func__);
2097 TAILQ_INSERT_TAIL(headers, header, next);
2103 * Parses header lines from a request or a response into the specified
2104 * request object given an event buffer.
2107 * DATA_CORRUPTED on error
2108 * MORE_DATA_EXPECTED when we need to read more headers
2109 * ALL_DATA_READ when all headers have been read.
2112 enum message_read_status
2113 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
2116 enum message_read_status status = ALL_DATA_READ;
2120 line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
2122 if (req->evcon != NULL &&
2123 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2124 return (DATA_TOO_LONG);
2126 return (MORE_DATA_EXPECTED);
2129 if (req->evcon != NULL && len > req->evcon->max_headers_size) {
2131 return (DATA_TOO_LONG);
2134 req->headers_size = len;
2136 switch (req->kind) {
2137 case EVHTTP_REQUEST:
2138 if (evhttp_parse_request_line(req, line, len) == -1)
2139 status = DATA_CORRUPTED;
2141 case EVHTTP_RESPONSE:
2142 if (evhttp_parse_response_line(req, line) == -1)
2143 status = DATA_CORRUPTED;
2146 status = DATA_CORRUPTED;
2154 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
2156 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
2158 size_t old_len, line_len;
2163 old_len = strlen(header->value);
2165 /* Strip space from start and end of line. */
2166 while (*line == ' ' || *line == '\t')
2168 evutil_rtrim_lws_(line);
2170 line_len = strlen(line);
2172 newval = mm_realloc(header->value, old_len + line_len + 2);
2176 newval[old_len] = ' ';
2177 memcpy(newval + old_len + 1, line, line_len + 1);
2178 header->value = newval;
2183 enum message_read_status
2184 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
2186 enum message_read_status errcode = DATA_CORRUPTED;
2188 enum message_read_status status = MORE_DATA_EXPECTED;
2190 struct evkeyvalq* headers = req->input_headers;
2192 while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
2194 char *skey, *svalue;
2196 req->headers_size += len;
2198 if (req->evcon != NULL &&
2199 req->headers_size > req->evcon->max_headers_size) {
2200 errcode = DATA_TOO_LONG;
2204 if (*line == '\0') { /* Last header - Done */
2205 status = ALL_DATA_READ;
2210 /* Check if this is a continuation line */
2211 if (*line == ' ' || *line == '\t') {
2212 if (evhttp_append_to_last_header(headers, line) == -1)
2218 /* Processing of header lines */
2220 skey = strsep(&svalue, ":");
2224 svalue += strspn(svalue, " ");
2225 evutil_rtrim_lws_(svalue);
2227 if (evhttp_add_header(headers, skey, svalue) == -1)
2233 if (status == MORE_DATA_EXPECTED) {
2234 if (req->evcon != NULL &&
2235 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2236 return (DATA_TOO_LONG);
2247 evhttp_get_body_length(struct evhttp_request *req)
2249 struct evkeyvalq *headers = req->input_headers;
2250 const char *content_length;
2251 const char *connection;
2253 content_length = evhttp_find_header(headers, "Content-Length");
2254 connection = evhttp_find_header(headers, "Connection");
2256 if (content_length == NULL && connection == NULL)
2258 else if (content_length == NULL &&
2259 evutil_ascii_strcasecmp(connection, "Close") != 0) {
2261 } else if (content_length == NULL) {
2265 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2266 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2267 event_debug(("%s: illegal content length: %s",
2268 __func__, content_length));
2271 req->ntoread = ntoread;
2274 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2275 __func__, EV_I64_ARG(req->ntoread),
2276 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2282 evhttp_method_may_have_body(enum evhttp_cmd_type type)
2285 case EVHTTP_REQ_POST:
2286 case EVHTTP_REQ_PUT:
2287 case EVHTTP_REQ_PATCH:
2288 case EVHTTP_REQ_PROPFIND:
2289 case EVHTTP_REQ_PROPPATCH:
2290 case EVHTTP_REQ_MKCOL:
2291 case EVHTTP_REQ_LOCK:
2292 case EVHTTP_REQ_UNLOCK:
2293 case EVHTTP_REQ_COPY:
2294 case EVHTTP_REQ_MOVE:
2296 case EVHTTP_REQ_GET:
2297 case EVHTTP_REQ_DELETE:
2298 case EVHTTP_REQ_OPTIONS:
2299 case EVHTTP_REQ_CONNECT:
2302 case EVHTTP_REQ_TRACE:
2303 case EVHTTP_REQ_HEAD:
2310 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2312 const char *xfer_enc;
2314 /* If this is a request without a body, then we are done */
2315 if (req->kind == EVHTTP_REQUEST &&
2316 !evhttp_method_may_have_body(req->type)) {
2317 evhttp_connection_done(evcon);
2320 evcon->state = EVCON_READING_BODY;
2321 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
2322 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
2326 if (evhttp_get_body_length(req) == -1) {
2327 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2330 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2331 /* An incoming request with no content-length and no
2332 * transfer-encoding has no body. */
2333 evhttp_connection_done(evcon);
2338 /* Should we send a 100 Continue status line? */
2339 switch (evhttp_have_expect(req, 1)) {
2341 /* XXX It would be nice to do some sanity
2342 checking here. Does the resource exist?
2343 Should the resource accept post requests? If
2344 no, we should respond with an error. For
2345 now, just optimistically tell the client to
2346 send their message body. */
2347 if (req->ntoread > 0) {
2348 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2349 if ((req->evcon->max_body_size <= EV_INT64_MAX) &&
2350 (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2351 evhttp_lingering_fail(evcon, req);
2355 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2356 evhttp_send_continue(evcon, req);
2359 evhttp_send_error(req, HTTP_EXPECTATIONFAILED, NULL);
2364 evhttp_read_body(evcon, req);
2365 /* note the request may have been freed in evhttp_read_body */
2369 evhttp_read_firstline(struct evhttp_connection *evcon,
2370 struct evhttp_request *req)
2372 enum message_read_status res;
2374 res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2375 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2376 /* Error while reading, terminate */
2377 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2378 __func__, EV_SOCK_ARG(evcon->fd)));
2379 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2381 } else if (res == MORE_DATA_EXPECTED) {
2382 /* Need more header lines */
2386 evcon->state = EVCON_READING_HEADERS;
2387 evhttp_read_header(evcon, req);
2391 evhttp_read_header(struct evhttp_connection *evcon,
2392 struct evhttp_request *req)
2394 enum message_read_status res;
2395 evutil_socket_t fd = evcon->fd;
2397 res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2398 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2399 /* Error while reading, terminate */
2400 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2401 __func__, EV_SOCK_ARG(fd)));
2402 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2404 } else if (res == MORE_DATA_EXPECTED) {
2405 /* Need more header lines */
2409 /* Callback can shut down connection with negative return value */
2410 if (req->header_cb != NULL) {
2411 if ((*req->header_cb)(req, req->cb_arg) < 0) {
2412 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2417 /* Done reading headers, do the real work */
2418 switch (req->kind) {
2419 case EVHTTP_REQUEST:
2420 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2421 __func__, EV_SOCK_ARG(fd)));
2422 evhttp_get_body(evcon, req);
2423 /* note the request may have been freed in evhttp_get_body */
2426 case EVHTTP_RESPONSE:
2427 /* Start over if we got a 100 Continue response. */
2428 if (req->response_code == 100) {
2429 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
2430 evbuffer_add_buffer(output, req->output_buffer);
2431 evhttp_start_write_(evcon);
2434 if (!evhttp_response_needs_body(req)) {
2435 event_debug(("%s: skipping body for code %d\n",
2436 __func__, req->response_code));
2437 evhttp_connection_done(evcon);
2439 event_debug(("%s: start of read body for %s on "
2441 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2442 evhttp_get_body(evcon, req);
2443 /* note the request may have been freed in
2444 * evhttp_get_body */
2449 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2451 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2454 /* request may have been freed above */
2458 * Creates a TCP connection to the specified port and executes a callback
2459 * when finished. Failure or success is indicate by the passed connection
2462 * Although this interface accepts a hostname, it is intended to take
2463 * only numeric hostnames so that non-blocking DNS resolution can
2467 struct evhttp_connection *
2468 evhttp_connection_new(const char *address, ev_uint16_t port)
2470 return (evhttp_connection_base_new(NULL, NULL, address, port));
2473 struct evhttp_connection *
2474 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2475 const char *address, ev_uint16_t port)
2477 struct evhttp_connection *evcon = NULL;
2479 event_debug(("Attempting connection to %s:%d\n", address, port));
2481 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2482 event_warn("%s: calloc failed", __func__);
2489 evcon->max_headers_size = EV_SIZE_MAX;
2490 evcon->max_body_size = EV_SIZE_MAX;
2492 evcon->timeout_connect.tv_sec = HTTP_CONNECT_TIMEOUT;
2493 evcon->timeout_read.tv_sec = HTTP_READ_TIMEOUT;
2494 evcon->timeout_write.tv_sec = HTTP_WRITE_TIMEOUT;
2495 evcon->initial_retry_timeout.tv_sec = HTTP_INITIAL_RETRY_TIMEOUT;
2497 evcon->retry_cnt = evcon->retry_max = 0;
2499 if ((evcon->address = mm_strdup(address)) == NULL) {
2500 event_warn("%s: strdup failed", __func__);
2505 if (!(bev = bufferevent_socket_new(base, -1, 0))) {
2506 event_warn("%s: bufferevent_socket_new failed", __func__);
2511 bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2514 evcon->state = EVCON_DISCONNECTED;
2515 TAILQ_INIT(&evcon->requests);
2519 if (bufferevent_get_base(bev) != base)
2520 bufferevent_base_set(base, evcon->bufev);
2523 event_deferred_cb_init_(
2524 &evcon->read_more_deferred_cb,
2525 bufferevent_get_priority(bev),
2526 evhttp_deferred_read_cb, evcon);
2528 evcon->dns_base = dnsbase;
2529 evcon->ai_family = AF_UNSPEC;
2535 evhttp_connection_free(evcon);
2539 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2541 return evcon->bufev;
2545 evhttp_connection_get_server(struct evhttp_connection *evcon)
2547 return evcon->http_server;
2550 struct evhttp_connection *
2551 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2552 const char *address, ev_uint16_t port)
2554 return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2557 void evhttp_connection_set_family(struct evhttp_connection *evcon,
2560 evcon->ai_family = family;
2563 int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2566 int avail_flags = 0;
2567 avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2568 avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2570 if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2572 evcon->flags &= ~avail_flags;
2574 evcon->flags |= flags;
2580 evhttp_connection_set_base(struct evhttp_connection *evcon,
2581 struct event_base *base)
2583 EVUTIL_ASSERT(evcon->base == NULL);
2584 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2586 bufferevent_base_set(base, evcon->bufev);
2590 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2593 if (timeout != -1) {
2594 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2596 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2598 evhttp_set_timeout_(&evcon->timeout_read, timeout, HTTP_READ_TIMEOUT);
2599 evhttp_set_timeout_(&evcon->timeout_write, timeout, HTTP_WRITE_TIMEOUT);
2600 bufferevent_set_timeouts(evcon->bufev,
2601 &evcon->timeout_read, &evcon->timeout_write);
2604 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2605 const struct timeval* tv)
2608 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2610 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2612 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, HTTP_READ_TIMEOUT);
2613 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, HTTP_WRITE_TIMEOUT);
2614 bufferevent_set_timeouts(evcon->bufev,
2615 &evcon->timeout_read, &evcon->timeout_write);
2617 void evhttp_connection_set_connect_timeout_tv(struct evhttp_connection *evcon,
2618 const struct timeval *tv)
2620 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2621 evhttp_set_timeout_tv_(&evcon->timeout_connect, tv, -1);
2622 if (evcon->state == EVCON_CONNECTING)
2623 bufferevent_set_timeouts(evcon->bufev,
2624 &evcon->timeout_connect, &evcon->timeout_connect);
2626 void evhttp_connection_set_read_timeout_tv(struct evhttp_connection *evcon,
2627 const struct timeval *tv)
2629 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2630 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, -1);
2631 if (evcon->state != EVCON_CONNECTING)
2632 bufferevent_set_timeouts(evcon->bufev,
2633 &evcon->timeout_read, &evcon->timeout_write);
2635 void evhttp_connection_set_write_timeout_tv(struct evhttp_connection *evcon,
2636 const struct timeval *tv)
2638 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2639 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, -1);
2640 if (evcon->state != EVCON_CONNECTING)
2641 bufferevent_set_timeouts(evcon->bufev,
2642 &evcon->timeout_read, &evcon->timeout_write);
2646 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2647 const struct timeval *tv)
2650 evcon->initial_retry_timeout = *tv;
2652 evutil_timerclear(&evcon->initial_retry_timeout);
2653 evcon->initial_retry_timeout.tv_sec = 2;
2658 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2661 evcon->retry_max = retry_max;
2665 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2666 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2668 evcon->closecb = cb;
2669 evcon->closecb_arg = cbarg;
2673 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2674 char **address, ev_uint16_t *port)
2676 *address = evcon->address;
2677 *port = evcon->port;
2680 const struct sockaddr*
2681 evhttp_connection_get_addr(struct evhttp_connection *evcon)
2683 return bufferevent_socket_get_conn_address_(evcon->bufev);
2687 evhttp_connection_connect_(struct evhttp_connection *evcon)
2689 int old_state = evcon->state;
2690 const char *address = evcon->address;
2691 const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
2694 if (evcon->state == EVCON_CONNECTING)
2697 evhttp_connection_reset_(evcon);
2699 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2700 evcon->flags |= EVHTTP_CON_OUTGOING;
2702 if (evcon->bind_address || evcon->bind_port) {
2703 evcon->fd = bind_socket(
2704 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2705 if (evcon->fd == -1) {
2706 event_debug(("%s: failed to bind to \"%s\"",
2707 __func__, evcon->bind_address));
2711 if (bufferevent_setfd(evcon->bufev, evcon->fd))
2714 if (bufferevent_setfd(evcon->bufev, -1))
2718 /* Set up a callback for successful connection setup */
2719 bufferevent_setcb(evcon->bufev,
2720 NULL /* evhttp_read_cb */,
2721 NULL /* evhttp_write_cb */,
2722 evhttp_connection_cb,
2724 bufferevent_set_timeouts(evcon->bufev,
2725 &evcon->timeout_connect, &evcon->timeout_connect);
2726 /* make sure that we get a write callback */
2727 if (bufferevent_enable(evcon->bufev, EV_WRITE))
2730 evcon->state = EVCON_CONNECTING;
2732 if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
2734 (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
2735 int socklen = sizeof(struct sockaddr_in);
2736 if (sa->sa_family == AF_INET6) {
2737 socklen = sizeof(struct sockaddr_in6);
2739 ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
2741 ret = bufferevent_socket_connect_hostname(evcon->bufev,
2742 evcon->dns_base, evcon->ai_family, address, evcon->port);
2746 evcon->state = old_state;
2747 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2748 __func__, evcon->address);
2749 /* some operating systems return ECONNREFUSED immediately
2750 * when connecting to a local address. the cleanup is going
2751 * to reschedule this function call.
2753 evhttp_connection_cb_cleanup(evcon);
2761 * Starts an HTTP request on the provided evhttp_connection object.
2762 * If the connection object is not connected to the web server already,
2763 * this will start the connection.
2767 evhttp_make_request(struct evhttp_connection *evcon,
2768 struct evhttp_request *req,
2769 enum evhttp_cmd_type type, const char *uri)
2771 /* We are making a request */
2772 req->kind = EVHTTP_REQUEST;
2774 if (req->uri != NULL)
2776 if ((req->uri = mm_strdup(uri)) == NULL) {
2777 event_warn("%s: strdup", __func__);
2778 evhttp_request_free_auto(req);
2782 /* Set the protocol version if it is not supplied */
2783 if (!req->major && !req->minor) {
2788 EVUTIL_ASSERT(req->evcon == NULL);
2790 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2792 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2794 /* We do not want to conflict with retry_ev */
2795 if (evcon->retry_cnt)
2798 /* If the connection object is not connected; make it so */
2799 if (!evhttp_connected(evcon)) {
2800 int res = evhttp_connection_connect_(evcon);
2801 /* evhttp_connection_fail_(), which is called through
2802 * evhttp_connection_connect_(), assumes that req lies in
2803 * evcon->requests. Thus, enqueue the request in advance and
2804 * remove it in the error case. */
2806 TAILQ_REMOVE(&evcon->requests, req, next);
2812 * If it's connected already and we are the first in the queue,
2813 * then we can dispatch this request immediately. Otherwise, it
2814 * will be dispatched once the pending requests are completed.
2816 if (TAILQ_FIRST(&evcon->requests) == req)
2817 evhttp_request_dispatch(evcon);
2823 evhttp_cancel_request(struct evhttp_request *req)
2825 struct evhttp_connection *evcon = req->evcon;
2826 if (evcon != NULL) {
2827 /* We need to remove it from the connection */
2828 if (TAILQ_FIRST(&evcon->requests) == req) {
2829 /* it's currently being worked on, so reset
2832 evhttp_connection_fail_(evcon,
2833 EVREQ_HTTP_REQUEST_CANCEL);
2835 /* connection fail freed the request */
2838 /* otherwise, we can just remove it from the
2841 TAILQ_REMOVE(&evcon->requests, req, next);
2845 evhttp_request_free_auto(req);
2849 * Reads data from file descriptor into request structure
2850 * Request structure needs to be set up correctly.
2854 evhttp_start_read_(struct evhttp_connection *evcon)
2856 bufferevent_disable(evcon->bufev, EV_WRITE);
2857 bufferevent_enable(evcon->bufev, EV_READ);
2859 evcon->state = EVCON_READING_FIRSTLINE;
2860 /* Reset the bufferevent callbacks */
2861 bufferevent_setcb(evcon->bufev,
2867 /* If there's still data pending, process it next time through the
2868 * loop. Don't do it now; that could get recusive. */
2869 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2870 event_deferred_cb_schedule_(get_deferred_queue(evcon),
2871 &evcon->read_more_deferred_cb);
2876 evhttp_start_write_(struct evhttp_connection *evcon)
2878 bufferevent_disable(evcon->bufev, EV_WRITE);
2879 bufferevent_enable(evcon->bufev, EV_READ);
2881 evcon->state = EVCON_WRITING;
2882 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
2886 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2889 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2890 TAILQ_REMOVE(&evcon->requests, req, next);
2892 if (req->on_complete_cb != NULL) {
2893 req->on_complete_cb(req, req->on_complete_cb_arg);
2897 (REQ_VERSION_BEFORE(req, 1, 1) &&
2898 !evhttp_is_connection_keepalive(req->input_headers)) ||
2899 evhttp_is_request_connection_close(req);
2901 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2902 evhttp_request_free(req);
2905 evhttp_connection_free(evcon);
2909 /* we have a persistent connection; try to accept another request. */
2910 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2911 evhttp_connection_free(evcon);
2916 * Returns an error page.
2920 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2923 #define ERR_FORMAT "<HTML><HEAD>\n" \
2924 "<TITLE>%d %s</TITLE>\n" \
2929 struct evbuffer *buf = evbuffer_new();
2931 /* if we cannot allocate memory; we just drop the connection */
2932 evhttp_connection_free(req->evcon);
2935 if (reason == NULL) {
2936 reason = evhttp_response_phrase_internal(error);
2939 evhttp_response_code_(req, error, reason);
2941 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2943 evhttp_send_page_(req, buf);
2949 /* Requires that headers and response code are already set up */
2952 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2954 struct evhttp_connection *evcon = req->evcon;
2956 if (evcon == NULL) {
2957 evhttp_request_free(req);
2961 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2963 /* we expect no more calls form the user on this request */
2966 /* xxx: not sure if we really should expose the data buffer this way */
2967 if (databuf != NULL)
2968 evbuffer_add_buffer(req->output_buffer, databuf);
2970 /* Adds headers to the response */
2971 evhttp_make_header(evcon, req);
2973 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2977 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2978 struct evbuffer *databuf)
2980 evhttp_response_code_(req, code, reason);
2982 evhttp_send(req, databuf);
2986 evhttp_send_reply_start(struct evhttp_request *req, int code,
2989 evhttp_response_code_(req, code, reason);
2991 if (req->evcon == NULL)
2994 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2995 REQ_VERSION_ATLEAST(req, 1, 1) &&
2996 evhttp_response_needs_body(req)) {
2998 * prefer HTTP/1.1 chunked encoding to closing the connection;
2999 * note RFC 2616 section 4.4 forbids it with Content-Length:
3000 * and it's not necessary then anyway.
3002 evhttp_add_header(req->output_headers, "Transfer-Encoding",
3008 evhttp_make_header(req->evcon, req);
3009 evhttp_write_buffer(req->evcon, NULL, NULL);
3013 evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
3014 void (*cb)(struct evhttp_connection *, void *), void *arg)
3016 struct evhttp_connection *evcon = req->evcon;
3017 struct evbuffer *output;
3022 output = bufferevent_get_output(evcon->bufev);
3024 if (evbuffer_get_length(databuf) == 0)
3026 if (!evhttp_response_needs_body(req))
3029 evbuffer_add_printf(output, "%x\r\n",
3030 (unsigned)evbuffer_get_length(databuf));
3032 evbuffer_add_buffer(output, databuf);
3034 evbuffer_add(output, "\r\n", 2);
3036 evhttp_write_buffer(evcon, cb, arg);
3040 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
3042 evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
3045 evhttp_send_reply_end(struct evhttp_request *req)
3047 struct evhttp_connection *evcon = req->evcon;
3048 struct evbuffer *output;
3050 if (evcon == NULL) {
3051 evhttp_request_free(req);
3055 output = bufferevent_get_output(evcon->bufev);
3057 /* we expect no more calls form the user on this request */
3061 evbuffer_add(output, "0\r\n\r\n", 5);
3062 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
3064 } else if (evbuffer_get_length(output) == 0) {
3065 /* let the connection know that we are done with the request */
3066 evhttp_send_done(evcon, NULL);
3068 /* make the callback execute after all data has been written */
3069 evcon->cb = evhttp_send_done;
3070 evcon->cb_arg = NULL;
3074 static const char *informational_phrases[] = {
3075 /* 100 */ "Continue",
3076 /* 101 */ "Switching Protocols"
3079 static const char *success_phrases[] = {
3081 /* 201 */ "Created",
3082 /* 202 */ "Accepted",
3083 /* 203 */ "Non-Authoritative Information",
3084 /* 204 */ "No Content",
3085 /* 205 */ "Reset Content",
3086 /* 206 */ "Partial Content"
3089 static const char *redirection_phrases[] = {
3090 /* 300 */ "Multiple Choices",
3091 /* 301 */ "Moved Permanently",
3093 /* 303 */ "See Other",
3094 /* 304 */ "Not Modified",
3095 /* 305 */ "Use Proxy",
3096 /* 307 */ "Temporary Redirect"
3099 static const char *client_error_phrases[] = {
3100 /* 400 */ "Bad Request",
3101 /* 401 */ "Unauthorized",
3102 /* 402 */ "Payment Required",
3103 /* 403 */ "Forbidden",
3104 /* 404 */ "Not Found",
3105 /* 405 */ "Method Not Allowed",
3106 /* 406 */ "Not Acceptable",
3107 /* 407 */ "Proxy Authentication Required",
3108 /* 408 */ "Request Time-out",
3109 /* 409 */ "Conflict",
3111 /* 411 */ "Length Required",
3112 /* 412 */ "Precondition Failed",
3113 /* 413 */ "Request Entity Too Large",
3114 /* 414 */ "Request-URI Too Large",
3115 /* 415 */ "Unsupported Media Type",
3116 /* 416 */ "Requested range not satisfiable",
3117 /* 417 */ "Expectation Failed"
3120 static const char *server_error_phrases[] = {
3121 /* 500 */ "Internal Server Error",
3122 /* 501 */ "Not Implemented",
3123 /* 502 */ "Bad Gateway",
3124 /* 503 */ "Service Unavailable",
3125 /* 504 */ "Gateway Time-out",
3126 /* 505 */ "HTTP Version not supported"
3129 struct response_class {
3131 size_t num_responses;
3132 const char **responses;
3136 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
3139 static const struct response_class response_classes[] = {
3140 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
3141 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
3142 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
3143 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
3144 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
3148 evhttp_response_phrase_internal(int code)
3150 int klass = code / 100 - 1;
3151 int subcode = code % 100;
3153 /* Unknown class - can't do any better here */
3154 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
3155 return "Unknown Status Class";
3157 /* Unknown sub-code, return class name at least */
3158 if (subcode >= (int) response_classes[klass].num_responses)
3159 return response_classes[klass].name;
3161 return response_classes[klass].responses[subcode];
3165 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
3167 req->kind = EVHTTP_RESPONSE;
3168 req->response_code = code;
3169 if (req->response_code_line != NULL)
3170 mm_free(req->response_code_line);
3172 reason = evhttp_response_phrase_internal(code);
3173 req->response_code_line = mm_strdup(reason);
3174 if (req->response_code_line == NULL) {
3175 event_warn("%s: strdup", __func__);
3176 /* XXX what else can we do? */
3181 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
3183 if (!req->major || !req->minor) {
3188 if (req->kind != EVHTTP_RESPONSE)
3189 evhttp_response_code_(req, 200, "OK");
3191 evhttp_clear_headers(req->output_headers);
3192 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
3193 evhttp_add_header(req->output_headers, "Connection", "close");
3195 evhttp_send(req, databuf);
3198 static const char uri_chars[256] = {
3200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
3203 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
3205 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3206 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
3207 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3208 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
3210 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3211 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3212 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3213 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3215 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3216 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3221 #define CHAR_IS_UNRESERVED(c) \
3222 (uri_chars[(unsigned char)(c)])
3225 * Helper functions to encode/decode a string for inclusion in a URI.
3226 * The returned string must be freed by the caller.
3229 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3231 struct evbuffer *buf = evbuffer_new();
3232 const char *p, *end;
3233 char *result = NULL;
3240 if (uri + len < uri) {
3246 size_t slen = strlen(uri);
3248 if (slen >= EV_SSIZE_MAX) {
3249 /* we don't want to mix signed and unsigned */
3253 if (uri + slen < uri) {
3260 for (p = uri; p < end; p++) {
3261 if (CHAR_IS_UNRESERVED(*p)) {
3262 evbuffer_add(buf, p, 1);
3263 } else if (*p == ' ' && space_as_plus) {
3264 evbuffer_add(buf, "+", 1);
3266 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3270 evbuffer_add(buf, "", 1); /* NUL-terminator. */
3271 result = mm_malloc(evbuffer_get_length(buf));
3274 evbuffer_remove(buf, result, evbuffer_get_length(buf));
3283 evhttp_encode_uri(const char *str)
3285 return evhttp_uriencode(str, -1, 0);
3289 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
3290 * If -1, when true we transform plus to space only after we've seen
3291 * a ?. -1 is deprecated.
3292 * @return the number of bytes written to 'ret'.
3295 evhttp_decode_uri_internal(
3296 const char *uri, size_t length, char *ret, int decode_plus_ctl)
3300 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3303 for (i = j = 0; i < length; i++) {
3306 if (decode_plus_ctl < 0)
3308 } else if (c == '+' && decode_plus) {
3310 } else if ((i + 2) < length && c == '%' &&
3311 EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3316 c = (char)strtol(tmp, NULL, 16);
3328 evhttp_decode_uri(const char *uri)
3332 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3333 event_warn("%s: malloc(%lu)", __func__,
3334 (unsigned long)(strlen(uri) + 1));
3338 evhttp_decode_uri_internal(uri, strlen(uri),
3339 ret, -1 /*always_decode_plus*/);
3345 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3350 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3351 event_warn("%s: malloc(%lu)", __func__,
3352 (unsigned long)(strlen(uri) + 1));
3356 n = evhttp_decode_uri_internal(uri, strlen(uri),
3357 ret, !!decode_plus/*always_decode_plus*/);
3360 EVUTIL_ASSERT(n >= 0);
3361 *size_out = (size_t)n;
3368 * Helper function to parse out arguments in a query.
3369 * The arguments are separated by key and value.
3373 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3374 int is_whole_uri, unsigned flags)
3379 const char *query_part;
3381 struct evhttp_uri *uri=NULL;
3383 TAILQ_INIT(headers);
3386 uri = evhttp_uri_parse(str);
3389 query_part = evhttp_uri_get_query(uri);
3394 /* No arguments - we are done */
3395 if (!query_part || !strlen(query_part)) {
3400 if ((line = mm_strdup(query_part)) == NULL) {
3401 event_warn("%s: strdup", __func__);
3405 p = argument = line;
3406 while (p != NULL && *p != '\0') {
3407 char *key, *value, *decoded_value;
3408 argument = strsep(&p, "&");
3411 key = strsep(&value, "=");
3412 if (flags & EVHTTP_URI_QUERY_NONCONFORMANT) {
3418 if (value == NULL || *key == '\0')
3422 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3423 event_warn("%s: mm_malloc", __func__);
3426 evhttp_decode_uri_internal(value, strlen(value),
3427 decoded_value, 1 /*always_decode_plus*/);
3428 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3429 if (flags & EVHTTP_URI_QUERY_LAST_VAL)
3430 evhttp_remove_header(headers, key);
3431 evhttp_add_header_internal(headers, key, decoded_value);
3432 mm_free(decoded_value);
3438 evhttp_clear_headers(headers);
3443 evhttp_uri_free(uri);
3448 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3450 return evhttp_parse_query_impl(uri, headers, 1, 0);
3453 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3455 return evhttp_parse_query_impl(uri, headers, 0, 0);
3458 evhttp_parse_query_str_flags(const char *uri, struct evkeyvalq *headers, unsigned flags)
3460 return evhttp_parse_query_impl(uri, headers, 0, flags);
3463 static struct evhttp_cb *
3464 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3466 struct evhttp_cb *cb;
3471 /* Test for different URLs */
3472 path = evhttp_uri_get_path(req->uri_elems);
3473 offset = strlen(path);
3474 if ((translated = mm_malloc(offset + 1)) == NULL)
3476 evhttp_decode_uri_internal(path, offset, translated,
3477 0 /* decode_plus */);
3479 TAILQ_FOREACH(cb, callbacks, next) {
3480 if (!strcmp(cb->what, translated)) {
3481 mm_free(translated);
3486 mm_free(translated);
3492 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3497 switch (c = *pattern++) {
3499 return *name == '\0';
3502 while (*name != '\0') {
3503 if (prefix_suffix_match(pattern, name,
3512 EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3522 Search the vhost hierarchy beginning with http for a server alias
3523 matching hostname. If a match is found, and outhttp is non-null,
3524 outhttp is set to the matching http object and 1 is returned.
3528 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3529 const char *hostname)
3531 struct evhttp_server_alias *alias;
3532 struct evhttp *vhost;
3534 TAILQ_FOREACH(alias, &http->aliases, next) {
3535 /* XXX Do we need to handle IP addresses? */
3536 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3543 /* XXX It might be good to avoid recursion here, but I don't
3544 see a way to do that w/o a list. */
3545 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3546 if (evhttp_find_alias(vhost, outhttp, hostname))
3554 Attempts to find the best http object to handle a request for a hostname.
3555 All aliases for the root http object and vhosts are searched for an exact
3556 match. Then, the vhost hierarchy is traversed again for a matching
3559 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3560 is set with the best matching http object. If there are no matches, the
3561 root http object is stored in outhttp and 0 is returned.
3565 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3566 const char *hostname)
3568 struct evhttp *vhost;
3569 struct evhttp *oldhttp;
3570 int match_found = 0;
3572 if (evhttp_find_alias(http, outhttp, hostname))
3577 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3578 if (prefix_suffix_match(vhost->vhost_pattern,
3579 hostname, 1 /* ignorecase */)) {
3585 } while (oldhttp != http);
3594 evhttp_handle_request(struct evhttp_request *req, void *arg)
3596 struct evhttp *http = arg;
3597 struct evhttp_cb *cb = NULL;
3598 const char *hostname;
3600 /* we have a new request on which the user needs to take action */
3603 bufferevent_disable(req->evcon->bufev, EV_READ);
3605 if (req->type == 0 || req->uri == NULL) {
3606 evhttp_send_error(req, req->response_code, NULL);
3610 if ((http->allowed_methods & req->type) == 0) {
3611 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3612 (unsigned)req->type, (unsigned)http->allowed_methods));
3613 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3617 /* handle potential virtual hosts */
3618 hostname = evhttp_request_get_host(req);
3619 if (hostname != NULL) {
3620 evhttp_find_vhost(http, &http, hostname);
3623 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3624 (*cb->cb)(req, cb->cbarg);
3628 /* Generic call back */
3630 (*http->gencb)(req, http->gencbarg);
3633 /* We need to send a 404 here */
3634 #define ERR_FORMAT "<html><head>" \
3635 "<title>404 Not Found</title>" \
3637 "<h1>Not Found</h1>" \
3638 "<p>The requested URL %s was not found on this server.</p>"\
3642 struct evbuffer *buf;
3644 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3645 evhttp_connection_free(req->evcon);
3649 if ((buf = evbuffer_new()) == NULL) {
3650 mm_free(escaped_html);
3651 evhttp_connection_free(req->evcon);
3655 evhttp_response_code_(req, HTTP_NOTFOUND, "Not Found");
3657 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3659 mm_free(escaped_html);
3661 evhttp_send_page_(req, buf);
3668 /* Listener callback when a connection arrives at a server. */
3670 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3672 struct evhttp *http = arg;
3674 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3678 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3680 struct evhttp_bound_socket *bound =
3681 evhttp_bind_socket_with_handle(http, address, port);
3687 struct evhttp_bound_socket *
3688 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3691 struct evhttp_bound_socket *bound;
3694 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3697 if (listen(fd, 128) == -1) {
3698 serrno = EVUTIL_SOCKET_ERROR();
3699 event_sock_warn(fd, "%s: listen", __func__);
3700 evutil_closesocket(fd);
3701 EVUTIL_SET_SOCKET_ERROR(serrno);
3705 bound = evhttp_accept_socket_with_handle(http, fd);
3707 if (bound != NULL) {
3708 event_debug(("Bound to port %d - Awaiting connections ... ",
3717 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3719 struct evhttp_bound_socket *bound =
3720 evhttp_accept_socket_with_handle(http, fd);
3727 evhttp_foreach_bound_socket(struct evhttp *http,
3728 evhttp_bound_socket_foreach_fn *function,
3731 struct evhttp_bound_socket *bound;
3733 TAILQ_FOREACH(bound, &http->sockets, next)
3734 function(bound, argument);
3737 struct evhttp_bound_socket *
3738 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3740 struct evhttp_bound_socket *bound;
3741 struct evconnlistener *listener;
3743 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3745 listener = evconnlistener_new(http->base, NULL, NULL,
3747 0, /* Backlog is '0' because we already said 'listen' */
3752 bound = evhttp_bind_listener(http, listener);
3754 evconnlistener_free(listener);
3760 struct evhttp_bound_socket *
3761 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3763 struct evhttp_bound_socket *bound;
3765 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3769 bound->listener = listener;
3770 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3772 evconnlistener_set_cb(listener, accept_socket_cb, http);
3777 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3779 return evconnlistener_get_fd(bound->listener);
3782 struct evconnlistener *
3783 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3785 return bound->listener;
3789 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3791 TAILQ_REMOVE(&http->sockets, bound, next);
3792 evconnlistener_free(bound->listener);
3796 static struct evhttp*
3797 evhttp_new_object(void)
3799 struct evhttp *http = NULL;
3801 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3802 event_warn("%s: calloc", __func__);
3806 evutil_timerclear(&http->timeout_read);
3807 evutil_timerclear(&http->timeout_write);
3809 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3810 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3811 evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
3812 evhttp_set_allowed_methods(http,
3819 TAILQ_INIT(&http->sockets);
3820 TAILQ_INIT(&http->callbacks);
3821 TAILQ_INIT(&http->connections);
3822 TAILQ_INIT(&http->virtualhosts);
3823 TAILQ_INIT(&http->aliases);
3829 evhttp_new(struct event_base *base)
3831 struct evhttp *http = NULL;
3833 http = evhttp_new_object();
3842 * Start a web server on the specified address and port.
3846 evhttp_start(const char *address, ev_uint16_t port)
3848 struct evhttp *http = NULL;
3850 http = evhttp_new_object();
3853 if (evhttp_bind_socket(http, address, port) == -1) {
3862 evhttp_free(struct evhttp* http)
3864 struct evhttp_cb *http_cb;
3865 struct evhttp_connection *evcon;
3866 struct evhttp_bound_socket *bound;
3867 struct evhttp* vhost;
3868 struct evhttp_server_alias *alias;
3870 /* Remove the accepting part */
3871 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3872 TAILQ_REMOVE(&http->sockets, bound, next);
3874 evconnlistener_free(bound->listener);
3879 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3880 /* evhttp_connection_free removes the connection */
3881 evhttp_connection_free(evcon);
3884 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3885 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3886 mm_free(http_cb->what);
3890 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3891 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3896 if (http->vhost_pattern != NULL)
3897 mm_free(http->vhost_pattern);
3899 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3900 TAILQ_REMOVE(&http->aliases, alias, next);
3901 mm_free(alias->alias);
3909 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3910 struct evhttp* vhost)
3912 /* a vhost can only be a vhost once and should not have bound sockets */
3913 if (vhost->vhost_pattern != NULL ||
3914 TAILQ_FIRST(&vhost->sockets) != NULL)
3917 vhost->vhost_pattern = mm_strdup(pattern);
3918 if (vhost->vhost_pattern == NULL)
3921 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3927 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3929 if (vhost->vhost_pattern == NULL)
3932 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3934 mm_free(vhost->vhost_pattern);
3935 vhost->vhost_pattern = NULL;
3941 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3943 struct evhttp_server_alias *evalias;
3945 evalias = mm_calloc(1, sizeof(*evalias));
3949 evalias->alias = mm_strdup(alias);
3950 if (!evalias->alias) {
3955 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3961 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3963 struct evhttp_server_alias *evalias;
3965 TAILQ_FOREACH(evalias, &http->aliases, next) {
3966 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3967 TAILQ_REMOVE(&http->aliases, evalias, next);
3968 mm_free(evalias->alias);
3978 evhttp_set_timeout(struct evhttp* http, int timeout)
3980 evhttp_set_timeout_(&http->timeout_read, timeout, -1);
3981 evhttp_set_timeout_(&http->timeout_write, timeout, -1);
3984 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
3986 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
3987 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
3990 evhttp_set_read_timeout_tv(struct evhttp* http, const struct timeval* tv)
3992 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
3995 evhttp_set_write_timeout_tv(struct evhttp* http, const struct timeval* tv)
3997 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4000 int evhttp_set_flags(struct evhttp *http, int flags)
4002 int avail_flags = 0;
4003 avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
4005 if (flags & ~avail_flags)
4007 http->flags &= ~avail_flags;
4009 http->flags |= flags;
4015 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
4017 if (max_headers_size < 0)
4018 http->default_max_headers_size = EV_SIZE_MAX;
4020 http->default_max_headers_size = max_headers_size;
4024 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
4026 if (max_body_size < 0)
4027 http->default_max_body_size = EV_UINT64_MAX;
4029 http->default_max_body_size = max_body_size;
4033 evhttp_set_default_content_type(struct evhttp *http,
4034 const char *content_type) {
4035 http->default_content_type = content_type;
4039 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
4041 http->allowed_methods = methods;
4045 evhttp_set_cb(struct evhttp *http, const char *uri,
4046 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4048 struct evhttp_cb *http_cb;
4050 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4051 if (strcmp(http_cb->what, uri) == 0)
4055 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
4056 event_warn("%s: calloc", __func__);
4060 http_cb->what = mm_strdup(uri);
4061 if (http_cb->what == NULL) {
4062 event_warn("%s: strdup", __func__);
4067 http_cb->cbarg = cbarg;
4069 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
4075 evhttp_del_cb(struct evhttp *http, const char *uri)
4077 struct evhttp_cb *http_cb;
4079 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4080 if (strcmp(http_cb->what, uri) == 0)
4083 if (http_cb == NULL)
4086 TAILQ_REMOVE(&http->callbacks, http_cb, next);
4087 mm_free(http_cb->what);
4094 evhttp_set_gencb(struct evhttp *http,
4095 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4098 http->gencbarg = cbarg;
4102 evhttp_set_bevcb(struct evhttp *http,
4103 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
4106 http->bevcbarg = cbarg;
4110 evhttp_set_newreqcb(struct evhttp *http,
4111 int (*cb)(struct evhttp_request *, void *), void *cbarg)
4113 http->newreqcb = cb;
4114 http->newreqcbarg = cbarg;
4118 * Request related functions
4121 struct evhttp_request *
4122 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
4124 struct evhttp_request *req = NULL;
4126 /* Allocate request structure */
4127 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
4128 event_warn("%s: calloc", __func__);
4132 req->headers_size = 0;
4135 req->kind = EVHTTP_RESPONSE;
4136 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4137 if (req->input_headers == NULL) {
4138 event_warn("%s: calloc", __func__);
4141 TAILQ_INIT(req->input_headers);
4143 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4144 if (req->output_headers == NULL) {
4145 event_warn("%s: calloc", __func__);
4148 TAILQ_INIT(req->output_headers);
4150 if ((req->input_buffer = evbuffer_new()) == NULL) {
4151 event_warn("%s: evbuffer_new", __func__);
4155 if ((req->output_buffer = evbuffer_new()) == NULL) {
4156 event_warn("%s: evbuffer_new", __func__);
4167 evhttp_request_free(req);
4172 evhttp_request_free(struct evhttp_request *req)
4174 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
4175 req->flags |= EVHTTP_REQ_NEEDS_FREE;
4179 if (req->remote_host != NULL)
4180 mm_free(req->remote_host);
4181 if (req->uri != NULL)
4183 if (req->uri_elems != NULL)
4184 evhttp_uri_free(req->uri_elems);
4185 if (req->response_code_line != NULL)
4186 mm_free(req->response_code_line);
4187 if (req->host_cache != NULL)
4188 mm_free(req->host_cache);
4190 evhttp_clear_headers(req->input_headers);
4191 mm_free(req->input_headers);
4193 evhttp_clear_headers(req->output_headers);
4194 mm_free(req->output_headers);
4196 if (req->input_buffer != NULL)
4197 evbuffer_free(req->input_buffer);
4199 if (req->output_buffer != NULL)
4200 evbuffer_free(req->output_buffer);
4206 evhttp_request_own(struct evhttp_request *req)
4208 req->flags |= EVHTTP_USER_OWNED;
4212 evhttp_request_is_owned(struct evhttp_request *req)
4214 return (req->flags & EVHTTP_USER_OWNED) != 0;
4217 struct evhttp_connection *
4218 evhttp_request_get_connection(struct evhttp_request *req)
4224 evhttp_connection_get_base(struct evhttp_connection *conn)
4230 evhttp_request_set_chunked_cb(struct evhttp_request *req,
4231 void (*cb)(struct evhttp_request *, void *))
4237 evhttp_request_set_header_cb(struct evhttp_request *req,
4238 int (*cb)(struct evhttp_request *, void *))
4240 req->header_cb = cb;
4244 evhttp_request_set_error_cb(struct evhttp_request *req,
4245 void (*cb)(enum evhttp_request_error, void *))
4251 evhttp_request_set_on_complete_cb(struct evhttp_request *req,
4252 void (*cb)(struct evhttp_request *, void *), void *cb_arg)
4254 req->on_complete_cb = cb;
4255 req->on_complete_cb_arg = cb_arg;
4259 * Allows for inspection of the request URI
4263 evhttp_request_get_uri(const struct evhttp_request *req) {
4264 if (req->uri == NULL)
4265 event_debug(("%s: request %p has no uri\n", __func__, req));
4269 const struct evhttp_uri *
4270 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4271 if (req->uri_elems == NULL)
4272 event_debug(("%s: request %p has no uri elems\n",
4274 return (req->uri_elems);
4278 evhttp_request_get_host(struct evhttp_request *req)
4280 const char *host = NULL;
4282 if (req->host_cache)
4283 return req->host_cache;
4286 host = evhttp_uri_get_host(req->uri_elems);
4287 if (!host && req->input_headers) {
4291 host = evhttp_find_header(req->input_headers, "Host");
4292 /* The Host: header may include a port. Remove it here
4293 to be consistent with uri_elems case above. */
4295 p = host + strlen(host) - 1;
4296 while (p > host && EVUTIL_ISDIGIT_(*p))
4298 if (p > host && *p == ':') {
4300 req->host_cache = mm_malloc(len + 1);
4301 if (!req->host_cache) {
4302 event_warn("%s: malloc", __func__);
4305 memcpy(req->host_cache, host, len);
4306 req->host_cache[len] = '\0';
4307 host = req->host_cache;
4315 enum evhttp_cmd_type
4316 evhttp_request_get_command(const struct evhttp_request *req) {
4321 evhttp_request_get_response_code(const struct evhttp_request *req)
4323 return req->response_code;
4327 evhttp_request_get_response_code_line(const struct evhttp_request *req)
4329 return req->response_code_line;
4332 /** Returns the input headers */
4333 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4335 return (req->input_headers);
4338 /** Returns the output headers */
4339 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4341 return (req->output_headers);
4344 /** Returns the input buffer */
4345 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4347 return (req->input_buffer);
4350 /** Returns the output buffer */
4351 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4353 return (req->output_buffer);
4358 * Takes a file descriptor to read a request from.
4359 * The callback is executed once the whole request has been read.
4362 static struct evhttp_connection*
4363 evhttp_get_request_connection(
4364 struct evhttp* http,
4365 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
4367 struct evhttp_connection *evcon;
4368 char *hostname = NULL, *portname = NULL;
4369 struct bufferevent* bev = NULL;
4371 name_from_addr(sa, salen, &hostname, &portname);
4372 if (hostname == NULL || portname == NULL) {
4373 if (hostname) mm_free(hostname);
4374 if (portname) mm_free(portname);
4378 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4379 __func__, hostname, portname, EV_SOCK_ARG(fd)));
4381 /* we need a connection object to put the http request on */
4382 if (http->bevcb != NULL) {
4383 bev = (*http->bevcb)(http->base, http->bevcbarg);
4385 evcon = evhttp_connection_base_bufferevent_new(
4386 http->base, NULL, bev, hostname, atoi(portname));
4392 evcon->max_headers_size = http->default_max_headers_size;
4393 evcon->max_body_size = http->default_max_body_size;
4394 if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4395 evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4397 evcon->flags |= EVHTTP_CON_INCOMING;
4398 evcon->state = EVCON_READING_FIRSTLINE;
4402 if (bufferevent_setfd(evcon->bufev, fd))
4404 if (bufferevent_enable(evcon->bufev, EV_READ))
4406 if (bufferevent_disable(evcon->bufev, EV_WRITE))
4408 bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
4413 evhttp_connection_free(evcon);
4418 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4420 struct evhttp *http = evcon->http_server;
4421 struct evhttp_request *req;
4422 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4425 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4426 event_warn("%s: strdup", __func__);
4427 evhttp_request_free(req);
4430 req->remote_port = evcon->port;
4432 req->evcon = evcon; /* the request ends up owning the connection */
4433 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4435 /* We did not present the request to the user yet, so treat it
4436 * as if the user was done with the request. This allows us
4437 * to free the request on a persistent connection if the
4438 * client drops it without sending a request.
4441 req->kind = EVHTTP_REQUEST;
4443 if (http->newreqcb && http->newreqcb(req, http->newreqcbarg) == -1) {
4444 evhttp_request_free(req);
4448 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4450 evhttp_start_read_(evcon);
4456 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4457 struct sockaddr *sa, ev_socklen_t salen)
4459 struct evhttp_connection *evcon;
4461 evcon = evhttp_get_request_connection(http, fd, sa, salen);
4462 if (evcon == NULL) {
4463 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4464 __func__, EV_SOCK_ARG(fd));
4465 evutil_closesocket(fd);
4469 /* the timeout can be used by the server to close idle connections */
4470 if (evutil_timerisset(&http->timeout_read))
4471 evhttp_connection_set_read_timeout_tv(evcon, &http->timeout_read);
4472 if (evutil_timerisset(&http->timeout_write))
4473 evhttp_connection_set_write_timeout_tv(evcon, &http->timeout_write);
4476 * if we want to accept more than one request on a connection,
4477 * we need to know which http server it belongs to.
4479 evcon->http_server = http;
4480 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4482 if (evhttp_associate_new_request_with_connection(evcon) == -1)
4483 evhttp_connection_free(evcon);
4488 * Network helper functions that we do not want to export to the rest of
4493 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4494 char **phost, char **pport)
4496 char ntop[NI_MAXHOST];
4497 char strport[NI_MAXSERV];
4500 #ifdef EVENT__HAVE_GETNAMEINFO
4501 ni_result = getnameinfo(sa, salen,
4502 ntop, sizeof(ntop), strport, sizeof(strport),
4503 NI_NUMERICHOST|NI_NUMERICSERV);
4505 if (ni_result != 0) {
4507 /* Windows doesn't have an EAI_SYSTEM. */
4508 if (ni_result == EAI_SYSTEM)
4509 event_err(1, "getnameinfo failed");
4512 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4516 ni_result = fake_getnameinfo(sa, salen,
4517 ntop, sizeof(ntop), strport, sizeof(strport),
4518 NI_NUMERICHOST|NI_NUMERICSERV);
4523 *phost = mm_strdup(ntop);
4524 *pport = mm_strdup(strport);
4527 /* Create a non-blocking socket and bind it */
4528 /* todo: rename this function */
4529 static evutil_socket_t
4530 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
4537 /* Create listen socket */
4538 fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
4539 SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
4541 event_sock_warn(-1, "socket");
4545 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
4548 if (evutil_make_listen_socket_reuseable(fd) < 0)
4553 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
4561 serrno = EVUTIL_SOCKET_ERROR();
4562 evutil_closesocket(fd);
4563 EVUTIL_SET_SOCKET_ERROR(serrno);
4567 static struct evutil_addrinfo *
4568 make_addrinfo(const char *address, ev_uint16_t port)
4570 struct evutil_addrinfo *ai = NULL;
4572 struct evutil_addrinfo hints;
4573 char strport[NI_MAXSERV];
4576 memset(&hints, 0, sizeof(hints));
4577 hints.ai_family = AF_UNSPEC;
4578 hints.ai_socktype = SOCK_STREAM;
4579 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
4580 * types we don't have an interface to connect to. */
4581 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
4582 evutil_snprintf(strport, sizeof(strport), "%d", port);
4583 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
4585 if (ai_result == EVUTIL_EAI_SYSTEM)
4586 event_warn("getaddrinfo");
4588 event_warnx("getaddrinfo: %s",
4589 evutil_gai_strerror(ai_result));
4596 static evutil_socket_t
4597 bind_socket(const char *address, ev_uint16_t port, int reuse)
4600 struct evutil_addrinfo *aitop = NULL;
4602 /* just create an unbound socket */
4603 if (address == NULL && port == 0)
4604 return bind_socket_ai(NULL, 0);
4606 aitop = make_addrinfo(address, port);
4611 fd = bind_socket_ai(aitop, reuse);
4613 evutil_freeaddrinfo(aitop);
4620 char *scheme; /* scheme; e.g http, ftp etc */
4621 char *userinfo; /* userinfo (typically username:pass), or NULL */
4622 char *host; /* hostname, IP address, or NULL */
4623 int port; /* port, or zero */
4624 char *path; /* path, or "". */
4625 char *query; /* query, or NULL */
4626 char *fragment; /* fragment or NULL */
4630 evhttp_uri_new(void)
4632 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
4639 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
4644 /* Return true if the string starting at s and ending immediately before eos
4645 * is a valid URI scheme according to RFC3986
4648 scheme_ok(const char *s, const char *eos)
4650 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4651 EVUTIL_ASSERT(eos >= s);
4654 if (!EVUTIL_ISALPHA_(*s))
4657 if (! EVUTIL_ISALNUM_(*s) &&
4658 *s != '+' && *s != '-' && *s != '.')
4664 #define SUBDELIMS "!$&'()*+,;="
4666 /* Return true iff [s..eos) is a valid userinfo */
4668 userinfo_ok(const char *s, const char *eos)
4671 if (CHAR_IS_UNRESERVED(*s) ||
4672 strchr(SUBDELIMS, *s) ||
4675 else if (*s == '%' && s+2 < eos &&
4676 EVUTIL_ISXDIGIT_(s[1]) &&
4677 EVUTIL_ISXDIGIT_(s[2]))
4686 regname_ok(const char *s, const char *eos)
4688 while (s && s<eos) {
4689 if (CHAR_IS_UNRESERVED(*s) ||
4690 strchr(SUBDELIMS, *s))
4692 else if (*s == '%' &&
4693 EVUTIL_ISXDIGIT_(s[1]) &&
4694 EVUTIL_ISXDIGIT_(s[2]))
4703 parse_port(const char *s, const char *eos)
4707 if (! EVUTIL_ISDIGIT_(*s))
4709 portnum = (portnum * 10) + (*s - '0');
4712 if (portnum > 65535)
4719 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4721 bracket_addr_ok(const char *s, const char *eos)
4723 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4726 /* IPvFuture, or junk.
4727 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4729 s += 2; /* skip [v */
4731 if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
4733 while (s < eos && *s != '.') {
4734 if (EVUTIL_ISXDIGIT_(*s))
4743 if (CHAR_IS_UNRESERVED(*s) ||
4744 strchr(SUBDELIMS, *s) ||
4754 ev_ssize_t n_chars = eos-s-2;
4755 struct in6_addr in6;
4756 if (n_chars >= 64) /* way too long */
4758 memcpy(buf, s+1, n_chars);
4760 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4765 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4770 uri->host = mm_strdup("");
4771 if (uri->host == NULL) {
4772 event_warn("%s: strdup", __func__);
4778 /* Optionally, we start with "userinfo@" */
4780 cp = strchr(s, '@');
4781 if (cp && cp < eos) {
4782 if (! userinfo_ok(s,cp))
4785 uri->userinfo = mm_strdup(s);
4786 if (uri->userinfo == NULL) {
4787 event_warn("%s: strdup", __func__);
4793 /* Optionally, we end with ":port" */
4794 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
4796 if (port >= cp && *port == ':') {
4797 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4800 else if ((uri->port = parse_port(port+1, eos))<0)
4804 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4805 * an IP-Literal, or a reg-name */
4806 EVUTIL_ASSERT(eos >= cp);
4807 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4808 /* IPv6address, IP-Literal, or junk. */
4809 if (! bracket_addr_ok(cp, eos))
4812 /* Make sure the host part is ok. */
4813 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4816 uri->host = mm_malloc(eos-cp+1);
4817 if (uri->host == NULL) {
4818 event_warn("%s: malloc", __func__);
4821 memcpy(uri->host, cp, eos-cp);
4822 uri->host[eos-cp] = '\0';
4828 end_of_authority(char *cp)
4831 if (*cp == '?' || *cp == '#' || *cp == '/')
4844 /* Return the character after the longest prefix of 'cp' that matches...
4845 * *pchar / "/" if allow_qchars is false, or
4846 * *(pchar / "/" / "?") if allow_qchars is true.
4849 end_of_path(char *cp, enum uri_part part, unsigned flags)
4851 if (flags & EVHTTP_URI_NONCONFORMANT) {
4852 /* If NONCONFORMANT:
4853 * Path is everything up to a # or ? or nul.
4854 * Query is everything up a # or nul
4855 * Fragment is everything up to a nul.
4859 while (*cp && *cp != '#' && *cp != '?')
4863 while (*cp && *cp != '#')
4874 if (CHAR_IS_UNRESERVED(*cp) ||
4875 strchr(SUBDELIMS, *cp) ||
4876 *cp == ':' || *cp == '@' || *cp == '/')
4878 else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
4879 EVUTIL_ISXDIGIT_(cp[2]))
4881 else if (*cp == '?' && part != PART_PATH)
4890 path_matches_noscheme(const char *cp)
4895 else if (*cp == '/')
4903 evhttp_uri_parse(const char *source_uri)
4905 return evhttp_uri_parse_with_flags(source_uri, 0);
4909 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4911 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4912 char *path = NULL, *fragment = NULL;
4913 int got_authority = 0;
4915 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4917 event_warn("%s: calloc", __func__);
4923 readbuf = mm_strdup(source_uri);
4924 if (readbuf == NULL) {
4925 event_warn("%s: strdup", __func__);
4932 /* We try to follow RFC3986 here as much as we can, and match
4935 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4937 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
4941 token = strchr(readp, ':');
4942 if (token && scheme_ok(readp,token)) {
4944 uri->scheme = mm_strdup(readp);
4945 if (uri->scheme == NULL) {
4946 event_warn("%s: strdup", __func__);
4949 readp = token+1; /* eat : */
4952 /* 2. Optionally, "//" then an 'authority' part. */
4953 if (readp[0]=='/' && readp[1] == '/') {
4957 path = end_of_authority(readp);
4958 if (parse_authority(uri, authority, path) < 0)
4964 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4967 readp = end_of_path(path, PART_PATH, flags);
4970 if (*readp == '?') {
4974 readp = end_of_path(readp, PART_QUERY, flags);
4977 if (*readp == '#') {
4981 readp = end_of_path(readp, PART_FRAGMENT, flags);
4983 if (*readp != '\0') {
4987 /* These next two cases may be unreachable; I'm leaving them
4988 * in to be defensive. */
4989 /* If you didn't get an authority, the path can't begin with "//" */
4990 if (!got_authority && path[0]=='/' && path[1]=='/')
4992 /* If you did get an authority, the path must begin with "/" or be
4994 if (got_authority && path[0] != '/' && path[0] != '\0')
4996 /* (End of maybe-unreachable cases) */
4998 /* If there was no scheme, the first part of the path (if any) must
4999 * have no colon in it. */
5000 if (! uri->scheme && !path_matches_noscheme(path))
5003 EVUTIL_ASSERT(path);
5004 uri->path = mm_strdup(path);
5005 if (uri->path == NULL) {
5006 event_warn("%s: strdup", __func__);
5011 uri->query = mm_strdup(query);
5012 if (uri->query == NULL) {
5013 event_warn("%s: strdup", __func__);
5018 uri->fragment = mm_strdup(fragment);
5019 if (uri->fragment == NULL) {
5020 event_warn("%s: strdup", __func__);
5030 evhttp_uri_free(uri);
5036 static struct evhttp_uri *
5037 evhttp_uri_parse_authority(char *source_uri)
5039 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
5043 event_warn("%s: calloc", __func__);
5049 end = end_of_authority(source_uri);
5050 if (parse_authority(uri, source_uri, end) < 0)
5053 uri->path = mm_strdup("");
5054 if (uri->path == NULL) {
5055 event_warn("%s: strdup", __func__);
5062 evhttp_uri_free(uri);
5067 evhttp_uri_free(struct evhttp_uri *uri)
5069 #define URI_FREE_STR_(f) \
5074 URI_FREE_STR_(scheme);
5075 URI_FREE_STR_(userinfo);
5076 URI_FREE_STR_(host);
5077 URI_FREE_STR_(path);
5078 URI_FREE_STR_(query);
5079 URI_FREE_STR_(fragment);
5082 #undef URI_FREE_STR_
5086 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
5088 struct evbuffer *tmp = 0;
5089 size_t joined_size = 0;
5090 char *output = NULL;
5092 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
5094 if (!uri || !buf || !limit)
5097 tmp = evbuffer_new();
5103 evbuffer_add(tmp, ":", 1);
5106 evbuffer_add(tmp, "//", 2);
5108 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
5111 evbuffer_add_printf(tmp,":%d", uri->port);
5113 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
5121 evbuffer_add(tmp, "?", 1);
5125 if (uri->fragment) {
5126 evbuffer_add(tmp, "#", 1);
5130 evbuffer_add(tmp, "\0", 1); /* NUL */
5132 joined_size = evbuffer_get_length(tmp);
5134 if (joined_size > limit) {
5135 /* It doesn't fit. */
5139 evbuffer_remove(tmp, buf, joined_size);
5150 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
5155 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
5157 return uri->userinfo;
5160 evhttp_uri_get_host(const struct evhttp_uri *uri)
5165 evhttp_uri_get_port(const struct evhttp_uri *uri)
5170 evhttp_uri_get_path(const struct evhttp_uri *uri)
5175 evhttp_uri_get_query(const struct evhttp_uri *uri)
5180 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
5182 return uri->fragment;
5185 #define URI_SET_STR_(f) do { \
5189 if ((uri->f = mm_strdup(f)) == NULL) { \
5190 event_warn("%s: strdup()", __func__); \
5199 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
5201 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
5204 URI_SET_STR_(scheme);
5208 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
5210 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
5212 URI_SET_STR_(userinfo);
5216 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
5219 if (host[0] == '[') {
5220 if (! bracket_addr_ok(host, host+strlen(host)))
5223 if (! regname_ok(host, host+strlen(host)))
5232 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
5239 #define end_of_cpath(cp,p,f) \
5240 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
5243 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
5245 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
5252 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
5254 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
5256 URI_SET_STR_(query);
5260 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
5262 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
5264 URI_SET_STR_(fragment);