2 * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
3 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "event2/event-config.h"
29 #include "evconfig-private.h"
31 #ifdef EVENT__HAVE_SYS_PARAM_H
32 #include <sys/param.h>
34 #ifdef EVENT__HAVE_SYS_TYPES_H
35 #include <sys/types.h>
38 #ifdef HAVE_SYS_IOCCOM_H
39 #include <sys/ioccom.h>
41 #ifdef EVENT__HAVE_SYS_RESOURCE_H
42 #include <sys/resource.h>
44 #ifdef EVENT__HAVE_SYS_TIME_H
47 #ifdef EVENT__HAVE_SYS_WAIT_H
52 #include <sys/socket.h>
59 #include <sys/queue.h>
61 #ifdef EVENT__HAVE_NETINET_IN_H
62 #include <netinet/in.h>
64 #ifdef EVENT__HAVE_ARPA_INET_H
65 #include <arpa/inet.h>
67 #ifdef EVENT__HAVE_NETDB_H
84 #ifdef EVENT__HAVE_UNISTD_H
87 #ifdef EVENT__HAVE_FCNTL_H
91 #undef timeout_pending
92 #undef timeout_initialized
94 #include "strlcpy-internal.h"
95 #include "event2/http.h"
96 #include "event2/event.h"
97 #include "event2/buffer.h"
98 #include "event2/bufferevent.h"
99 #include "event2/http_struct.h"
100 #include "event2/http_compat.h"
101 #include "event2/util.h"
102 #include "event2/listener.h"
103 #include "log-internal.h"
104 #include "util-internal.h"
105 #include "http-internal.h"
106 #include "mm-internal.h"
107 #include "bufferevent-internal.h"
109 #ifndef EVENT__HAVE_GETNAMEINFO
110 #define NI_MAXSERV 32
111 #define NI_MAXHOST 1025
113 #ifndef NI_NUMERICHOST
114 #define NI_NUMERICHOST 1
117 #ifndef NI_NUMERICSERV
118 #define NI_NUMERICSERV 2
122 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
123 size_t hostlen, char *serv, size_t servlen, int flags)
125 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
129 evutil_snprintf(tmpserv, sizeof(tmpserv),
130 "%d", ntohs(sin->sin_port));
131 if (strlcpy(serv, tmpserv, servlen) >= servlen)
136 if (flags & NI_NUMERICHOST) {
137 if (strlcpy(host, inet_ntoa(sin->sin_addr),
144 hp = gethostbyaddr((char *)&sin->sin_addr,
145 sizeof(struct in_addr), AF_INET);
149 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
160 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \
161 ((req)->major < (major_v) || \
162 ((req)->major == (major_v) && (req)->minor < (minor_v)))
164 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \
165 ((req)->major > (major_v) || \
166 ((req)->major == (major_v) && (req)->minor >= (minor_v)))
169 #define MIN(a,b) (((a)<(b))?(a):(b))
174 static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse);
175 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
176 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
177 static int evhttp_associate_new_request_with_connection(
178 struct evhttp_connection *evcon);
179 static void evhttp_connection_start_detectclose(
180 struct evhttp_connection *evcon);
181 static void evhttp_connection_stop_detectclose(
182 struct evhttp_connection *evcon);
183 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
184 static void evhttp_read_firstline(struct evhttp_connection *evcon,
185 struct evhttp_request *req);
186 static void evhttp_read_header(struct evhttp_connection *evcon,
187 struct evhttp_request *req);
188 static int evhttp_add_header_internal(struct evkeyvalq *headers,
189 const char *key, const char *value);
190 static const char *evhttp_response_phrase_internal(int code);
191 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t);
192 static void evhttp_write_buffer(struct evhttp_connection *,
193 void (*)(struct evhttp_connection *, void *), void *);
194 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
196 /* callbacks for bufferevent */
197 static void evhttp_read_cb(struct bufferevent *, void *);
198 static void evhttp_write_cb(struct bufferevent *, void *);
199 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
200 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
201 const char *hostname);
203 #ifndef EVENT__HAVE_STRSEP
204 /* strsep replacement for platforms that lack it. Only works if
205 * del is one character long. */
207 strsep(char **s, const char *del)
210 EVUTIL_ASSERT(strlen(del) == 1);
214 d = strstr(tok, del);
225 html_replace(const char ch, const char **escaped)
251 * Replaces <, >, ", ' and & with <, >, ",
252 * ' and & correspondingly.
254 * The returned string needs to be freed by the caller.
258 evhttp_htmlescape(const char *html)
261 size_t new_size = 0, old_size = 0;
262 char *escaped_html, *p;
267 old_size = strlen(html);
268 for (i = 0; i < old_size; ++i) {
269 const char *replaced = NULL;
270 const size_t replace_size = html_replace(html[i], &replaced);
271 if (replace_size > EV_SIZE_MAX - new_size) {
272 event_warn("%s: html_replace overflow", __func__);
275 new_size += replace_size;
278 if (new_size == EV_SIZE_MAX)
280 p = escaped_html = mm_malloc(new_size + 1);
281 if (escaped_html == NULL) {
282 event_warn("%s: malloc(%lu)", __func__,
283 (unsigned long)(new_size + 1));
286 for (i = 0; i < old_size; ++i) {
287 const char *replaced = &html[i];
288 const size_t len = html_replace(html[i], &replaced);
289 memcpy(p, replaced, len);
295 return (escaped_html);
298 /** Given an evhttp_cmd_type, returns a constant string containing the
299 * equivalent HTTP command, or NULL if the evhttp_command_type is
302 evhttp_method(enum evhttp_cmd_type type)
310 case EVHTTP_REQ_POST:
313 case EVHTTP_REQ_HEAD:
319 case EVHTTP_REQ_DELETE:
322 case EVHTTP_REQ_OPTIONS:
325 case EVHTTP_REQ_TRACE:
328 case EVHTTP_REQ_CONNECT:
331 case EVHTTP_REQ_PATCH:
343 * Determines if a response should have a body.
344 * Follows the rules in RFC 2616 section 4.3.
345 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
349 evhttp_response_needs_body(struct evhttp_request *req)
351 return (req->response_code != HTTP_NOCONTENT &&
352 req->response_code != HTTP_NOTMODIFIED &&
353 (req->response_code < 100 || req->response_code >= 200) &&
354 req->type != EVHTTP_REQ_HEAD);
357 /** Helper: called after we've added some data to an evcon's bufferevent's
358 * output buffer. Sets the evconn's writing-is-done callback, and puts
359 * the bufferevent into writing mode.
362 evhttp_write_buffer(struct evhttp_connection *evcon,
363 void (*cb)(struct evhttp_connection *, void *), void *arg)
365 event_debug(("%s: preparing to write buffer\n", __func__));
371 /* Disable the read callback: we don't actually care about data;
372 * we only care about close detection. (We don't disable reading,
373 * since we *do* want to learn about any close events.) */
374 bufferevent_setcb(evcon->bufev,
380 bufferevent_enable(evcon->bufev, EV_WRITE);
384 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
386 bufferevent_disable(evcon->bufev, EV_WRITE);
390 evhttp_send_continue(struct evhttp_connection *evcon,
391 struct evhttp_request *req)
393 bufferevent_enable(evcon->bufev, EV_WRITE);
394 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
395 "HTTP/%d.%d 100 Continue\r\n\r\n",
396 req->major, req->minor);
397 evcon->cb = evhttp_send_continue_done;
398 evcon->cb_arg = NULL;
399 bufferevent_setcb(evcon->bufev,
406 /** Helper: returns true iff evconn is in any connected state. */
408 evhttp_connected(struct evhttp_connection *evcon)
410 switch (evcon->state) {
411 case EVCON_DISCONNECTED:
412 case EVCON_CONNECTING:
415 case EVCON_READING_FIRSTLINE:
416 case EVCON_READING_HEADERS:
417 case EVCON_READING_BODY:
418 case EVCON_READING_TRAILER:
425 /* Create the headers needed for an outgoing HTTP request, adds them to
426 * the request's header list, and writes the request line to the
427 * connection's output buffer.
430 evhttp_make_header_request(struct evhttp_connection *evcon,
431 struct evhttp_request *req)
435 evhttp_remove_header(req->output_headers, "Proxy-Connection");
437 /* Generate request line */
438 method = evhttp_method(req->type);
439 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
440 "%s %s HTTP/%d.%d\r\n",
441 method, req->uri, req->major, req->minor);
443 /* Add the content length on a post or put request if missing */
444 if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
445 evhttp_find_header(req->output_headers, "Content-Length") == NULL){
447 evutil_snprintf(size, sizeof(size), EV_SIZE_FMT,
448 EV_SIZE_ARG(evbuffer_get_length(req->output_buffer)));
449 evhttp_add_header(req->output_headers, "Content-Length", size);
453 /** Return true if the list of headers in 'headers', intepreted with respect
454 * to flags, means that we should send a "connection: close" when the request
457 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
459 if (flags & EVHTTP_PROXY_REQUEST) {
460 /* proxy connection */
461 const char *connection = evhttp_find_header(headers, "Proxy-Connection");
462 return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
464 const char *connection = evhttp_find_header(headers, "Connection");
465 return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
469 evhttp_is_request_connection_close(struct evhttp_request *req)
472 evhttp_is_connection_close(req->flags, req->input_headers) ||
473 evhttp_is_connection_close(req->flags, req->output_headers);
476 /* Return true iff 'headers' contains 'Connection: keep-alive' */
478 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
480 const char *connection = evhttp_find_header(headers, "Connection");
481 return (connection != NULL
482 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
485 /* Add a correct "Date" header to headers, unless it already has one. */
487 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
489 if (evhttp_find_header(headers, "Date") == NULL) {
495 time_t t = time(NULL);
502 if (strftime(date, sizeof(date),
503 "%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) {
504 evhttp_add_header(headers, "Date", date);
509 /* Add a "Content-Length" header with value 'content_length' to headers,
510 * unless it already has a content-length or transfer-encoding header. */
512 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
513 size_t content_length)
515 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
516 evhttp_find_header(headers, "Content-Length") == NULL) {
518 evutil_snprintf(len, sizeof(len), EV_SIZE_FMT,
519 EV_SIZE_ARG(content_length));
520 evhttp_add_header(headers, "Content-Length", len);
525 * Create the headers needed for an HTTP reply in req->output_headers,
526 * and write the first HTTP response for req line to evcon.
529 evhttp_make_header_response(struct evhttp_connection *evcon,
530 struct evhttp_request *req)
532 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
533 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
534 "HTTP/%d.%d %d %s\r\n",
535 req->major, req->minor, req->response_code,
536 req->response_code_line);
538 if (req->major == 1) {
540 evhttp_maybe_add_date_header(req->output_headers);
543 * if the protocol is 1.0; and the connection was keep-alive
544 * we need to add a keep-alive header, too.
546 if (req->minor == 0 && is_keepalive)
547 evhttp_add_header(req->output_headers,
548 "Connection", "keep-alive");
550 if ((req->minor >= 1 || is_keepalive) &&
551 evhttp_response_needs_body(req)) {
553 * we need to add the content length if the
554 * user did not give it, this is required for
555 * persistent connections to work.
557 evhttp_maybe_add_content_length_header(
559 evbuffer_get_length(req->output_buffer));
563 /* Potentially add headers for unidentified content. */
564 if (evhttp_response_needs_body(req)) {
565 if (evhttp_find_header(req->output_headers,
566 "Content-Type") == NULL
567 && evcon->http_server->default_content_type) {
568 evhttp_add_header(req->output_headers,
570 evcon->http_server->default_content_type);
574 /* if the request asked for a close, we send a close, too */
575 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
576 evhttp_remove_header(req->output_headers, "Connection");
577 if (!(req->flags & EVHTTP_PROXY_REQUEST))
578 evhttp_add_header(req->output_headers, "Connection", "close");
579 evhttp_remove_header(req->output_headers, "Proxy-Connection");
583 /** Generate all headers appropriate for sending the http request in req (or
584 * the response, if we're sending a response), and write them to evcon's
585 * bufferevent. Also writes all data from req->output_buffer */
587 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
589 struct evkeyval *header;
590 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
593 * Depending if this is a HTTP request or response, we might need to
594 * add some new headers or remove existing headers.
596 if (req->kind == EVHTTP_REQUEST) {
597 evhttp_make_header_request(evcon, req);
599 evhttp_make_header_response(evcon, req);
602 TAILQ_FOREACH(header, req->output_headers, next) {
603 evbuffer_add_printf(output, "%s: %s\r\n",
604 header->key, header->value);
606 evbuffer_add(output, "\r\n", 2);
608 if (evbuffer_get_length(req->output_buffer) > 0) {
610 * For a request, we add the POST data, for a reply, this
611 * is the regular data.
613 /* XXX We might want to support waiting (a limited amount of
614 time) for a continue status line from the server before
615 sending POST/PUT message bodies. */
616 evbuffer_add_buffer(output, req->output_buffer);
621 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
622 ev_ssize_t new_max_headers_size)
624 if (new_max_headers_size<0)
625 evcon->max_headers_size = EV_SIZE_MAX;
627 evcon->max_headers_size = new_max_headers_size;
630 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
631 ev_ssize_t new_max_body_size)
633 if (new_max_body_size<0)
634 evcon->max_body_size = EV_UINT64_MAX;
636 evcon->max_body_size = new_max_body_size;
640 evhttp_connection_incoming_fail(struct evhttp_request *req,
641 enum evhttp_request_error error)
644 case EVREQ_HTTP_TIMEOUT:
647 * these are cases in which we probably should just
648 * close the connection and not send a reply. this
649 * case may happen when a browser keeps a persistent
650 * connection open and we timeout on the read. when
651 * the request is still being used for sending, we
652 * need to disassociated it from the connection here.
654 if (!req->userdone) {
655 /* remove it so that it will not be freed */
656 TAILQ_REMOVE(&req->evcon->requests, req, next);
657 /* indicate that this request no longer has a
663 case EVREQ_HTTP_INVALID_HEADER:
664 case EVREQ_HTTP_BUFFER_ERROR:
665 case EVREQ_HTTP_REQUEST_CANCEL:
666 case EVREQ_HTTP_DATA_TOO_LONG:
667 default: /* xxx: probably should just error on default */
668 /* the callback looks at the uri to determine errors */
673 if (req->uri_elems) {
674 evhttp_uri_free(req->uri_elems);
675 req->uri_elems = NULL;
679 * the callback needs to send a reply, once the reply has
680 * been send, the connection should get freed.
682 (*req->cb)(req, req->cb_arg);
688 /* Free connection ownership of which can be acquired by user using
689 * evhttp_request_own(). */
691 evhttp_request_free_auto(struct evhttp_request *req)
693 if (!(req->flags & EVHTTP_USER_OWNED))
694 evhttp_request_free(req);
698 evhttp_request_free_(struct evhttp_connection *evcon, struct evhttp_request *req)
700 TAILQ_REMOVE(&evcon->requests, req, next);
701 evhttp_request_free_auto(req);
704 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
705 * given in error. If it's an outgoing connection, reset the connection,
706 * retry any pending requests, and inform the user. If it's incoming,
707 * delegates to evhttp_connection_incoming_fail(). */
709 evhttp_connection_fail_(struct evhttp_connection *evcon,
710 enum evhttp_request_error error)
712 const int errsave = EVUTIL_SOCKET_ERROR();
713 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
714 void (*cb)(struct evhttp_request *, void *);
716 void (*error_cb)(enum evhttp_request_error, void *);
718 EVUTIL_ASSERT(req != NULL);
720 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
722 if (evcon->flags & EVHTTP_CON_INCOMING) {
724 * for incoming requests, there are two different
725 * failure cases. it's either a network level error
726 * or an http layer error. for problems on the network
727 * layer like timeouts we just drop the connections.
728 * For HTTP problems, we might have to send back a
729 * reply before the connection can be freed.
731 if (evhttp_connection_incoming_fail(req, error) == -1)
732 evhttp_connection_free(evcon);
736 error_cb = req->error_cb;
737 error_cb_arg = req->cb_arg;
738 /* when the request was canceled, the callback is not executed */
739 if (error != EVREQ_HTTP_REQUEST_CANCEL) {
740 /* save the callback for later; the cb might free our object */
742 cb_arg = req->cb_arg;
748 /* do not fail all requests; the next request is going to get
749 * send over a new connection. when a user cancels a request,
750 * all other pending requests should be processed as normal
752 evhttp_request_free_(evcon, req);
754 /* reset the connection */
755 evhttp_connection_reset_(evcon);
757 /* We are trying the next request that was queued on us */
758 if (TAILQ_FIRST(&evcon->requests) != NULL)
759 evhttp_connection_connect_(evcon);
761 /* The call to evhttp_connection_reset_ overwrote errno.
762 * Let's restore the original errno, so that the user's
763 * callback can have a better idea of what the error was.
765 EVUTIL_SET_SOCKET_ERROR(errsave);
767 /* inform the user */
768 if (error_cb != NULL)
769 error_cb(error, error_cb_arg);
774 /* Bufferevent callback: invoked when any data has been written from an
775 * http connection's bufferevent */
777 evhttp_write_cb(struct bufferevent *bufev, void *arg)
779 struct evhttp_connection *evcon = arg;
781 /* Activate our call back */
782 if (evcon->cb != NULL)
783 (*evcon->cb)(evcon, evcon->cb_arg);
787 * Advance the connection state.
788 * - If this is an outgoing connection, we've just processed the response;
789 * idle or close the connection.
790 * - If this is an incoming connection, we've just processed the request;
794 evhttp_connection_done(struct evhttp_connection *evcon)
796 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
797 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
801 /* idle or close the connection */
802 int need_close = evhttp_is_request_connection_close(req);
803 TAILQ_REMOVE(&evcon->requests, req, next);
806 evcon->state = EVCON_IDLE;
808 /* check if we got asked to close the connection */
810 evhttp_connection_reset_(evcon);
812 if (TAILQ_FIRST(&evcon->requests) != NULL) {
814 * We have more requests; reset the connection
815 * and deal with the next request.
817 if (!evhttp_connected(evcon))
818 evhttp_connection_connect_(evcon);
820 evhttp_request_dispatch(evcon);
821 } else if (!need_close) {
823 * The connection is going to be persistent, but we
824 * need to detect if the other side closes it.
826 evhttp_connection_start_detectclose(evcon);
827 } else if ((evcon->flags & EVHTTP_CON_AUTOFREE)) {
829 * If we have no more requests that need completion
830 * and we're not waiting for the connection to close
836 * incoming connection - we need to leave the request on the
837 * connection so that we can reply to it.
839 evcon->state = EVCON_WRITING;
842 /* notify the user of the request */
843 (*req->cb)(req, req->cb_arg);
845 /* if this was an outgoing request, we own and it's done. so free it. */
847 evhttp_request_free_auto(req);
850 /* If this was the last request of an outgoing connection and we're
851 * not waiting to receive a connection close event and we want to
852 * automatically free the connection. We check to ensure our request
853 * list is empty one last time just in case our callback added a
856 if (free_evcon && TAILQ_FIRST(&evcon->requests) == NULL) {
857 evhttp_connection_free(evcon);
862 * Handles reading from a chunked request.
863 * return ALL_DATA_READ:
864 * all data has been read
865 * return MORE_DATA_EXPECTED:
866 * more data is expected
867 * return DATA_CORRUPTED:
869 * return REQUEST_CANCELED:
870 * request was canceled by the user calling evhttp_cancel_request
871 * return DATA_TOO_LONG:
872 * ran over the maximum limit
875 static enum message_read_status
876 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
878 if (req == NULL || buf == NULL) {
879 return DATA_CORRUPTED;
885 if ((buflen = evbuffer_get_length(buf)) == 0) {
889 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
890 * check for overflow conditions */
891 if (buflen > EV_SSIZE_MAX) {
892 return DATA_CORRUPTED;
895 if (req->ntoread < 0) {
896 /* Read chunk size */
898 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
903 /* the last chunk is on a new line? */
904 if (strlen(p) == 0) {
908 ntoread = evutil_strtoll(p, &endp, 16);
909 error = (*p == '\0' ||
910 (*endp != '\0' && *endp != ' ') ||
914 /* could not get chunk size */
915 return (DATA_CORRUPTED);
918 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
919 if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
920 return DATA_CORRUPTED;
923 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
924 /* failed body length test */
925 event_debug(("Request body is too long"));
926 return (DATA_TOO_LONG);
929 req->body_size += (size_t)ntoread;
930 req->ntoread = ntoread;
931 if (req->ntoread == 0) {
933 return (ALL_DATA_READ);
938 /* req->ntoread is signed int64, len is ssize_t, based on arch,
939 * ssize_t could only be 32b, check for these conditions */
940 if (req->ntoread > EV_SSIZE_MAX) {
941 return DATA_CORRUPTED;
944 /* don't have enough to complete a chunk; wait for more */
945 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
946 return (MORE_DATA_EXPECTED);
948 /* Completed chunk */
949 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
951 if (req->chunk_cb != NULL) {
952 req->flags |= EVHTTP_REQ_DEFER_FREE;
953 (*req->chunk_cb)(req, req->cb_arg);
954 evbuffer_drain(req->input_buffer,
955 evbuffer_get_length(req->input_buffer));
956 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
957 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
958 return (REQUEST_CANCELED);
963 return (MORE_DATA_EXPECTED);
967 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
969 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
971 switch (evhttp_parse_headers_(req, buf)) {
974 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
977 bufferevent_disable(evcon->bufev, EV_READ);
978 evhttp_connection_done(evcon);
980 case MORE_DATA_EXPECTED:
981 case REQUEST_CANCELED: /* ??? */
988 evhttp_lingering_close(struct evhttp_connection *evcon, struct evhttp_request *req)
990 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
992 size_t n = evbuffer_get_length(buf);
993 if (n > (size_t) req->ntoread)
994 n = (size_t) req->ntoread;
998 event_debug(("Request body is too long, left " EV_SIZE_FMT,
999 EV_SIZE_ARG(req->ntoread)));
1001 evbuffer_drain(buf, n);
1003 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1007 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1009 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1012 switch (evhttp_handle_chunked_read(req, buf)) {
1014 /* finished last chunk */
1015 evcon->state = EVCON_READING_TRAILER;
1016 evhttp_read_trailer(evcon, req);
1018 case DATA_CORRUPTED:
1020 /* corrupted data */
1021 evhttp_connection_fail_(evcon,
1022 EVREQ_HTTP_DATA_TOO_LONG);
1024 case REQUEST_CANCELED:
1025 /* request canceled */
1026 evhttp_request_free_auto(req);
1028 case MORE_DATA_EXPECTED:
1032 } else if (req->ntoread < 0) {
1033 /* Read until connection close. */
1034 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
1035 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
1039 req->body_size += evbuffer_get_length(buf);
1040 evbuffer_add_buffer(req->input_buffer, buf);
1041 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
1042 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
1043 /* We've postponed moving the data until now, but we're
1044 * about to use it. */
1045 size_t n = evbuffer_get_length(buf);
1047 if (n > (size_t) req->ntoread)
1048 n = (size_t) req->ntoread;
1050 req->body_size += n;
1051 evbuffer_remove_buffer(buf, req->input_buffer, n);
1054 if (req->body_size > req->evcon->max_body_size ||
1055 (!req->chunked && req->ntoread >= 0 &&
1056 (size_t)req->ntoread > req->evcon->max_body_size)) {
1057 /* XXX: The above casted comparison must checked for overflow */
1058 /* failed body length test */
1060 if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE)
1061 evhttp_lingering_close(evcon, req);
1063 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1068 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1069 req->flags |= EVHTTP_REQ_DEFER_FREE;
1070 (*req->chunk_cb)(req, req->cb_arg);
1071 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1072 evbuffer_drain(req->input_buffer,
1073 evbuffer_get_length(req->input_buffer));
1074 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1075 evhttp_request_free_auto(req);
1080 if (!req->ntoread) {
1081 bufferevent_disable(evcon->bufev, EV_READ);
1082 /* Completed content length */
1083 evhttp_connection_done(evcon);
1088 #define get_deferred_queue(evcon) \
1092 * Gets called when more data becomes available
1096 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1098 struct evhttp_connection *evcon = arg;
1099 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1101 /* Cancel if it's pending. */
1102 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1103 &evcon->read_more_deferred_cb);
1105 switch (evcon->state) {
1106 case EVCON_READING_FIRSTLINE:
1107 evhttp_read_firstline(evcon, req);
1108 /* note the request may have been freed in
1109 * evhttp_read_body */
1111 case EVCON_READING_HEADERS:
1112 evhttp_read_header(evcon, req);
1113 /* note the request may have been freed in
1114 * evhttp_read_body */
1116 case EVCON_READING_BODY:
1117 evhttp_read_body(evcon, req);
1118 /* note the request may have been freed in
1119 * evhttp_read_body */
1121 case EVCON_READING_TRAILER:
1122 evhttp_read_trailer(evcon, req);
1127 struct evbuffer *input;
1130 input = bufferevent_get_input(evcon->bufev);
1131 total_len = evbuffer_get_length(input);
1132 event_debug(("%s: read "EV_SIZE_FMT
1133 " bytes in EVCON_IDLE state,"
1134 " resetting connection",
1135 __func__, EV_SIZE_ARG(total_len)));
1138 evhttp_connection_reset_(evcon);
1141 case EVCON_DISCONNECTED:
1142 case EVCON_CONNECTING:
1145 event_errx(1, "%s: illegal connection state %d",
1146 __func__, evcon->state);
1151 evhttp_deferred_read_cb(struct event_callback *cb, void *data)
1153 struct evhttp_connection *evcon = data;
1154 evhttp_read_cb(evcon->bufev, evcon);
1158 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1160 /* This is after writing the request to the server */
1161 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1162 EVUTIL_ASSERT(req != NULL);
1164 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1166 /* We need to wait until we've written all of our output data before we can continue */
1167 if (evbuffer_get_length(bufferevent_get_output(evcon->bufev)) > 0) { return; }
1169 /* We are done writing our header and are now expecting the response */
1170 req->kind = EVHTTP_RESPONSE;
1172 evhttp_start_read_(evcon);
1176 * Clean up a connection object
1180 evhttp_connection_free(struct evhttp_connection *evcon)
1182 struct evhttp_request *req;
1184 /* notify interested parties that this connection is going down */
1185 if (evcon->fd != -1) {
1186 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1187 (*evcon->closecb)(evcon, evcon->closecb_arg);
1190 /* remove all requests that might be queued on this
1191 * connection. for server connections, this should be empty.
1192 * because it gets dequeued either in evhttp_connection_done or
1193 * evhttp_connection_fail_.
1195 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1196 evhttp_request_free_(evcon, req);
1199 if (evcon->http_server != NULL) {
1200 struct evhttp *http = evcon->http_server;
1201 TAILQ_REMOVE(&http->connections, evcon, next);
1204 if (event_initialized(&evcon->retry_ev)) {
1205 event_del(&evcon->retry_ev);
1206 event_debug_unassign(&evcon->retry_ev);
1209 if (evcon->bufev != NULL)
1210 bufferevent_free(evcon->bufev);
1212 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1213 &evcon->read_more_deferred_cb);
1215 if (evcon->fd != -1) {
1216 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
1217 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1218 if (!(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE)) {
1219 evutil_closesocket(evcon->fd);
1223 if (evcon->bind_address != NULL)
1224 mm_free(evcon->bind_address);
1226 if (evcon->address != NULL)
1227 mm_free(evcon->address);
1233 evhttp_connection_free_on_completion(struct evhttp_connection *evcon) {
1234 evcon->flags |= EVHTTP_CON_AUTOFREE;
1238 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1239 const char *address)
1241 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1242 if (evcon->bind_address)
1243 mm_free(evcon->bind_address);
1244 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1245 event_warn("%s: strdup", __func__);
1249 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1252 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1253 evcon->bind_port = port;
1257 evhttp_request_dispatch(struct evhttp_connection* evcon)
1259 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1261 /* this should not usually happy but it's possible */
1265 /* delete possible close detection events */
1266 evhttp_connection_stop_detectclose(evcon);
1268 /* we assume that the connection is connected already */
1269 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1271 evcon->state = EVCON_WRITING;
1273 /* Create the header from the store arguments */
1274 evhttp_make_header(evcon, req);
1276 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1279 /* Reset our connection state: disables reading/writing, closes our fd (if
1280 * any), clears out buffers, and puts us in state DISCONNECTED. */
1282 evhttp_connection_reset_(struct evhttp_connection *evcon)
1284 struct evbuffer *tmp;
1286 /* XXXX This is not actually an optimal fix. Instead we ought to have
1287 an API for "stop connecting", or use bufferevent_setfd to turn off
1288 connecting. But for Libevent 2.0, this seems like a minimal change
1289 least likely to disrupt the rest of the bufferevent and http code.
1291 Why is this here? If the fd is set in the bufferevent, and the
1292 bufferevent is connecting, then you can't actually stop the
1293 bufferevent from trying to connect with bufferevent_disable(). The
1294 connect will never trigger, since we close the fd, but the timeout
1295 might. That caused an assertion failure in evhttp_connection_fail_.
1297 bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE);
1299 if (evcon->fd != -1) {
1300 /* inform interested parties about connection close */
1301 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1302 (*evcon->closecb)(evcon, evcon->closecb_arg);
1304 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1305 evutil_closesocket(evcon->fd);
1306 bufferevent_setfd(evcon->bufev, -1);
1310 /* we need to clean up any buffered data */
1311 tmp = bufferevent_get_output(evcon->bufev);
1312 evbuffer_drain(tmp, evbuffer_get_length(tmp));
1313 tmp = bufferevent_get_input(evcon->bufev);
1314 evbuffer_drain(tmp, evbuffer_get_length(tmp));
1316 evcon->state = EVCON_DISCONNECTED;
1320 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1322 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1324 bufferevent_enable(evcon->bufev, EV_READ);
1328 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1330 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1332 bufferevent_disable(evcon->bufev, EV_READ);
1336 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1338 struct evhttp_connection *evcon = arg;
1340 evcon->state = EVCON_DISCONNECTED;
1341 evhttp_connection_connect_(evcon);
1345 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1347 struct evcon_requestq requests;
1349 evhttp_connection_reset_(evcon);
1350 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1351 struct timeval tv_retry = evcon->initial_retry_timeout;
1353 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1354 /* XXXX handle failure from evhttp_add_event */
1355 for (i=0; i < evcon->retry_cnt; ++i) {
1356 tv_retry.tv_usec *= 2;
1357 if (tv_retry.tv_usec > 1000000) {
1358 tv_retry.tv_usec -= 1000000;
1359 tv_retry.tv_sec += 1;
1361 tv_retry.tv_sec *= 2;
1362 if (tv_retry.tv_sec > 3600) {
1363 tv_retry.tv_sec = 3600;
1364 tv_retry.tv_usec = 0;
1367 event_add(&evcon->retry_ev, &tv_retry);
1373 * User callback can do evhttp_make_request() on the same
1374 * evcon so new request will be added to evcon->requests. To
1375 * avoid freeing it prematurely we iterate over the copy of
1378 TAILQ_INIT(&requests);
1379 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1380 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1381 TAILQ_REMOVE(&evcon->requests, request, next);
1382 TAILQ_INSERT_TAIL(&requests, request, next);
1385 /* for now, we just signal all requests by executing their callbacks */
1386 while (TAILQ_FIRST(&requests) != NULL) {
1387 struct evhttp_request *request = TAILQ_FIRST(&requests);
1388 TAILQ_REMOVE(&requests, request, next);
1389 request->evcon = NULL;
1391 /* we might want to set an error here */
1392 request->cb(request, request->cb_arg);
1393 evhttp_request_free_auto(request);
1398 evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
1399 struct evhttp_request *req)
1401 struct evbuffer *buf;
1403 evcon->state = EVCON_READING_FIRSTLINE;
1404 req->kind = EVHTTP_RESPONSE;
1406 buf = bufferevent_get_output(evcon->bufev);
1407 evbuffer_unfreeze(buf, 1);
1408 evbuffer_drain(buf, evbuffer_get_length(buf));
1409 evbuffer_freeze(buf, 1);
1411 bufferevent_setcb(evcon->bufev,
1413 NULL, /* evhttp_write_cb */
1416 evhttp_connection_start_detectclose(evcon);
1420 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1422 struct evhttp_connection *evcon = arg;
1423 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1425 if (evcon->fd == -1)
1426 evcon->fd = bufferevent_getfd(bufev);
1428 switch (evcon->state) {
1429 case EVCON_CONNECTING:
1430 if (what & BEV_EVENT_TIMEOUT) {
1431 event_debug(("%s: connection timeout for \"%s:%d\" on "
1433 __func__, evcon->address, evcon->port,
1434 EV_SOCK_ARG(evcon->fd)));
1435 evhttp_connection_cb_cleanup(evcon);
1440 case EVCON_READING_BODY:
1441 if (!req->chunked && req->ntoread < 0
1442 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1443 /* EOF on read can be benign */
1444 evhttp_connection_done(evcon);
1449 case EVCON_DISCONNECTED:
1451 case EVCON_READING_FIRSTLINE:
1452 case EVCON_READING_HEADERS:
1453 case EVCON_READING_TRAILER:
1459 /* when we are in close detect mode, a read error means that
1460 * the other side closed their connection.
1462 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1463 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1464 EVUTIL_ASSERT(evcon->http_server == NULL);
1465 /* For connections from the client, we just
1466 * reset the connection so that it becomes
1469 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1470 evhttp_connection_reset_(evcon);
1473 * If we have no more requests that need completion
1474 * and we want to auto-free the connection when all
1475 * requests have been completed.
1477 if (TAILQ_FIRST(&evcon->requests) == NULL
1478 && (evcon->flags & EVHTTP_CON_OUTGOING)
1479 && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1480 evhttp_connection_free(evcon);
1485 if (what & BEV_EVENT_TIMEOUT) {
1486 evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
1487 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1488 if (what & BEV_EVENT_WRITING &&
1489 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR) {
1490 evhttp_connection_read_on_write_error(evcon, req);
1494 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1495 } else if (what == BEV_EVENT_CONNECTED) {
1497 evhttp_connection_fail_(evcon, EVREQ_HTTP_BUFFER_ERROR);
1502 * Event callback for asynchronous connection attempt.
1505 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1507 struct evhttp_connection *evcon = arg;
1509 ev_socklen_t errsz = sizeof(error);
1511 if (evcon->fd == -1)
1512 evcon->fd = bufferevent_getfd(bufev);
1514 if (!(what & BEV_EVENT_CONNECTED)) {
1515 /* some operating systems return ECONNREFUSED immediately
1516 * when connecting to a local address. the cleanup is going
1517 * to reschedule this function call.
1520 if (errno == ECONNREFUSED)
1523 evhttp_error_cb(bufev, what, arg);
1527 if (evcon->fd == -1) {
1528 event_debug(("%s: bufferevent_getfd returned -1",
1533 /* Check if the connection completed */
1534 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1536 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT,
1537 __func__, evcon->address, evcon->port,
1538 EV_SOCK_ARG(evcon->fd)));
1543 event_debug(("%s: connect failed for \"%s:%d\" on "
1545 __func__, evcon->address, evcon->port,
1546 EV_SOCK_ARG(evcon->fd),
1547 evutil_socket_error_to_string(error)));
1551 /* We are connected to the server now */
1552 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1553 __func__, evcon->address, evcon->port,
1554 EV_SOCK_ARG(evcon->fd)));
1556 /* Reset the retry count as we were successful in connecting */
1557 evcon->retry_cnt = 0;
1558 evcon->state = EVCON_IDLE;
1560 /* reset the bufferevent cbs */
1561 bufferevent_setcb(evcon->bufev,
1567 if (!evutil_timerisset(&evcon->timeout)) {
1568 const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 };
1569 const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 };
1570 bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv);
1572 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
1575 /* try to start requests that have queued up on this connection */
1576 evhttp_request_dispatch(evcon);
1580 evhttp_connection_cb_cleanup(evcon);
1584 * Check if we got a valid response code.
1588 evhttp_valid_response_code(int code)
1597 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1601 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1602 if (n != 2 || major > 1) {
1603 event_debug(("%s: bad version %s on message %p from %s",
1604 __func__, version, req, req->remote_host));
1612 /* Parses the status line of a web server */
1615 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1619 const char *readable = "";
1621 protocol = strsep(&line, " ");
1624 number = strsep(&line, " ");
1628 if (evhttp_parse_http_version(protocol, req) < 0)
1631 req->response_code = atoi(number);
1632 if (!evhttp_valid_response_code(req->response_code)) {
1633 event_debug(("%s: bad response code \"%s\"",
1638 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1639 event_warn("%s: strdup", __func__);
1646 /* Parse the first line of a HTTP request */
1649 evhttp_parse_request_line(struct evhttp_request *req, char *line)
1654 const char *hostname;
1657 enum evhttp_cmd_type type;
1659 /* Parse the request line */
1660 method = strsep(&line, " ");
1663 uri = strsep(&line, " ");
1666 version = strsep(&line, " ");
1670 method_len = (uri - method) - 1;
1671 type = EVHTTP_REQ_UNKNOWN_;
1674 switch (method_len) {
1676 /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1678 /* Since both GET and PUT share the same character 'T' at the end,
1679 * if the string doesn't have 'T', we can immediately determine this
1680 * is an invalid HTTP method */
1682 if (method[2] != 'T') {
1688 /* This first byte is 'G', so make sure the next byte is
1689 * 'E', if it isn't then this isn't a valid method */
1691 if (method[1] == 'E') {
1692 type = EVHTTP_REQ_GET;
1697 /* First byte is P, check second byte for 'U', if not,
1698 * we know it's an invalid method */
1699 if (method[1] == 'U') {
1700 type = EVHTTP_REQ_PUT;
1708 /* The method length is 4 bytes, leaving only the methods "POST" and "HEAD" */
1711 if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') {
1712 type = EVHTTP_REQ_POST;
1716 if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') {
1717 type = EVHTTP_REQ_HEAD;
1725 /* Method length is 5 bytes, which can only encompass PATCH and TRACE */
1728 if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') {
1729 type = EVHTTP_REQ_PATCH;
1733 if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') {
1734 type = EVHTTP_REQ_TRACE;
1743 /* Method length is 6, only valid method 6 bytes in length is DELEte */
1745 /* If the first byte isn't 'D' then it's invalid */
1746 if (*method != 'D') {
1750 if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' && method[2] == 'L' && method[1] == 'E') {
1751 type = EVHTTP_REQ_DELETE;
1756 /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1759 if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' &&
1760 method[3] == 'I' && method[2] == 'T' && method[1] == 'P') {
1761 type = EVHTTP_REQ_OPTIONS;
1766 if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' &&
1767 method[3] == 'N' && method[2] == 'N' && method[1] == 'O') {
1768 type = EVHTTP_REQ_CONNECT;
1778 if ((int)type == EVHTTP_REQ_UNKNOWN_) {
1779 event_debug(("%s: bad method %s on request %p from %s",
1780 __func__, method, req, req->remote_host));
1781 /* No error yet; we'll give a better error later when
1782 * we see that req->type is unsupported. */
1787 if (evhttp_parse_http_version(version, req) < 0)
1790 if ((req->uri = mm_strdup(uri)) == NULL) {
1791 event_debug(("%s: mm_strdup", __func__));
1795 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
1796 EVHTTP_URI_NONCONFORMANT)) == NULL) {
1800 /* If we have an absolute-URI, check to see if it is an http request
1801 for a known vhost or server alias. If we don't know about this
1802 host, we consider it a proxy request. */
1803 scheme = evhttp_uri_get_scheme(req->uri_elems);
1804 hostname = evhttp_uri_get_host(req->uri_elems);
1805 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1806 !evutil_ascii_strcasecmp(scheme, "https")) &&
1808 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1809 req->flags |= EVHTTP_PROXY_REQUEST;
1815 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1817 struct evkeyval *header;
1819 TAILQ_FOREACH(header, headers, next) {
1820 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1821 return (header->value);
1828 evhttp_clear_headers(struct evkeyvalq *headers)
1830 struct evkeyval *header;
1832 for (header = TAILQ_FIRST(headers);
1834 header = TAILQ_FIRST(headers)) {
1835 TAILQ_REMOVE(headers, header, next);
1836 mm_free(header->key);
1837 mm_free(header->value);
1843 * Returns 0, if the header was successfully removed.
1844 * Returns -1, if the header could not be found.
1848 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1850 struct evkeyval *header;
1852 TAILQ_FOREACH(header, headers, next) {
1853 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1860 /* Free and remove the header that we found */
1861 TAILQ_REMOVE(headers, header, next);
1862 mm_free(header->key);
1863 mm_free(header->value);
1870 evhttp_header_is_valid_value(const char *value)
1872 const char *p = value;
1874 while ((p = strpbrk(p, "\r\n")) != NULL) {
1875 /* we really expect only one new line */
1876 p += strspn(p, "\r\n");
1877 /* we expect a space or tab for continuation */
1878 if (*p != ' ' && *p != '\t')
1885 evhttp_add_header(struct evkeyvalq *headers,
1886 const char *key, const char *value)
1888 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1890 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1891 /* drop illegal headers */
1892 event_debug(("%s: dropping illegal header key\n", __func__));
1896 if (!evhttp_header_is_valid_value(value)) {
1897 event_debug(("%s: dropping illegal header value\n", __func__));
1901 return (evhttp_add_header_internal(headers, key, value));
1905 evhttp_add_header_internal(struct evkeyvalq *headers,
1906 const char *key, const char *value)
1908 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
1909 if (header == NULL) {
1910 event_warn("%s: calloc", __func__);
1913 if ((header->key = mm_strdup(key)) == NULL) {
1915 event_warn("%s: strdup", __func__);
1918 if ((header->value = mm_strdup(value)) == NULL) {
1919 mm_free(header->key);
1921 event_warn("%s: strdup", __func__);
1925 TAILQ_INSERT_TAIL(headers, header, next);
1931 * Parses header lines from a request or a response into the specified
1932 * request object given an event buffer.
1935 * DATA_CORRUPTED on error
1936 * MORE_DATA_EXPECTED when we need to read more headers
1937 * ALL_DATA_READ when all headers have been read.
1940 enum message_read_status
1941 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
1944 enum message_read_status status = ALL_DATA_READ;
1948 line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF);
1950 if (req->evcon != NULL &&
1951 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1952 return (DATA_TOO_LONG);
1954 return (MORE_DATA_EXPECTED);
1957 if (req->evcon != NULL &&
1958 line_length > req->evcon->max_headers_size) {
1960 return (DATA_TOO_LONG);
1963 req->headers_size = line_length;
1965 switch (req->kind) {
1966 case EVHTTP_REQUEST:
1967 if (evhttp_parse_request_line(req, line) == -1)
1968 status = DATA_CORRUPTED;
1970 case EVHTTP_RESPONSE:
1971 if (evhttp_parse_response_line(req, line) == -1)
1972 status = DATA_CORRUPTED;
1975 status = DATA_CORRUPTED;
1983 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
1985 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
1987 size_t old_len, line_len;
1992 old_len = strlen(header->value);
1994 /* Strip space from start and end of line. */
1995 while (*line == ' ' || *line == '\t')
1997 evutil_rtrim_lws_(line);
1999 line_len = strlen(line);
2001 newval = mm_realloc(header->value, old_len + line_len + 2);
2005 newval[old_len] = ' ';
2006 memcpy(newval + old_len + 1, line, line_len + 1);
2007 header->value = newval;
2012 enum message_read_status
2013 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
2015 enum message_read_status errcode = DATA_CORRUPTED;
2017 enum message_read_status status = MORE_DATA_EXPECTED;
2019 struct evkeyvalq* headers = req->input_headers;
2021 while ((line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF))
2023 char *skey, *svalue;
2025 req->headers_size += line_length;
2027 if (req->evcon != NULL &&
2028 req->headers_size > req->evcon->max_headers_size) {
2029 errcode = DATA_TOO_LONG;
2033 if (*line == '\0') { /* Last header - Done */
2034 status = ALL_DATA_READ;
2039 /* Check if this is a continuation line */
2040 if (*line == ' ' || *line == '\t') {
2041 if (evhttp_append_to_last_header(headers, line) == -1)
2047 /* Processing of header lines */
2049 skey = strsep(&svalue, ":");
2053 svalue += strspn(svalue, " ");
2054 evutil_rtrim_lws_(svalue);
2056 if (evhttp_add_header(headers, skey, svalue) == -1)
2062 if (status == MORE_DATA_EXPECTED) {
2063 if (req->evcon != NULL &&
2064 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2065 return (DATA_TOO_LONG);
2076 evhttp_get_body_length(struct evhttp_request *req)
2078 struct evkeyvalq *headers = req->input_headers;
2079 const char *content_length;
2080 const char *connection;
2082 content_length = evhttp_find_header(headers, "Content-Length");
2083 connection = evhttp_find_header(headers, "Connection");
2085 if (content_length == NULL && connection == NULL)
2087 else if (content_length == NULL &&
2088 evutil_ascii_strcasecmp(connection, "Close") != 0) {
2089 /* Bad combination, we don't know when it will end */
2090 event_warnx("%s: we got no content length, but the "
2091 "server wants to keep the connection open: %s.",
2092 __func__, connection);
2094 } else if (content_length == NULL) {
2098 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2099 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2100 event_debug(("%s: illegal content length: %s",
2101 __func__, content_length));
2104 req->ntoread = ntoread;
2107 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2108 __func__, EV_I64_ARG(req->ntoread),
2109 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2115 evhttp_method_may_have_body(enum evhttp_cmd_type type)
2118 case EVHTTP_REQ_POST:
2119 case EVHTTP_REQ_PUT:
2120 case EVHTTP_REQ_PATCH:
2122 case EVHTTP_REQ_TRACE:
2124 /* XXX May any of the below methods have a body? */
2125 case EVHTTP_REQ_GET:
2126 case EVHTTP_REQ_HEAD:
2127 case EVHTTP_REQ_DELETE:
2128 case EVHTTP_REQ_OPTIONS:
2129 case EVHTTP_REQ_CONNECT:
2137 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2139 const char *xfer_enc;
2141 /* If this is a request without a body, then we are done */
2142 if (req->kind == EVHTTP_REQUEST &&
2143 !evhttp_method_may_have_body(req->type)) {
2144 evhttp_connection_done(evcon);
2147 evcon->state = EVCON_READING_BODY;
2148 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
2149 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
2153 if (evhttp_get_body_length(req) == -1) {
2154 evhttp_connection_fail_(evcon,
2155 EVREQ_HTTP_INVALID_HEADER);
2158 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2159 /* An incoming request with no content-length and no
2160 * transfer-encoding has no body. */
2161 evhttp_connection_done(evcon);
2166 /* Should we send a 100 Continue status line? */
2167 if (req->kind == EVHTTP_REQUEST && REQ_VERSION_ATLEAST(req, 1, 1)) {
2170 expect = evhttp_find_header(req->input_headers, "Expect");
2172 if (!evutil_ascii_strcasecmp(expect, "100-continue")) {
2173 /* XXX It would be nice to do some sanity
2174 checking here. Does the resource exist?
2175 Should the resource accept post requests? If
2176 no, we should respond with an error. For
2177 now, just optimistically tell the client to
2178 send their message body. */
2179 if (req->ntoread > 0) {
2180 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2181 if ((req->evcon->max_body_size <= EV_INT64_MAX) && (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2182 evhttp_send_error(req, HTTP_ENTITYTOOLARGE, NULL);
2186 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2187 evhttp_send_continue(evcon, req);
2189 evhttp_send_error(req, HTTP_EXPECTATIONFAILED,
2196 evhttp_read_body(evcon, req);
2197 /* note the request may have been freed in evhttp_read_body */
2201 evhttp_read_firstline(struct evhttp_connection *evcon,
2202 struct evhttp_request *req)
2204 enum message_read_status res;
2206 res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2207 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2208 /* Error while reading, terminate */
2209 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2210 __func__, EV_SOCK_ARG(evcon->fd)));
2211 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2213 } else if (res == MORE_DATA_EXPECTED) {
2214 /* Need more header lines */
2218 evcon->state = EVCON_READING_HEADERS;
2219 evhttp_read_header(evcon, req);
2223 evhttp_read_header(struct evhttp_connection *evcon,
2224 struct evhttp_request *req)
2226 enum message_read_status res;
2227 evutil_socket_t fd = evcon->fd;
2229 res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2230 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2231 /* Error while reading, terminate */
2232 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2233 __func__, EV_SOCK_ARG(fd)));
2234 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2236 } else if (res == MORE_DATA_EXPECTED) {
2237 /* Need more header lines */
2241 /* Callback can shut down connection with negative return value */
2242 if (req->header_cb != NULL) {
2243 if ((*req->header_cb)(req, req->cb_arg) < 0) {
2244 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2249 /* Done reading headers, do the real work */
2250 switch (req->kind) {
2251 case EVHTTP_REQUEST:
2252 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2253 __func__, EV_SOCK_ARG(fd)));
2254 evhttp_get_body(evcon, req);
2255 /* note the request may have been freed in evhttp_get_body */
2258 case EVHTTP_RESPONSE:
2259 /* Start over if we got a 100 Continue response. */
2260 if (req->response_code == 100) {
2261 evhttp_start_read_(evcon);
2264 if (!evhttp_response_needs_body(req)) {
2265 event_debug(("%s: skipping body for code %d\n",
2266 __func__, req->response_code));
2267 evhttp_connection_done(evcon);
2269 event_debug(("%s: start of read body for %s on "
2271 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2272 evhttp_get_body(evcon, req);
2273 /* note the request may have been freed in
2274 * evhttp_get_body */
2279 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2281 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2284 /* request may have been freed above */
2288 * Creates a TCP connection to the specified port and executes a callback
2289 * when finished. Failure or success is indicate by the passed connection
2292 * Although this interface accepts a hostname, it is intended to take
2293 * only numeric hostnames so that non-blocking DNS resolution can
2297 struct evhttp_connection *
2298 evhttp_connection_new(const char *address, unsigned short port)
2300 return (evhttp_connection_base_new(NULL, NULL, address, port));
2303 struct evhttp_connection *
2304 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2305 const char *address, unsigned short port)
2307 struct evhttp_connection *evcon = NULL;
2309 event_debug(("Attempting connection to %s:%d\n", address, port));
2311 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2312 event_warn("%s: calloc failed", __func__);
2319 evcon->max_headers_size = EV_SIZE_MAX;
2320 evcon->max_body_size = EV_SIZE_MAX;
2322 evutil_timerclear(&evcon->timeout);
2323 evcon->retry_cnt = evcon->retry_max = 0;
2325 if ((evcon->address = mm_strdup(address)) == NULL) {
2326 event_warn("%s: strdup failed", __func__);
2331 if (!(bev = bufferevent_socket_new(base, -1, 0))) {
2332 event_warn("%s: bufferevent_socket_new failed", __func__);
2337 bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2340 evcon->state = EVCON_DISCONNECTED;
2341 TAILQ_INIT(&evcon->requests);
2343 evcon->initial_retry_timeout.tv_sec = 2;
2344 evcon->initial_retry_timeout.tv_usec = 0;
2348 if (bufferevent_get_base(bev) != base)
2349 bufferevent_base_set(base, evcon->bufev);
2352 event_deferred_cb_init_(
2353 &evcon->read_more_deferred_cb,
2354 bufferevent_get_priority(bev),
2355 evhttp_deferred_read_cb, evcon);
2357 evcon->dns_base = dnsbase;
2358 evcon->ai_family = AF_UNSPEC;
2364 evhttp_connection_free(evcon);
2368 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2370 return evcon->bufev;
2374 evhttp_connection_get_server(struct evhttp_connection *evcon)
2376 return evcon->http_server;
2379 struct evhttp_connection *
2380 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2381 const char *address, unsigned short port)
2383 return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2386 void evhttp_connection_set_family(struct evhttp_connection *evcon,
2389 evcon->ai_family = family;
2392 int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2395 int avail_flags = 0;
2396 avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2397 avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2399 if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2401 evcon->flags &= ~avail_flags;
2403 evcon->flags |= flags;
2409 evhttp_connection_set_base(struct evhttp_connection *evcon,
2410 struct event_base *base)
2412 EVUTIL_ASSERT(evcon->base == NULL);
2413 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2415 bufferevent_base_set(base, evcon->bufev);
2419 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2420 int timeout_in_secs)
2422 if (timeout_in_secs == -1)
2423 evhttp_connection_set_timeout_tv(evcon, NULL);
2426 tv.tv_sec = timeout_in_secs;
2428 evhttp_connection_set_timeout_tv(evcon, &tv);
2433 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2434 const struct timeval* tv)
2437 evcon->timeout = *tv;
2438 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
2440 const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 };
2441 const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 };
2442 evutil_timerclear(&evcon->timeout);
2443 bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv);
2448 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2449 const struct timeval *tv)
2452 evcon->initial_retry_timeout = *tv;
2454 evutil_timerclear(&evcon->initial_retry_timeout);
2455 evcon->initial_retry_timeout.tv_sec = 2;
2460 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2463 evcon->retry_max = retry_max;
2467 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2468 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2470 evcon->closecb = cb;
2471 evcon->closecb_arg = cbarg;
2475 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2476 char **address, ev_uint16_t *port)
2478 *address = evcon->address;
2479 *port = evcon->port;
2482 const struct sockaddr*
2483 evhttp_connection_get_addr(struct evhttp_connection *evcon)
2485 return bufferevent_socket_get_conn_address_(evcon->bufev);
2489 evhttp_connection_connect_(struct evhttp_connection *evcon)
2491 int old_state = evcon->state;
2492 const char *address = evcon->address;
2493 const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
2496 if (evcon->state == EVCON_CONNECTING)
2499 evhttp_connection_reset_(evcon);
2501 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2502 evcon->flags |= EVHTTP_CON_OUTGOING;
2504 if (evcon->bind_address || evcon->bind_port) {
2505 evcon->fd = bind_socket(
2506 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2507 if (evcon->fd == -1) {
2508 event_debug(("%s: failed to bind to \"%s\"",
2509 __func__, evcon->bind_address));
2513 bufferevent_setfd(evcon->bufev, evcon->fd);
2515 bufferevent_setfd(evcon->bufev, -1);
2518 /* Set up a callback for successful connection setup */
2519 bufferevent_setcb(evcon->bufev,
2520 NULL /* evhttp_read_cb */,
2521 NULL /* evhttp_write_cb */,
2522 evhttp_connection_cb,
2524 if (!evutil_timerisset(&evcon->timeout)) {
2525 const struct timeval conn_tv = { HTTP_CONNECT_TIMEOUT, 0 };
2526 bufferevent_set_timeouts(evcon->bufev, &conn_tv, &conn_tv);
2528 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout);
2530 /* make sure that we get a write callback */
2531 bufferevent_enable(evcon->bufev, EV_WRITE);
2533 evcon->state = EVCON_CONNECTING;
2535 if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
2537 (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
2538 int socklen = sizeof(struct sockaddr_in);
2539 if (sa->sa_family == AF_INET6) {
2540 socklen = sizeof(struct sockaddr_in6);
2542 ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
2544 ret = bufferevent_socket_connect_hostname(evcon->bufev,
2545 evcon->dns_base, evcon->ai_family, address, evcon->port);
2549 evcon->state = old_state;
2550 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2551 __func__, evcon->address);
2552 /* some operating systems return ECONNREFUSED immediately
2553 * when connecting to a local address. the cleanup is going
2554 * to reschedule this function call.
2556 evhttp_connection_cb_cleanup(evcon);
2564 * Starts an HTTP request on the provided evhttp_connection object.
2565 * If the connection object is not connected to the web server already,
2566 * this will start the connection.
2570 evhttp_make_request(struct evhttp_connection *evcon,
2571 struct evhttp_request *req,
2572 enum evhttp_cmd_type type, const char *uri)
2574 /* We are making a request */
2575 req->kind = EVHTTP_REQUEST;
2577 if (req->uri != NULL)
2579 if ((req->uri = mm_strdup(uri)) == NULL) {
2580 event_warn("%s: strdup", __func__);
2581 evhttp_request_free_auto(req);
2585 /* Set the protocol version if it is not supplied */
2586 if (!req->major && !req->minor) {
2591 EVUTIL_ASSERT(req->evcon == NULL);
2593 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2595 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2597 /* If the connection object is not connected; make it so */
2598 if (!evhttp_connected(evcon)) {
2599 int res = evhttp_connection_connect_(evcon);
2600 /* evhttp_connection_fail_(), which is called through
2601 * evhttp_connection_connect_(), assumes that req lies in
2602 * evcon->requests. Thus, enqueue the request in advance and
2603 * remove it in the error case. */
2605 TAILQ_REMOVE(&evcon->requests, req, next);
2611 * If it's connected already and we are the first in the queue,
2612 * then we can dispatch this request immediately. Otherwise, it
2613 * will be dispatched once the pending requests are completed.
2615 if (TAILQ_FIRST(&evcon->requests) == req)
2616 evhttp_request_dispatch(evcon);
2622 evhttp_cancel_request(struct evhttp_request *req)
2624 struct evhttp_connection *evcon = req->evcon;
2625 if (evcon != NULL) {
2626 /* We need to remove it from the connection */
2627 if (TAILQ_FIRST(&evcon->requests) == req) {
2628 /* it's currently being worked on, so reset
2631 evhttp_connection_fail_(evcon,
2632 EVREQ_HTTP_REQUEST_CANCEL);
2634 /* connection fail freed the request */
2637 /* otherwise, we can just remove it from the
2640 TAILQ_REMOVE(&evcon->requests, req, next);
2644 evhttp_request_free_auto(req);
2648 * Reads data from file descriptor into request structure
2649 * Request structure needs to be set up correctly.
2653 evhttp_start_read_(struct evhttp_connection *evcon)
2655 bufferevent_disable(evcon->bufev, EV_WRITE);
2656 bufferevent_enable(evcon->bufev, EV_READ);
2658 evcon->state = EVCON_READING_FIRSTLINE;
2659 /* Reset the bufferevent callbacks */
2660 bufferevent_setcb(evcon->bufev,
2666 /* If there's still data pending, process it next time through the
2667 * loop. Don't do it now; that could get recusive. */
2668 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2669 event_deferred_cb_schedule_(get_deferred_queue(evcon),
2670 &evcon->read_more_deferred_cb);
2675 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2678 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2679 TAILQ_REMOVE(&evcon->requests, req, next);
2681 if (req->on_complete_cb != NULL) {
2682 req->on_complete_cb(req, req->on_complete_cb_arg);
2686 (REQ_VERSION_BEFORE(req, 1, 1) &&
2687 !evhttp_is_connection_keepalive(req->input_headers)) ||
2688 evhttp_is_request_connection_close(req);
2690 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2691 evhttp_request_free(req);
2694 evhttp_connection_free(evcon);
2698 /* we have a persistent connection; try to accept another request. */
2699 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2700 evhttp_connection_free(evcon);
2705 * Returns an error page.
2709 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2712 #define ERR_FORMAT "<HTML><HEAD>\n" \
2713 "<TITLE>%d %s</TITLE>\n" \
2718 struct evbuffer *buf = evbuffer_new();
2720 /* if we cannot allocate memory; we just drop the connection */
2721 evhttp_connection_free(req->evcon);
2724 if (reason == NULL) {
2725 reason = evhttp_response_phrase_internal(error);
2728 evhttp_response_code_(req, error, reason);
2730 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2732 evhttp_send_page_(req, buf);
2738 /* Requires that headers and response code are already set up */
2741 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2743 struct evhttp_connection *evcon = req->evcon;
2745 if (evcon == NULL) {
2746 evhttp_request_free(req);
2750 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2752 /* we expect no more calls form the user on this request */
2755 /* xxx: not sure if we really should expose the data buffer this way */
2756 if (databuf != NULL)
2757 evbuffer_add_buffer(req->output_buffer, databuf);
2759 /* Adds headers to the response */
2760 evhttp_make_header(evcon, req);
2762 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2766 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2767 struct evbuffer *databuf)
2769 evhttp_response_code_(req, code, reason);
2771 evhttp_send(req, databuf);
2775 evhttp_send_reply_start(struct evhttp_request *req, int code,
2778 evhttp_response_code_(req, code, reason);
2779 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2780 REQ_VERSION_ATLEAST(req, 1, 1) &&
2781 evhttp_response_needs_body(req)) {
2783 * prefer HTTP/1.1 chunked encoding to closing the connection;
2784 * note RFC 2616 section 4.4 forbids it with Content-Length:
2785 * and it's not necessary then anyway.
2787 evhttp_add_header(req->output_headers, "Transfer-Encoding",
2793 evhttp_make_header(req->evcon, req);
2794 evhttp_write_buffer(req->evcon, NULL, NULL);
2798 evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
2799 void (*cb)(struct evhttp_connection *, void *), void *arg)
2801 struct evhttp_connection *evcon = req->evcon;
2802 struct evbuffer *output;
2807 output = bufferevent_get_output(evcon->bufev);
2809 if (evbuffer_get_length(databuf) == 0)
2811 if (!evhttp_response_needs_body(req))
2814 evbuffer_add_printf(output, "%x\r\n",
2815 (unsigned)evbuffer_get_length(databuf));
2817 evbuffer_add_buffer(output, databuf);
2819 evbuffer_add(output, "\r\n", 2);
2821 evhttp_write_buffer(evcon, cb, arg);
2825 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
2827 evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
2830 evhttp_send_reply_end(struct evhttp_request *req)
2832 struct evhttp_connection *evcon = req->evcon;
2833 struct evbuffer *output;
2835 if (evcon == NULL) {
2836 evhttp_request_free(req);
2840 output = bufferevent_get_output(evcon->bufev);
2842 /* we expect no more calls form the user on this request */
2846 evbuffer_add(output, "0\r\n\r\n", 5);
2847 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2849 } else if (evbuffer_get_length(output) == 0) {
2850 /* let the connection know that we are done with the request */
2851 evhttp_send_done(evcon, NULL);
2853 /* make the callback execute after all data has been written */
2854 evcon->cb = evhttp_send_done;
2855 evcon->cb_arg = NULL;
2859 static const char *informational_phrases[] = {
2860 /* 100 */ "Continue",
2861 /* 101 */ "Switching Protocols"
2864 static const char *success_phrases[] = {
2866 /* 201 */ "Created",
2867 /* 202 */ "Accepted",
2868 /* 203 */ "Non-Authoritative Information",
2869 /* 204 */ "No Content",
2870 /* 205 */ "Reset Content",
2871 /* 206 */ "Partial Content"
2874 static const char *redirection_phrases[] = {
2875 /* 300 */ "Multiple Choices",
2876 /* 301 */ "Moved Permanently",
2878 /* 303 */ "See Other",
2879 /* 304 */ "Not Modified",
2880 /* 305 */ "Use Proxy",
2881 /* 307 */ "Temporary Redirect"
2884 static const char *client_error_phrases[] = {
2885 /* 400 */ "Bad Request",
2886 /* 401 */ "Unauthorized",
2887 /* 402 */ "Payment Required",
2888 /* 403 */ "Forbidden",
2889 /* 404 */ "Not Found",
2890 /* 405 */ "Method Not Allowed",
2891 /* 406 */ "Not Acceptable",
2892 /* 407 */ "Proxy Authentication Required",
2893 /* 408 */ "Request Time-out",
2894 /* 409 */ "Conflict",
2896 /* 411 */ "Length Required",
2897 /* 412 */ "Precondition Failed",
2898 /* 413 */ "Request Entity Too Large",
2899 /* 414 */ "Request-URI Too Large",
2900 /* 415 */ "Unsupported Media Type",
2901 /* 416 */ "Requested range not satisfiable",
2902 /* 417 */ "Expectation Failed"
2905 static const char *server_error_phrases[] = {
2906 /* 500 */ "Internal Server Error",
2907 /* 501 */ "Not Implemented",
2908 /* 502 */ "Bad Gateway",
2909 /* 503 */ "Service Unavailable",
2910 /* 504 */ "Gateway Time-out",
2911 /* 505 */ "HTTP Version not supported"
2914 struct response_class {
2916 size_t num_responses;
2917 const char **responses;
2921 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
2924 static const struct response_class response_classes[] = {
2925 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
2926 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
2927 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
2928 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
2929 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
2933 evhttp_response_phrase_internal(int code)
2935 int klass = code / 100 - 1;
2936 int subcode = code % 100;
2938 /* Unknown class - can't do any better here */
2939 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
2940 return "Unknown Status Class";
2942 /* Unknown sub-code, return class name at least */
2943 if (subcode >= (int) response_classes[klass].num_responses)
2944 return response_classes[klass].name;
2946 return response_classes[klass].responses[subcode];
2950 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
2952 req->kind = EVHTTP_RESPONSE;
2953 req->response_code = code;
2954 if (req->response_code_line != NULL)
2955 mm_free(req->response_code_line);
2957 reason = evhttp_response_phrase_internal(code);
2958 req->response_code_line = mm_strdup(reason);
2959 if (req->response_code_line == NULL) {
2960 event_warn("%s: strdup", __func__);
2961 /* XXX what else can we do? */
2966 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
2968 if (!req->major || !req->minor) {
2973 if (req->kind != EVHTTP_RESPONSE)
2974 evhttp_response_code_(req, 200, "OK");
2976 evhttp_clear_headers(req->output_headers);
2977 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
2978 evhttp_add_header(req->output_headers, "Connection", "close");
2980 evhttp_send(req, databuf);
2983 static const char uri_chars[256] = {
2985 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2986 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2987 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
2988 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
2990 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2991 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
2992 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2993 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
2995 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2996 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2997 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2998 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3000 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3001 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3002 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3003 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3006 #define CHAR_IS_UNRESERVED(c) \
3007 (uri_chars[(unsigned char)(c)])
3010 * Helper functions to encode/decode a string for inclusion in a URI.
3011 * The returned string must be freed by the caller.
3014 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3016 struct evbuffer *buf = evbuffer_new();
3017 const char *p, *end;
3026 end = uri+strlen(uri);
3028 for (p = uri; p < end; p++) {
3029 if (CHAR_IS_UNRESERVED(*p)) {
3030 evbuffer_add(buf, p, 1);
3031 } else if (*p == ' ' && space_as_plus) {
3032 evbuffer_add(buf, "+", 1);
3034 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3037 evbuffer_add(buf, "", 1); /* NUL-terminator. */
3038 result = mm_malloc(evbuffer_get_length(buf));
3040 evbuffer_remove(buf, result, evbuffer_get_length(buf));
3047 evhttp_encode_uri(const char *str)
3049 return evhttp_uriencode(str, -1, 0);
3053 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
3054 * If -1, when true we transform plus to space only after we've seen
3055 * a ?. -1 is deprecated.
3056 * @return the number of bytes written to 'ret'.
3059 evhttp_decode_uri_internal(
3060 const char *uri, size_t length, char *ret, int decode_plus_ctl)
3064 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3067 for (i = j = 0; i < length; i++) {
3070 if (decode_plus_ctl < 0)
3072 } else if (c == '+' && decode_plus) {
3074 } else if ((i + 2) < length && c == '%' &&
3075 EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3080 c = (char)strtol(tmp, NULL, 16);
3092 evhttp_decode_uri(const char *uri)
3096 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3097 event_warn("%s: malloc(%lu)", __func__,
3098 (unsigned long)(strlen(uri) + 1));
3102 evhttp_decode_uri_internal(uri, strlen(uri),
3103 ret, -1 /*always_decode_plus*/);
3109 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3114 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3115 event_warn("%s: malloc(%lu)", __func__,
3116 (unsigned long)(strlen(uri) + 1));
3120 n = evhttp_decode_uri_internal(uri, strlen(uri),
3121 ret, !!decode_plus/*always_decode_plus*/);
3124 EVUTIL_ASSERT(n >= 0);
3125 *size_out = (size_t)n;
3132 * Helper function to parse out arguments in a query.
3133 * The arguments are separated by key and value.
3137 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3143 const char *query_part;
3145 struct evhttp_uri *uri=NULL;
3147 TAILQ_INIT(headers);
3150 uri = evhttp_uri_parse(str);
3153 query_part = evhttp_uri_get_query(uri);
3158 /* No arguments - we are done */
3159 if (!query_part || !strlen(query_part)) {
3164 if ((line = mm_strdup(query_part)) == NULL) {
3165 event_warn("%s: strdup", __func__);
3169 p = argument = line;
3170 while (p != NULL && *p != '\0') {
3171 char *key, *value, *decoded_value;
3172 argument = strsep(&p, "&");
3175 key = strsep(&value, "=");
3176 if (value == NULL || *key == '\0') {
3180 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3181 event_warn("%s: mm_malloc", __func__);
3184 evhttp_decode_uri_internal(value, strlen(value),
3185 decoded_value, 1 /*always_decode_plus*/);
3186 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3187 evhttp_add_header_internal(headers, key, decoded_value);
3188 mm_free(decoded_value);
3194 evhttp_clear_headers(headers);
3199 evhttp_uri_free(uri);
3204 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3206 return evhttp_parse_query_impl(uri, headers, 1);
3209 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3211 return evhttp_parse_query_impl(uri, headers, 0);
3214 static struct evhttp_cb *
3215 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3217 struct evhttp_cb *cb;
3222 /* Test for different URLs */
3223 path = evhttp_uri_get_path(req->uri_elems);
3224 offset = strlen(path);
3225 if ((translated = mm_malloc(offset + 1)) == NULL)
3227 evhttp_decode_uri_internal(path, offset, translated,
3228 0 /* decode_plus */);
3230 TAILQ_FOREACH(cb, callbacks, next) {
3231 if (!strcmp(cb->what, translated)) {
3232 mm_free(translated);
3237 mm_free(translated);
3243 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3248 switch (c = *pattern++) {
3250 return *name == '\0';
3253 while (*name != '\0') {
3254 if (prefix_suffix_match(pattern, name,
3263 EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3273 Search the vhost hierarchy beginning with http for a server alias
3274 matching hostname. If a match is found, and outhttp is non-null,
3275 outhttp is set to the matching http object and 1 is returned.
3279 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3280 const char *hostname)
3282 struct evhttp_server_alias *alias;
3283 struct evhttp *vhost;
3285 TAILQ_FOREACH(alias, &http->aliases, next) {
3286 /* XXX Do we need to handle IP addresses? */
3287 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3294 /* XXX It might be good to avoid recursion here, but I don't
3295 see a way to do that w/o a list. */
3296 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3297 if (evhttp_find_alias(vhost, outhttp, hostname))
3305 Attempts to find the best http object to handle a request for a hostname.
3306 All aliases for the root http object and vhosts are searched for an exact
3307 match. Then, the vhost hierarchy is traversed again for a matching
3310 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3311 is set with the best matching http object. If there are no matches, the
3312 root http object is stored in outhttp and 0 is returned.
3316 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3317 const char *hostname)
3319 struct evhttp *vhost;
3320 struct evhttp *oldhttp;
3321 int match_found = 0;
3323 if (evhttp_find_alias(http, outhttp, hostname))
3328 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3329 if (prefix_suffix_match(vhost->vhost_pattern,
3330 hostname, 1 /* ignorecase */)) {
3336 } while (oldhttp != http);
3345 evhttp_handle_request(struct evhttp_request *req, void *arg)
3347 struct evhttp *http = arg;
3348 struct evhttp_cb *cb = NULL;
3349 const char *hostname;
3351 /* we have a new request on which the user needs to take action */
3354 if (req->type == 0 || req->uri == NULL) {
3355 evhttp_send_error(req, HTTP_BADREQUEST, NULL);
3359 if ((http->allowed_methods & req->type) == 0) {
3360 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3361 (unsigned)req->type, (unsigned)http->allowed_methods));
3362 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3366 /* handle potential virtual hosts */
3367 hostname = evhttp_request_get_host(req);
3368 if (hostname != NULL) {
3369 evhttp_find_vhost(http, &http, hostname);
3372 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3373 (*cb->cb)(req, cb->cbarg);
3377 /* Generic call back */
3379 (*http->gencb)(req, http->gencbarg);
3382 /* We need to send a 404 here */
3383 #define ERR_FORMAT "<html><head>" \
3384 "<title>404 Not Found</title>" \
3386 "<h1>Not Found</h1>" \
3387 "<p>The requested URL %s was not found on this server.</p>"\
3391 struct evbuffer *buf;
3393 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3394 evhttp_connection_free(req->evcon);
3398 if ((buf = evbuffer_new()) == NULL) {
3399 mm_free(escaped_html);
3400 evhttp_connection_free(req->evcon);
3404 evhttp_response_code_(req, HTTP_NOTFOUND, "Not Found");
3406 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3408 mm_free(escaped_html);
3410 evhttp_send_page_(req, buf);
3417 /* Listener callback when a connection arrives at a server. */
3419 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3421 struct evhttp *http = arg;
3423 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3427 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3429 struct evhttp_bound_socket *bound =
3430 evhttp_bind_socket_with_handle(http, address, port);
3436 struct evhttp_bound_socket *
3437 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3440 struct evhttp_bound_socket *bound;
3442 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3445 if (listen(fd, 128) == -1) {
3446 event_sock_warn(fd, "%s: listen", __func__);
3447 evutil_closesocket(fd);
3451 bound = evhttp_accept_socket_with_handle(http, fd);
3453 if (bound != NULL) {
3454 event_debug(("Bound to port %d - Awaiting connections ... ",
3463 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3465 struct evhttp_bound_socket *bound =
3466 evhttp_accept_socket_with_handle(http, fd);
3473 evhttp_foreach_bound_socket(struct evhttp *http,
3474 evhttp_bound_socket_foreach_fn *function,
3477 struct evhttp_bound_socket *bound;
3479 TAILQ_FOREACH(bound, &http->sockets, next)
3480 function(bound, argument);
3483 struct evhttp_bound_socket *
3484 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3486 struct evhttp_bound_socket *bound;
3487 struct evconnlistener *listener;
3489 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3491 listener = evconnlistener_new(http->base, NULL, NULL,
3493 0, /* Backlog is '0' because we already said 'listen' */
3498 bound = evhttp_bind_listener(http, listener);
3500 evconnlistener_free(listener);
3506 struct evhttp_bound_socket *
3507 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3509 struct evhttp_bound_socket *bound;
3511 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3515 bound->listener = listener;
3516 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3518 evconnlistener_set_cb(listener, accept_socket_cb, http);
3523 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3525 return evconnlistener_get_fd(bound->listener);
3528 struct evconnlistener *
3529 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3531 return bound->listener;
3535 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3537 TAILQ_REMOVE(&http->sockets, bound, next);
3538 evconnlistener_free(bound->listener);
3542 static struct evhttp*
3543 evhttp_new_object(void)
3545 struct evhttp *http = NULL;
3547 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3548 event_warn("%s: calloc", __func__);
3552 evutil_timerclear(&http->timeout);
3553 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3554 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3555 evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
3556 evhttp_set_allowed_methods(http,
3563 TAILQ_INIT(&http->sockets);
3564 TAILQ_INIT(&http->callbacks);
3565 TAILQ_INIT(&http->connections);
3566 TAILQ_INIT(&http->virtualhosts);
3567 TAILQ_INIT(&http->aliases);
3573 evhttp_new(struct event_base *base)
3575 struct evhttp *http = NULL;
3577 http = evhttp_new_object();
3586 * Start a web server on the specified address and port.
3590 evhttp_start(const char *address, unsigned short port)
3592 struct evhttp *http = NULL;
3594 http = evhttp_new_object();
3597 if (evhttp_bind_socket(http, address, port) == -1) {
3606 evhttp_free(struct evhttp* http)
3608 struct evhttp_cb *http_cb;
3609 struct evhttp_connection *evcon;
3610 struct evhttp_bound_socket *bound;
3611 struct evhttp* vhost;
3612 struct evhttp_server_alias *alias;
3614 /* Remove the accepting part */
3615 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3616 TAILQ_REMOVE(&http->sockets, bound, next);
3618 evconnlistener_free(bound->listener);
3623 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3624 /* evhttp_connection_free removes the connection */
3625 evhttp_connection_free(evcon);
3628 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3629 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3630 mm_free(http_cb->what);
3634 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3635 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3640 if (http->vhost_pattern != NULL)
3641 mm_free(http->vhost_pattern);
3643 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3644 TAILQ_REMOVE(&http->aliases, alias, next);
3645 mm_free(alias->alias);
3653 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3654 struct evhttp* vhost)
3656 /* a vhost can only be a vhost once and should not have bound sockets */
3657 if (vhost->vhost_pattern != NULL ||
3658 TAILQ_FIRST(&vhost->sockets) != NULL)
3661 vhost->vhost_pattern = mm_strdup(pattern);
3662 if (vhost->vhost_pattern == NULL)
3665 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3671 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3673 if (vhost->vhost_pattern == NULL)
3676 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3678 mm_free(vhost->vhost_pattern);
3679 vhost->vhost_pattern = NULL;
3685 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3687 struct evhttp_server_alias *evalias;
3689 evalias = mm_calloc(1, sizeof(*evalias));
3693 evalias->alias = mm_strdup(alias);
3694 if (!evalias->alias) {
3699 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3705 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3707 struct evhttp_server_alias *evalias;
3709 TAILQ_FOREACH(evalias, &http->aliases, next) {
3710 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3711 TAILQ_REMOVE(&http->aliases, evalias, next);
3712 mm_free(evalias->alias);
3722 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
3724 if (timeout_in_secs == -1) {
3725 evhttp_set_timeout_tv(http, NULL);
3728 tv.tv_sec = timeout_in_secs;
3730 evhttp_set_timeout_tv(http, &tv);
3735 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
3738 http->timeout = *tv;
3740 evutil_timerclear(&http->timeout);
3744 int evhttp_set_flags(struct evhttp *http, int flags)
3746 int avail_flags = 0;
3747 avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
3749 if (flags & ~avail_flags)
3751 http->flags &= ~avail_flags;
3753 http->flags |= flags;
3759 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
3761 if (max_headers_size < 0)
3762 http->default_max_headers_size = EV_SIZE_MAX;
3764 http->default_max_headers_size = max_headers_size;
3768 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
3770 if (max_body_size < 0)
3771 http->default_max_body_size = EV_UINT64_MAX;
3773 http->default_max_body_size = max_body_size;
3777 evhttp_set_default_content_type(struct evhttp *http,
3778 const char *content_type) {
3779 http->default_content_type = content_type;
3783 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
3785 http->allowed_methods = methods;
3789 evhttp_set_cb(struct evhttp *http, const char *uri,
3790 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3792 struct evhttp_cb *http_cb;
3794 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3795 if (strcmp(http_cb->what, uri) == 0)
3799 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
3800 event_warn("%s: calloc", __func__);
3804 http_cb->what = mm_strdup(uri);
3805 if (http_cb->what == NULL) {
3806 event_warn("%s: strdup", __func__);
3811 http_cb->cbarg = cbarg;
3813 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
3819 evhttp_del_cb(struct evhttp *http, const char *uri)
3821 struct evhttp_cb *http_cb;
3823 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3824 if (strcmp(http_cb->what, uri) == 0)
3827 if (http_cb == NULL)
3830 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3831 mm_free(http_cb->what);
3838 evhttp_set_gencb(struct evhttp *http,
3839 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3842 http->gencbarg = cbarg;
3846 evhttp_set_bevcb(struct evhttp *http,
3847 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
3850 http->bevcbarg = cbarg;
3854 * Request related functions
3857 struct evhttp_request *
3858 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
3860 struct evhttp_request *req = NULL;
3862 /* Allocate request structure */
3863 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
3864 event_warn("%s: calloc", __func__);
3868 req->headers_size = 0;
3871 req->kind = EVHTTP_RESPONSE;
3872 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3873 if (req->input_headers == NULL) {
3874 event_warn("%s: calloc", __func__);
3877 TAILQ_INIT(req->input_headers);
3879 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3880 if (req->output_headers == NULL) {
3881 event_warn("%s: calloc", __func__);
3884 TAILQ_INIT(req->output_headers);
3886 if ((req->input_buffer = evbuffer_new()) == NULL) {
3887 event_warn("%s: evbuffer_new", __func__);
3891 if ((req->output_buffer = evbuffer_new()) == NULL) {
3892 event_warn("%s: evbuffer_new", __func__);
3903 evhttp_request_free(req);
3908 evhttp_request_free(struct evhttp_request *req)
3910 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
3911 req->flags |= EVHTTP_REQ_NEEDS_FREE;
3915 if (req->remote_host != NULL)
3916 mm_free(req->remote_host);
3917 if (req->uri != NULL)
3919 if (req->uri_elems != NULL)
3920 evhttp_uri_free(req->uri_elems);
3921 if (req->response_code_line != NULL)
3922 mm_free(req->response_code_line);
3923 if (req->host_cache != NULL)
3924 mm_free(req->host_cache);
3926 evhttp_clear_headers(req->input_headers);
3927 mm_free(req->input_headers);
3929 evhttp_clear_headers(req->output_headers);
3930 mm_free(req->output_headers);
3932 if (req->input_buffer != NULL)
3933 evbuffer_free(req->input_buffer);
3935 if (req->output_buffer != NULL)
3936 evbuffer_free(req->output_buffer);
3942 evhttp_request_own(struct evhttp_request *req)
3944 req->flags |= EVHTTP_USER_OWNED;
3948 evhttp_request_is_owned(struct evhttp_request *req)
3950 return (req->flags & EVHTTP_USER_OWNED) != 0;
3953 struct evhttp_connection *
3954 evhttp_request_get_connection(struct evhttp_request *req)
3960 evhttp_connection_get_base(struct evhttp_connection *conn)
3966 evhttp_request_set_chunked_cb(struct evhttp_request *req,
3967 void (*cb)(struct evhttp_request *, void *))
3973 evhttp_request_set_header_cb(struct evhttp_request *req,
3974 int (*cb)(struct evhttp_request *, void *))
3976 req->header_cb = cb;
3980 evhttp_request_set_error_cb(struct evhttp_request *req,
3981 void (*cb)(enum evhttp_request_error, void *))
3987 evhttp_request_set_on_complete_cb(struct evhttp_request *req,
3988 void (*cb)(struct evhttp_request *, void *), void *cb_arg)
3990 req->on_complete_cb = cb;
3991 req->on_complete_cb_arg = cb_arg;
3995 * Allows for inspection of the request URI
3999 evhttp_request_get_uri(const struct evhttp_request *req) {
4000 if (req->uri == NULL)
4001 event_debug(("%s: request %p has no uri\n", __func__, req));
4005 const struct evhttp_uri *
4006 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4007 if (req->uri_elems == NULL)
4008 event_debug(("%s: request %p has no uri elems\n",
4010 return (req->uri_elems);
4014 evhttp_request_get_host(struct evhttp_request *req)
4016 const char *host = NULL;
4018 if (req->host_cache)
4019 return req->host_cache;
4022 host = evhttp_uri_get_host(req->uri_elems);
4023 if (!host && req->input_headers) {
4027 host = evhttp_find_header(req->input_headers, "Host");
4028 /* The Host: header may include a port. Remove it here
4029 to be consistent with uri_elems case above. */
4031 p = host + strlen(host) - 1;
4032 while (p > host && EVUTIL_ISDIGIT_(*p))
4034 if (p > host && *p == ':') {
4036 req->host_cache = mm_malloc(len + 1);
4037 if (!req->host_cache) {
4038 event_warn("%s: malloc", __func__);
4041 memcpy(req->host_cache, host, len);
4042 req->host_cache[len] = '\0';
4043 host = req->host_cache;
4051 enum evhttp_cmd_type
4052 evhttp_request_get_command(const struct evhttp_request *req) {
4057 evhttp_request_get_response_code(const struct evhttp_request *req)
4059 return req->response_code;
4063 evhttp_request_get_response_code_line(const struct evhttp_request *req)
4065 return req->response_code_line;
4068 /** Returns the input headers */
4069 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4071 return (req->input_headers);
4074 /** Returns the output headers */
4075 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4077 return (req->output_headers);
4080 /** Returns the input buffer */
4081 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4083 return (req->input_buffer);
4086 /** Returns the output buffer */
4087 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4089 return (req->output_buffer);
4094 * Takes a file descriptor to read a request from.
4095 * The callback is executed once the whole request has been read.
4098 static struct evhttp_connection*
4099 evhttp_get_request_connection(
4100 struct evhttp* http,
4101 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
4103 struct evhttp_connection *evcon;
4104 char *hostname = NULL, *portname = NULL;
4105 struct bufferevent* bev = NULL;
4107 name_from_addr(sa, salen, &hostname, &portname);
4108 if (hostname == NULL || portname == NULL) {
4109 if (hostname) mm_free(hostname);
4110 if (portname) mm_free(portname);
4114 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4115 __func__, hostname, portname, EV_SOCK_ARG(fd)));
4117 /* we need a connection object to put the http request on */
4118 if (http->bevcb != NULL) {
4119 bev = (*http->bevcb)(http->base, http->bevcbarg);
4121 evcon = evhttp_connection_base_bufferevent_new(
4122 http->base, NULL, bev, hostname, atoi(portname));
4128 evcon->max_headers_size = http->default_max_headers_size;
4129 evcon->max_body_size = http->default_max_body_size;
4130 if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4131 evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4133 evcon->flags |= EVHTTP_CON_INCOMING;
4134 evcon->state = EVCON_READING_FIRSTLINE;
4138 bufferevent_enable(evcon->bufev, EV_READ);
4139 bufferevent_disable(evcon->bufev, EV_WRITE);
4140 bufferevent_setfd(evcon->bufev, fd);
4146 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4148 struct evhttp *http = evcon->http_server;
4149 struct evhttp_request *req;
4150 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4153 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4154 event_warn("%s: strdup", __func__);
4155 evhttp_request_free(req);
4158 req->remote_port = evcon->port;
4160 req->evcon = evcon; /* the request ends up owning the connection */
4161 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4163 /* We did not present the request to the user user yet, so treat it as
4164 * if the user was done with the request. This allows us to free the
4165 * request on a persistent connection if the client drops it without
4166 * sending a request.
4170 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4172 req->kind = EVHTTP_REQUEST;
4175 evhttp_start_read_(evcon);
4181 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4182 struct sockaddr *sa, ev_socklen_t salen)
4184 struct evhttp_connection *evcon;
4186 evcon = evhttp_get_request_connection(http, fd, sa, salen);
4187 if (evcon == NULL) {
4188 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4189 __func__, EV_SOCK_ARG(fd));
4190 evutil_closesocket(fd);
4194 /* the timeout can be used by the server to close idle connections */
4195 if (evutil_timerisset(&http->timeout))
4196 evhttp_connection_set_timeout_tv(evcon, &http->timeout);
4199 * if we want to accept more than one request on a connection,
4200 * we need to know which http server it belongs to.
4202 evcon->http_server = http;
4203 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4205 if (evhttp_associate_new_request_with_connection(evcon) == -1)
4206 evhttp_connection_free(evcon);
4211 * Network helper functions that we do not want to export to the rest of
4216 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4217 char **phost, char **pport)
4219 char ntop[NI_MAXHOST];
4220 char strport[NI_MAXSERV];
4223 #ifdef EVENT__HAVE_GETNAMEINFO
4224 ni_result = getnameinfo(sa, salen,
4225 ntop, sizeof(ntop), strport, sizeof(strport),
4226 NI_NUMERICHOST|NI_NUMERICSERV);
4228 if (ni_result != 0) {
4230 /* Windows doesn't have an EAI_SYSTEM. */
4231 if (ni_result == EAI_SYSTEM)
4232 event_err(1, "getnameinfo failed");
4235 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4239 ni_result = fake_getnameinfo(sa, salen,
4240 ntop, sizeof(ntop), strport, sizeof(strport),
4241 NI_NUMERICHOST|NI_NUMERICSERV);
4246 *phost = mm_strdup(ntop);
4247 *pport = mm_strdup(strport);
4250 /* Create a non-blocking socket and bind it */
4251 /* todo: rename this function */
4252 static evutil_socket_t
4253 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
4260 /* Create listen socket */
4261 fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
4262 SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
4264 event_sock_warn(-1, "socket");
4268 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
4271 if (evutil_make_listen_socket_reuseable(fd) < 0)
4276 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
4284 serrno = EVUTIL_SOCKET_ERROR();
4285 evutil_closesocket(fd);
4286 EVUTIL_SET_SOCKET_ERROR(serrno);
4290 static struct evutil_addrinfo *
4291 make_addrinfo(const char *address, ev_uint16_t port)
4293 struct evutil_addrinfo *ai = NULL;
4295 struct evutil_addrinfo hints;
4296 char strport[NI_MAXSERV];
4299 memset(&hints, 0, sizeof(hints));
4300 hints.ai_family = AF_UNSPEC;
4301 hints.ai_socktype = SOCK_STREAM;
4302 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
4303 * types we don't have an interface to connect to. */
4304 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
4305 evutil_snprintf(strport, sizeof(strport), "%d", port);
4306 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
4308 if (ai_result == EVUTIL_EAI_SYSTEM)
4309 event_warn("getaddrinfo");
4311 event_warnx("getaddrinfo: %s",
4312 evutil_gai_strerror(ai_result));
4319 static evutil_socket_t
4320 bind_socket(const char *address, ev_uint16_t port, int reuse)
4323 struct evutil_addrinfo *aitop = NULL;
4325 /* just create an unbound socket */
4326 if (address == NULL && port == 0)
4327 return bind_socket_ai(NULL, 0);
4329 aitop = make_addrinfo(address, port);
4334 fd = bind_socket_ai(aitop, reuse);
4336 evutil_freeaddrinfo(aitop);
4343 char *scheme; /* scheme; e.g http, ftp etc */
4344 char *userinfo; /* userinfo (typically username:pass), or NULL */
4345 char *host; /* hostname, IP address, or NULL */
4346 int port; /* port, or zero */
4347 char *path; /* path, or "". */
4348 char *query; /* query, or NULL */
4349 char *fragment; /* fragment or NULL */
4353 evhttp_uri_new(void)
4355 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
4362 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
4367 /* Return true if the string starting at s and ending immediately before eos
4368 * is a valid URI scheme according to RFC3986
4371 scheme_ok(const char *s, const char *eos)
4373 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4374 EVUTIL_ASSERT(eos >= s);
4377 if (!EVUTIL_ISALPHA_(*s))
4380 if (! EVUTIL_ISALNUM_(*s) &&
4381 *s != '+' && *s != '-' && *s != '.')
4387 #define SUBDELIMS "!$&'()*+,;="
4389 /* Return true iff [s..eos) is a valid userinfo */
4391 userinfo_ok(const char *s, const char *eos)
4394 if (CHAR_IS_UNRESERVED(*s) ||
4395 strchr(SUBDELIMS, *s) ||
4398 else if (*s == '%' && s+2 < eos &&
4399 EVUTIL_ISXDIGIT_(s[1]) &&
4400 EVUTIL_ISXDIGIT_(s[2]))
4409 regname_ok(const char *s, const char *eos)
4411 while (s && s<eos) {
4412 if (CHAR_IS_UNRESERVED(*s) ||
4413 strchr(SUBDELIMS, *s))
4415 else if (*s == '%' &&
4416 EVUTIL_ISXDIGIT_(s[1]) &&
4417 EVUTIL_ISXDIGIT_(s[2]))
4426 parse_port(const char *s, const char *eos)
4430 if (! EVUTIL_ISDIGIT_(*s))
4432 portnum = (portnum * 10) + (*s - '0');
4435 if (portnum > 65535)
4442 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4444 bracket_addr_ok(const char *s, const char *eos)
4446 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4449 /* IPvFuture, or junk.
4450 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4452 s += 2; /* skip [v */
4454 if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
4456 while (s < eos && *s != '.') {
4457 if (EVUTIL_ISXDIGIT_(*s))
4466 if (CHAR_IS_UNRESERVED(*s) ||
4467 strchr(SUBDELIMS, *s) ||
4477 ev_ssize_t n_chars = eos-s-2;
4478 struct in6_addr in6;
4479 if (n_chars >= 64) /* way too long */
4481 memcpy(buf, s+1, n_chars);
4483 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4488 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4493 uri->host = mm_strdup("");
4494 if (uri->host == NULL) {
4495 event_warn("%s: strdup", __func__);
4501 /* Optionally, we start with "userinfo@" */
4503 cp = strchr(s, '@');
4504 if (cp && cp < eos) {
4505 if (! userinfo_ok(s,cp))
4508 uri->userinfo = mm_strdup(s);
4509 if (uri->userinfo == NULL) {
4510 event_warn("%s: strdup", __func__);
4516 /* Optionally, we end with ":port" */
4517 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
4519 if (port >= cp && *port == ':') {
4520 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4523 else if ((uri->port = parse_port(port+1, eos))<0)
4527 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4528 * an IP-Literal, or a reg-name */
4529 EVUTIL_ASSERT(eos >= cp);
4530 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4531 /* IPv6address, IP-Literal, or junk. */
4532 if (! bracket_addr_ok(cp, eos))
4535 /* Make sure the host part is ok. */
4536 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4539 uri->host = mm_malloc(eos-cp+1);
4540 if (uri->host == NULL) {
4541 event_warn("%s: malloc", __func__);
4544 memcpy(uri->host, cp, eos-cp);
4545 uri->host[eos-cp] = '\0';
4551 end_of_authority(char *cp)
4554 if (*cp == '?' || *cp == '#' || *cp == '/')
4567 /* Return the character after the longest prefix of 'cp' that matches...
4568 * *pchar / "/" if allow_qchars is false, or
4569 * *(pchar / "/" / "?") if allow_qchars is true.
4572 end_of_path(char *cp, enum uri_part part, unsigned flags)
4574 if (flags & EVHTTP_URI_NONCONFORMANT) {
4575 /* If NONCONFORMANT:
4576 * Path is everything up to a # or ? or nul.
4577 * Query is everything up a # or nul
4578 * Fragment is everything up to a nul.
4582 while (*cp && *cp != '#' && *cp != '?')
4586 while (*cp && *cp != '#')
4597 if (CHAR_IS_UNRESERVED(*cp) ||
4598 strchr(SUBDELIMS, *cp) ||
4599 *cp == ':' || *cp == '@' || *cp == '/')
4601 else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
4602 EVUTIL_ISXDIGIT_(cp[2]))
4604 else if (*cp == '?' && part != PART_PATH)
4613 path_matches_noscheme(const char *cp)
4618 else if (*cp == '/')
4626 evhttp_uri_parse(const char *source_uri)
4628 return evhttp_uri_parse_with_flags(source_uri, 0);
4632 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4634 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4635 char *path = NULL, *fragment = NULL;
4636 int got_authority = 0;
4638 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4640 event_warn("%s: calloc", __func__);
4646 readbuf = mm_strdup(source_uri);
4647 if (readbuf == NULL) {
4648 event_warn("%s: strdup", __func__);
4655 /* We try to follow RFC3986 here as much as we can, and match
4658 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4660 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
4664 token = strchr(readp, ':');
4665 if (token && scheme_ok(readp,token)) {
4667 uri->scheme = mm_strdup(readp);
4668 if (uri->scheme == NULL) {
4669 event_warn("%s: strdup", __func__);
4672 readp = token+1; /* eat : */
4675 /* 2. Optionally, "//" then an 'authority' part. */
4676 if (readp[0]=='/' && readp[1] == '/') {
4680 path = end_of_authority(readp);
4681 if (parse_authority(uri, authority, path) < 0)
4687 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4690 readp = end_of_path(path, PART_PATH, flags);
4693 if (*readp == '?') {
4697 readp = end_of_path(readp, PART_QUERY, flags);
4700 if (*readp == '#') {
4704 readp = end_of_path(readp, PART_FRAGMENT, flags);
4706 if (*readp != '\0') {
4710 /* These next two cases may be unreachable; I'm leaving them
4711 * in to be defensive. */
4712 /* If you didn't get an authority, the path can't begin with "//" */
4713 if (!got_authority && path[0]=='/' && path[1]=='/')
4715 /* If you did get an authority, the path must begin with "/" or be
4717 if (got_authority && path[0] != '/' && path[0] != '\0')
4719 /* (End of maybe-unreachable cases) */
4721 /* If there was no scheme, the first part of the path (if any) must
4722 * have no colon in it. */
4723 if (! uri->scheme && !path_matches_noscheme(path))
4726 EVUTIL_ASSERT(path);
4727 uri->path = mm_strdup(path);
4728 if (uri->path == NULL) {
4729 event_warn("%s: strdup", __func__);
4734 uri->query = mm_strdup(query);
4735 if (uri->query == NULL) {
4736 event_warn("%s: strdup", __func__);
4741 uri->fragment = mm_strdup(fragment);
4742 if (uri->fragment == NULL) {
4743 event_warn("%s: strdup", __func__);
4753 evhttp_uri_free(uri);
4760 evhttp_uri_free(struct evhttp_uri *uri)
4762 #define URI_FREE_STR_(f) \
4767 URI_FREE_STR_(scheme);
4768 URI_FREE_STR_(userinfo);
4769 URI_FREE_STR_(host);
4770 URI_FREE_STR_(path);
4771 URI_FREE_STR_(query);
4772 URI_FREE_STR_(fragment);
4775 #undef URI_FREE_STR_
4779 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
4781 struct evbuffer *tmp = 0;
4782 size_t joined_size = 0;
4783 char *output = NULL;
4785 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
4787 if (!uri || !buf || !limit)
4790 tmp = evbuffer_new();
4796 evbuffer_add(tmp, ":", 1);
4799 evbuffer_add(tmp, "//", 2);
4801 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
4804 evbuffer_add_printf(tmp,":%d", uri->port);
4806 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
4814 evbuffer_add(tmp, "?", 1);
4818 if (uri->fragment) {
4819 evbuffer_add(tmp, "#", 1);
4823 evbuffer_add(tmp, "\0", 1); /* NUL */
4825 joined_size = evbuffer_get_length(tmp);
4827 if (joined_size > limit) {
4828 /* It doesn't fit. */
4832 evbuffer_remove(tmp, buf, joined_size);
4843 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
4848 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
4850 return uri->userinfo;
4853 evhttp_uri_get_host(const struct evhttp_uri *uri)
4858 evhttp_uri_get_port(const struct evhttp_uri *uri)
4863 evhttp_uri_get_path(const struct evhttp_uri *uri)
4868 evhttp_uri_get_query(const struct evhttp_uri *uri)
4873 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
4875 return uri->fragment;
4878 #define URI_SET_STR_(f) do { \
4882 if ((uri->f = mm_strdup(f)) == NULL) { \
4883 event_warn("%s: strdup()", __func__); \
4892 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
4894 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
4897 URI_SET_STR_(scheme);
4901 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
4903 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
4905 URI_SET_STR_(userinfo);
4909 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
4912 if (host[0] == '[') {
4913 if (! bracket_addr_ok(host, host+strlen(host)))
4916 if (! regname_ok(host, host+strlen(host)))
4925 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
4932 #define end_of_cpath(cp,p,f) \
4933 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
4936 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
4938 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
4945 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
4947 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
4949 URI_SET_STR_(query);
4953 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
4955 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
4957 URI_SET_STR_(fragment);