2 * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
3 * Copyright (c) 2007-2010 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"
30 #ifdef _EVENT_HAVE_SYS_PARAM_H
31 #include <sys/param.h>
33 #ifdef _EVENT_HAVE_SYS_TYPES_H
34 #include <sys/types.h>
37 #ifdef _EVENT_HAVE_SYS_TIME_H
40 #ifdef HAVE_SYS_IOCCOM_H
41 #include <sys/ioccom.h>
45 #include <sys/resource.h>
46 #include <sys/socket.h>
54 #include <sys/queue.h>
56 #ifdef _EVENT_HAVE_NETINET_IN_H
57 #include <netinet/in.h>
59 #ifdef _EVENT_HAVE_ARPA_INET_H
60 #include <arpa/inet.h>
62 #ifdef _EVENT_HAVE_NETDB_H
79 #ifdef _EVENT_HAVE_UNISTD_H
82 #ifdef _EVENT_HAVE_FCNTL_H
86 #undef timeout_pending
87 #undef timeout_initialized
89 #include "strlcpy-internal.h"
90 #include "event2/http.h"
91 #include "event2/event.h"
92 #include "event2/buffer.h"
93 #include "event2/bufferevent.h"
94 #include "event2/bufferevent_compat.h"
95 #include "event2/http_struct.h"
96 #include "event2/http_compat.h"
97 #include "event2/util.h"
98 #include "event2/listener.h"
99 #include "log-internal.h"
100 #include "util-internal.h"
101 #include "http-internal.h"
102 #include "mm-internal.h"
103 #include "bufferevent-internal.h"
105 #ifndef _EVENT_HAVE_GETNAMEINFO
106 #define NI_MAXSERV 32
107 #define NI_MAXHOST 1025
109 #ifndef NI_NUMERICHOST
110 #define NI_NUMERICHOST 1
113 #ifndef NI_NUMERICSERV
114 #define NI_NUMERICSERV 2
118 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
119 size_t hostlen, char *serv, size_t servlen, int flags)
121 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
125 evutil_snprintf(tmpserv, sizeof(tmpserv),
126 "%d", ntohs(sin->sin_port));
127 if (strlcpy(serv, tmpserv, servlen) >= servlen)
132 if (flags & NI_NUMERICHOST) {
133 if (strlcpy(host, inet_ntoa(sin->sin_addr),
140 hp = gethostbyaddr((char *)&sin->sin_addr,
141 sizeof(struct in_addr), AF_INET);
145 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
156 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \
157 ((req)->major < (major_v) || \
158 ((req)->major == (major_v) && (req)->minor < (minor_v)))
160 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \
161 ((req)->major > (major_v) || \
162 ((req)->major == (major_v) && (req)->minor >= (minor_v)))
165 #define MIN(a,b) (((a)<(b))?(a):(b))
170 static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse);
171 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
172 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
173 static int evhttp_associate_new_request_with_connection(
174 struct evhttp_connection *evcon);
175 static void evhttp_connection_start_detectclose(
176 struct evhttp_connection *evcon);
177 static void evhttp_connection_stop_detectclose(
178 struct evhttp_connection *evcon);
179 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
180 static void evhttp_read_firstline(struct evhttp_connection *evcon,
181 struct evhttp_request *req);
182 static void evhttp_read_header(struct evhttp_connection *evcon,
183 struct evhttp_request *req);
184 static int evhttp_add_header_internal(struct evkeyvalq *headers,
185 const char *key, const char *value);
186 static const char *evhttp_response_phrase_internal(int code);
187 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t);
188 static void evhttp_write_buffer(struct evhttp_connection *,
189 void (*)(struct evhttp_connection *, void *), void *);
190 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
192 /* callbacks for bufferevent */
193 static void evhttp_read_cb(struct bufferevent *, void *);
194 static void evhttp_write_cb(struct bufferevent *, void *);
195 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
196 static int evhttp_decode_uri_internal(const char *uri, size_t length,
197 char *ret, int decode_plus);
198 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
199 const char *hostname);
201 #ifndef _EVENT_HAVE_STRSEP
202 /* strsep replacement for platforms that lack it. Only works if
203 * del is one character long. */
205 strsep(char **s, const char *del)
208 EVUTIL_ASSERT(strlen(del) == 1);
212 d = strstr(tok, del);
223 html_replace(const char ch, const char **escaped)
249 * Replaces <, >, ", ' and & with <, >, ",
250 * ' and & correspondingly.
252 * The returned string needs to be freed by the caller.
256 evhttp_htmlescape(const char *html)
259 size_t new_size = 0, old_size = 0;
260 char *escaped_html, *p;
265 old_size = strlen(html);
266 for (i = 0; i < old_size; ++i) {
267 const char *replaced = NULL;
268 const size_t replace_size = html_replace(html[i], &replaced);
269 if (replace_size > EV_SIZE_MAX - new_size) {
270 event_warn("%s: html_replace overflow", __func__);
273 new_size += replace_size;
276 if (new_size == EV_SIZE_MAX)
278 p = escaped_html = mm_malloc(new_size + 1);
279 if (escaped_html == NULL) {
280 event_warn("%s: malloc(%lu)", __func__,
281 (unsigned long)(new_size + 1));
284 for (i = 0; i < old_size; ++i) {
285 const char *replaced = &html[i];
286 const size_t len = html_replace(html[i], &replaced);
287 memcpy(p, replaced, len);
293 return (escaped_html);
296 /** Given an evhttp_cmd_type, returns a constant string containing the
297 * equivalent HTTP command, or NULL if the evhttp_command_type is
300 evhttp_method(enum evhttp_cmd_type type)
308 case EVHTTP_REQ_POST:
311 case EVHTTP_REQ_HEAD:
317 case EVHTTP_REQ_DELETE:
320 case EVHTTP_REQ_OPTIONS:
323 case EVHTTP_REQ_TRACE:
326 case EVHTTP_REQ_CONNECT:
329 case EVHTTP_REQ_PATCH:
341 * Determines if a response should have a body.
342 * Follows the rules in RFC 2616 section 4.3.
343 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
347 evhttp_response_needs_body(struct evhttp_request *req)
349 return (req->response_code != HTTP_NOCONTENT &&
350 req->response_code != HTTP_NOTMODIFIED &&
351 (req->response_code < 100 || req->response_code >= 200) &&
352 req->type != EVHTTP_REQ_HEAD);
355 /** Helper: adds the event 'ev' with the timeout 'timeout', or with
356 * default_timeout if timeout is -1.
359 evhttp_add_event(struct event *ev, int timeout, int default_timeout)
364 evutil_timerclear(&tv);
365 tv.tv_sec = timeout != -1 ? timeout : default_timeout;
366 return event_add(ev, &tv);
368 return event_add(ev, NULL);
372 /** Helper: called after we've added some data to an evcon's bufferevent's
373 * output buffer. Sets the evconn's writing-is-done callback, and puts
374 * the bufferevent into writing mode.
377 evhttp_write_buffer(struct evhttp_connection *evcon,
378 void (*cb)(struct evhttp_connection *, void *), void *arg)
380 event_debug(("%s: preparing to write buffer\n", __func__));
386 bufferevent_enable(evcon->bufev, EV_WRITE);
388 /* Disable the read callback: we don't actually care about data;
389 * we only care about close detection. (We don't disable reading,
390 * since we *do* want to learn about any close events.) */
391 bufferevent_setcb(evcon->bufev,
399 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
401 bufferevent_disable(evcon->bufev, EV_WRITE);
405 evhttp_send_continue(struct evhttp_connection *evcon,
406 struct evhttp_request *req)
408 bufferevent_enable(evcon->bufev, EV_WRITE);
409 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
410 "HTTP/%d.%d 100 Continue\r\n\r\n",
411 req->major, req->minor);
412 evcon->cb = evhttp_send_continue_done;
413 evcon->cb_arg = NULL;
414 bufferevent_setcb(evcon->bufev,
421 /** Helper: returns true iff evconn is in any connected state. */
423 evhttp_connected(struct evhttp_connection *evcon)
425 switch (evcon->state) {
426 case EVCON_DISCONNECTED:
427 case EVCON_CONNECTING:
430 case EVCON_READING_FIRSTLINE:
431 case EVCON_READING_HEADERS:
432 case EVCON_READING_BODY:
433 case EVCON_READING_TRAILER:
440 /* Create the headers needed for an outgoing HTTP request, adds them to
441 * the request's header list, and writes the request line to the
442 * connection's output buffer.
445 evhttp_make_header_request(struct evhttp_connection *evcon,
446 struct evhttp_request *req)
450 evhttp_remove_header(req->output_headers, "Proxy-Connection");
452 /* Generate request line */
453 method = evhttp_method(req->type);
454 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
455 "%s %s HTTP/%d.%d\r\n",
456 method, req->uri, req->major, req->minor);
458 /* Add the content length on a post or put request if missing */
459 if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
460 evhttp_find_header(req->output_headers, "Content-Length") == NULL){
462 evutil_snprintf(size, sizeof(size), "%ld",
463 (long)evbuffer_get_length(req->output_buffer));
464 evhttp_add_header(req->output_headers, "Content-Length", size);
468 /** Return true if the list of headers in 'headers', intepreted with respect
469 * to flags, means that we should send a "connection: close" when the request
472 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
474 if (flags & EVHTTP_PROXY_REQUEST) {
475 /* proxy connection */
476 const char *connection = evhttp_find_header(headers, "Proxy-Connection");
477 return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
479 const char *connection = evhttp_find_header(headers, "Connection");
480 return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
484 /* Return true iff 'headers' contains 'Connection: keep-alive' */
486 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
488 const char *connection = evhttp_find_header(headers, "Connection");
489 return (connection != NULL
490 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
493 /* Add a correct "Date" header to headers, unless it already has one. */
495 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
497 if (evhttp_find_header(headers, "Date") == NULL) {
503 time_t t = time(NULL);
510 if (strftime(date, sizeof(date),
511 "%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) {
512 evhttp_add_header(headers, "Date", date);
517 /* Add a "Content-Length" header with value 'content_length' to headers,
518 * unless it already has a content-length or transfer-encoding header. */
520 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
521 long content_length) /* XXX use size_t or int64, not long. */
523 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
524 evhttp_find_header(headers, "Content-Length") == NULL) {
526 evutil_snprintf(len, sizeof(len), "%ld", content_length);
527 evhttp_add_header(headers, "Content-Length", len);
532 * Create the headers needed for an HTTP reply in req->output_headers,
533 * and write the first HTTP response for req line to evcon.
536 evhttp_make_header_response(struct evhttp_connection *evcon,
537 struct evhttp_request *req)
539 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
540 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
541 "HTTP/%d.%d %d %s\r\n",
542 req->major, req->minor, req->response_code,
543 req->response_code_line);
545 if (req->major == 1) {
547 evhttp_maybe_add_date_header(req->output_headers);
550 * if the protocol is 1.0; and the connection was keep-alive
551 * we need to add a keep-alive header, too.
553 if (req->minor == 0 && is_keepalive)
554 evhttp_add_header(req->output_headers,
555 "Connection", "keep-alive");
557 if ((req->minor >= 1 || is_keepalive) &&
558 evhttp_response_needs_body(req)) {
560 * we need to add the content length if the
561 * user did not give it, this is required for
562 * persistent connections to work.
564 evhttp_maybe_add_content_length_header(
566 (long)evbuffer_get_length(req->output_buffer));
570 /* Potentially add headers for unidentified content. */
571 if (evhttp_response_needs_body(req)) {
572 if (evhttp_find_header(req->output_headers,
573 "Content-Type") == NULL) {
574 evhttp_add_header(req->output_headers,
575 "Content-Type", "text/html; charset=ISO-8859-1");
579 /* if the request asked for a close, we send a close, too */
580 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
581 evhttp_remove_header(req->output_headers, "Connection");
582 if (!(req->flags & EVHTTP_PROXY_REQUEST))
583 evhttp_add_header(req->output_headers, "Connection", "close");
584 evhttp_remove_header(req->output_headers, "Proxy-Connection");
588 /** Generate all headers appropriate for sending the http request in req (or
589 * the response, if we're sending a response), and write them to evcon's
590 * bufferevent. Also writes all data from req->output_buffer */
592 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
594 struct evkeyval *header;
595 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
598 * Depending if this is a HTTP request or response, we might need to
599 * add some new headers or remove existing headers.
601 if (req->kind == EVHTTP_REQUEST) {
602 evhttp_make_header_request(evcon, req);
604 evhttp_make_header_response(evcon, req);
607 TAILQ_FOREACH(header, req->output_headers, next) {
608 evbuffer_add_printf(output, "%s: %s\r\n",
609 header->key, header->value);
611 evbuffer_add(output, "\r\n", 2);
613 if (evbuffer_get_length(req->output_buffer) > 0) {
615 * For a request, we add the POST data, for a reply, this
616 * is the regular data.
618 /* XXX We might want to support waiting (a limited amount of
619 time) for a continue status line from the server before
620 sending POST/PUT message bodies. */
621 evbuffer_add_buffer(output, req->output_buffer);
626 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
627 ev_ssize_t new_max_headers_size)
629 if (new_max_headers_size<0)
630 evcon->max_headers_size = EV_SIZE_MAX;
632 evcon->max_headers_size = new_max_headers_size;
635 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
636 ev_ssize_t new_max_body_size)
638 if (new_max_body_size<0)
639 evcon->max_body_size = EV_UINT64_MAX;
641 evcon->max_body_size = new_max_body_size;
645 evhttp_connection_incoming_fail(struct evhttp_request *req,
646 enum evhttp_connection_error error)
649 case EVCON_HTTP_TIMEOUT:
652 * these are cases in which we probably should just
653 * close the connection and not send a reply. this
654 * case may happen when a browser keeps a persistent
655 * connection open and we timeout on the read. when
656 * the request is still being used for sending, we
657 * need to disassociated it from the connection here.
659 if (!req->userdone) {
660 /* remove it so that it will not be freed */
661 TAILQ_REMOVE(&req->evcon->requests, req, next);
662 /* indicate that this request no longer has a
668 case EVCON_HTTP_INVALID_HEADER:
669 case EVCON_HTTP_BUFFER_ERROR:
670 case EVCON_HTTP_REQUEST_CANCEL:
671 default: /* xxx: probably should just error on default */
672 /* the callback looks at the uri to determine errors */
677 if (req->uri_elems) {
678 evhttp_uri_free(req->uri_elems);
679 req->uri_elems = NULL;
683 * the callback needs to send a reply, once the reply has
684 * been send, the connection should get freed.
686 (*req->cb)(req, req->cb_arg);
692 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
693 * given in error. If it's an outgoing connection, reset the connection,
694 * retry any pending requests, and inform the user. If it's incoming,
695 * delegates to evhttp_connection_incoming_fail(). */
697 evhttp_connection_fail(struct evhttp_connection *evcon,
698 enum evhttp_connection_error error)
700 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
701 void (*cb)(struct evhttp_request *, void *);
703 EVUTIL_ASSERT(req != NULL);
705 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
707 if (evcon->flags & EVHTTP_CON_INCOMING) {
709 * for incoming requests, there are two different
710 * failure cases. it's either a network level error
711 * or an http layer error. for problems on the network
712 * layer like timeouts we just drop the connections.
713 * For HTTP problems, we might have to send back a
714 * reply before the connection can be freed.
716 if (evhttp_connection_incoming_fail(req, error) == -1)
717 evhttp_connection_free(evcon);
721 /* when the request was canceled, the callback is not executed */
722 if (error != EVCON_HTTP_REQUEST_CANCEL) {
723 /* save the callback for later; the cb might free our object */
725 cb_arg = req->cb_arg;
731 /* do not fail all requests; the next request is going to get
732 * send over a new connection. when a user cancels a request,
733 * all other pending requests should be processed as normal
735 TAILQ_REMOVE(&evcon->requests, req, next);
736 evhttp_request_free(req);
738 /* reset the connection */
739 evhttp_connection_reset(evcon);
741 /* We are trying the next request that was queued on us */
742 if (TAILQ_FIRST(&evcon->requests) != NULL)
743 evhttp_connection_connect(evcon);
745 /* inform the user */
750 /* Bufferevent callback: invoked when any data has been written from an
751 * http connection's bufferevent */
753 evhttp_write_cb(struct bufferevent *bufev, void *arg)
755 struct evhttp_connection *evcon = arg;
757 /* Activate our call back */
758 if (evcon->cb != NULL)
759 (*evcon->cb)(evcon, evcon->cb_arg);
763 * Advance the connection state.
764 * - If this is an outgoing connection, we've just processed the response;
765 * idle or close the connection.
766 * - If this is an incoming connection, we've just processed the request;
770 evhttp_connection_done(struct evhttp_connection *evcon)
772 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
773 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
776 /* idle or close the connection */
778 TAILQ_REMOVE(&evcon->requests, req, next);
781 evcon->state = EVCON_IDLE;
784 evhttp_is_connection_close(req->flags, req->input_headers)||
785 evhttp_is_connection_close(req->flags, req->output_headers);
787 /* check if we got asked to close the connection */
789 evhttp_connection_reset(evcon);
791 if (TAILQ_FIRST(&evcon->requests) != NULL) {
793 * We have more requests; reset the connection
794 * and deal with the next request.
796 if (!evhttp_connected(evcon))
797 evhttp_connection_connect(evcon);
799 evhttp_request_dispatch(evcon);
800 } else if (!need_close) {
802 * The connection is going to be persistent, but we
803 * need to detect if the other side closes it.
805 evhttp_connection_start_detectclose(evcon);
809 * incoming connection - we need to leave the request on the
810 * connection so that we can reply to it.
812 evcon->state = EVCON_WRITING;
815 /* notify the user of the request */
816 (*req->cb)(req, req->cb_arg);
818 /* if this was an outgoing request, we own and it's done. so free it.
819 * unless the callback specifically requested to own the request.
821 if (con_outgoing && ((req->flags & EVHTTP_USER_OWNED) == 0)) {
822 evhttp_request_free(req);
827 * Handles reading from a chunked request.
828 * return ALL_DATA_READ:
829 * all data has been read
830 * return MORE_DATA_EXPECTED:
831 * more data is expected
832 * return DATA_CORRUPTED:
834 * return REQUEST_CANCELED:
835 * request was canceled by the user calling evhttp_cancel_request
836 * return DATA_TOO_LONG:
837 * ran over the maximum limit
840 static enum message_read_status
841 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
843 if (req == NULL || buf == NULL) {
844 return DATA_CORRUPTED;
850 if ((buflen = evbuffer_get_length(buf)) == 0) {
854 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
855 * check for overflow conditions */
856 if (buflen > EV_SSIZE_MAX) {
857 return DATA_CORRUPTED;
860 if (req->ntoread < 0) {
861 /* Read chunk size */
863 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
868 /* the last chunk is on a new line? */
869 if (strlen(p) == 0) {
873 ntoread = evutil_strtoll(p, &endp, 16);
874 error = (*p == '\0' ||
875 (*endp != '\0' && *endp != ' ') ||
879 /* could not get chunk size */
880 return (DATA_CORRUPTED);
883 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
884 if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
885 return DATA_CORRUPTED;
888 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
889 /* failed body length test */
890 event_debug(("Request body is too long"));
891 return (DATA_TOO_LONG);
894 req->body_size += (size_t)ntoread;
895 req->ntoread = ntoread;
896 if (req->ntoread == 0) {
898 return (ALL_DATA_READ);
903 /* req->ntoread is signed int64, len is ssize_t, based on arch,
904 * ssize_t could only be 32b, check for these conditions */
905 if (req->ntoread > EV_SSIZE_MAX) {
906 return DATA_CORRUPTED;
909 /* don't have enough to complete a chunk; wait for more */
910 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
911 return (MORE_DATA_EXPECTED);
913 /* Completed chunk */
914 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
916 if (req->chunk_cb != NULL) {
917 req->flags |= EVHTTP_REQ_DEFER_FREE;
918 (*req->chunk_cb)(req, req->cb_arg);
919 evbuffer_drain(req->input_buffer,
920 evbuffer_get_length(req->input_buffer));
921 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
922 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
923 return (REQUEST_CANCELED);
928 return (MORE_DATA_EXPECTED);
932 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
934 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
936 switch (evhttp_parse_headers(req, buf)) {
939 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
942 bufferevent_disable(evcon->bufev, EV_READ);
943 evhttp_connection_done(evcon);
945 case MORE_DATA_EXPECTED:
946 case REQUEST_CANCELED: /* ??? */
948 bufferevent_enable(evcon->bufev, EV_READ);
954 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
956 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
959 switch (evhttp_handle_chunked_read(req, buf)) {
961 /* finished last chunk */
962 evcon->state = EVCON_READING_TRAILER;
963 evhttp_read_trailer(evcon, req);
966 case DATA_TOO_LONG:/*separate error for this? XXX */
968 evhttp_connection_fail(evcon,
969 EVCON_HTTP_INVALID_HEADER);
971 case REQUEST_CANCELED:
972 /* request canceled */
973 evhttp_request_free(req);
975 case MORE_DATA_EXPECTED:
979 } else if (req->ntoread < 0) {
980 /* Read until connection close. */
981 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
982 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
986 req->body_size += evbuffer_get_length(buf);
987 evbuffer_add_buffer(req->input_buffer, buf);
988 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
989 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
990 /* We've postponed moving the data until now, but we're
991 * about to use it. */
992 size_t n = evbuffer_get_length(buf);
994 if (n > (size_t) req->ntoread)
995 n = (size_t) req->ntoread;
998 evbuffer_remove_buffer(buf, req->input_buffer, n);
1001 if (req->body_size > req->evcon->max_body_size ||
1002 (!req->chunked && req->ntoread >= 0 &&
1003 (size_t)req->ntoread > req->evcon->max_body_size)) {
1004 /* XXX: The above casted comparison must checked for overflow */
1005 /* failed body length test */
1006 event_debug(("Request body is too long"));
1007 evhttp_connection_fail(evcon,
1008 EVCON_HTTP_INVALID_HEADER);
1012 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1013 req->flags |= EVHTTP_REQ_DEFER_FREE;
1014 (*req->chunk_cb)(req, req->cb_arg);
1015 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1016 evbuffer_drain(req->input_buffer,
1017 evbuffer_get_length(req->input_buffer));
1018 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1019 evhttp_request_free(req);
1024 if (req->ntoread == 0) {
1025 bufferevent_disable(evcon->bufev, EV_READ);
1026 /* Completed content length */
1027 evhttp_connection_done(evcon);
1032 bufferevent_enable(evcon->bufev, EV_READ);
1035 #define get_deferred_queue(evcon) \
1036 (event_base_get_deferred_cb_queue((evcon)->base))
1039 * Gets called when more data becomes available
1043 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1045 struct evhttp_connection *evcon = arg;
1046 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1048 /* Cancel if it's pending. */
1049 event_deferred_cb_cancel(get_deferred_queue(evcon),
1050 &evcon->read_more_deferred_cb);
1052 switch (evcon->state) {
1053 case EVCON_READING_FIRSTLINE:
1054 evhttp_read_firstline(evcon, req);
1055 /* note the request may have been freed in
1056 * evhttp_read_body */
1058 case EVCON_READING_HEADERS:
1059 evhttp_read_header(evcon, req);
1060 /* note the request may have been freed in
1061 * evhttp_read_body */
1063 case EVCON_READING_BODY:
1064 evhttp_read_body(evcon, req);
1065 /* note the request may have been freed in
1066 * evhttp_read_body */
1068 case EVCON_READING_TRAILER:
1069 evhttp_read_trailer(evcon, req);
1074 struct evbuffer *input;
1077 input = bufferevent_get_input(evcon->bufev);
1078 total_len = evbuffer_get_length(input);
1079 event_debug(("%s: read %d bytes in EVCON_IDLE state,"
1080 " resetting connection",
1081 __func__, (int)total_len));
1084 evhttp_connection_reset(evcon);
1087 case EVCON_DISCONNECTED:
1088 case EVCON_CONNECTING:
1091 event_errx(1, "%s: illegal connection state %d",
1092 __func__, evcon->state);
1097 evhttp_deferred_read_cb(struct deferred_cb *cb, void *data)
1099 struct evhttp_connection *evcon = data;
1100 evhttp_read_cb(evcon->bufev, evcon);
1104 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1106 /* This is after writing the request to the server */
1107 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1108 EVUTIL_ASSERT(req != NULL);
1110 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1112 /* We are done writing our header and are now expecting the response */
1113 req->kind = EVHTTP_RESPONSE;
1115 evhttp_start_read(evcon);
1119 * Clean up a connection object
1123 evhttp_connection_free(struct evhttp_connection *evcon)
1125 struct evhttp_request *req;
1127 /* notify interested parties that this connection is going down */
1128 if (evcon->fd != -1) {
1129 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1130 (*evcon->closecb)(evcon, evcon->closecb_arg);
1133 /* remove all requests that might be queued on this
1134 * connection. for server connections, this should be empty.
1135 * because it gets dequeued either in evhttp_connection_done or
1136 * evhttp_connection_fail.
1138 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1139 TAILQ_REMOVE(&evcon->requests, req, next);
1140 evhttp_request_free(req);
1143 if (evcon->http_server != NULL) {
1144 struct evhttp *http = evcon->http_server;
1145 TAILQ_REMOVE(&http->connections, evcon, next);
1148 if (event_initialized(&evcon->retry_ev)) {
1149 event_del(&evcon->retry_ev);
1150 event_debug_unassign(&evcon->retry_ev);
1153 if (evcon->bufev != NULL)
1154 bufferevent_free(evcon->bufev);
1156 event_deferred_cb_cancel(get_deferred_queue(evcon),
1157 &evcon->read_more_deferred_cb);
1159 if (evcon->fd != -1) {
1160 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1161 evutil_closesocket(evcon->fd);
1164 if (evcon->bind_address != NULL)
1165 mm_free(evcon->bind_address);
1167 if (evcon->address != NULL)
1168 mm_free(evcon->address);
1174 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1175 const char *address)
1177 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1178 if (evcon->bind_address)
1179 mm_free(evcon->bind_address);
1180 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1181 event_warn("%s: strdup", __func__);
1185 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1188 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1189 evcon->bind_port = port;
1193 evhttp_request_dispatch(struct evhttp_connection* evcon)
1195 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1197 /* this should not usually happy but it's possible */
1201 /* delete possible close detection events */
1202 evhttp_connection_stop_detectclose(evcon);
1204 /* we assume that the connection is connected already */
1205 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1207 evcon->state = EVCON_WRITING;
1209 /* Create the header from the store arguments */
1210 evhttp_make_header(evcon, req);
1212 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1215 /* Reset our connection state: disables reading/writing, closes our fd (if
1216 * any), clears out buffers, and puts us in state DISCONNECTED. */
1218 evhttp_connection_reset(struct evhttp_connection *evcon)
1220 struct evbuffer *tmp;
1222 /* XXXX This is not actually an optimal fix. Instead we ought to have
1223 an API for "stop connecting", or use bufferevent_setfd to turn off
1224 connecting. But for Libevent 2.0, this seems like a minimal change
1225 least likely to disrupt the rest of the bufferevent and http code.
1227 Why is this here? If the fd is set in the bufferevent, and the
1228 bufferevent is connecting, then you can't actually stop the
1229 bufferevent from trying to connect with bufferevent_disable(). The
1230 connect will never trigger, since we close the fd, but the timeout
1231 might. That caused an assertion failure in evhttp_connection_fail.
1233 bufferevent_disable_hard(evcon->bufev, EV_READ|EV_WRITE);
1235 if (evcon->fd != -1) {
1236 /* inform interested parties about connection close */
1237 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1238 (*evcon->closecb)(evcon, evcon->closecb_arg);
1240 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1241 evutil_closesocket(evcon->fd);
1245 /* we need to clean up any buffered data */
1246 tmp = bufferevent_get_output(evcon->bufev);
1247 evbuffer_drain(tmp, evbuffer_get_length(tmp));
1248 tmp = bufferevent_get_input(evcon->bufev);
1249 evbuffer_drain(tmp, evbuffer_get_length(tmp));
1251 evcon->state = EVCON_DISCONNECTED;
1255 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1257 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1259 bufferevent_enable(evcon->bufev, EV_READ);
1263 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1265 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1267 bufferevent_disable(evcon->bufev, EV_READ);
1271 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1273 struct evhttp_connection *evcon = arg;
1275 evcon->state = EVCON_DISCONNECTED;
1276 evhttp_connection_connect(evcon);
1280 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1282 struct evcon_requestq requests;
1284 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1285 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1286 /* XXXX handle failure from evhttp_add_event */
1287 evhttp_add_event(&evcon->retry_ev,
1288 MIN(3600, 2 << evcon->retry_cnt),
1289 HTTP_CONNECT_TIMEOUT);
1293 evhttp_connection_reset(evcon);
1296 * User callback can do evhttp_make_request() on the same
1297 * evcon so new request will be added to evcon->requests. To
1298 * avoid freeing it prematurely we iterate over the copy of
1301 TAILQ_INIT(&requests);
1302 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1303 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1304 TAILQ_REMOVE(&evcon->requests, request, next);
1305 TAILQ_INSERT_TAIL(&requests, request, next);
1308 /* for now, we just signal all requests by executing their callbacks */
1309 while (TAILQ_FIRST(&requests) != NULL) {
1310 struct evhttp_request *request = TAILQ_FIRST(&requests);
1311 TAILQ_REMOVE(&requests, request, next);
1312 request->evcon = NULL;
1314 /* we might want to set an error here */
1315 request->cb(request, request->cb_arg);
1316 evhttp_request_free(request);
1321 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1323 struct evhttp_connection *evcon = arg;
1324 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1326 switch (evcon->state) {
1327 case EVCON_CONNECTING:
1328 if (what & BEV_EVENT_TIMEOUT) {
1329 event_debug(("%s: connection timeout for \"%s:%d\" on %d",
1330 __func__, evcon->address, evcon->port,
1332 evhttp_connection_cb_cleanup(evcon);
1337 case EVCON_READING_BODY:
1338 if (!req->chunked && req->ntoread < 0
1339 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1340 /* EOF on read can be benign */
1341 evhttp_connection_done(evcon);
1346 case EVCON_DISCONNECTED:
1348 case EVCON_READING_FIRSTLINE:
1349 case EVCON_READING_HEADERS:
1350 case EVCON_READING_TRAILER:
1356 /* when we are in close detect mode, a read error means that
1357 * the other side closed their connection.
1359 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1360 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1361 EVUTIL_ASSERT(evcon->http_server == NULL);
1362 /* For connections from the client, we just
1363 * reset the connection so that it becomes
1366 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1367 evhttp_connection_reset(evcon);
1371 if (what & BEV_EVENT_TIMEOUT) {
1372 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
1373 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1374 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
1376 evhttp_connection_fail(evcon, EVCON_HTTP_BUFFER_ERROR);
1381 * Event callback for asynchronous connection attempt.
1384 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1386 struct evhttp_connection *evcon = arg;
1388 ev_socklen_t errsz = sizeof(error);
1390 if (!(what & BEV_EVENT_CONNECTED)) {
1391 /* some operating systems return ECONNREFUSED immediately
1392 * when connecting to a local address. the cleanup is going
1393 * to reschedule this function call.
1396 if (errno == ECONNREFUSED)
1399 evhttp_error_cb(bufev, what, arg);
1403 /* Check if the connection completed */
1404 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1406 event_debug(("%s: getsockopt for \"%s:%d\" on %d",
1407 __func__, evcon->address, evcon->port, evcon->fd));
1412 event_debug(("%s: connect failed for \"%s:%d\" on %d: %s",
1413 __func__, evcon->address, evcon->port, evcon->fd,
1414 evutil_socket_error_to_string(error)));
1418 /* We are connected to the server now */
1419 event_debug(("%s: connected to \"%s:%d\" on %d\n",
1420 __func__, evcon->address, evcon->port, evcon->fd));
1422 /* Reset the retry count as we were successful in connecting */
1423 evcon->retry_cnt = 0;
1424 evcon->state = EVCON_IDLE;
1426 /* reset the bufferevent cbs */
1427 bufferevent_setcb(evcon->bufev,
1433 if (evcon->timeout == -1)
1434 bufferevent_settimeout(evcon->bufev,
1435 HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
1438 tv.tv_sec = evcon->timeout;
1440 bufferevent_set_timeouts(evcon->bufev, &tv, &tv);
1443 /* try to start requests that have queued up on this connection */
1444 evhttp_request_dispatch(evcon);
1448 evhttp_connection_cb_cleanup(evcon);
1452 * Check if we got a valid response code.
1456 evhttp_valid_response_code(int code)
1465 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1469 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1470 if (n > 2 || major > 1) {
1471 event_debug(("%s: bad version %s on message %p from %s",
1472 __func__, version, req, req->remote_host));
1480 /* Parses the status line of a web server */
1483 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1487 const char *readable = "";
1489 protocol = strsep(&line, " ");
1492 number = strsep(&line, " ");
1496 if (evhttp_parse_http_version(protocol, req) < 0)
1499 req->response_code = atoi(number);
1500 if (!evhttp_valid_response_code(req->response_code)) {
1501 event_debug(("%s: bad response code \"%s\"",
1506 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1507 event_warn("%s: strdup", __func__);
1514 /* Parse the first line of a HTTP request */
1517 evhttp_parse_request_line(struct evhttp_request *req, char *line)
1522 const char *hostname;
1525 /* Parse the request line */
1526 method = strsep(&line, " ");
1529 uri = strsep(&line, " ");
1532 version = strsep(&line, " ");
1537 if (strcmp(method, "GET") == 0) {
1538 req->type = EVHTTP_REQ_GET;
1539 } else if (strcmp(method, "POST") == 0) {
1540 req->type = EVHTTP_REQ_POST;
1541 } else if (strcmp(method, "HEAD") == 0) {
1542 req->type = EVHTTP_REQ_HEAD;
1543 } else if (strcmp(method, "PUT") == 0) {
1544 req->type = EVHTTP_REQ_PUT;
1545 } else if (strcmp(method, "DELETE") == 0) {
1546 req->type = EVHTTP_REQ_DELETE;
1547 } else if (strcmp(method, "OPTIONS") == 0) {
1548 req->type = EVHTTP_REQ_OPTIONS;
1549 } else if (strcmp(method, "TRACE") == 0) {
1550 req->type = EVHTTP_REQ_TRACE;
1551 } else if (strcmp(method, "PATCH") == 0) {
1552 req->type = EVHTTP_REQ_PATCH;
1554 req->type = _EVHTTP_REQ_UNKNOWN;
1555 event_debug(("%s: bad method %s on request %p from %s",
1556 __func__, method, req, req->remote_host));
1557 /* No error yet; we'll give a better error later when
1558 * we see that req->type is unsupported. */
1561 if (evhttp_parse_http_version(version, req) < 0)
1564 if ((req->uri = mm_strdup(uri)) == NULL) {
1565 event_debug(("%s: mm_strdup", __func__));
1569 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
1570 EVHTTP_URI_NONCONFORMANT)) == NULL) {
1574 /* If we have an absolute-URI, check to see if it is an http request
1575 for a known vhost or server alias. If we don't know about this
1576 host, we consider it a proxy request. */
1577 scheme = evhttp_uri_get_scheme(req->uri_elems);
1578 hostname = evhttp_uri_get_host(req->uri_elems);
1579 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1580 !evutil_ascii_strcasecmp(scheme, "https")) &&
1582 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1583 req->flags |= EVHTTP_PROXY_REQUEST;
1589 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1591 struct evkeyval *header;
1593 TAILQ_FOREACH(header, headers, next) {
1594 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1595 return (header->value);
1602 evhttp_clear_headers(struct evkeyvalq *headers)
1604 struct evkeyval *header;
1606 for (header = TAILQ_FIRST(headers);
1608 header = TAILQ_FIRST(headers)) {
1609 TAILQ_REMOVE(headers, header, next);
1610 mm_free(header->key);
1611 mm_free(header->value);
1617 * Returns 0, if the header was successfully removed.
1618 * Returns -1, if the header could not be found.
1622 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1624 struct evkeyval *header;
1626 TAILQ_FOREACH(header, headers, next) {
1627 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1634 /* Free and remove the header that we found */
1635 TAILQ_REMOVE(headers, header, next);
1636 mm_free(header->key);
1637 mm_free(header->value);
1644 evhttp_header_is_valid_value(const char *value)
1646 const char *p = value;
1648 while ((p = strpbrk(p, "\r\n")) != NULL) {
1649 /* we really expect only one new line */
1650 p += strspn(p, "\r\n");
1651 /* we expect a space or tab for continuation */
1652 if (*p != ' ' && *p != '\t')
1659 evhttp_add_header(struct evkeyvalq *headers,
1660 const char *key, const char *value)
1662 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1664 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1665 /* drop illegal headers */
1666 event_debug(("%s: dropping illegal header key\n", __func__));
1670 if (!evhttp_header_is_valid_value(value)) {
1671 event_debug(("%s: dropping illegal header value\n", __func__));
1675 return (evhttp_add_header_internal(headers, key, value));
1679 evhttp_add_header_internal(struct evkeyvalq *headers,
1680 const char *key, const char *value)
1682 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
1683 if (header == NULL) {
1684 event_warn("%s: calloc", __func__);
1687 if ((header->key = mm_strdup(key)) == NULL) {
1689 event_warn("%s: strdup", __func__);
1692 if ((header->value = mm_strdup(value)) == NULL) {
1693 mm_free(header->key);
1695 event_warn("%s: strdup", __func__);
1699 TAILQ_INSERT_TAIL(headers, header, next);
1705 * Parses header lines from a request or a response into the specified
1706 * request object given an event buffer.
1709 * DATA_CORRUPTED on error
1710 * MORE_DATA_EXPECTED when we need to read more headers
1711 * ALL_DATA_READ when all headers have been read.
1714 enum message_read_status
1715 evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
1718 enum message_read_status status = ALL_DATA_READ;
1722 line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF);
1724 if (req->evcon != NULL &&
1725 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1726 return (DATA_TOO_LONG);
1728 return (MORE_DATA_EXPECTED);
1731 if (req->evcon != NULL &&
1732 line_length > req->evcon->max_headers_size) {
1734 return (DATA_TOO_LONG);
1737 req->headers_size = line_length;
1739 switch (req->kind) {
1740 case EVHTTP_REQUEST:
1741 if (evhttp_parse_request_line(req, line) == -1)
1742 status = DATA_CORRUPTED;
1744 case EVHTTP_RESPONSE:
1745 if (evhttp_parse_response_line(req, line) == -1)
1746 status = DATA_CORRUPTED;
1749 status = DATA_CORRUPTED;
1757 evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
1759 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
1761 size_t old_len, line_len;
1766 old_len = strlen(header->value);
1767 line_len = strlen(line);
1769 newval = mm_realloc(header->value, old_len + line_len + 1);
1773 memcpy(newval + old_len, line, line_len + 1);
1774 header->value = newval;
1779 enum message_read_status
1780 evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
1782 enum message_read_status errcode = DATA_CORRUPTED;
1784 enum message_read_status status = MORE_DATA_EXPECTED;
1786 struct evkeyvalq* headers = req->input_headers;
1788 while ((line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF))
1790 char *skey, *svalue;
1792 req->headers_size += line_length;
1794 if (req->evcon != NULL &&
1795 req->headers_size > req->evcon->max_headers_size) {
1796 errcode = DATA_TOO_LONG;
1800 if (*line == '\0') { /* Last header - Done */
1801 status = ALL_DATA_READ;
1806 /* Check if this is a continuation line */
1807 if (*line == ' ' || *line == '\t') {
1808 if (evhttp_append_to_last_header(headers, line) == -1)
1814 /* Processing of header lines */
1816 skey = strsep(&svalue, ":");
1820 svalue += strspn(svalue, " ");
1822 if (evhttp_add_header(headers, skey, svalue) == -1)
1828 if (status == MORE_DATA_EXPECTED) {
1829 if (req->evcon != NULL &&
1830 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1831 return (DATA_TOO_LONG);
1842 evhttp_get_body_length(struct evhttp_request *req)
1844 struct evkeyvalq *headers = req->input_headers;
1845 const char *content_length;
1846 const char *connection;
1848 content_length = evhttp_find_header(headers, "Content-Length");
1849 connection = evhttp_find_header(headers, "Connection");
1851 if (content_length == NULL && connection == NULL)
1853 else if (content_length == NULL &&
1854 evutil_ascii_strcasecmp(connection, "Close") != 0) {
1855 /* Bad combination, we don't know when it will end */
1856 event_warnx("%s: we got no content length, but the "
1857 "server wants to keep the connection open: %s.",
1858 __func__, connection);
1860 } else if (content_length == NULL) {
1864 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
1865 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
1866 event_debug(("%s: illegal content length: %s",
1867 __func__, content_length));
1870 req->ntoread = ntoread;
1873 event_debug(("%s: bytes to read: %ld (in buffer %ld)\n",
1874 __func__, (long)req->ntoread,
1875 evbuffer_get_length(bufferevent_get_input(req->evcon->bufev))));
1881 evhttp_method_may_have_body(enum evhttp_cmd_type type)
1884 case EVHTTP_REQ_POST:
1885 case EVHTTP_REQ_PUT:
1886 case EVHTTP_REQ_PATCH:
1888 case EVHTTP_REQ_TRACE:
1890 /* XXX May any of the below methods have a body? */
1891 case EVHTTP_REQ_GET:
1892 case EVHTTP_REQ_HEAD:
1893 case EVHTTP_REQ_DELETE:
1894 case EVHTTP_REQ_OPTIONS:
1895 case EVHTTP_REQ_CONNECT:
1903 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1905 const char *xfer_enc;
1907 /* If this is a request without a body, then we are done */
1908 if (req->kind == EVHTTP_REQUEST &&
1909 !evhttp_method_may_have_body(req->type)) {
1910 evhttp_connection_done(evcon);
1913 evcon->state = EVCON_READING_BODY;
1914 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
1915 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
1919 if (evhttp_get_body_length(req) == -1) {
1920 evhttp_connection_fail(evcon,
1921 EVCON_HTTP_INVALID_HEADER);
1924 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
1925 /* An incoming request with no content-length and no
1926 * transfer-encoding has no body. */
1927 evhttp_connection_done(evcon);
1932 /* Should we send a 100 Continue status line? */
1933 if (req->kind == EVHTTP_REQUEST && REQ_VERSION_ATLEAST(req, 1, 1)) {
1936 expect = evhttp_find_header(req->input_headers, "Expect");
1938 if (!evutil_ascii_strcasecmp(expect, "100-continue")) {
1939 /* XXX It would be nice to do some sanity
1940 checking here. Does the resource exist?
1941 Should the resource accept post requests? If
1942 no, we should respond with an error. For
1943 now, just optimistically tell the client to
1944 send their message body. */
1945 if (req->ntoread > 0) {
1946 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
1947 if ((req->evcon->max_body_size <= EV_INT64_MAX) && (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
1948 evhttp_send_error(req, HTTP_ENTITYTOOLARGE, NULL);
1952 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
1953 evhttp_send_continue(evcon, req);
1955 evhttp_send_error(req, HTTP_EXPECTATIONFAILED,
1962 evhttp_read_body(evcon, req);
1963 /* note the request may have been freed in evhttp_read_body */
1967 evhttp_read_firstline(struct evhttp_connection *evcon,
1968 struct evhttp_request *req)
1970 enum message_read_status res;
1972 res = evhttp_parse_firstline(req, bufferevent_get_input(evcon->bufev));
1973 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
1974 /* Error while reading, terminate */
1975 event_debug(("%s: bad header lines on %d\n",
1976 __func__, evcon->fd));
1977 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1979 } else if (res == MORE_DATA_EXPECTED) {
1980 /* Need more header lines */
1984 evcon->state = EVCON_READING_HEADERS;
1985 evhttp_read_header(evcon, req);
1989 evhttp_read_header(struct evhttp_connection *evcon,
1990 struct evhttp_request *req)
1992 enum message_read_status res;
1993 evutil_socket_t fd = evcon->fd;
1995 res = evhttp_parse_headers(req, bufferevent_get_input(evcon->bufev));
1996 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
1997 /* Error while reading, terminate */
1998 event_debug(("%s: bad header lines on %d\n", __func__, fd));
1999 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
2001 } else if (res == MORE_DATA_EXPECTED) {
2002 /* Need more header lines */
2006 /* Disable reading for now */
2007 bufferevent_disable(evcon->bufev, EV_READ);
2009 /* Done reading headers, do the real work */
2010 switch (req->kind) {
2011 case EVHTTP_REQUEST:
2012 event_debug(("%s: checking for post data on %d\n",
2014 evhttp_get_body(evcon, req);
2015 /* note the request may have been freed in evhttp_get_body */
2018 case EVHTTP_RESPONSE:
2019 /* Start over if we got a 100 Continue response. */
2020 if (req->response_code == 100) {
2021 evhttp_start_read(evcon);
2024 if (!evhttp_response_needs_body(req)) {
2025 event_debug(("%s: skipping body for code %d\n",
2026 __func__, req->response_code));
2027 evhttp_connection_done(evcon);
2029 event_debug(("%s: start of read body for %s on %d\n",
2030 __func__, req->remote_host, fd));
2031 evhttp_get_body(evcon, req);
2032 /* note the request may have been freed in
2033 * evhttp_get_body */
2038 event_warnx("%s: bad header on %d", __func__, fd);
2039 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
2042 /* request may have been freed above */
2046 * Creates a TCP connection to the specified port and executes a callback
2047 * when finished. Failure or success is indicate by the passed connection
2050 * Although this interface accepts a hostname, it is intended to take
2051 * only numeric hostnames so that non-blocking DNS resolution can
2055 struct evhttp_connection *
2056 evhttp_connection_new(const char *address, unsigned short port)
2058 return (evhttp_connection_base_new(NULL, NULL, address, port));
2061 struct evhttp_connection *
2062 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2063 const char *address, unsigned short port)
2065 struct evhttp_connection *evcon = NULL;
2067 event_debug(("Attempting connection to %s:%d\n", address, port));
2069 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2070 event_warn("%s: calloc failed", __func__);
2077 evcon->max_headers_size = EV_SIZE_MAX;
2078 evcon->max_body_size = EV_SIZE_MAX;
2080 evcon->timeout = -1;
2081 evcon->retry_cnt = evcon->retry_max = 0;
2083 if ((evcon->address = mm_strdup(address)) == NULL) {
2084 event_warn("%s: strdup failed", __func__);
2088 if ((evcon->bufev = bufferevent_new(-1,
2091 evhttp_error_cb, evcon)) == NULL) {
2092 event_warn("%s: bufferevent_new failed", __func__);
2096 evcon->state = EVCON_DISCONNECTED;
2097 TAILQ_INIT(&evcon->requests);
2101 bufferevent_base_set(base, evcon->bufev);
2105 event_deferred_cb_init(&evcon->read_more_deferred_cb,
2106 evhttp_deferred_read_cb, evcon);
2108 evcon->dns_base = dnsbase;
2114 evhttp_connection_free(evcon);
2119 evhttp_connection_set_base(struct evhttp_connection *evcon,
2120 struct event_base *base)
2122 EVUTIL_ASSERT(evcon->base == NULL);
2123 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2125 bufferevent_base_set(base, evcon->bufev);
2129 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2130 int timeout_in_secs)
2132 evcon->timeout = timeout_in_secs;
2134 if (evcon->timeout == -1)
2135 bufferevent_settimeout(evcon->bufev,
2136 HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
2138 bufferevent_settimeout(evcon->bufev,
2139 evcon->timeout, evcon->timeout);
2143 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2146 evcon->retry_max = retry_max;
2150 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2151 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2153 evcon->closecb = cb;
2154 evcon->closecb_arg = cbarg;
2158 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2159 char **address, ev_uint16_t *port)
2161 *address = evcon->address;
2162 *port = evcon->port;
2166 evhttp_connection_connect(struct evhttp_connection *evcon)
2168 if (evcon->state == EVCON_CONNECTING)
2171 evhttp_connection_reset(evcon);
2173 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2174 evcon->flags |= EVHTTP_CON_OUTGOING;
2176 evcon->fd = bind_socket(
2177 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2178 if (evcon->fd == -1) {
2179 event_debug(("%s: failed to bind to \"%s\"",
2180 __func__, evcon->bind_address));
2184 /* Set up a callback for successful connection setup */
2185 bufferevent_setfd(evcon->bufev, evcon->fd);
2186 bufferevent_setcb(evcon->bufev,
2187 NULL /* evhttp_read_cb */,
2188 NULL /* evhttp_write_cb */,
2189 evhttp_connection_cb,
2191 bufferevent_settimeout(evcon->bufev, 0,
2192 evcon->timeout != -1 ? evcon->timeout : HTTP_CONNECT_TIMEOUT);
2193 /* make sure that we get a write callback */
2194 bufferevent_enable(evcon->bufev, EV_WRITE);
2196 if (bufferevent_socket_connect_hostname(evcon->bufev, evcon->dns_base,
2197 AF_UNSPEC, evcon->address, evcon->port) < 0) {
2198 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2199 __func__, evcon->address);
2200 /* some operating systems return ECONNREFUSED immediately
2201 * when connecting to a local address. the cleanup is going
2202 * to reschedule this function call.
2204 evhttp_connection_cb_cleanup(evcon);
2208 evcon->state = EVCON_CONNECTING;
2214 * Starts an HTTP request on the provided evhttp_connection object.
2215 * If the connection object is not connected to the web server already,
2216 * this will start the connection.
2220 evhttp_make_request(struct evhttp_connection *evcon,
2221 struct evhttp_request *req,
2222 enum evhttp_cmd_type type, const char *uri)
2224 /* We are making a request */
2225 req->kind = EVHTTP_REQUEST;
2227 if (req->uri != NULL)
2229 if ((req->uri = mm_strdup(uri)) == NULL) {
2230 event_warn("%s: strdup", __func__);
2231 evhttp_request_free(req);
2235 /* Set the protocol version if it is not supplied */
2236 if (!req->major && !req->minor) {
2241 EVUTIL_ASSERT(req->evcon == NULL);
2243 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2245 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2247 /* If the connection object is not connected; make it so */
2248 if (!evhttp_connected(evcon)) {
2249 int res = evhttp_connection_connect(evcon);
2250 /* evhttp_connection_fail(), which is called through
2251 * evhttp_connection_connect(), assumes that req lies in
2252 * evcon->requests. Thus, enqueue the request in advance and r
2253 * it in the error case. */
2255 TAILQ_REMOVE(&evcon->requests, req, next);
2261 * If it's connected already and we are the first in the queue,
2262 * then we can dispatch this request immediately. Otherwise, it
2263 * will be dispatched once the pending requests are completed.
2265 if (TAILQ_FIRST(&evcon->requests) == req)
2266 evhttp_request_dispatch(evcon);
2272 evhttp_cancel_request(struct evhttp_request *req)
2274 struct evhttp_connection *evcon = req->evcon;
2275 if (evcon != NULL) {
2276 /* We need to remove it from the connection */
2277 if (TAILQ_FIRST(&evcon->requests) == req) {
2278 /* it's currently being worked on, so reset
2281 evhttp_connection_fail(evcon,
2282 EVCON_HTTP_REQUEST_CANCEL);
2284 /* connection fail freed the request */
2287 /* otherwise, we can just remove it from the
2290 TAILQ_REMOVE(&evcon->requests, req, next);
2294 evhttp_request_free(req);
2298 * Reads data from file descriptor into request structure
2299 * Request structure needs to be set up correctly.
2303 evhttp_start_read(struct evhttp_connection *evcon)
2305 /* Set up an event to read the headers */
2306 bufferevent_disable(evcon->bufev, EV_WRITE);
2307 bufferevent_enable(evcon->bufev, EV_READ);
2308 evcon->state = EVCON_READING_FIRSTLINE;
2309 /* Reset the bufferevent callbacks */
2310 bufferevent_setcb(evcon->bufev,
2316 /* If there's still data pending, process it next time through the
2317 * loop. Don't do it now; that could get recusive. */
2318 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2319 event_deferred_cb_schedule(get_deferred_queue(evcon),
2320 &evcon->read_more_deferred_cb);
2325 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2328 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2329 TAILQ_REMOVE(&evcon->requests, req, next);
2332 (REQ_VERSION_BEFORE(req, 1, 1) &&
2333 !evhttp_is_connection_keepalive(req->input_headers))||
2334 evhttp_is_connection_close(req->flags, req->input_headers) ||
2335 evhttp_is_connection_close(req->flags, req->output_headers);
2337 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2338 evhttp_request_free(req);
2341 evhttp_connection_free(evcon);
2345 /* we have a persistent connection; try to accept another request. */
2346 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2347 evhttp_connection_free(evcon);
2352 * Returns an error page.
2356 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2359 #define ERR_FORMAT "<HTML><HEAD>\n" \
2360 "<TITLE>%d %s</TITLE>\n" \
2365 struct evbuffer *buf = evbuffer_new();
2367 /* if we cannot allocate memory; we just drop the connection */
2368 evhttp_connection_free(req->evcon);
2371 if (reason == NULL) {
2372 reason = evhttp_response_phrase_internal(error);
2375 evhttp_response_code(req, error, reason);
2377 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2379 evhttp_send_page(req, buf);
2385 /* Requires that headers and response code are already set up */
2388 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2390 struct evhttp_connection *evcon = req->evcon;
2392 if (evcon == NULL) {
2393 evhttp_request_free(req);
2397 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2399 /* we expect no more calls form the user on this request */
2402 /* xxx: not sure if we really should expose the data buffer this way */
2403 if (databuf != NULL)
2404 evbuffer_add_buffer(req->output_buffer, databuf);
2406 /* Adds headers to the response */
2407 evhttp_make_header(evcon, req);
2409 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2413 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2414 struct evbuffer *databuf)
2416 evhttp_response_code(req, code, reason);
2418 evhttp_send(req, databuf);
2422 evhttp_send_reply_start(struct evhttp_request *req, int code,
2425 evhttp_response_code(req, code, reason);
2426 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2427 REQ_VERSION_ATLEAST(req, 1, 1) &&
2428 evhttp_response_needs_body(req)) {
2430 * prefer HTTP/1.1 chunked encoding to closing the connection;
2431 * note RFC 2616 section 4.4 forbids it with Content-Length:
2432 * and it's not necessary then anyway.
2434 evhttp_add_header(req->output_headers, "Transfer-Encoding",
2440 evhttp_make_header(req->evcon, req);
2441 evhttp_write_buffer(req->evcon, NULL, NULL);
2445 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
2447 struct evhttp_connection *evcon = req->evcon;
2448 struct evbuffer *output;
2453 output = bufferevent_get_output(evcon->bufev);
2455 if (evbuffer_get_length(databuf) == 0)
2457 if (!evhttp_response_needs_body(req))
2460 evbuffer_add_printf(output, "%x\r\n",
2461 (unsigned)evbuffer_get_length(databuf));
2463 evbuffer_add_buffer(output, databuf);
2465 evbuffer_add(output, "\r\n", 2);
2467 evhttp_write_buffer(evcon, NULL, NULL);
2471 evhttp_send_reply_end(struct evhttp_request *req)
2473 struct evhttp_connection *evcon = req->evcon;
2474 struct evbuffer *output;
2476 if (evcon == NULL) {
2477 evhttp_request_free(req);
2481 output = bufferevent_get_output(evcon->bufev);
2483 /* we expect no more calls form the user on this request */
2487 evbuffer_add(output, "0\r\n\r\n", 5);
2488 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2490 } else if (evbuffer_get_length(output) == 0) {
2491 /* let the connection know that we are done with the request */
2492 evhttp_send_done(evcon, NULL);
2494 /* make the callback execute after all data has been written */
2495 evcon->cb = evhttp_send_done;
2496 evcon->cb_arg = NULL;
2500 static const char *informational_phrases[] = {
2501 /* 100 */ "Continue",
2502 /* 101 */ "Switching Protocols"
2505 static const char *success_phrases[] = {
2507 /* 201 */ "Created",
2508 /* 202 */ "Accepted",
2509 /* 203 */ "Non-Authoritative Information",
2510 /* 204 */ "No Content",
2511 /* 205 */ "Reset Content",
2512 /* 206 */ "Partial Content"
2515 static const char *redirection_phrases[] = {
2516 /* 300 */ "Multiple Choices",
2517 /* 301 */ "Moved Permanently",
2519 /* 303 */ "See Other",
2520 /* 304 */ "Not Modified",
2521 /* 305 */ "Use Proxy",
2522 /* 307 */ "Temporary Redirect"
2525 static const char *client_error_phrases[] = {
2526 /* 400 */ "Bad Request",
2527 /* 401 */ "Unauthorized",
2528 /* 402 */ "Payment Required",
2529 /* 403 */ "Forbidden",
2530 /* 404 */ "Not Found",
2531 /* 405 */ "Method Not Allowed",
2532 /* 406 */ "Not Acceptable",
2533 /* 407 */ "Proxy Authentication Required",
2534 /* 408 */ "Request Time-out",
2535 /* 409 */ "Conflict",
2537 /* 411 */ "Length Required",
2538 /* 412 */ "Precondition Failed",
2539 /* 413 */ "Request Entity Too Large",
2540 /* 414 */ "Request-URI Too Large",
2541 /* 415 */ "Unsupported Media Type",
2542 /* 416 */ "Requested range not satisfiable",
2543 /* 417 */ "Expectation Failed"
2546 static const char *server_error_phrases[] = {
2547 /* 500 */ "Internal Server Error",
2548 /* 501 */ "Not Implemented",
2549 /* 502 */ "Bad Gateway",
2550 /* 503 */ "Service Unavailable",
2551 /* 504 */ "Gateway Time-out",
2552 /* 505 */ "HTTP Version not supported"
2555 struct response_class {
2557 size_t num_responses;
2558 const char **responses;
2562 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
2565 static const struct response_class response_classes[] = {
2566 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
2567 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
2568 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
2569 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
2570 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
2574 evhttp_response_phrase_internal(int code)
2576 int klass = code / 100 - 1;
2577 int subcode = code % 100;
2579 /* Unknown class - can't do any better here */
2580 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
2581 return "Unknown Status Class";
2583 /* Unknown sub-code, return class name at least */
2584 if (subcode >= (int) response_classes[klass].num_responses)
2585 return response_classes[klass].name;
2587 return response_classes[klass].responses[subcode];
2591 evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
2593 req->kind = EVHTTP_RESPONSE;
2594 req->response_code = code;
2595 if (req->response_code_line != NULL)
2596 mm_free(req->response_code_line);
2598 reason = evhttp_response_phrase_internal(code);
2599 req->response_code_line = mm_strdup(reason);
2600 if (req->response_code_line == NULL) {
2601 event_warn("%s: strdup", __func__);
2602 /* XXX what else can we do? */
2607 evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
2609 if (!req->major || !req->minor) {
2614 if (req->kind != EVHTTP_RESPONSE)
2615 evhttp_response_code(req, 200, "OK");
2617 evhttp_clear_headers(req->output_headers);
2618 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
2619 evhttp_add_header(req->output_headers, "Connection", "close");
2621 evhttp_send(req, databuf);
2624 static const char uri_chars[256] = {
2626 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2627 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2628 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
2629 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
2631 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2632 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
2633 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2634 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
2636 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2637 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2638 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2639 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2641 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2642 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2643 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2644 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2647 #define CHAR_IS_UNRESERVED(c) \
2648 (uri_chars[(unsigned char)(c)])
2651 * Helper functions to encode/decode a string for inclusion in a URI.
2652 * The returned string must be freed by the caller.
2655 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
2657 struct evbuffer *buf = evbuffer_new();
2658 const char *p, *end;
2667 end = uri+strlen(uri);
2669 for (p = uri; p < end; p++) {
2670 if (CHAR_IS_UNRESERVED(*p)) {
2671 evbuffer_add(buf, p, 1);
2672 } else if (*p == ' ' && space_as_plus) {
2673 evbuffer_add(buf, "+", 1);
2675 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
2678 evbuffer_add(buf, "", 1); /* NUL-terminator. */
2679 result = mm_malloc(evbuffer_get_length(buf));
2682 evbuffer_remove(buf, result, evbuffer_get_length(buf));
2689 evhttp_encode_uri(const char *str)
2691 return evhttp_uriencode(str, -1, 0);
2695 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
2696 * If -1, when true we transform plus to space only after we've seen
2697 * a ?. -1 is deprecated.
2698 * @return the number of bytes written to 'ret'.
2701 evhttp_decode_uri_internal(
2702 const char *uri, size_t length, char *ret, int decode_plus_ctl)
2706 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
2709 for (i = j = 0; i < length; i++) {
2712 if (decode_plus_ctl < 0)
2714 } else if (c == '+' && decode_plus) {
2716 } else if (c == '%' && EVUTIL_ISXDIGIT(uri[i+1]) &&
2717 EVUTIL_ISXDIGIT(uri[i+2])) {
2722 c = (char)strtol(tmp, NULL, 16);
2734 evhttp_decode_uri(const char *uri)
2738 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2739 event_warn("%s: malloc(%lu)", __func__,
2740 (unsigned long)(strlen(uri) + 1));
2744 evhttp_decode_uri_internal(uri, strlen(uri),
2745 ret, -1 /*always_decode_plus*/);
2751 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
2756 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2757 event_warn("%s: malloc(%lu)", __func__,
2758 (unsigned long)(strlen(uri) + 1));
2762 n = evhttp_decode_uri_internal(uri, strlen(uri),
2763 ret, !!decode_plus/*always_decode_plus*/);
2766 EVUTIL_ASSERT(n >= 0);
2767 *size_out = (size_t)n;
2774 * Helper function to parse out arguments in a query.
2775 * The arguments are separated by key and value.
2779 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
2785 const char *query_part;
2787 struct evhttp_uri *uri=NULL;
2789 TAILQ_INIT(headers);
2792 uri = evhttp_uri_parse(str);
2795 query_part = evhttp_uri_get_query(uri);
2800 /* No arguments - we are done */
2801 if (!query_part || !strlen(query_part)) {
2806 if ((line = mm_strdup(query_part)) == NULL) {
2807 event_warn("%s: strdup", __func__);
2811 p = argument = line;
2812 while (p != NULL && *p != '\0') {
2813 char *key, *value, *decoded_value;
2814 argument = strsep(&p, "&");
2817 key = strsep(&value, "=");
2818 if (value == NULL || *key == '\0') {
2822 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
2823 event_warn("%s: mm_malloc", __func__);
2826 evhttp_decode_uri_internal(value, strlen(value),
2827 decoded_value, 1 /*always_decode_plus*/);
2828 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
2829 evhttp_add_header_internal(headers, key, decoded_value);
2830 mm_free(decoded_value);
2836 evhttp_clear_headers(headers);
2841 evhttp_uri_free(uri);
2846 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
2848 return evhttp_parse_query_impl(uri, headers, 1);
2851 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
2853 return evhttp_parse_query_impl(uri, headers, 0);
2856 static struct evhttp_cb *
2857 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
2859 struct evhttp_cb *cb;
2864 /* Test for different URLs */
2865 path = evhttp_uri_get_path(req->uri_elems);
2866 offset = strlen(path);
2867 if ((translated = mm_malloc(offset + 1)) == NULL)
2869 evhttp_decode_uri_internal(path, offset, translated,
2870 0 /* decode_plus */);
2872 TAILQ_FOREACH(cb, callbacks, next) {
2873 if (!strcmp(cb->what, translated)) {
2874 mm_free(translated);
2879 mm_free(translated);
2885 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
2890 switch (c = *pattern++) {
2892 return *name == '\0';
2895 while (*name != '\0') {
2896 if (prefix_suffix_match(pattern, name,
2905 EVUTIL_TOLOWER(c) != EVUTIL_TOLOWER(*name))
2915 Search the vhost hierarchy beginning with http for a server alias
2916 matching hostname. If a match is found, and outhttp is non-null,
2917 outhttp is set to the matching http object and 1 is returned.
2921 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
2922 const char *hostname)
2924 struct evhttp_server_alias *alias;
2925 struct evhttp *vhost;
2927 TAILQ_FOREACH(alias, &http->aliases, next) {
2928 /* XXX Do we need to handle IP addresses? */
2929 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
2936 /* XXX It might be good to avoid recursion here, but I don't
2937 see a way to do that w/o a list. */
2938 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
2939 if (evhttp_find_alias(vhost, outhttp, hostname))
2947 Attempts to find the best http object to handle a request for a hostname.
2948 All aliases for the root http object and vhosts are searched for an exact
2949 match. Then, the vhost hierarchy is traversed again for a matching
2952 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
2953 is set with the best matching http object. If there are no matches, the
2954 root http object is stored in outhttp and 0 is returned.
2958 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
2959 const char *hostname)
2961 struct evhttp *vhost;
2962 struct evhttp *oldhttp;
2963 int match_found = 0;
2965 if (evhttp_find_alias(http, outhttp, hostname))
2970 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
2971 if (prefix_suffix_match(vhost->vhost_pattern,
2972 hostname, 1 /* ignorecase */)) {
2978 } while (oldhttp != http);
2987 evhttp_handle_request(struct evhttp_request *req, void *arg)
2989 struct evhttp *http = arg;
2990 struct evhttp_cb *cb = NULL;
2991 const char *hostname;
2993 /* we have a new request on which the user needs to take action */
2996 if (req->type == 0 || req->uri == NULL) {
2997 evhttp_send_error(req, HTTP_BADREQUEST, NULL);
3001 if ((http->allowed_methods & req->type) == 0) {
3002 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3003 (unsigned)req->type, (unsigned)http->allowed_methods));
3004 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3008 /* handle potential virtual hosts */
3009 hostname = evhttp_request_get_host(req);
3010 if (hostname != NULL) {
3011 evhttp_find_vhost(http, &http, hostname);
3014 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3015 (*cb->cb)(req, cb->cbarg);
3019 /* Generic call back */
3021 (*http->gencb)(req, http->gencbarg);
3024 /* We need to send a 404 here */
3025 #define ERR_FORMAT "<html><head>" \
3026 "<title>404 Not Found</title>" \
3028 "<h1>Not Found</h1>" \
3029 "<p>The requested URL %s was not found on this server.</p>"\
3033 struct evbuffer *buf;
3035 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3036 evhttp_connection_free(req->evcon);
3040 if ((buf = evbuffer_new()) == NULL) {
3041 mm_free(escaped_html);
3042 evhttp_connection_free(req->evcon);
3046 evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
3048 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3050 mm_free(escaped_html);
3052 evhttp_send_page(req, buf);
3059 /* Listener callback when a connection arrives at a server. */
3061 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3063 struct evhttp *http = arg;
3065 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3069 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3071 struct evhttp_bound_socket *bound =
3072 evhttp_bind_socket_with_handle(http, address, port);
3078 struct evhttp_bound_socket *
3079 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3082 struct evhttp_bound_socket *bound;
3084 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3087 if (listen(fd, 128) == -1) {
3088 event_sock_warn(fd, "%s: listen", __func__);
3089 evutil_closesocket(fd);
3093 bound = evhttp_accept_socket_with_handle(http, fd);
3095 if (bound != NULL) {
3096 event_debug(("Bound to port %d - Awaiting connections ... ",
3105 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3107 struct evhttp_bound_socket *bound =
3108 evhttp_accept_socket_with_handle(http, fd);
3115 struct evhttp_bound_socket *
3116 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3118 struct evhttp_bound_socket *bound;
3119 struct evconnlistener *listener;
3121 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3123 listener = evconnlistener_new(http->base, NULL, NULL,
3125 0, /* Backlog is '0' because we already said 'listen' */
3130 bound = evhttp_bind_listener(http, listener);
3132 evconnlistener_free(listener);
3138 struct evhttp_bound_socket *
3139 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3141 struct evhttp_bound_socket *bound;
3143 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3147 bound->listener = listener;
3148 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3150 evconnlistener_set_cb(listener, accept_socket_cb, http);
3155 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3157 return evconnlistener_get_fd(bound->listener);
3160 struct evconnlistener *
3161 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3163 return bound->listener;
3167 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3169 TAILQ_REMOVE(&http->sockets, bound, next);
3170 evconnlistener_free(bound->listener);
3174 static struct evhttp*
3175 evhttp_new_object(void)
3177 struct evhttp *http = NULL;
3179 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3180 event_warn("%s: calloc", __func__);
3185 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3186 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3187 evhttp_set_allowed_methods(http,
3194 TAILQ_INIT(&http->sockets);
3195 TAILQ_INIT(&http->callbacks);
3196 TAILQ_INIT(&http->connections);
3197 TAILQ_INIT(&http->virtualhosts);
3198 TAILQ_INIT(&http->aliases);
3204 evhttp_new(struct event_base *base)
3206 struct evhttp *http = evhttp_new_object();
3214 * Start a web server on the specified address and port.
3218 evhttp_start(const char *address, unsigned short port)
3220 struct evhttp *http = evhttp_new_object();
3222 if (evhttp_bind_socket(http, address, port) == -1) {
3231 evhttp_free(struct evhttp* http)
3233 struct evhttp_cb *http_cb;
3234 struct evhttp_connection *evcon;
3235 struct evhttp_bound_socket *bound;
3236 struct evhttp* vhost;
3237 struct evhttp_server_alias *alias;
3239 /* Remove the accepting part */
3240 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3241 TAILQ_REMOVE(&http->sockets, bound, next);
3243 evconnlistener_free(bound->listener);
3248 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3249 /* evhttp_connection_free removes the connection */
3250 evhttp_connection_free(evcon);
3253 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3254 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3255 mm_free(http_cb->what);
3259 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3260 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3265 if (http->vhost_pattern != NULL)
3266 mm_free(http->vhost_pattern);
3268 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3269 TAILQ_REMOVE(&http->aliases, alias, next);
3270 mm_free(alias->alias);
3278 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3279 struct evhttp* vhost)
3281 /* a vhost can only be a vhost once and should not have bound sockets */
3282 if (vhost->vhost_pattern != NULL ||
3283 TAILQ_FIRST(&vhost->sockets) != NULL)
3286 vhost->vhost_pattern = mm_strdup(pattern);
3287 if (vhost->vhost_pattern == NULL)
3290 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3296 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3298 if (vhost->vhost_pattern == NULL)
3301 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3303 mm_free(vhost->vhost_pattern);
3304 vhost->vhost_pattern = NULL;
3310 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3312 struct evhttp_server_alias *evalias;
3314 evalias = mm_calloc(1, sizeof(*evalias));
3318 evalias->alias = mm_strdup(alias);
3319 if (!evalias->alias) {
3324 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3330 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3332 struct evhttp_server_alias *evalias;
3334 TAILQ_FOREACH(evalias, &http->aliases, next) {
3335 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3336 TAILQ_REMOVE(&http->aliases, evalias, next);
3337 mm_free(evalias->alias);
3347 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
3349 http->timeout = timeout_in_secs;
3353 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
3355 if (max_headers_size < 0)
3356 http->default_max_headers_size = EV_SIZE_MAX;
3358 http->default_max_headers_size = max_headers_size;
3362 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
3364 if (max_body_size < 0)
3365 http->default_max_body_size = EV_UINT64_MAX;
3367 http->default_max_body_size = max_body_size;
3371 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
3373 http->allowed_methods = methods;
3377 evhttp_set_cb(struct evhttp *http, const char *uri,
3378 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3380 struct evhttp_cb *http_cb;
3382 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3383 if (strcmp(http_cb->what, uri) == 0)
3387 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
3388 event_warn("%s: calloc", __func__);
3392 http_cb->what = mm_strdup(uri);
3393 if (http_cb->what == NULL) {
3394 event_warn("%s: strdup", __func__);
3399 http_cb->cbarg = cbarg;
3401 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
3407 evhttp_del_cb(struct evhttp *http, const char *uri)
3409 struct evhttp_cb *http_cb;
3411 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3412 if (strcmp(http_cb->what, uri) == 0)
3415 if (http_cb == NULL)
3418 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3419 mm_free(http_cb->what);
3426 evhttp_set_gencb(struct evhttp *http,
3427 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3430 http->gencbarg = cbarg;
3434 * Request related functions
3437 struct evhttp_request *
3438 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
3440 struct evhttp_request *req = NULL;
3442 /* Allocate request structure */
3443 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
3444 event_warn("%s: calloc", __func__);
3448 req->headers_size = 0;
3451 req->kind = EVHTTP_RESPONSE;
3452 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3453 if (req->input_headers == NULL) {
3454 event_warn("%s: calloc", __func__);
3457 TAILQ_INIT(req->input_headers);
3459 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3460 if (req->output_headers == NULL) {
3461 event_warn("%s: calloc", __func__);
3464 TAILQ_INIT(req->output_headers);
3466 if ((req->input_buffer = evbuffer_new()) == NULL) {
3467 event_warn("%s: evbuffer_new", __func__);
3471 if ((req->output_buffer = evbuffer_new()) == NULL) {
3472 event_warn("%s: evbuffer_new", __func__);
3483 evhttp_request_free(req);
3488 evhttp_request_free(struct evhttp_request *req)
3490 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
3491 req->flags |= EVHTTP_REQ_NEEDS_FREE;
3495 if (req->remote_host != NULL)
3496 mm_free(req->remote_host);
3497 if (req->uri != NULL)
3499 if (req->uri_elems != NULL)
3500 evhttp_uri_free(req->uri_elems);
3501 if (req->response_code_line != NULL)
3502 mm_free(req->response_code_line);
3503 if (req->host_cache != NULL)
3504 mm_free(req->host_cache);
3506 evhttp_clear_headers(req->input_headers);
3507 mm_free(req->input_headers);
3509 evhttp_clear_headers(req->output_headers);
3510 mm_free(req->output_headers);
3512 if (req->input_buffer != NULL)
3513 evbuffer_free(req->input_buffer);
3515 if (req->output_buffer != NULL)
3516 evbuffer_free(req->output_buffer);
3522 evhttp_request_own(struct evhttp_request *req)
3524 req->flags |= EVHTTP_USER_OWNED;
3528 evhttp_request_is_owned(struct evhttp_request *req)
3530 return (req->flags & EVHTTP_USER_OWNED) != 0;
3533 struct evhttp_connection *
3534 evhttp_request_get_connection(struct evhttp_request *req)
3540 evhttp_connection_get_base(struct evhttp_connection *conn)
3546 evhttp_request_set_chunked_cb(struct evhttp_request *req,
3547 void (*cb)(struct evhttp_request *, void *))
3553 * Allows for inspection of the request URI
3557 evhttp_request_get_uri(const struct evhttp_request *req) {
3558 if (req->uri == NULL)
3559 event_debug(("%s: request %p has no uri\n", __func__, req));
3563 const struct evhttp_uri *
3564 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
3565 if (req->uri_elems == NULL)
3566 event_debug(("%s: request %p has no uri elems\n",
3568 return (req->uri_elems);
3572 evhttp_request_get_host(struct evhttp_request *req)
3574 const char *host = NULL;
3576 if (req->host_cache)
3577 return req->host_cache;
3580 host = evhttp_uri_get_host(req->uri_elems);
3581 if (!host && req->input_headers) {
3585 host = evhttp_find_header(req->input_headers, "Host");
3586 /* The Host: header may include a port. Remove it here
3587 to be consistent with uri_elems case above. */
3589 p = host + strlen(host) - 1;
3590 while (p > host && EVUTIL_ISDIGIT(*p))
3592 if (p > host && *p == ':') {
3594 req->host_cache = mm_malloc(len + 1);
3595 if (!req->host_cache) {
3596 event_warn("%s: malloc", __func__);
3599 memcpy(req->host_cache, host, len);
3600 req->host_cache[len] = '\0';
3601 host = req->host_cache;
3609 enum evhttp_cmd_type
3610 evhttp_request_get_command(const struct evhttp_request *req) {
3615 evhttp_request_get_response_code(const struct evhttp_request *req)
3617 return req->response_code;
3620 /** Returns the input headers */
3621 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
3623 return (req->input_headers);
3626 /** Returns the output headers */
3627 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
3629 return (req->output_headers);
3632 /** Returns the input buffer */
3633 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
3635 return (req->input_buffer);
3638 /** Returns the output buffer */
3639 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
3641 return (req->output_buffer);
3646 * Takes a file descriptor to read a request from.
3647 * The callback is executed once the whole request has been read.
3650 static struct evhttp_connection*
3651 evhttp_get_request_connection(
3652 struct evhttp* http,
3653 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
3655 struct evhttp_connection *evcon;
3656 char *hostname = NULL, *portname = NULL;
3658 name_from_addr(sa, salen, &hostname, &portname);
3659 if (hostname == NULL || portname == NULL) {
3660 if (hostname) mm_free(hostname);
3661 if (portname) mm_free(portname);
3665 event_debug(("%s: new request from %s:%s on %d\n",
3666 __func__, hostname, portname, fd));
3668 /* we need a connection object to put the http request on */
3669 evcon = evhttp_connection_base_new(
3670 http->base, NULL, hostname, atoi(portname));
3676 evcon->max_headers_size = http->default_max_headers_size;
3677 evcon->max_body_size = http->default_max_body_size;
3679 evcon->flags |= EVHTTP_CON_INCOMING;
3680 evcon->state = EVCON_READING_FIRSTLINE;
3684 bufferevent_setfd(evcon->bufev, fd);
3690 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
3692 struct evhttp *http = evcon->http_server;
3693 struct evhttp_request *req;
3694 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
3697 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
3698 event_warn("%s: strdup", __func__);
3699 evhttp_request_free(req);
3702 req->remote_port = evcon->port;
3704 req->evcon = evcon; /* the request ends up owning the connection */
3705 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
3707 /* We did not present the request to the user user yet, so treat it as
3708 * if the user was done with the request. This allows us to free the
3709 * request on a persistent connection if the client drops it without
3710 * sending a request.
3714 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
3716 req->kind = EVHTTP_REQUEST;
3719 evhttp_start_read(evcon);
3725 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
3726 struct sockaddr *sa, ev_socklen_t salen)
3728 struct evhttp_connection *evcon;
3730 evcon = evhttp_get_request_connection(http, fd, sa, salen);
3731 if (evcon == NULL) {
3732 event_sock_warn(fd, "%s: cannot get connection on %d", __func__, fd);
3733 evutil_closesocket(fd);
3737 /* the timeout can be used by the server to close idle connections */
3738 if (http->timeout != -1)
3739 evhttp_connection_set_timeout(evcon, http->timeout);
3742 * if we want to accept more than one request on a connection,
3743 * we need to know which http server it belongs to.
3745 evcon->http_server = http;
3746 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
3748 if (evhttp_associate_new_request_with_connection(evcon) == -1)
3749 evhttp_connection_free(evcon);
3754 * Network helper functions that we do not want to export to the rest of
3759 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
3760 char **phost, char **pport)
3762 char ntop[NI_MAXHOST];
3763 char strport[NI_MAXSERV];
3766 #ifdef _EVENT_HAVE_GETNAMEINFO
3767 ni_result = getnameinfo(sa, salen,
3768 ntop, sizeof(ntop), strport, sizeof(strport),
3769 NI_NUMERICHOST|NI_NUMERICSERV);
3771 if (ni_result != 0) {
3773 /* Windows doesn't have an EAI_SYSTEM. */
3774 if (ni_result == EAI_SYSTEM)
3775 event_err(1, "getnameinfo failed");
3778 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
3782 ni_result = fake_getnameinfo(sa, salen,
3783 ntop, sizeof(ntop), strport, sizeof(strport),
3784 NI_NUMERICHOST|NI_NUMERICSERV);
3789 *phost = mm_strdup(ntop);
3790 *pport = mm_strdup(strport);
3793 /* Create a non-blocking socket and bind it */
3794 /* todo: rename this function */
3795 static evutil_socket_t
3796 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
3803 /* Create listen socket */
3804 fd = socket(ai ? ai->ai_family : AF_INET, SOCK_STREAM, 0);
3806 event_sock_warn(-1, "socket");
3810 if (evutil_make_socket_nonblocking(fd) < 0)
3812 if (evutil_make_socket_closeonexec(fd) < 0)
3815 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
3817 evutil_make_listen_socket_reuseable(fd);
3820 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
3828 serrno = EVUTIL_SOCKET_ERROR();
3829 evutil_closesocket(fd);
3830 EVUTIL_SET_SOCKET_ERROR(serrno);
3834 static struct evutil_addrinfo *
3835 make_addrinfo(const char *address, ev_uint16_t port)
3837 struct evutil_addrinfo *ai = NULL;
3839 struct evutil_addrinfo hints;
3840 char strport[NI_MAXSERV];
3843 memset(&hints, 0, sizeof(hints));
3844 hints.ai_family = AF_UNSPEC;
3845 hints.ai_socktype = SOCK_STREAM;
3846 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
3847 * types we don't have an interface to connect to. */
3848 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
3849 evutil_snprintf(strport, sizeof(strport), "%d", port);
3850 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
3852 if (ai_result == EVUTIL_EAI_SYSTEM)
3853 event_warn("getaddrinfo");
3855 event_warnx("getaddrinfo: %s",
3856 evutil_gai_strerror(ai_result));
3863 static evutil_socket_t
3864 bind_socket(const char *address, ev_uint16_t port, int reuse)
3867 struct evutil_addrinfo *aitop = NULL;
3869 /* just create an unbound socket */
3870 if (address == NULL && port == 0)
3871 return bind_socket_ai(NULL, 0);
3873 aitop = make_addrinfo(address, port);
3878 fd = bind_socket_ai(aitop, reuse);
3880 evutil_freeaddrinfo(aitop);
3887 char *scheme; /* scheme; e.g http, ftp etc */
3888 char *userinfo; /* userinfo (typically username:pass), or NULL */
3889 char *host; /* hostname, IP address, or NULL */
3890 int port; /* port, or zero */
3891 char *path; /* path, or "". */
3892 char *query; /* query, or NULL */
3893 char *fragment; /* fragment or NULL */
3897 evhttp_uri_new(void)
3899 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
3906 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
3911 /* Return true if the string starting at s and ending immediately before eos
3912 * is a valid URI scheme according to RFC3986
3915 scheme_ok(const char *s, const char *eos)
3917 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
3918 EVUTIL_ASSERT(eos >= s);
3921 if (!EVUTIL_ISALPHA(*s))
3924 if (! EVUTIL_ISALNUM(*s) &&
3925 *s != '+' && *s != '-' && *s != '.')
3931 #define SUBDELIMS "!$&'()*+,;="
3933 /* Return true iff [s..eos) is a valid userinfo */
3935 userinfo_ok(const char *s, const char *eos)
3938 if (CHAR_IS_UNRESERVED(*s) ||
3939 strchr(SUBDELIMS, *s) ||
3942 else if (*s == '%' && s+2 < eos &&
3943 EVUTIL_ISXDIGIT(s[1]) &&
3944 EVUTIL_ISXDIGIT(s[2]))
3953 regname_ok(const char *s, const char *eos)
3955 while (s && s<eos) {
3956 if (CHAR_IS_UNRESERVED(*s) ||
3957 strchr(SUBDELIMS, *s))
3959 else if (*s == '%' &&
3960 EVUTIL_ISXDIGIT(s[1]) &&
3961 EVUTIL_ISXDIGIT(s[2]))
3970 parse_port(const char *s, const char *eos)
3974 if (! EVUTIL_ISDIGIT(*s))
3976 portnum = (portnum * 10) + (*s - '0');
3984 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
3986 bracket_addr_ok(const char *s, const char *eos)
3988 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
3991 /* IPvFuture, or junk.
3992 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
3994 s += 2; /* skip [v */
3996 if (!EVUTIL_ISXDIGIT(*s)) /*require at least one*/
3998 while (s < eos && *s != '.') {
3999 if (EVUTIL_ISXDIGIT(*s))
4008 if (CHAR_IS_UNRESERVED(*s) ||
4009 strchr(SUBDELIMS, *s) ||
4019 ev_ssize_t n_chars = eos-s-2;
4020 struct in6_addr in6;
4021 if (n_chars >= 64) /* way too long */
4023 memcpy(buf, s+1, n_chars);
4025 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4030 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4035 uri->host = mm_strdup("");
4036 if (uri->host == NULL) {
4037 event_warn("%s: strdup", __func__);
4043 /* Optionally, we start with "userinfo@" */
4045 cp = strchr(s, '@');
4046 if (cp && cp < eos) {
4047 if (! userinfo_ok(s,cp))
4050 uri->userinfo = mm_strdup(s);
4051 if (uri->userinfo == NULL) {
4052 event_warn("%s: strdup", __func__);
4058 /* Optionally, we end with ":port" */
4059 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT(*port); --port)
4061 if (port >= cp && *port == ':') {
4062 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4065 else if ((uri->port = parse_port(port+1, eos))<0)
4069 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4070 * an IP-Literal, or a reg-name */
4071 EVUTIL_ASSERT(eos >= cp);
4072 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4073 /* IPv6address, IP-Literal, or junk. */
4074 if (! bracket_addr_ok(cp, eos))
4077 /* Make sure the host part is ok. */
4078 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4081 uri->host = mm_malloc(eos-cp+1);
4082 if (uri->host == NULL) {
4083 event_warn("%s: malloc", __func__);
4086 memcpy(uri->host, cp, eos-cp);
4087 uri->host[eos-cp] = '\0';
4093 end_of_authority(char *cp)
4096 if (*cp == '?' || *cp == '#' || *cp == '/')
4109 /* Return the character after the longest prefix of 'cp' that matches...
4110 * *pchar / "/" if allow_qchars is false, or
4111 * *(pchar / "/" / "?") if allow_qchars is true.
4114 end_of_path(char *cp, enum uri_part part, unsigned flags)
4116 if (flags & EVHTTP_URI_NONCONFORMANT) {
4117 /* If NONCONFORMANT:
4118 * Path is everything up to a # or ? or nul.
4119 * Query is everything up a # or nul
4120 * Fragment is everything up to a nul.
4124 while (*cp && *cp != '#' && *cp != '?')
4128 while (*cp && *cp != '#')
4139 if (CHAR_IS_UNRESERVED(*cp) ||
4140 strchr(SUBDELIMS, *cp) ||
4141 *cp == ':' || *cp == '@' || *cp == '/')
4143 else if (*cp == '%' && EVUTIL_ISXDIGIT(cp[1]) &&
4144 EVUTIL_ISXDIGIT(cp[2]))
4146 else if (*cp == '?' && part != PART_PATH)
4155 path_matches_noscheme(const char *cp)
4160 else if (*cp == '/')
4168 evhttp_uri_parse(const char *source_uri)
4170 return evhttp_uri_parse_with_flags(source_uri, 0);
4174 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4176 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4177 char *path = NULL, *fragment = NULL;
4178 int got_authority = 0;
4180 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4182 event_warn("%s: calloc", __func__);
4188 readbuf = mm_strdup(source_uri);
4189 if (readbuf == NULL) {
4190 event_warn("%s: strdup", __func__);
4197 /* We try to follow RFC3986 here as much as we can, and match
4200 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4202 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
4206 token = strchr(readp, ':');
4207 if (token && scheme_ok(readp,token)) {
4209 uri->scheme = mm_strdup(readp);
4210 if (uri->scheme == NULL) {
4211 event_warn("%s: strdup", __func__);
4214 readp = token+1; /* eat : */
4217 /* 2. Optionally, "//" then an 'authority' part. */
4218 if (readp[0]=='/' && readp[1] == '/') {
4222 path = end_of_authority(readp);
4223 if (parse_authority(uri, authority, path) < 0)
4229 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4232 readp = end_of_path(path, PART_PATH, flags);
4235 if (*readp == '?') {
4239 readp = end_of_path(readp, PART_QUERY, flags);
4242 if (*readp == '#') {
4246 readp = end_of_path(readp, PART_FRAGMENT, flags);
4248 if (*readp != '\0') {
4252 /* These next two cases may be unreachable; I'm leaving them
4253 * in to be defensive. */
4254 /* If you didn't get an authority, the path can't begin with "//" */
4255 if (!got_authority && path[0]=='/' && path[1]=='/')
4257 /* If you did get an authority, the path must begin with "/" or be
4259 if (got_authority && path[0] != '/' && path[0] != '\0')
4261 /* (End of maybe-unreachable cases) */
4263 /* If there was no scheme, the first part of the path (if any) must
4264 * have no colon in it. */
4265 if (! uri->scheme && !path_matches_noscheme(path))
4268 EVUTIL_ASSERT(path);
4269 uri->path = mm_strdup(path);
4270 if (uri->path == NULL) {
4271 event_warn("%s: strdup", __func__);
4276 uri->query = mm_strdup(query);
4277 if (uri->query == NULL) {
4278 event_warn("%s: strdup", __func__);
4283 uri->fragment = mm_strdup(fragment);
4284 if (uri->fragment == NULL) {
4285 event_warn("%s: strdup", __func__);
4295 evhttp_uri_free(uri);
4302 evhttp_uri_free(struct evhttp_uri *uri)
4304 #define _URI_FREE_STR(f) \
4309 _URI_FREE_STR(scheme);
4310 _URI_FREE_STR(userinfo);
4311 _URI_FREE_STR(host);
4312 _URI_FREE_STR(path);
4313 _URI_FREE_STR(query);
4314 _URI_FREE_STR(fragment);
4317 #undef _URI_FREE_STR
4321 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
4323 struct evbuffer *tmp = 0;
4324 size_t joined_size = 0;
4325 char *output = NULL;
4327 #define _URI_ADD(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
4329 if (!uri || !buf || !limit)
4332 tmp = evbuffer_new();
4338 evbuffer_add(tmp, ":", 1);
4341 evbuffer_add(tmp, "//", 2);
4343 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
4346 evbuffer_add_printf(tmp,":%d", uri->port);
4348 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
4356 evbuffer_add(tmp, "?", 1);
4360 if (uri->fragment) {
4361 evbuffer_add(tmp, "#", 1);
4365 evbuffer_add(tmp, "\0", 1); /* NUL */
4367 joined_size = evbuffer_get_length(tmp);
4369 if (joined_size > limit) {
4370 /* It doesn't fit. */
4374 evbuffer_remove(tmp, buf, joined_size);
4385 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
4390 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
4392 return uri->userinfo;
4395 evhttp_uri_get_host(const struct evhttp_uri *uri)
4400 evhttp_uri_get_port(const struct evhttp_uri *uri)
4405 evhttp_uri_get_path(const struct evhttp_uri *uri)
4410 evhttp_uri_get_query(const struct evhttp_uri *uri)
4415 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
4417 return uri->fragment;
4420 #define _URI_SET_STR(f) do { \
4424 if ((uri->f = mm_strdup(f)) == NULL) { \
4425 event_warn("%s: strdup()", __func__); \
4434 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
4436 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
4439 _URI_SET_STR(scheme);
4443 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
4445 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
4447 _URI_SET_STR(userinfo);
4451 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
4454 if (host[0] == '[') {
4455 if (! bracket_addr_ok(host, host+strlen(host)))
4458 if (! regname_ok(host, host+strlen(host)))
4467 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
4474 #define end_of_cpath(cp,p,f) \
4475 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
4478 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
4480 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
4487 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
4489 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
4491 _URI_SET_STR(query);
4495 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
4497 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
4499 _URI_SET_STR(fragment);