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 #define member_size(type, member) sizeof(((type *)0)->member)
33 #ifdef EVENT__HAVE_SYS_PARAM_H
34 #include <sys/param.h>
36 #ifdef EVENT__HAVE_SYS_TYPES_H
37 #include <sys/types.h>
40 #ifdef HAVE_SYS_IOCCOM_H
41 #include <sys/ioccom.h>
43 #ifdef EVENT__HAVE_SYS_RESOURCE_H
44 #include <sys/resource.h>
46 #ifdef EVENT__HAVE_SYS_TIME_H
49 #ifdef EVENT__HAVE_SYS_WAIT_H
54 #include <sys/socket.h>
61 #ifdef EVENT__HAVE_SYS_UN_H
64 #ifdef EVENT__HAVE_AFUNIX_H
68 #include <sys/queue.h>
70 #ifdef EVENT__HAVE_NETINET_IN_H
71 #include <netinet/in.h>
73 #ifdef EVENT__HAVE_ARPA_INET_H
74 #include <arpa/inet.h>
76 #ifdef EVENT__HAVE_NETDB_H
92 #ifdef EVENT__HAVE_UNISTD_H
95 #ifdef EVENT__HAVE_FCNTL_H
99 #undef timeout_pending
100 #undef timeout_initialized
102 #include "strlcpy-internal.h"
103 #include "event2/http.h"
104 #include "event2/event.h"
105 #include "event2/buffer.h"
106 #include "event2/bufferevent.h"
107 #include "event2/http_struct.h"
108 #include "event2/http_compat.h"
109 #include "event2/util.h"
110 #include "event2/listener.h"
111 #include "log-internal.h"
112 #include "util-internal.h"
113 #include "http-internal.h"
114 #include "mm-internal.h"
115 #include "bufferevent-internal.h"
117 #ifndef EVENT__HAVE_GETNAMEINFO
118 #define NI_MAXSERV 32
119 #define NI_MAXHOST 1025
121 #ifndef NI_NUMERICHOST
122 #define NI_NUMERICHOST 1
125 #ifndef NI_NUMERICSERV
126 #define NI_NUMERICSERV 2
130 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
131 size_t hostlen, char *serv, size_t servlen, int flags)
133 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
137 evutil_snprintf(tmpserv, sizeof(tmpserv),
138 "%d", ntohs(sin->sin_port));
139 if (strlcpy(serv, tmpserv, servlen) >= servlen)
144 if (flags & NI_NUMERICHOST) {
145 if (strlcpy(host, inet_ntoa(sin->sin_addr),
152 hp = gethostbyaddr((char *)&sin->sin_addr,
153 sizeof(struct in_addr), AF_INET);
157 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
168 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \
169 ((req)->major < (major_v) || \
170 ((req)->major == (major_v) && (req)->minor < (minor_v)))
172 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \
173 ((req)->major > (major_v) || \
174 ((req)->major == (major_v) && (req)->minor >= (minor_v)))
177 #define MIN(a,b) (((a)<(b))?(a):(b))
182 static evutil_socket_t create_bind_socket_nonblock(struct evutil_addrinfo *, int reuse);
183 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
184 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
185 static struct evhttp_uri *evhttp_uri_parse_authority(char *source_uri, unsigned flags);
186 static int evhttp_associate_new_request_with_connection(
187 struct evhttp_connection *evcon);
188 static void evhttp_connection_start_detectclose(
189 struct evhttp_connection *evcon);
190 static void evhttp_connection_stop_detectclose(
191 struct evhttp_connection *evcon);
192 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
193 static void evhttp_read_firstline(struct evhttp_connection *evcon,
194 struct evhttp_request *req);
195 static void evhttp_read_header(struct evhttp_connection *evcon,
196 struct evhttp_request *req);
197 static int evhttp_add_header_internal(struct evkeyvalq *headers,
198 const char *key, const char *value);
199 static const char *evhttp_response_phrase_internal(int code);
200 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t, struct bufferevent *bev);
201 static void evhttp_write_buffer(struct evhttp_connection *,
202 void (*)(struct evhttp_connection *, void *), void *);
203 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
204 static int evhttp_method_may_have_body_(struct evhttp_connection *, enum evhttp_cmd_type);
206 /* callbacks for bufferevent */
207 static void evhttp_read_cb(struct bufferevent *, void *);
208 static void evhttp_write_cb(struct bufferevent *, void *);
209 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
210 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp, const char *hostname);
211 static const char *evhttp_method_(struct evhttp_connection *evcon,
212 enum evhttp_cmd_type type, ev_uint16_t *flags);
214 #ifndef EVENT__HAVE_STRSEP
215 /* strsep replacement for platforms that lack it. Only works if
216 * del is one character long. */
218 strsep(char **s, const char *del)
221 EVUTIL_ASSERT(strlen(del) == 1);
225 d = strstr(tok, del);
236 html_replace(const char ch, const char **escaped)
262 * Replaces <, >, ", ' and & with <, >, ",
263 * ' and & correspondingly.
265 * The returned string needs to be freed by the caller.
269 evhttp_htmlescape(const char *html)
272 size_t new_size = 0, old_size = 0;
273 char *escaped_html, *p;
278 old_size = strlen(html);
279 for (i = 0; i < old_size; ++i) {
280 const char *replaced = NULL;
281 const size_t replace_size = html_replace(html[i], &replaced);
282 if (replace_size > EV_SIZE_MAX - new_size) {
283 event_warn("%s: html_replace overflow", __func__);
286 new_size += replace_size;
289 if (new_size == EV_SIZE_MAX)
291 p = escaped_html = mm_malloc(new_size + 1);
292 if (escaped_html == NULL) {
293 event_warn("%s: malloc(%lu)", __func__,
294 (unsigned long)(new_size + 1));
297 for (i = 0; i < old_size; ++i) {
298 const char *replaced = &html[i];
299 const size_t len = html_replace(html[i], &replaced);
300 memcpy(p, replaced, len);
306 return (escaped_html);
309 /** Given an evhttp_cmd_type, returns a constant string containing the
310 * equivalent HTTP command, or NULL if the evhttp_cmd_type is
313 evhttp_method_(struct evhttp_connection *evcon,
314 enum evhttp_cmd_type type, ev_uint16_t *flags)
316 struct evhttp_ext_method ext_method;
317 const char *method = NULL;
318 ev_uint16_t tmp_flags = EVHTTP_METHOD_HAS_BODY;
324 case EVHTTP_REQ_POST:
327 case EVHTTP_REQ_HEAD:
329 tmp_flags &= ~EVHTTP_METHOD_HAS_BODY;
334 case EVHTTP_REQ_DELETE:
337 case EVHTTP_REQ_OPTIONS:
340 case EVHTTP_REQ_TRACE:
342 tmp_flags &= ~EVHTTP_METHOD_HAS_BODY;
344 case EVHTTP_REQ_CONNECT:
347 case EVHTTP_REQ_PATCH:
350 case EVHTTP_REQ_PROPFIND:
353 case EVHTTP_REQ_PROPPATCH:
354 method = "PROPPATCH";
356 case EVHTTP_REQ_MKCOL:
359 case EVHTTP_REQ_LOCK:
362 case EVHTTP_REQ_UNLOCK:
365 case EVHTTP_REQ_COPY:
368 case EVHTTP_REQ_MOVE:
372 /* setup the structure to allow for the cmp.
374 * if the cmp function is set, it has the ability to
375 * modify method and flags. Other fields will be
378 * NOTE: the flags returned are OR'd with the current
382 ext_method.method = NULL;
383 ext_method.type = type;
384 ext_method.flags = tmp_flags;
386 if (evcon->ext_method_cmp != NULL &&
387 evcon->ext_method_cmp(&ext_method) == 0) {
389 if (ext_method.type != type) {
390 event_debug(("%s: callback modified type from %u to %u, not allowed",
391 __func__, type, ext_method.type));
395 method = ext_method.method;
396 tmp_flags |= ext_method.flags;
402 event_debug(("%s: type=%04x => '%s' flags=%04x",
403 __func__, (int)type, method, tmp_flags));
411 * Determines if a response should have a body.
412 * Follows the rules in RFC 2616 section 4.3.
413 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
417 evhttp_response_needs_body(struct evhttp_request *req)
419 return (req->response_code != HTTP_NOCONTENT &&
420 req->response_code != HTTP_NOTMODIFIED &&
421 (req->response_code < 100 || req->response_code >= 200) &&
422 req->type != EVHTTP_REQ_CONNECT &&
423 req->type != EVHTTP_REQ_HEAD);
426 /** Helper: called after we've added some data to an evcon's bufferevent's
427 * output buffer. Sets the evconn's writing-is-done callback, and puts
428 * the bufferevent into writing mode.
431 evhttp_write_buffer(struct evhttp_connection *evcon,
432 void (*cb)(struct evhttp_connection *, void *), void *arg)
434 event_debug(("%s: preparing to write buffer\n", __func__));
440 /* Disable the read callback: we don't actually care about data;
441 * we only care about close detection. (We don't disable reading --
442 * EV_READ, since we *do* want to learn about any close events.) */
443 bufferevent_setcb(evcon->bufev,
449 bufferevent_enable(evcon->bufev, EV_READ|EV_WRITE);
453 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
455 bufferevent_disable(evcon->bufev, EV_WRITE);
459 evhttp_send_continue(struct evhttp_connection *evcon,
460 struct evhttp_request *req)
462 bufferevent_enable(evcon->bufev, EV_WRITE);
463 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
464 "HTTP/%d.%d 100 Continue\r\n\r\n",
465 req->major, req->minor);
466 evcon->cb = evhttp_send_continue_done;
467 evcon->cb_arg = NULL;
468 bufferevent_setcb(evcon->bufev,
475 /** Helper: returns true iff evconn is in any connected state. */
477 evhttp_connected(struct evhttp_connection *evcon)
479 switch (evcon->state) {
480 case EVCON_DISCONNECTED:
481 case EVCON_CONNECTING:
484 case EVCON_READING_FIRSTLINE:
485 case EVCON_READING_HEADERS:
486 case EVCON_READING_BODY:
487 case EVCON_READING_TRAILER:
494 /* Create the headers needed for an outgoing HTTP request, adds them to
495 * the request's header list, and writes the request line to the
496 * connection's output buffer.
499 evhttp_make_header_request(struct evhttp_connection *evcon,
500 struct evhttp_request *req)
503 /* NOTE: some version of GCC reports a warning that flags may be uninitialized, hence assignment */
504 ev_uint16_t flags = 0;
506 evhttp_remove_header(req->output_headers, "Proxy-Connection");
508 /* Generate request line */
509 if (!(method = evhttp_method_(evcon, req->type, &flags))) {
513 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
514 "%s %s HTTP/%d.%d\r\n",
515 method, req->uri, req->major, req->minor);
517 /* Add the content length on a request if missing
518 * Always add it for POST and PUT requests as clients expect it */
519 if ((flags & EVHTTP_METHOD_HAS_BODY) &&
520 (evbuffer_get_length(req->output_buffer) > 0 ||
521 req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
522 evhttp_find_header(req->output_headers, "Content-Length") == NULL) {
524 evutil_snprintf(size, sizeof(size), EV_SIZE_FMT,
525 EV_SIZE_ARG(evbuffer_get_length(req->output_buffer)));
526 evhttp_add_header(req->output_headers, "Content-Length", size);
530 /** Return true if the list of headers in 'headers', intepreted with respect
531 * to flags, means that we should send a "connection: close" when the request
534 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
536 if (flags & EVHTTP_PROXY_REQUEST) {
537 /* proxy connection */
538 const char *connection = evhttp_find_header(headers, "Proxy-Connection");
539 return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
541 const char *connection = evhttp_find_header(headers, "Connection");
542 return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
546 evhttp_is_request_connection_close(struct evhttp_request *req)
548 if (req->type == EVHTTP_REQ_CONNECT)
552 evhttp_is_connection_close(req->flags, req->input_headers) ||
553 evhttp_is_connection_close(req->flags, req->output_headers);
556 /* Return true iff 'headers' contains 'Connection: keep-alive' */
558 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
560 const char *connection = evhttp_find_header(headers, "Connection");
561 return (connection != NULL
562 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
565 /* Add a correct "Date" header to headers, unless it already has one. */
567 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
569 if (evhttp_find_header(headers, "Date") == NULL) {
571 if ((signed)sizeof(date) > evutil_date_rfc1123(date, sizeof(date), NULL)) {
572 evhttp_add_header(headers, "Date", date);
577 /* Add a "Content-Length" header with value 'content_length' to headers,
578 * unless it already has a content-length or transfer-encoding header. */
580 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
581 size_t content_length)
583 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
584 evhttp_find_header(headers, "Content-Length") == NULL) {
586 evutil_snprintf(len, sizeof(len), EV_SIZE_FMT,
587 EV_SIZE_ARG(content_length));
588 evhttp_add_header(headers, "Content-Length", len);
593 * Create the headers needed for an HTTP reply in req->output_headers,
594 * and write the first HTTP response for req line to evcon.
597 evhttp_make_header_response(struct evhttp_connection *evcon,
598 struct evhttp_request *req)
600 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
601 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
602 "HTTP/%d.%d %d %s\r\n",
603 req->major, req->minor, req->response_code,
604 req->response_code_line);
606 if (req->major == 1) {
608 evhttp_maybe_add_date_header(req->output_headers);
611 * if the protocol is 1.0; and the connection was keep-alive
612 * we need to add a keep-alive header, too.
614 if (req->minor == 0 && is_keepalive)
615 evhttp_add_header(req->output_headers,
616 "Connection", "keep-alive");
618 if ((req->minor >= 1 || is_keepalive) &&
619 evhttp_response_needs_body(req)) {
621 * we need to add the content length if the
622 * user did not give it, this is required for
623 * persistent connections to work.
625 evhttp_maybe_add_content_length_header(
627 evbuffer_get_length(req->output_buffer));
631 /* Potentially add headers for unidentified content. */
632 if (evhttp_response_needs_body(req)) {
633 if (evhttp_find_header(req->output_headers,
634 "Content-Type") == NULL
635 && evcon->http_server->default_content_type) {
636 evhttp_add_header(req->output_headers,
638 evcon->http_server->default_content_type);
642 /* if the request asked for a close, we send a close, too */
643 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
644 evhttp_remove_header(req->output_headers, "Connection");
645 if (!(req->flags & EVHTTP_PROXY_REQUEST))
646 evhttp_add_header(req->output_headers, "Connection", "close");
647 evhttp_remove_header(req->output_headers, "Proxy-Connection");
651 enum expect { NO, CONTINUE, OTHER };
652 static enum expect evhttp_have_expect(struct evhttp_request *req, int input)
655 struct evkeyvalq *h = input ? req->input_headers : req->output_headers;
657 if (!(req->kind == EVHTTP_REQUEST) || !REQ_VERSION_ATLEAST(req, 1, 1))
660 expect = evhttp_find_header(h, "Expect");
664 return !evutil_ascii_strcasecmp(expect, "100-continue") ? CONTINUE : OTHER;
668 /** Generate all headers appropriate for sending the http request in req (or
669 * the response, if we're sending a response), and write them to evcon's
670 * bufferevent. Also writes all data from req->output_buffer */
672 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
674 struct evkeyval *header;
675 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
678 * Depending if this is a HTTP request or response, we might need to
679 * add some new headers or remove existing headers.
681 if (req->kind == EVHTTP_REQUEST) {
682 evhttp_make_header_request(evcon, req);
684 evhttp_make_header_response(evcon, req);
687 TAILQ_FOREACH(header, req->output_headers, next) {
688 evbuffer_add_printf(output, "%s: %s\r\n",
689 header->key, header->value);
691 evbuffer_add(output, "\r\n", 2);
693 if (evhttp_have_expect(req, 0) != CONTINUE &&
694 evbuffer_get_length(req->output_buffer)) {
696 * For a request, we add the POST data, for a reply, this
697 * is the regular data.
699 evbuffer_add_buffer(output, req->output_buffer);
704 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
705 ev_ssize_t new_max_headers_size)
707 if (new_max_headers_size<0)
708 evcon->max_headers_size = EV_SIZE_MAX;
710 evcon->max_headers_size = new_max_headers_size;
713 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
714 ev_ssize_t new_max_body_size)
716 if (new_max_body_size<0)
717 evcon->max_body_size = EV_UINT64_MAX;
719 evcon->max_body_size = new_max_body_size;
723 evhttp_connection_incoming_fail(struct evhttp_request *req,
724 enum evhttp_request_error error)
727 case EVREQ_HTTP_DATA_TOO_LONG:
728 req->response_code = HTTP_ENTITYTOOLARGE;
731 req->response_code = HTTP_BADREQUEST;
735 case EVREQ_HTTP_TIMEOUT:
738 * these are cases in which we probably should just
739 * close the connection and not send a reply. this
740 * case may happen when a browser keeps a persistent
741 * connection open and we timeout on the read. when
742 * the request is still being used for sending, we
743 * need to disassociated it from the connection here.
745 if (!req->userdone) {
746 /* remove it so that it will not be freed */
747 TAILQ_REMOVE(&req->evcon->requests, req, next);
748 /* indicate that this request no longer has a
754 case EVREQ_HTTP_INVALID_HEADER:
755 case EVREQ_HTTP_BUFFER_ERROR:
756 case EVREQ_HTTP_REQUEST_CANCEL:
757 case EVREQ_HTTP_DATA_TOO_LONG:
758 default: /* xxx: probably should just error on default */
759 /* the callback looks at the uri to determine errors */
764 if (req->uri_elems) {
765 evhttp_uri_free(req->uri_elems);
766 req->uri_elems = NULL;
770 * the callback needs to send a reply, once the reply has
771 * been send, the connection should get freed.
773 (*req->cb)(req, req->cb_arg);
779 /* Free connection ownership of which can be acquired by user using
780 * evhttp_request_own(). */
782 evhttp_request_free_auto(struct evhttp_request *req)
784 if (!(req->flags & EVHTTP_USER_OWNED))
785 evhttp_request_free(req);
789 evhttp_request_free_(struct evhttp_connection *evcon, struct evhttp_request *req)
791 TAILQ_REMOVE(&evcon->requests, req, next);
792 evhttp_request_free_auto(req);
796 evhttp_set_timeout_tv_(struct timeval *tv, const struct timeval *timeout, int def)
798 if (timeout == NULL && def != -1) {
807 evutil_timerclear(tv);
811 evhttp_set_timeout_(struct timeval *tv, int timeout, int def)
818 evutil_timerclear(tv);
820 struct timeval timeout_tv;
821 timeout_tv.tv_sec = timeout;
822 timeout_tv.tv_usec = 0;
827 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
828 * given in error. If it's an outgoing connection, reset the connection,
829 * retry any pending requests, and inform the user. If it's incoming,
830 * delegates to evhttp_connection_incoming_fail(). */
832 evhttp_connection_fail_(struct evhttp_connection *evcon,
833 enum evhttp_request_error error)
835 const int errsave = EVUTIL_SOCKET_ERROR();
836 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
837 void (*cb)(struct evhttp_request *, void *);
839 void (*error_cb)(enum evhttp_request_error, void *);
841 EVUTIL_ASSERT(req != NULL);
843 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
845 if (evcon->flags & EVHTTP_CON_INCOMING) {
847 * for incoming requests, there are two different
848 * failure cases. it's either a network level error
849 * or an http layer error. for problems on the network
850 * layer like timeouts we just drop the connections.
851 * For HTTP problems, we might have to send back a
852 * reply before the connection can be freed.
854 if (evhttp_connection_incoming_fail(req, error) == -1)
855 evhttp_connection_free(evcon);
859 error_cb = req->error_cb;
860 error_cb_arg = req->cb_arg;
861 /* when the request was canceled, the callback is not executed */
862 if (error != EVREQ_HTTP_REQUEST_CANCEL) {
863 /* save the callback for later; the cb might free our object */
865 cb_arg = req->cb_arg;
871 /* do not fail all requests; the next request is going to get
872 * send over a new connection. when a user cancels a request,
873 * all other pending requests should be processed as normal
875 evhttp_request_free_(evcon, req);
877 /* reset the connection */
878 evhttp_connection_reset_(evcon, 1);
880 /* We are trying the next request that was queued on us */
881 if (TAILQ_FIRST(&evcon->requests) != NULL)
882 evhttp_connection_connect_(evcon);
884 if ((evcon->flags & EVHTTP_CON_OUTGOING) &&
885 (evcon->flags & EVHTTP_CON_AUTOFREE)) {
886 evhttp_connection_free(evcon);
889 /* The call to evhttp_connection_reset_ overwrote errno.
890 * Let's restore the original errno, so that the user's
891 * callback can have a better idea of what the error was.
893 EVUTIL_SET_SOCKET_ERROR(errsave);
895 /* inform the user */
896 if (error_cb != NULL)
897 error_cb(error, error_cb_arg);
902 /* Bufferevent callback: invoked when any data has been written from an
903 * http connection's bufferevent */
905 evhttp_write_cb(struct bufferevent *bufev, void *arg)
907 struct evhttp_connection *evcon = arg;
909 /* Activate our call back */
910 if (evcon->cb != NULL)
911 (*evcon->cb)(evcon, evcon->cb_arg);
915 * Advance the connection state.
916 * - If this is an outgoing connection, we've just processed the response;
917 * idle or close the connection.
918 * - If this is an incoming connection, we've just processed the request;
922 evhttp_connection_done(struct evhttp_connection *evcon)
924 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
925 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
929 /* idle or close the connection */
930 int need_close = evhttp_is_request_connection_close(req);
931 TAILQ_REMOVE(&evcon->requests, req, next);
934 evcon->state = EVCON_IDLE;
936 /* check if we got asked to close the connection */
938 evhttp_connection_reset_(evcon, 1);
940 if (TAILQ_FIRST(&evcon->requests) != NULL) {
942 * We have more requests; reset the connection
943 * and deal with the next request.
945 if (!evhttp_connected(evcon))
946 evhttp_connection_connect_(evcon);
948 evhttp_request_dispatch(evcon);
949 } else if (!need_close) {
951 * The connection is going to be persistent, but we
952 * need to detect if the other side closes it.
954 evhttp_connection_start_detectclose(evcon);
955 } else if ((evcon->flags & EVHTTP_CON_AUTOFREE)) {
957 * If we have no more requests that need completion
958 * and we're not waiting for the connection to close
964 * incoming connection - we need to leave the request on the
965 * connection so that we can reply to it.
967 evcon->state = EVCON_WRITING;
970 /* notify the user of the request */
971 (*req->cb)(req, req->cb_arg);
973 /* if this was an outgoing request, we own and it's done. so free it. */
975 evhttp_request_free_auto(req);
978 /* If this was the last request of an outgoing connection and we're
979 * not waiting to receive a connection close event and we want to
980 * automatically free the connection. We check to ensure our request
981 * list is empty one last time just in case our callback added a
984 if (free_evcon && TAILQ_FIRST(&evcon->requests) == NULL) {
985 evhttp_connection_free(evcon);
990 * Handles reading from a chunked request.
991 * return ALL_DATA_READ:
992 * all data has been read
993 * return MORE_DATA_EXPECTED:
994 * more data is expected
995 * return DATA_CORRUPTED:
997 * return REQUEST_CANCELED:
998 * request was canceled by the user calling evhttp_cancel_request
999 * return DATA_TOO_LONG:
1000 * ran over the maximum limit
1003 static enum message_read_status
1004 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
1006 if (req == NULL || buf == NULL) {
1007 return DATA_CORRUPTED;
1013 if ((buflen = evbuffer_get_length(buf)) == 0) {
1017 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
1018 * check for overflow conditions */
1019 if (buflen > EV_SSIZE_MAX) {
1020 return DATA_CORRUPTED;
1023 if (req->ntoread < 0) {
1024 /* Read chunk size */
1026 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
1031 /* the last chunk is on a new line? */
1032 if (strlen(p) == 0) {
1036 ntoread = evutil_strtoll(p, &endp, 16);
1037 error = (*p == '\0' ||
1038 (*endp != '\0' && *endp != ' ') ||
1042 /* could not get chunk size */
1043 return (DATA_CORRUPTED);
1046 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
1047 if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
1048 return DATA_CORRUPTED;
1051 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
1052 /* failed body length test */
1053 event_debug(("Request body is too long"));
1054 return (DATA_TOO_LONG);
1057 req->body_size += (size_t)ntoread;
1058 req->ntoread = ntoread;
1059 if (req->ntoread == 0) {
1061 return (ALL_DATA_READ);
1066 /* req->ntoread is signed int64, len is ssize_t, based on arch,
1067 * ssize_t could only be 32b, check for these conditions */
1068 if (req->ntoread > EV_SSIZE_MAX) {
1069 return DATA_CORRUPTED;
1072 /* don't have enough to complete a chunk; wait for more */
1073 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
1074 return (MORE_DATA_EXPECTED);
1076 /* Completed chunk */
1077 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
1079 if (req->chunk_cb != NULL) {
1080 req->flags |= EVHTTP_REQ_DEFER_FREE;
1081 (*req->chunk_cb)(req, req->cb_arg);
1082 evbuffer_drain(req->input_buffer,
1083 evbuffer_get_length(req->input_buffer));
1084 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1085 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1086 return (REQUEST_CANCELED);
1091 return (MORE_DATA_EXPECTED);
1095 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
1097 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1099 switch (evhttp_parse_headers_(req, buf)) {
1100 case DATA_CORRUPTED:
1102 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1105 bufferevent_disable(evcon->bufev, EV_READ);
1106 evhttp_connection_done(evcon);
1108 case MORE_DATA_EXPECTED:
1109 case REQUEST_CANCELED: /* ??? */
1116 evhttp_lingering_close(struct evhttp_connection *evcon,
1117 struct evhttp_request *req)
1119 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1121 size_t n = evbuffer_get_length(buf);
1122 if (n > (size_t) req->ntoread)
1123 n = (size_t) req->ntoread;
1125 req->body_size += n;
1127 event_debug(("Request body is too long, left " EV_I64_FMT,
1128 EV_I64_ARG(req->ntoread)));
1130 evbuffer_drain(buf, n);
1132 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1135 evhttp_lingering_fail(struct evhttp_connection *evcon,
1136 struct evhttp_request *req)
1138 if (evcon->flags & EVHTTP_CON_LINGERING_CLOSE)
1139 evhttp_lingering_close(evcon, req);
1141 evhttp_connection_fail_(evcon, EVREQ_HTTP_DATA_TOO_LONG);
1145 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1147 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
1150 switch (evhttp_handle_chunked_read(req, buf)) {
1152 /* finished last chunk */
1153 evcon->state = EVCON_READING_TRAILER;
1154 evhttp_read_trailer(evcon, req);
1156 case DATA_CORRUPTED:
1158 /* corrupted data */
1159 evhttp_connection_fail_(evcon,
1160 EVREQ_HTTP_DATA_TOO_LONG);
1162 case REQUEST_CANCELED:
1163 /* request canceled */
1164 evhttp_request_free_auto(req);
1166 case MORE_DATA_EXPECTED:
1170 } else if (req->ntoread < 0) {
1171 /* Read until connection close. */
1172 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
1173 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
1177 req->body_size += evbuffer_get_length(buf);
1178 evbuffer_add_buffer(req->input_buffer, buf);
1179 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
1180 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
1181 /* We've postponed moving the data until now, but we're
1182 * about to use it. */
1183 size_t n = evbuffer_get_length(buf);
1185 if (n > (size_t) req->ntoread)
1186 n = (size_t) req->ntoread;
1188 req->body_size += n;
1189 evbuffer_remove_buffer(buf, req->input_buffer, n);
1192 if (req->body_size > req->evcon->max_body_size ||
1193 (!req->chunked && req->ntoread >= 0 &&
1194 (size_t)req->ntoread > req->evcon->max_body_size)) {
1195 /* XXX: The above casted comparison must checked for overflow */
1196 /* failed body length test */
1198 evhttp_lingering_fail(evcon, req);
1202 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1203 req->flags |= EVHTTP_REQ_DEFER_FREE;
1204 (*req->chunk_cb)(req, req->cb_arg);
1205 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1206 evbuffer_drain(req->input_buffer,
1207 evbuffer_get_length(req->input_buffer));
1208 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1209 evhttp_request_free_auto(req);
1214 if (!req->ntoread) {
1215 bufferevent_disable(evcon->bufev, EV_READ);
1216 /* Completed content length */
1217 evhttp_connection_done(evcon);
1222 #define get_deferred_queue(evcon) \
1226 * Gets called when more data becomes available
1230 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1232 struct evhttp_connection *evcon = arg;
1233 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1235 /* Cancel if it's pending. */
1236 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1237 &evcon->read_more_deferred_cb);
1239 switch (evcon->state) {
1240 case EVCON_READING_FIRSTLINE:
1241 evhttp_read_firstline(evcon, req);
1242 /* note the request may have been freed in
1243 * evhttp_read_body */
1245 case EVCON_READING_HEADERS:
1246 evhttp_read_header(evcon, req);
1247 /* note the request may have been freed in
1248 * evhttp_read_body */
1250 case EVCON_READING_BODY:
1251 evhttp_read_body(evcon, req);
1252 /* note the request may have been freed in
1253 * evhttp_read_body */
1255 case EVCON_READING_TRAILER:
1256 evhttp_read_trailer(evcon, req);
1261 struct evbuffer *input;
1264 input = bufferevent_get_input(evcon->bufev);
1265 total_len = evbuffer_get_length(input);
1266 event_debug(("%s: read "EV_SIZE_FMT
1267 " bytes in EVCON_IDLE state,"
1268 " resetting connection",
1269 __func__, EV_SIZE_ARG(total_len)));
1272 evhttp_connection_reset_(evcon, 1);
1275 case EVCON_DISCONNECTED:
1276 case EVCON_CONNECTING:
1279 event_errx(1, "%s: illegal connection state %d",
1280 __func__, evcon->state);
1285 evhttp_deferred_read_cb(struct event_callback *cb, void *data)
1287 struct evhttp_connection *evcon = data;
1288 struct bufferevent *bev = evcon->bufev;
1290 (bev->readcb)(evcon->bufev, evcon);
1294 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1296 /* This is after writing the request to the server */
1297 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1298 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
1299 EVUTIL_ASSERT(req != NULL);
1301 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1303 /* We need to wait until we've written all of our output data before we can
1305 if (evbuffer_get_length(output) > 0)
1308 /* We are done writing our header and are now expecting the response */
1309 req->kind = EVHTTP_RESPONSE;
1311 evhttp_start_read_(evcon);
1315 * Clean up a connection object
1319 evhttp_connection_free(struct evhttp_connection *evcon)
1321 struct evhttp_request *req;
1323 /* notify interested parties that this connection is going down */
1324 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1325 (*evcon->closecb)(evcon, evcon->closecb_arg);
1327 /* remove all requests that might be queued on this
1328 * connection. for server connections, this should be empty.
1329 * because it gets dequeued either in evhttp_connection_done or
1330 * evhttp_connection_fail_.
1332 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1333 evhttp_request_free_(evcon, req);
1336 if (evcon->http_server != NULL) {
1337 struct evhttp *http = evcon->http_server;
1338 TAILQ_REMOVE(&http->connections, evcon, next);
1339 http->connection_cnt--;
1342 if (event_initialized(&evcon->retry_ev)) {
1343 event_del(&evcon->retry_ev);
1344 event_debug_unassign(&evcon->retry_ev);
1347 event_deferred_cb_cancel_(get_deferred_queue(evcon),
1348 &evcon->read_more_deferred_cb);
1350 if (evcon->bufev != NULL) {
1351 bufferevent_free(evcon->bufev);
1354 if (evcon->bind_address != NULL)
1355 mm_free(evcon->bind_address);
1357 if (evcon->address != NULL)
1358 mm_free(evcon->address);
1361 if (evcon->unixsocket != NULL)
1362 mm_free(evcon->unixsocket);
1369 evhttp_connection_free_on_completion(struct evhttp_connection *evcon) {
1370 evcon->flags |= EVHTTP_CON_AUTOFREE;
1374 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1375 const char *address)
1377 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1378 if (evcon->bind_address)
1379 mm_free(evcon->bind_address);
1380 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1381 event_warn("%s: strdup", __func__);
1385 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1388 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1389 evcon->bind_port = port;
1393 evhttp_request_dispatch(struct evhttp_connection* evcon)
1395 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1397 /* this should not usually happy but it's possible */
1401 EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST);
1403 /* delete possible close detection events */
1404 evhttp_connection_stop_detectclose(evcon);
1406 /* we assume that the connection is connected already */
1407 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1409 evcon->state = EVCON_WRITING;
1411 /* Create the header from the store arguments */
1412 evhttp_make_header(evcon, req);
1414 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1417 /** Hard-reset our connection state
1421 * - clears out buffers
1425 evhttp_connection_reset_hard_(struct evhttp_connection *evcon)
1427 struct evbuffer *tmp;
1430 /* XXXX This is not actually an optimal fix. Instead we ought to have
1431 an API for "stop connecting", or use bufferevent_replacefd to turn off
1432 connecting. But for Libevent 2.0, this seems like a minimal change
1433 least likely to disrupt the rest of the bufferevent and http code.
1435 Why is this here? If the fd is set in the bufferevent, and the
1436 bufferevent is connecting, then you can't actually stop the
1437 bufferevent from trying to connect with bufferevent_disable(). The
1438 connect will never trigger, since we close the fd, but the timeout
1439 might. That caused an assertion failure in evhttp_connection_fail_.
1441 bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE);
1443 /* inform interested parties about connection close */
1444 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1445 (*evcon->closecb)(evcon, evcon->closecb_arg);
1447 /** FIXME: manipulating with fd is unwanted */
1448 err = bufferevent_replacefd(evcon->bufev, -1);
1449 EVUTIL_ASSERT(!err && "setfd");
1451 /* we need to clean up any buffered data */
1452 tmp = bufferevent_get_output(evcon->bufev);
1453 err = evbuffer_drain(tmp, -1);
1454 EVUTIL_ASSERT(!err && "drain output");
1455 tmp = bufferevent_get_input(evcon->bufev);
1456 err = evbuffer_drain(tmp, -1);
1457 EVUTIL_ASSERT(!err && "drain input");
1460 /** Reset our connection state
1463 * - disables reading/writing
1464 * - puts us in DISCONNECTED state
1466 * @param hard - hard reset will (@see evhttp_connection_reset_hard_())
1469 evhttp_connection_reset_(struct evhttp_connection *evcon, int hard)
1471 bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL);
1474 evhttp_connection_reset_hard_(evcon);
1477 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1478 evcon->state = EVCON_DISCONNECTED;
1482 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1484 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1485 bufferevent_enable(evcon->bufev, EV_READ);
1489 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1491 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1492 bufferevent_disable(evcon->bufev, EV_READ);
1496 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1498 struct evhttp_connection *evcon = arg;
1500 evcon->state = EVCON_DISCONNECTED;
1501 evhttp_connection_connect_(evcon);
1505 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1507 struct evcon_requestq requests;
1508 EVUTIL_ASSERT(evcon->flags & EVHTTP_CON_OUTGOING);
1510 evhttp_connection_reset_(evcon, 1);
1512 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1513 struct timeval tv_retry = evcon->initial_retry_timeout;
1515 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1516 /* XXXX handle failure from evhttp_add_event */
1517 for (i=0; i < evcon->retry_cnt; ++i) {
1518 tv_retry.tv_usec *= 2;
1519 if (tv_retry.tv_usec > 1000000) {
1520 tv_retry.tv_usec -= 1000000;
1521 tv_retry.tv_sec += 1;
1523 tv_retry.tv_sec *= 2;
1524 if (tv_retry.tv_sec > 3600) {
1525 tv_retry.tv_sec = 3600;
1526 tv_retry.tv_usec = 0;
1529 event_add(&evcon->retry_ev, &tv_retry);
1535 * User callback can do evhttp_make_request() on the same
1536 * evcon so new request will be added to evcon->requests. To
1537 * avoid freeing it prematurely we iterate over the copy of
1540 TAILQ_INIT(&requests);
1541 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1542 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1543 TAILQ_REMOVE(&evcon->requests, request, next);
1544 TAILQ_INSERT_TAIL(&requests, request, next);
1547 /* for now, we just signal all requests by executing their callbacks */
1548 while (TAILQ_FIRST(&requests) != NULL) {
1549 struct evhttp_request *request = TAILQ_FIRST(&requests);
1550 TAILQ_REMOVE(&requests, request, next);
1551 request->evcon = NULL;
1553 /* we might want to set an error here */
1554 request->cb(request, request->cb_arg);
1555 evhttp_request_free_auto(request);
1558 if (TAILQ_FIRST(&evcon->requests) == NULL
1559 && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1560 evhttp_connection_free(evcon);
1566 evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
1567 struct evhttp_request *req)
1569 struct evbuffer *buf;
1571 /** Second time, we can't read anything */
1572 if (evcon->flags & EVHTTP_CON_READING_ERROR) {
1573 evcon->flags &= ~EVHTTP_CON_READING_ERROR;
1574 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1578 req->kind = EVHTTP_RESPONSE;
1580 buf = bufferevent_get_output(evcon->bufev);
1581 evbuffer_unfreeze(buf, 1);
1582 evbuffer_drain(buf, evbuffer_get_length(buf));
1583 evbuffer_freeze(buf, 1);
1585 evhttp_start_read_(evcon);
1586 evcon->flags |= EVHTTP_CON_READING_ERROR;
1590 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1592 struct evhttp_connection *evcon = arg;
1593 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1595 switch (evcon->state) {
1596 case EVCON_CONNECTING:
1597 if (what & BEV_EVENT_TIMEOUT) {
1598 event_debug(("%s: connection timeout for \"%s:%d\" on "
1600 __func__, evcon->address, evcon->port,
1601 EV_SOCK_ARG(bufferevent_getfd(bufev))));
1602 evhttp_connection_cb_cleanup(evcon);
1607 case EVCON_READING_BODY:
1608 if (!req->chunked && req->ntoread < 0
1609 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1610 /* EOF on read can be benign */
1611 evhttp_connection_done(evcon);
1616 case EVCON_DISCONNECTED:
1618 case EVCON_READING_FIRSTLINE:
1619 case EVCON_READING_HEADERS:
1620 case EVCON_READING_TRAILER:
1626 /* when we are in close detect mode, a read error means that
1627 * the other side closed their connection.
1629 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1630 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1631 EVUTIL_ASSERT(evcon->http_server == NULL);
1632 /* For connections from the client, we just
1633 * reset the connection so that it becomes
1636 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1637 evhttp_connection_reset_(evcon, 1);
1640 * If we have no more requests that need completion
1641 * and we want to auto-free the connection when all
1642 * requests have been completed.
1644 if (TAILQ_FIRST(&evcon->requests) == NULL
1645 && (evcon->flags & EVHTTP_CON_OUTGOING)
1646 && (evcon->flags & EVHTTP_CON_AUTOFREE)) {
1647 evhttp_connection_free(evcon);
1652 if (what & BEV_EVENT_TIMEOUT) {
1653 evhttp_connection_fail_(evcon, EVREQ_HTTP_TIMEOUT);
1654 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1655 if (what & BEV_EVENT_WRITING &&
1656 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR) {
1657 evhttp_connection_read_on_write_error(evcon, req);
1661 if (what & BEV_EVENT_READING &&
1662 evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR &&
1663 evbuffer_get_length(bufferevent_get_input(bufev))) {
1664 event_deferred_cb_schedule_(get_deferred_queue(evcon),
1665 &evcon->read_more_deferred_cb);
1669 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
1670 } else if (what == BEV_EVENT_CONNECTED) {
1672 evhttp_connection_fail_(evcon, EVREQ_HTTP_BUFFER_ERROR);
1677 * Event callback for asynchronous connection attempt.
1680 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1682 struct evhttp_connection *evcon = arg;
1684 if (!(what & BEV_EVENT_CONNECTED)) {
1685 /* some operating systems return ECONNREFUSED immediately
1686 * when connecting to a local address. the cleanup is going
1687 * to reschedule this function call.
1690 if (errno == ECONNREFUSED)
1693 evhttp_error_cb(bufev, what, arg);
1697 /* We are connected to the server now */
1698 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1699 __func__, evcon->address, evcon->port,
1700 EV_SOCK_ARG(bufferevent_getfd(bufev))));
1702 /* Reset the retry count as we were successful in connecting */
1703 evcon->retry_cnt = 0;
1704 evcon->state = EVCON_IDLE;
1706 /* reset the bufferevent cbs */
1707 bufferevent_setcb(evcon->bufev,
1713 bufferevent_set_timeouts(evcon->bufev,
1714 &evcon->timeout_read, &evcon->timeout_write);
1716 /* try to start requests that have queued up on this connection */
1717 evhttp_request_dispatch(evcon);
1721 evhttp_connection_cb_cleanup(evcon);
1725 * Check if we got a valid response code.
1729 evhttp_valid_response_code(int code)
1738 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1742 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1743 if (n != 2 || major > 1) {
1744 event_debug(("%s: bad version %s on message %p from %s",
1745 __func__, version, req, req->remote_host));
1753 /* Parses the status line of a web server */
1756 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1760 const char *readable = "";
1762 protocol = strsep(&line, " ");
1765 number = strsep(&line, " ");
1769 if (evhttp_parse_http_version(protocol, req) < 0)
1772 req->response_code = atoi(number);
1773 if (!evhttp_valid_response_code(req->response_code)) {
1774 event_debug(("%s: bad response code \"%s\"",
1779 if (req->response_code_line != NULL)
1780 mm_free(req->response_code_line);
1781 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1782 event_warn("%s: strdup", __func__);
1789 /* Parse the first line of a HTTP request */
1792 evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len)
1794 char *eos = line + len;
1798 const char *hostname;
1801 enum evhttp_cmd_type type = 0;
1803 while (eos > line && *(eos-1) == ' ') {
1808 if (len < strlen("GET / HTTP/1.0"))
1811 /* Parse the request line */
1812 method = strsep(&line, " ");
1816 version = strrchr(uri, ' ');
1817 if (!version || uri == version)
1822 method_len = (uri - method) - 1;
1825 switch (method_len) {
1827 /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1829 /* Since both GET and PUT share the same character 'T' at the end,
1830 * if the string doesn't have 'T', we can immediately determine this
1831 * is an invalid HTTP method */
1833 if (method[2] != 'T') {
1839 /* This first byte is 'G', so make sure the next byte is
1840 * 'E', if it isn't then this isn't a valid method */
1842 if (method[1] == 'E') {
1843 type = EVHTTP_REQ_GET;
1848 /* First byte is P, check second byte for 'U', if not,
1849 * we know it's an invalid method */
1850 if (method[1] == 'U') {
1851 type = EVHTTP_REQ_PUT;
1859 /* The method length is 4 bytes, leaving only the methods POST, HEAD, LOCK, COPY and MOVE */
1862 if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') {
1863 type = EVHTTP_REQ_POST;
1867 if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') {
1868 type = EVHTTP_REQ_HEAD;
1872 if (method[3] == 'K' && method[2] == 'C' && method[1] == 'O') {
1873 type = EVHTTP_REQ_LOCK;
1877 if (method[3] == 'Y' && method[2] == 'P' && method[1] == 'O') {
1878 type = EVHTTP_REQ_COPY;
1882 if (method[3] == 'E' && method[2] == 'V' && method[1] == 'O') {
1883 type = EVHTTP_REQ_MOVE;
1891 /* Method length is 5 bytes, which can only encompass PATCH, TRACE and MKCOL */
1894 if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') {
1895 type = EVHTTP_REQ_PATCH;
1899 if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') {
1900 type = EVHTTP_REQ_TRACE;
1905 if (method[4] == 'L' && method[3] == 'O' && method[2] == 'C' && method[1] == 'K') {
1906 type = EVHTTP_REQ_MKCOL;
1914 /* Method length is 6, only valid methods 6 bytes in length is DELETE and UNLOCK */
1917 if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' &&
1918 method[2] == 'L' && method[1] == 'E') {
1919 type = EVHTTP_REQ_DELETE;
1923 if (method[5] == 'K' && method[4] == 'C' && method[3] == 'O' &&
1924 method[2] == 'L' && method[1] == 'N') {
1925 type = EVHTTP_REQ_UNLOCK;
1933 /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1936 if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' &&
1937 method[3] == 'I' && method[2] == 'T' && method[1] == 'P') {
1938 type = EVHTTP_REQ_OPTIONS;
1943 if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' &&
1944 method[3] == 'N' && method[2] == 'N' && method[1] == 'O') {
1945 type = EVHTTP_REQ_CONNECT;
1954 /* Method length is 8, only valid method 8 bytes in length is PROPFIND */
1956 /* If the first byte isn't 'P' then it's invalid */
1957 if (*method != 'P') {
1961 if (method[7] == 'D' && method[6] == 'N' && method[5] == 'I' &&
1962 method[4] == 'F' && method[3] == 'P' && method[2] == 'O' &&
1964 type = EVHTTP_REQ_PROPFIND;
1969 /* Method length is 9, only valid method 9 bytes in length is PROPPATCH */
1971 /* If the first byte isn't 'P' then it's invalid */
1972 if (*method != 'P') {
1976 if (method[8] == 'H' && method[7] == 'C' && method[6] == 'T' &&
1977 method[5] == 'A' && method[4] == 'P' && method[3] == 'P' &&
1978 method[2] == 'O' && method[1] == 'R') {
1979 type = EVHTTP_REQ_PROPPATCH;
1986 /* check extended methods, we only care about the
1987 * type set by the cmp function if the cmp function
1988 * returns a 0 value.
1990 struct evhttp_ext_method ext_method;
1992 ext_method.method = method;
1993 ext_method.type = 0;
1994 ext_method.flags = 0;
1996 if (req->evcon->ext_method_cmp &&
1997 req->evcon->ext_method_cmp(&ext_method) == 0) {
1998 /* make sure the other fields in ext_method are
1999 * not changed by the callback.
2001 if (strcmp(ext_method.method, method) != 0) {
2002 event_warn("%s: modifying the 'method' field of ext_method_cmp's "
2003 "parameter is not allowed", __func__);
2006 if (ext_method.flags != 0) {
2007 event_warn("%s: modifying the 'flags' field of ext_method_cmp's "
2008 "parameter is not allowed", __func__);
2011 type = ext_method.type;
2016 event_debug(("%s: bad method %s on request %p from %s",
2017 __func__, method, req, req->remote_host));
2018 /* No error yet; we'll give a better error later when
2019 * we see that req->type is unsupported. */
2024 if (evhttp_parse_http_version(version, req) < 0)
2027 if ((req->uri = mm_strdup(uri)) == NULL) {
2028 event_debug(("%s: mm_strdup", __func__));
2032 if (type == EVHTTP_REQ_CONNECT) {
2033 if ((req->uri_elems = evhttp_uri_parse_authority(req->uri, 0)) == NULL) {
2037 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
2038 EVHTTP_URI_NONCONFORMANT)) == NULL) {
2043 /* If we have an absolute-URI, check to see if it is an http request
2044 for a known vhost or server alias. If we don't know about this
2045 host, we consider it a proxy request. */
2046 scheme = evhttp_uri_get_scheme(req->uri_elems);
2047 hostname = evhttp_uri_get_host(req->uri_elems);
2048 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
2049 !evutil_ascii_strcasecmp(scheme, "https")) &&
2051 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
2052 req->flags |= EVHTTP_PROXY_REQUEST;
2058 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
2060 struct evkeyval *header;
2062 TAILQ_FOREACH(header, headers, next) {
2063 if (evutil_ascii_strcasecmp(header->key, key) == 0)
2064 return (header->value);
2071 evhttp_clear_headers(struct evkeyvalq *headers)
2073 struct evkeyval *header;
2075 for (header = TAILQ_FIRST(headers);
2077 header = TAILQ_FIRST(headers)) {
2078 TAILQ_REMOVE(headers, header, next);
2079 mm_free(header->key);
2080 mm_free(header->value);
2086 * Returns 0, if the header was successfully removed.
2087 * Returns -1, if the header could not be found.
2091 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
2093 struct evkeyval *header;
2095 TAILQ_FOREACH(header, headers, next) {
2096 if (evutil_ascii_strcasecmp(header->key, key) == 0)
2103 /* Free and remove the header that we found */
2104 TAILQ_REMOVE(headers, header, next);
2105 mm_free(header->key);
2106 mm_free(header->value);
2113 evhttp_header_is_valid_value(const char *value)
2115 const char *p = value;
2117 while ((p = strpbrk(p, "\r\n")) != NULL) {
2118 /* we really expect only one new line */
2119 p += strspn(p, "\r\n");
2120 /* we expect a space or tab for continuation */
2121 if (*p != ' ' && *p != '\t')
2128 evhttp_add_header(struct evkeyvalq *headers,
2129 const char *key, const char *value)
2131 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
2133 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
2134 /* drop illegal headers */
2135 event_debug(("%s: dropping illegal header key\n", __func__));
2139 if (!evhttp_header_is_valid_value(value)) {
2140 event_debug(("%s: dropping illegal header value\n", __func__));
2144 return (evhttp_add_header_internal(headers, key, value));
2148 evhttp_add_header_internal(struct evkeyvalq *headers,
2149 const char *key, const char *value)
2151 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
2152 if (header == NULL) {
2153 event_warn("%s: calloc", __func__);
2156 if ((header->key = mm_strdup(key)) == NULL) {
2158 event_warn("%s: strdup", __func__);
2161 if ((header->value = mm_strdup(value)) == NULL) {
2162 mm_free(header->key);
2164 event_warn("%s: strdup", __func__);
2168 TAILQ_INSERT_TAIL(headers, header, next);
2174 * Parses header lines from a request or a response into the specified
2175 * request object given an event buffer.
2178 * DATA_CORRUPTED on error
2179 * MORE_DATA_EXPECTED when we need to read more headers
2180 * ALL_DATA_READ when all headers have been read.
2183 enum message_read_status
2184 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer)
2187 enum message_read_status status = ALL_DATA_READ;
2191 line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF);
2193 if (req->evcon != NULL &&
2194 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2195 return (DATA_TOO_LONG);
2197 return (MORE_DATA_EXPECTED);
2200 if (req->evcon != NULL && len > req->evcon->max_headers_size) {
2202 return (DATA_TOO_LONG);
2205 req->headers_size = len;
2207 switch (req->kind) {
2208 case EVHTTP_REQUEST:
2209 if (evhttp_parse_request_line(req, line, len) == -1)
2210 status = DATA_CORRUPTED;
2212 case EVHTTP_RESPONSE:
2213 if (evhttp_parse_response_line(req, line) == -1)
2214 status = DATA_CORRUPTED;
2217 status = DATA_CORRUPTED;
2225 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line)
2227 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
2229 size_t old_len, line_len;
2234 old_len = strlen(header->value);
2236 /* Strip space from start and end of line. */
2237 while (*line == ' ' || *line == '\t')
2239 evutil_rtrim_lws_(line);
2241 line_len = strlen(line);
2243 newval = mm_realloc(header->value, old_len + line_len + 2);
2247 newval[old_len] = ' ';
2248 memcpy(newval + old_len + 1, line, line_len + 1);
2249 header->value = newval;
2254 enum message_read_status
2255 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
2257 enum message_read_status errcode = DATA_CORRUPTED;
2259 enum message_read_status status = MORE_DATA_EXPECTED;
2261 struct evkeyvalq* headers = req->input_headers;
2263 while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF))
2265 char *skey, *svalue;
2267 req->headers_size += len;
2269 if (req->evcon != NULL &&
2270 req->headers_size > req->evcon->max_headers_size) {
2271 errcode = DATA_TOO_LONG;
2275 if (*line == '\0') { /* Last header - Done */
2276 status = ALL_DATA_READ;
2281 /* Check if this is a continuation line */
2282 if (*line == ' ' || *line == '\t') {
2283 if (evhttp_append_to_last_header(headers, line) == -1)
2289 /* Processing of header lines */
2291 skey = strsep(&svalue, ":");
2295 svalue += strspn(svalue, " ");
2296 evutil_rtrim_lws_(svalue);
2298 if (evhttp_add_header(headers, skey, svalue) == -1)
2304 if (status == MORE_DATA_EXPECTED) {
2305 if (req->evcon != NULL &&
2306 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
2307 return (DATA_TOO_LONG);
2318 evhttp_get_body_length(struct evhttp_request *req)
2320 struct evkeyvalq *headers = req->input_headers;
2321 const char *content_length;
2322 const char *connection;
2324 content_length = evhttp_find_header(headers, "Content-Length");
2325 connection = evhttp_find_header(headers, "Connection");
2327 if (content_length == NULL && connection == NULL)
2329 else if (content_length == NULL &&
2330 evutil_ascii_strcasecmp(connection, "Close") != 0) {
2332 } else if (content_length == NULL) {
2336 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
2337 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
2338 event_debug(("%s: illegal content length: %s",
2339 __func__, content_length));
2342 req->ntoread = ntoread;
2345 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
2346 __func__, EV_I64_ARG(req->ntoread),
2347 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
2353 evhttp_method_may_have_body_(struct evhttp_connection *evcon, enum evhttp_cmd_type type)
2355 /* NOTE: some version of GCC reports a warning that flags may be uninitialized, hence assignment */
2356 ev_uint16_t flags = 0;
2357 evhttp_method_(evcon, type, &flags);
2358 return (flags & EVHTTP_METHOD_HAS_BODY) ? 1 : 0;
2362 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
2364 const char *xfer_enc;
2366 /* If this is a request without a body, then we are done */
2367 if (req->kind == EVHTTP_REQUEST &&
2368 !evhttp_method_may_have_body_(evcon, req->type)) {
2369 evhttp_connection_done(evcon);
2372 evcon->state = EVCON_READING_BODY;
2373 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
2374 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
2378 if (evhttp_get_body_length(req) == -1) {
2379 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2382 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
2383 /* An incoming request with no content-length and no
2384 * transfer-encoding has no body. */
2385 evhttp_connection_done(evcon);
2390 /* Should we send a 100 Continue status line? */
2391 switch (evhttp_have_expect(req, 1)) {
2393 /* XXX It would be nice to do some sanity
2394 checking here. Does the resource exist?
2395 Should the resource accept post requests? If
2396 no, we should respond with an error. For
2397 now, just optimistically tell the client to
2398 send their message body. */
2399 if (req->ntoread > 0) {
2400 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2401 if ((req->evcon->max_body_size <= EV_INT64_MAX) &&
2402 (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
2403 evhttp_lingering_fail(evcon, req);
2407 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
2408 evhttp_send_continue(evcon, req);
2411 evhttp_send_error(req, HTTP_EXPECTATIONFAILED, NULL);
2416 evhttp_read_body(evcon, req);
2417 /* note the request may have been freed in evhttp_read_body */
2421 evhttp_read_firstline(struct evhttp_connection *evcon,
2422 struct evhttp_request *req)
2424 enum message_read_status res;
2426 res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev));
2427 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2428 /* Error while reading, terminate */
2429 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2430 __func__, EV_SOCK_ARG(bufferevent_getfd(evcon->bufev))));
2431 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2433 } else if (res == MORE_DATA_EXPECTED) {
2434 /* Need more header lines */
2438 evcon->state = EVCON_READING_HEADERS;
2439 evhttp_read_header(evcon, req);
2443 evhttp_read_header(struct evhttp_connection *evcon,
2444 struct evhttp_request *req)
2446 enum message_read_status res;
2447 evutil_socket_t fd = bufferevent_getfd(evcon->bufev);
2449 res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev));
2450 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2451 /* Error while reading, terminate */
2452 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2453 __func__, EV_SOCK_ARG(fd)));
2454 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2456 } else if (res == MORE_DATA_EXPECTED) {
2457 /* Need more header lines */
2461 /* Callback can shut down connection with negative return value */
2462 if (req->header_cb != NULL) {
2463 if ((*req->header_cb)(req, req->cb_arg) < 0) {
2464 evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
2469 /* Done reading headers, do the real work */
2470 switch (req->kind) {
2471 case EVHTTP_REQUEST:
2472 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2473 __func__, EV_SOCK_ARG(fd)));
2474 evhttp_get_body(evcon, req);
2475 /* note the request may have been freed in evhttp_get_body */
2478 case EVHTTP_RESPONSE:
2479 /* Start over if we got a 100 Continue response. */
2480 if (req->response_code == 100) {
2481 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
2482 evbuffer_add_buffer(output, req->output_buffer);
2483 evhttp_start_write_(evcon);
2486 if (!evhttp_response_needs_body(req)) {
2487 event_debug(("%s: skipping body for code %d\n",
2488 __func__, req->response_code));
2489 evhttp_connection_done(evcon);
2491 event_debug(("%s: start of read body for %s on "
2493 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2494 evhttp_get_body(evcon, req);
2495 /* note the request may have been freed in
2496 * evhttp_get_body */
2501 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2503 evhttp_connection_fail_(evcon, EVREQ_HTTP_INVALID_HEADER);
2506 /* request may have been freed above */
2510 * Creates a TCP connection to the specified port and executes a callback
2511 * when finished. Failure or success is indicate by the passed connection
2514 * Although this interface accepts a hostname, it is intended to take
2515 * only numeric hostnames so that non-blocking DNS resolution can
2519 struct evhttp_connection *
2520 evhttp_connection_new(const char *address, ev_uint16_t port)
2522 return (evhttp_connection_base_new(NULL, NULL, address, port));
2525 static struct evhttp_connection *
2526 evhttp_connection_new_(struct event_base *base, struct bufferevent* bev)
2528 struct evhttp_connection *evcon;
2530 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2531 event_warn("%s: calloc failed", __func__);
2535 evcon->max_headers_size = EV_SIZE_MAX;
2536 evcon->max_body_size = EV_SIZE_MAX;
2538 evcon->timeout_connect.tv_sec = HTTP_CONNECT_TIMEOUT;
2539 evcon->timeout_read.tv_sec = HTTP_READ_TIMEOUT;
2540 evcon->timeout_write.tv_sec = HTTP_WRITE_TIMEOUT;
2541 evcon->initial_retry_timeout.tv_sec = HTTP_INITIAL_RETRY_TIMEOUT;
2543 evcon->retry_cnt = evcon->retry_max = 0;
2546 if (!(bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE))) {
2547 event_warn("%s: bufferevent_socket_new failed", __func__);
2552 bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon);
2555 evcon->state = EVCON_DISCONNECTED;
2556 TAILQ_INIT(&evcon->requests);
2560 if (bufferevent_get_base(bev) != base)
2561 bufferevent_base_set(base, evcon->bufev);
2564 event_deferred_cb_init_(
2565 &evcon->read_more_deferred_cb,
2566 bufferevent_get_priority(bev),
2567 evhttp_deferred_read_cb, evcon);
2569 evcon->ai_family = AF_UNSPEC;
2575 evhttp_connection_free(evcon);
2580 struct evhttp_connection *
2581 evhttp_connection_base_bufferevent_unix_new(struct event_base *base, struct bufferevent* bev, const char *unixsocket)
2583 struct evhttp_connection *evcon;
2585 if (strlen(unixsocket) >= member_size(struct sockaddr_un, sun_path)) {
2586 event_warn("%s: unix socket too long", __func__);
2590 evcon = evhttp_connection_new_(base, bev);
2594 if ((evcon->unixsocket = mm_strdup(unixsocket)) == NULL) {
2595 event_warn("%s: strdup failed", __func__);
2599 evcon->ai_family = AF_UNIX;
2604 evhttp_connection_free(evcon);
2609 struct evhttp_connection *
2610 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev,
2611 const char *address, unsigned short port)
2613 struct evhttp_connection *evcon;
2615 event_debug(("Attempting connection to %s:%d\n", address, port));
2617 evcon = evhttp_connection_new_(base, bev);
2621 if ((evcon->address = mm_strdup(address)) == NULL) {
2622 event_warn("%s: strdup failed", __func__);
2626 evcon->dns_base = dnsbase;
2631 evhttp_connection_free(evcon);
2636 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2638 return evcon->bufev;
2642 evhttp_connection_get_server(struct evhttp_connection *evcon)
2644 return evcon->http_server;
2647 struct evhttp_connection *
2648 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2649 const char *address, ev_uint16_t port)
2651 return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port);
2654 void evhttp_connection_set_family(struct evhttp_connection *evcon,
2657 evcon->ai_family = family;
2660 int evhttp_connection_set_flags(struct evhttp_connection *evcon,
2663 int avail_flags = 0;
2664 avail_flags |= EVHTTP_CON_REUSE_CONNECTED_ADDR;
2665 avail_flags |= EVHTTP_CON_READ_ON_WRITE_ERROR;
2667 if (flags & ~avail_flags || flags > EVHTTP_CON_PUBLIC_FLAGS_END)
2669 evcon->flags &= ~avail_flags;
2671 evcon->flags |= flags;
2677 evhttp_connection_set_ext_method_cmp(struct evhttp_connection *evcon,
2678 evhttp_ext_method_cb cmp)
2680 evcon->ext_method_cmp = cmp;
2684 evhttp_connection_set_base(struct evhttp_connection *evcon,
2685 struct event_base *base)
2687 EVUTIL_ASSERT(evcon->base == NULL);
2688 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2690 bufferevent_base_set(base, evcon->bufev);
2694 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2697 if (timeout != -1) {
2698 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2700 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2702 evhttp_set_timeout_(&evcon->timeout_read, timeout, HTTP_READ_TIMEOUT);
2703 evhttp_set_timeout_(&evcon->timeout_write, timeout, HTTP_WRITE_TIMEOUT);
2704 bufferevent_set_timeouts(evcon->bufev,
2705 &evcon->timeout_read, &evcon->timeout_write);
2708 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon,
2709 const struct timeval* tv)
2712 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2714 evcon->flags &= ~EVHTTP_CON_TIMEOUT_ADJUSTED;
2716 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, HTTP_READ_TIMEOUT);
2717 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, HTTP_WRITE_TIMEOUT);
2718 bufferevent_set_timeouts(evcon->bufev,
2719 &evcon->timeout_read, &evcon->timeout_write);
2721 void evhttp_connection_set_connect_timeout_tv(struct evhttp_connection *evcon,
2722 const struct timeval *tv)
2724 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2725 evhttp_set_timeout_tv_(&evcon->timeout_connect, tv, -1);
2726 if (evcon->state == EVCON_CONNECTING)
2727 bufferevent_set_timeouts(evcon->bufev,
2728 &evcon->timeout_connect, &evcon->timeout_connect);
2730 void evhttp_connection_set_read_timeout_tv(struct evhttp_connection *evcon,
2731 const struct timeval *tv)
2733 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2734 evhttp_set_timeout_tv_(&evcon->timeout_read, tv, -1);
2735 if (evcon->state != EVCON_CONNECTING)
2736 bufferevent_set_timeouts(evcon->bufev,
2737 &evcon->timeout_read, &evcon->timeout_write);
2739 void evhttp_connection_set_write_timeout_tv(struct evhttp_connection *evcon,
2740 const struct timeval *tv)
2742 evcon->flags |= EVHTTP_CON_TIMEOUT_ADJUSTED;
2743 evhttp_set_timeout_tv_(&evcon->timeout_write, tv, -1);
2744 if (evcon->state != EVCON_CONNECTING)
2745 bufferevent_set_timeouts(evcon->bufev,
2746 &evcon->timeout_read, &evcon->timeout_write);
2750 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon,
2751 const struct timeval *tv)
2754 evcon->initial_retry_timeout = *tv;
2756 evutil_timerclear(&evcon->initial_retry_timeout);
2757 evcon->initial_retry_timeout.tv_sec = 2;
2762 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2765 evcon->retry_max = retry_max;
2769 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2770 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2772 evcon->closecb = cb;
2773 evcon->closecb_arg = cbarg;
2777 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2778 const char **address, ev_uint16_t *port)
2780 *address = evcon->address;
2781 *port = evcon->port;
2784 const struct sockaddr*
2785 evhttp_connection_get_addr(struct evhttp_connection *evcon)
2787 return bufferevent_socket_get_conn_address_(evcon->bufev);
2791 evhttp_connection_connect_(struct evhttp_connection *evcon)
2793 int old_state = evcon->state;
2794 const char *address = evcon->address;
2795 const struct sockaddr *sa = evhttp_connection_get_addr(evcon);
2798 if (evcon->state == EVCON_CONNECTING)
2801 /* Do not do hard reset, since this will reset the fd, but someone may
2802 * change some options for it (i.e. setsockopt(), #875)
2804 * However don't think that this options will be preserved for all
2805 * connection lifetime, they will be reseted in the following cases:
2806 * - evhttp_connection_set_local_address()
2807 * - evhttp_connection_set_local_port()
2808 * - evhttp_connection_set_retries()
2810 evhttp_connection_reset_(evcon, 0);
2812 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2813 evcon->flags |= EVHTTP_CON_OUTGOING;
2815 if (evcon->bind_address || evcon->bind_port) {
2816 int fd = bind_socket(evcon->bind_address, evcon->bind_port,
2819 event_debug(("%s: failed to bind to \"%s\"",
2820 __func__, evcon->bind_address));
2824 if (bufferevent_replacefd(evcon->bufev, fd))
2828 /* Set up a callback for successful connection setup */
2829 bufferevent_setcb(evcon->bufev,
2830 NULL /* evhttp_read_cb */,
2831 NULL /* evhttp_write_cb */,
2832 evhttp_connection_cb,
2834 bufferevent_set_timeouts(evcon->bufev,
2835 &evcon->timeout_connect, &evcon->timeout_connect);
2836 /* make sure that we get a write callback */
2837 if (bufferevent_enable(evcon->bufev, EV_WRITE))
2840 evcon->state = EVCON_CONNECTING;
2842 if (evcon->flags & EVHTTP_CON_REUSE_CONNECTED_ADDR &&
2844 (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)) {
2845 int socklen = sizeof(struct sockaddr_in);
2846 if (sa->sa_family == AF_INET6) {
2847 socklen = sizeof(struct sockaddr_in6);
2849 ret = bufferevent_socket_connect(evcon->bufev, sa, socklen);
2852 else if (evcon->unixsocket) {
2853 struct sockaddr_un sockaddr;
2854 sockaddr.sun_family = AF_UNIX;
2855 strcpy(sockaddr.sun_path, evcon->unixsocket);
2856 ret = bufferevent_socket_connect(evcon->bufev, (const struct sockaddr*)&sockaddr, sizeof(sockaddr));
2860 ret = bufferevent_socket_connect_hostname(evcon->bufev,
2861 evcon->dns_base, evcon->ai_family, address, evcon->port);
2865 evcon->state = old_state;
2866 event_sock_warn(bufferevent_getfd(evcon->bufev), "%s: connection to \"%s\" failed",
2867 __func__, evcon->address);
2868 /* some operating systems return ECONNREFUSED immediately
2869 * when connecting to a local address. the cleanup is going
2870 * to reschedule this function call.
2872 evhttp_connection_cb_cleanup(evcon);
2880 * Starts an HTTP request on the provided evhttp_connection object.
2881 * If the connection object is not connected to the web server already,
2882 * this will start the connection.
2886 evhttp_make_request(struct evhttp_connection *evcon,
2887 struct evhttp_request *req,
2888 enum evhttp_cmd_type type, const char *uri)
2890 /* We are making a request */
2891 req->kind = EVHTTP_REQUEST;
2893 if (req->uri != NULL)
2895 if ((req->uri = mm_strdup(uri)) == NULL) {
2896 event_warn("%s: strdup", __func__);
2897 evhttp_request_free_auto(req);
2901 /* Set the protocol version if it is not supplied */
2902 if (!req->major && !req->minor) {
2907 EVUTIL_ASSERT(req->evcon == NULL);
2909 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2911 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2913 /* We do not want to conflict with retry_ev */
2914 if (evcon->retry_cnt)
2917 /* If the connection object is not connected; make it so */
2918 if (!evhttp_connected(evcon)) {
2919 int res = evhttp_connection_connect_(evcon);
2920 /* evhttp_connection_fail_(), which is called through
2921 * evhttp_connection_connect_(), assumes that req lies in
2922 * evcon->requests. Thus, enqueue the request in advance and
2923 * remove it in the error case. */
2925 TAILQ_REMOVE(&evcon->requests, req, next);
2931 * If it's connected already and we are the first in the queue,
2932 * then we can dispatch this request immediately. Otherwise, it
2933 * will be dispatched once the pending requests are completed.
2935 if (TAILQ_FIRST(&evcon->requests) == req)
2936 evhttp_request_dispatch(evcon);
2942 evhttp_cancel_request(struct evhttp_request *req)
2944 struct evhttp_connection *evcon = req->evcon;
2945 if (evcon != NULL) {
2946 /* We need to remove it from the connection */
2947 if (TAILQ_FIRST(&evcon->requests) == req) {
2948 /* it's currently being worked on, so reset
2951 evhttp_connection_fail_(evcon,
2952 EVREQ_HTTP_REQUEST_CANCEL);
2954 /* connection fail freed the request */
2957 /* otherwise, we can just remove it from the
2960 TAILQ_REMOVE(&evcon->requests, req, next);
2964 evhttp_request_free_auto(req);
2968 * Reads data from file descriptor into request structure
2969 * Request structure needs to be set up correctly.
2973 evhttp_start_read_(struct evhttp_connection *evcon)
2975 bufferevent_disable(evcon->bufev, EV_WRITE);
2976 bufferevent_enable(evcon->bufev, EV_READ);
2978 evcon->state = EVCON_READING_FIRSTLINE;
2979 /* Reset the bufferevent callbacks */
2980 bufferevent_setcb(evcon->bufev,
2986 /* If there's still data pending, process it next time through the
2987 * loop. Don't do it now; that could get recusive. */
2988 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2989 event_deferred_cb_schedule_(get_deferred_queue(evcon),
2990 &evcon->read_more_deferred_cb);
2995 evhttp_start_write_(struct evhttp_connection *evcon)
2997 bufferevent_disable(evcon->bufev, EV_WRITE);
2998 bufferevent_enable(evcon->bufev, EV_READ);
3000 evcon->state = EVCON_WRITING;
3001 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
3005 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
3008 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
3009 TAILQ_REMOVE(&evcon->requests, req, next);
3011 if (req->on_complete_cb != NULL) {
3012 req->on_complete_cb(req, req->on_complete_cb_arg);
3016 (REQ_VERSION_BEFORE(req, 1, 1) &&
3017 !evhttp_is_connection_keepalive(req->input_headers)) ||
3018 evhttp_is_request_connection_close(req);
3020 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
3021 evhttp_request_free(req);
3024 evhttp_connection_free(evcon);
3028 /* we have a persistent connection; try to accept another request. */
3029 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
3030 evhttp_connection_free(evcon);
3035 * Returns an error page.
3038 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
3040 #define ERR_FORMAT "<html><head>" \
3041 "<title>%d %s</title>" \
3043 "<h1>%d %s</h1>%s" \
3046 struct evbuffer *buf = evbuffer_new();
3047 struct evhttp *http = req->evcon->http_server;
3050 /* if we cannot allocate memory; we just drop the connection */
3051 evhttp_connection_free(req->evcon);
3055 evhttp_response_code_(req, error, reason);
3057 /* Output error using callback for connection's evhttp, if available */
3058 if ((http->errorcb == NULL) ||
3059 ((*http->errorcb)(req, buf, error, reason, http->errorcbarg) < 0))
3061 const char *heading = evhttp_response_phrase_internal(error);
3063 evbuffer_drain(buf, evbuffer_get_length(buf));
3064 evbuffer_add_printf(buf, ERR_FORMAT,
3065 error, heading, error, heading,
3066 (reason ? reason : ""));
3069 evhttp_send_page_(req, buf);
3075 evhttp_send_notfound(struct evhttp_request *req, const char *url)
3077 #define REASON_FORMAT "<p>The requested URL %s was not found on this server.</p>"
3078 char *escaped_url = NULL;
3079 char *reason = NULL;
3082 url = (url != NULL ? url : req->uri);
3084 escaped_url = evhttp_htmlescape(url);
3086 if (escaped_url != NULL) {
3087 reason_len = strlen(REASON_FORMAT)+strlen(escaped_url)+1;
3088 reason = mm_malloc(reason_len);
3091 if ((escaped_url != NULL) && (reason != NULL))
3092 evutil_snprintf(reason, reason_len, REASON_FORMAT, escaped_url);
3094 evhttp_send_error(req, HTTP_NOTFOUND, reason);
3098 if (escaped_url != NULL)
3099 mm_free(escaped_url);
3100 #undef REASON_FORMAT
3104 /* Requires that headers and response code are already set up */
3107 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
3109 struct evhttp_connection *evcon = req->evcon;
3111 if (evcon == NULL) {
3112 evhttp_request_free(req);
3116 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
3118 /* we expect no more calls form the user on this request */
3121 /* xxx: not sure if we really should expose the data buffer this way */
3122 if (databuf != NULL)
3123 evbuffer_add_buffer(req->output_buffer, databuf);
3125 /* Adds headers to the response */
3126 evhttp_make_header(evcon, req);
3128 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
3132 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
3133 struct evbuffer *databuf)
3135 evhttp_response_code_(req, code, reason);
3137 evhttp_send(req, databuf);
3141 evhttp_send_reply_start(struct evhttp_request *req, int code,
3144 evhttp_response_code_(req, code, reason);
3146 if (req->evcon == NULL)
3149 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
3150 REQ_VERSION_ATLEAST(req, 1, 1) &&
3151 evhttp_response_needs_body(req)) {
3153 * prefer HTTP/1.1 chunked encoding to closing the connection;
3154 * note RFC 2616 section 4.4 forbids it with Content-Length:
3155 * and it's not necessary then anyway.
3157 evhttp_add_header(req->output_headers, "Transfer-Encoding",
3163 evhttp_make_header(req->evcon, req);
3164 evhttp_write_buffer(req->evcon, NULL, NULL);
3168 evhttp_send_reply_chunk_with_cb(struct evhttp_request *req, struct evbuffer *databuf,
3169 void (*cb)(struct evhttp_connection *, void *), void *arg)
3171 struct evhttp_connection *evcon = req->evcon;
3172 struct evbuffer *output;
3177 output = bufferevent_get_output(evcon->bufev);
3179 if (evbuffer_get_length(databuf) == 0)
3181 if (!evhttp_response_needs_body(req))
3184 evbuffer_add_printf(output, "%x\r\n",
3185 (unsigned)evbuffer_get_length(databuf));
3187 evbuffer_add_buffer(output, databuf);
3189 evbuffer_add(output, "\r\n", 2);
3191 evhttp_write_buffer(evcon, cb, arg);
3195 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
3197 evhttp_send_reply_chunk_with_cb(req, databuf, NULL, NULL);
3200 evhttp_send_reply_end(struct evhttp_request *req)
3202 struct evhttp_connection *evcon = req->evcon;
3203 struct evbuffer *output;
3205 if (evcon == NULL) {
3206 evhttp_request_free(req);
3210 output = bufferevent_get_output(evcon->bufev);
3212 /* we expect no more calls form the user on this request */
3216 evbuffer_add(output, "0\r\n\r\n", 5);
3217 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
3219 } else if (evbuffer_get_length(output) == 0) {
3220 /* let the connection know that we are done with the request */
3221 evhttp_send_done(evcon, NULL);
3223 /* make the callback execute after all data has been written */
3224 evcon->cb = evhttp_send_done;
3225 evcon->cb_arg = NULL;
3229 static const char *informational_phrases[] = {
3230 /* 100 */ "Continue",
3231 /* 101 */ "Switching Protocols"
3234 static const char *success_phrases[] = {
3236 /* 201 */ "Created",
3237 /* 202 */ "Accepted",
3238 /* 203 */ "Non-Authoritative Information",
3239 /* 204 */ "No Content",
3240 /* 205 */ "Reset Content",
3241 /* 206 */ "Partial Content"
3244 static const char *redirection_phrases[] = {
3245 /* 300 */ "Multiple Choices",
3246 /* 301 */ "Moved Permanently",
3248 /* 303 */ "See Other",
3249 /* 304 */ "Not Modified",
3250 /* 305 */ "Use Proxy",
3251 /* 307 */ "Temporary Redirect"
3254 static const char *client_error_phrases[] = {
3255 /* 400 */ "Bad Request",
3256 /* 401 */ "Unauthorized",
3257 /* 402 */ "Payment Required",
3258 /* 403 */ "Forbidden",
3259 /* 404 */ "Not Found",
3260 /* 405 */ "Method Not Allowed",
3261 /* 406 */ "Not Acceptable",
3262 /* 407 */ "Proxy Authentication Required",
3263 /* 408 */ "Request Time-out",
3264 /* 409 */ "Conflict",
3266 /* 411 */ "Length Required",
3267 /* 412 */ "Precondition Failed",
3268 /* 413 */ "Request Entity Too Large",
3269 /* 414 */ "Request-URI Too Large",
3270 /* 415 */ "Unsupported Media Type",
3271 /* 416 */ "Requested range not satisfiable",
3272 /* 417 */ "Expectation Failed"
3275 static const char *server_error_phrases[] = {
3276 /* 500 */ "Internal Server Error",
3277 /* 501 */ "Not Implemented",
3278 /* 502 */ "Bad Gateway",
3279 /* 503 */ "Service Unavailable",
3280 /* 504 */ "Gateway Time-out",
3281 /* 505 */ "HTTP Version not supported"
3284 struct response_class {
3286 size_t num_responses;
3287 const char **responses;
3291 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
3294 static const struct response_class response_classes[] = {
3295 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
3296 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
3297 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
3298 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
3299 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
3303 evhttp_response_phrase_internal(int code)
3305 int klass = code / 100 - 1;
3306 int subcode = code % 100;
3308 /* Unknown class - can't do any better here */
3309 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
3310 return "Unknown Status Class";
3312 /* Unknown sub-code, return class name at least */
3313 if (subcode >= (int) response_classes[klass].num_responses)
3314 return response_classes[klass].name;
3316 return response_classes[klass].responses[subcode];
3320 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason)
3322 req->kind = EVHTTP_RESPONSE;
3323 req->response_code = code;
3324 if (req->response_code_line != NULL)
3325 mm_free(req->response_code_line);
3327 reason = evhttp_response_phrase_internal(code);
3328 req->response_code_line = mm_strdup(reason);
3329 if (req->response_code_line == NULL) {
3330 event_warn("%s: strdup", __func__);
3331 /* XXX what else can we do? */
3336 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf)
3338 if (!req->major || !req->minor) {
3343 if (req->kind != EVHTTP_RESPONSE)
3344 evhttp_response_code_(req, 200, "OK");
3346 evhttp_clear_headers(req->output_headers);
3347 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
3348 evhttp_add_header(req->output_headers, "Connection", "close");
3350 evhttp_send(req, databuf);
3353 static const char uri_chars[256] = {
3355 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3356 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3357 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
3358 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
3360 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3361 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
3362 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
3363 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
3365 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3366 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3367 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3368 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3370 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3371 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3372 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3373 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3376 #define CHAR_IS_UNRESERVED(c) \
3377 (uri_chars[(unsigned char)(c)])
3380 * Helper functions to encode/decode a string for inclusion in a URI.
3381 * The returned string must be freed by the caller.
3384 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
3386 struct evbuffer *buf = evbuffer_new();
3387 const char *p, *end;
3388 char *result = NULL;
3395 if (uri + len < uri) {
3401 size_t slen = strlen(uri);
3403 if (slen >= EV_SSIZE_MAX) {
3404 /* we don't want to mix signed and unsigned */
3408 if (uri + slen < uri) {
3415 for (p = uri; p < end; p++) {
3416 if (CHAR_IS_UNRESERVED(*p)) {
3417 evbuffer_add(buf, p, 1);
3418 } else if (*p == ' ' && space_as_plus) {
3419 evbuffer_add(buf, "+", 1);
3421 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
3425 evbuffer_add(buf, "", 1); /* NUL-terminator. */
3426 result = mm_malloc(evbuffer_get_length(buf));
3429 evbuffer_remove(buf, result, evbuffer_get_length(buf));
3438 evhttp_encode_uri(const char *str)
3440 return evhttp_uriencode(str, -1, 0);
3444 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
3445 * If -1, when true we transform plus to space only after we've seen
3446 * a ?. -1 is deprecated.
3447 * @return the number of bytes written to 'ret'.
3450 evhttp_decode_uri_internal(
3451 const char *uri, size_t length, char *ret, int decode_plus_ctl)
3455 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
3458 for (i = j = 0; i < length; i++) {
3461 if (decode_plus_ctl < 0)
3463 } else if (c == '+' && decode_plus) {
3465 } else if ((i + 2) < length && c == '%' &&
3466 EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) {
3471 c = (char)strtol(tmp, NULL, 16);
3483 evhttp_decode_uri(const char *uri)
3487 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3488 event_warn("%s: malloc(%lu)", __func__,
3489 (unsigned long)(strlen(uri) + 1));
3493 evhttp_decode_uri_internal(uri, strlen(uri),
3494 ret, -1 /*always_decode_plus*/);
3500 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
3505 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
3506 event_warn("%s: malloc(%lu)", __func__,
3507 (unsigned long)(strlen(uri) + 1));
3511 n = evhttp_decode_uri_internal(uri, strlen(uri),
3512 ret, !!decode_plus/*always_decode_plus*/);
3515 EVUTIL_ASSERT(n >= 0);
3516 *size_out = (size_t)n;
3523 * Helper function to parse out arguments in a query.
3524 * The arguments are separated by key and value.
3528 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
3529 int is_whole_uri, unsigned flags)
3534 const char *query_part;
3536 struct evhttp_uri *uri=NULL;
3538 TAILQ_INIT(headers);
3541 uri = evhttp_uri_parse(str);
3544 query_part = evhttp_uri_get_query(uri);
3549 /* No arguments - we are done */
3550 if (!query_part || !strlen(query_part)) {
3555 if ((line = mm_strdup(query_part)) == NULL) {
3556 event_warn("%s: strdup", __func__);
3560 p = argument = line;
3561 while (p != NULL && *p != '\0') {
3562 char *key, *value, *decoded_value;
3564 argument = strsep(&p, "&");
3567 key = strsep(&value, "=");
3568 if (flags & EVHTTP_URI_QUERY_NONCONFORMANT) {
3574 if (value == NULL || *key == '\0')
3578 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
3579 event_warn("%s: mm_malloc", __func__);
3582 evhttp_decode_uri_internal(value, strlen(value),
3583 decoded_value, 1 /*always_decode_plus*/);
3584 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
3585 if (flags & EVHTTP_URI_QUERY_LAST_VAL)
3586 evhttp_remove_header(headers, key);
3587 err = evhttp_add_header_internal(headers, key, decoded_value);
3588 mm_free(decoded_value);
3596 evhttp_clear_headers(headers);
3601 evhttp_uri_free(uri);
3606 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
3608 return evhttp_parse_query_impl(uri, headers, 1, 0);
3611 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
3613 return evhttp_parse_query_impl(uri, headers, 0, 0);
3616 evhttp_parse_query_str_flags(const char *uri, struct evkeyvalq *headers, unsigned flags)
3618 return evhttp_parse_query_impl(uri, headers, 0, flags);
3621 static struct evhttp_cb *
3622 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
3624 struct evhttp_cb *cb;
3629 /* Test for different URLs */
3630 path = evhttp_uri_get_path(req->uri_elems);
3631 offset = strlen(path);
3632 if ((translated = mm_malloc(offset + 1)) == NULL)
3634 evhttp_decode_uri_internal(path, offset, translated,
3635 0 /* decode_plus */);
3637 TAILQ_FOREACH(cb, callbacks, next) {
3638 if (!strcmp(cb->what, translated)) {
3639 mm_free(translated);
3644 mm_free(translated);
3650 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
3655 switch (c = *pattern++) {
3657 return *name == '\0';
3660 while (*name != '\0') {
3661 if (prefix_suffix_match(pattern, name,
3670 EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name))
3680 Search the vhost hierarchy beginning with http for a server alias
3681 matching hostname. If a match is found, and outhttp is non-null,
3682 outhttp is set to the matching http object and 1 is returned.
3686 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
3687 const char *hostname)
3689 struct evhttp_server_alias *alias;
3690 struct evhttp *vhost;
3692 TAILQ_FOREACH(alias, &http->aliases, next) {
3693 /* XXX Do we need to handle IP addresses? */
3694 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
3701 /* XXX It might be good to avoid recursion here, but I don't
3702 see a way to do that w/o a list. */
3703 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3704 if (evhttp_find_alias(vhost, outhttp, hostname))
3712 Attempts to find the best http object to handle a request for a hostname.
3713 All aliases for the root http object and vhosts are searched for an exact
3714 match. Then, the vhost hierarchy is traversed again for a matching
3717 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3718 is set with the best matching http object. If there are no matches, the
3719 root http object is stored in outhttp and 0 is returned.
3723 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
3724 const char *hostname)
3726 struct evhttp *vhost;
3727 struct evhttp *oldhttp;
3728 int match_found = 0;
3730 if (evhttp_find_alias(http, outhttp, hostname))
3735 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
3736 if (prefix_suffix_match(vhost->vhost_pattern,
3737 hostname, 1 /* ignorecase */)) {
3743 } while (oldhttp != http);
3752 evhttp_handle_request(struct evhttp_request *req, void *arg)
3754 struct evhttp *http = arg;
3755 struct evhttp_cb *cb = NULL;
3756 const char *hostname;
3758 /* we have a new request on which the user needs to take action */
3761 bufferevent_disable(req->evcon->bufev, EV_READ);
3763 if (req->uri == NULL) {
3764 evhttp_send_error(req, req->response_code, NULL);
3768 if ((http->allowed_methods & req->type) == 0) {
3769 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3770 (unsigned)req->type, (unsigned)http->allowed_methods));
3771 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3775 /* handle potential virtual hosts */
3776 hostname = evhttp_request_get_host(req);
3777 if (hostname != NULL) {
3778 evhttp_find_vhost(http, &http, hostname);
3781 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3782 (*cb->cb)(req, cb->cbarg);
3786 /* Generic call back */
3788 (*http->gencb)(req, http->gencbarg);
3791 evhttp_send_notfound(req, NULL);
3794 /* Listener callback when a connection arrives at a server. */
3796 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3798 struct evhttp_bound_socket *bound = arg;
3800 struct evhttp *http = bound->http;
3802 struct bufferevent *bev = NULL;
3804 bev = bound->bevcb(http->base, bound->bevcbarg);
3806 evhttp_get_request(http, nfd, peer_sa, peer_socklen, bev);
3810 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3812 struct evhttp_bound_socket *bound =
3813 evhttp_bind_socket_with_handle(http, address, port);
3819 struct evhttp_bound_socket *
3820 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3823 struct evhttp_bound_socket *bound;
3826 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3829 if (listen(fd, 128) == -1) {
3830 serrno = EVUTIL_SOCKET_ERROR();
3831 event_sock_warn(fd, "%s: listen", __func__);
3832 evutil_closesocket(fd);
3833 EVUTIL_SET_SOCKET_ERROR(serrno);
3837 bound = evhttp_accept_socket_with_handle(http, fd);
3839 if (bound != NULL) {
3840 event_debug(("Bound to port %d - Awaiting connections ... ",
3849 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3851 struct evhttp_bound_socket *bound =
3852 evhttp_accept_socket_with_handle(http, fd);
3859 evhttp_foreach_bound_socket(struct evhttp *http,
3860 evhttp_bound_socket_foreach_fn *function,
3863 struct evhttp_bound_socket *bound;
3865 TAILQ_FOREACH(bound, &http->sockets, next)
3866 function(bound, argument);
3869 struct evhttp_bound_socket *
3870 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3872 struct evhttp_bound_socket *bound;
3873 struct evconnlistener *listener;
3875 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3877 listener = evconnlistener_new(http->base, NULL, NULL,
3879 0, /* Backlog is '0' because we already said 'listen' */
3884 bound = evhttp_bind_listener(http, listener);
3886 evconnlistener_free(listener);
3892 struct evhttp_bound_socket *
3893 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3895 struct evhttp_bound_socket *bound;
3897 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3901 bound->listener = listener;
3902 bound->bevcb = NULL;
3904 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3906 evconnlistener_set_cb(listener, accept_socket_cb, bound);
3911 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3913 return evconnlistener_get_fd(bound->listener);
3916 struct evconnlistener *
3917 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3919 return bound->listener;
3923 evhttp_bound_set_bevcb(struct evhttp_bound_socket *bound,
3924 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
3927 bound->bevcbarg = cbarg;
3931 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3933 TAILQ_REMOVE(&http->sockets, bound, next);
3934 evconnlistener_free(bound->listener);
3938 static struct evhttp*
3939 evhttp_new_object(void)
3941 struct evhttp *http = NULL;
3943 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3944 event_warn("%s: calloc", __func__);
3948 evutil_timerclear(&http->timeout_read);
3949 evutil_timerclear(&http->timeout_write);
3951 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3952 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3953 evhttp_set_default_content_type(http, "text/html; charset=ISO-8859-1");
3954 evhttp_set_allowed_methods(http,
3961 TAILQ_INIT(&http->sockets);
3962 TAILQ_INIT(&http->callbacks);
3963 TAILQ_INIT(&http->connections);
3964 TAILQ_INIT(&http->virtualhosts);
3965 TAILQ_INIT(&http->aliases);
3971 evhttp_new(struct event_base *base)
3973 struct evhttp *http = NULL;
3975 http = evhttp_new_object();
3984 * Start a web server on the specified address and port.
3988 evhttp_start(const char *address, ev_uint16_t port)
3990 struct evhttp *http = NULL;
3992 http = evhttp_new_object();
3995 if (evhttp_bind_socket(http, address, port) == -1) {
4004 evhttp_free(struct evhttp* http)
4006 struct evhttp_cb *http_cb;
4007 struct evhttp_connection *evcon;
4008 struct evhttp_bound_socket *bound;
4009 struct evhttp* vhost;
4010 struct evhttp_server_alias *alias;
4012 /* Remove the accepting part */
4013 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
4014 TAILQ_REMOVE(&http->sockets, bound, next);
4016 evconnlistener_free(bound->listener);
4021 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
4022 /* evhttp_connection_free removes the connection */
4023 evhttp_connection_free(evcon);
4026 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
4027 TAILQ_REMOVE(&http->callbacks, http_cb, next);
4028 mm_free(http_cb->what);
4032 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
4033 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
4038 if (http->vhost_pattern != NULL)
4039 mm_free(http->vhost_pattern);
4041 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
4042 TAILQ_REMOVE(&http->aliases, alias, next);
4043 mm_free(alias->alias);
4051 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
4052 struct evhttp* vhost)
4054 /* a vhost can only be a vhost once and should not have bound sockets */
4055 if (vhost->vhost_pattern != NULL ||
4056 TAILQ_FIRST(&vhost->sockets) != NULL)
4059 vhost->vhost_pattern = mm_strdup(pattern);
4060 if (vhost->vhost_pattern == NULL)
4063 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
4069 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
4071 if (vhost->vhost_pattern == NULL)
4074 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
4076 mm_free(vhost->vhost_pattern);
4077 vhost->vhost_pattern = NULL;
4083 evhttp_add_server_alias(struct evhttp *http, const char *alias)
4085 struct evhttp_server_alias *evalias;
4087 evalias = mm_calloc(1, sizeof(*evalias));
4091 evalias->alias = mm_strdup(alias);
4092 if (!evalias->alias) {
4097 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
4103 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
4105 struct evhttp_server_alias *evalias;
4107 TAILQ_FOREACH(evalias, &http->aliases, next) {
4108 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
4109 TAILQ_REMOVE(&http->aliases, evalias, next);
4110 mm_free(evalias->alias);
4120 evhttp_set_timeout(struct evhttp* http, int timeout)
4122 evhttp_set_timeout_(&http->timeout_read, timeout, -1);
4123 evhttp_set_timeout_(&http->timeout_write, timeout, -1);
4126 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv)
4128 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4129 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4132 evhttp_set_read_timeout_tv(struct evhttp* http, const struct timeval* tv)
4134 evhttp_set_timeout_tv_(&http->timeout_read, tv, -1);
4137 evhttp_set_write_timeout_tv(struct evhttp* http, const struct timeval* tv)
4139 evhttp_set_timeout_tv_(&http->timeout_write, tv, -1);
4142 int evhttp_set_flags(struct evhttp *http, int flags)
4144 int avail_flags = 0;
4145 avail_flags |= EVHTTP_SERVER_LINGERING_CLOSE;
4147 if (flags & ~avail_flags)
4149 http->flags &= ~avail_flags;
4151 http->flags |= flags;
4157 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
4159 if (max_headers_size < 0)
4160 http->default_max_headers_size = EV_SIZE_MAX;
4162 http->default_max_headers_size = max_headers_size;
4166 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
4168 if (max_body_size < 0)
4169 http->default_max_body_size = EV_UINT64_MAX;
4171 http->default_max_body_size = max_body_size;
4175 evhttp_set_max_connections(struct evhttp* http, int max_connections)
4177 if (max_connections < 0)
4178 http->connection_max = 0;
4180 http->connection_max = max_connections;
4184 evhttp_get_connection_count(struct evhttp* http)
4186 return http->connection_cnt;
4190 evhttp_set_default_content_type(struct evhttp *http,
4191 const char *content_type) {
4192 http->default_content_type = content_type;
4196 evhttp_set_allowed_methods(struct evhttp* http, ev_uint32_t methods)
4198 http->allowed_methods = methods;
4202 evhttp_set_ext_method_cmp(struct evhttp *http, evhttp_ext_method_cb cmp)
4204 http->ext_method_cmp = cmp;
4208 evhttp_set_cb(struct evhttp *http, const char *uri,
4209 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4211 struct evhttp_cb *http_cb;
4213 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4214 if (strcmp(http_cb->what, uri) == 0)
4218 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
4219 event_warn("%s: calloc", __func__);
4223 http_cb->what = mm_strdup(uri);
4224 if (http_cb->what == NULL) {
4225 event_warn("%s: strdup", __func__);
4230 http_cb->cbarg = cbarg;
4232 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
4238 evhttp_del_cb(struct evhttp *http, const char *uri)
4240 struct evhttp_cb *http_cb;
4242 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
4243 if (strcmp(http_cb->what, uri) == 0)
4246 if (http_cb == NULL)
4249 TAILQ_REMOVE(&http->callbacks, http_cb, next);
4250 mm_free(http_cb->what);
4257 evhttp_set_gencb(struct evhttp *http,
4258 void (*cb)(struct evhttp_request *, void *), void *cbarg)
4261 http->gencbarg = cbarg;
4265 evhttp_set_bevcb(struct evhttp *http,
4266 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg)
4269 http->bevcbarg = cbarg;
4273 evhttp_set_newreqcb(struct evhttp *http,
4274 int (*cb)(struct evhttp_request *, void *), void *cbarg)
4276 http->newreqcb = cb;
4277 http->newreqcbarg = cbarg;
4280 evhttp_set_errorcb(struct evhttp *http,
4281 int (*cb)(struct evhttp_request *, struct evbuffer *, int, const char *, void *),
4285 http->errorcbarg = cbarg;
4289 * Request related functions
4292 struct evhttp_request *
4293 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
4295 struct evhttp_request *req = NULL;
4297 /* Allocate request structure */
4298 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
4299 event_warn("%s: calloc", __func__);
4303 req->headers_size = 0;
4306 req->kind = EVHTTP_RESPONSE;
4307 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4308 if (req->input_headers == NULL) {
4309 event_warn("%s: calloc", __func__);
4312 TAILQ_INIT(req->input_headers);
4314 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
4315 if (req->output_headers == NULL) {
4316 event_warn("%s: calloc", __func__);
4319 TAILQ_INIT(req->output_headers);
4321 if ((req->input_buffer = evbuffer_new()) == NULL) {
4322 event_warn("%s: evbuffer_new", __func__);
4326 if ((req->output_buffer = evbuffer_new()) == NULL) {
4327 event_warn("%s: evbuffer_new", __func__);
4338 evhttp_request_free(req);
4343 evhttp_request_free(struct evhttp_request *req)
4345 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
4346 req->flags |= EVHTTP_REQ_NEEDS_FREE;
4350 if (req->remote_host != NULL)
4351 mm_free(req->remote_host);
4352 if (req->uri != NULL)
4354 if (req->uri_elems != NULL)
4355 evhttp_uri_free(req->uri_elems);
4356 if (req->response_code_line != NULL)
4357 mm_free(req->response_code_line);
4358 if (req->host_cache != NULL)
4359 mm_free(req->host_cache);
4361 evhttp_clear_headers(req->input_headers);
4362 mm_free(req->input_headers);
4364 evhttp_clear_headers(req->output_headers);
4365 mm_free(req->output_headers);
4367 if (req->input_buffer != NULL)
4368 evbuffer_free(req->input_buffer);
4370 if (req->output_buffer != NULL)
4371 evbuffer_free(req->output_buffer);
4377 evhttp_request_own(struct evhttp_request *req)
4379 req->flags |= EVHTTP_USER_OWNED;
4383 evhttp_request_is_owned(struct evhttp_request *req)
4385 return (req->flags & EVHTTP_USER_OWNED) != 0;
4388 struct evhttp_connection *
4389 evhttp_request_get_connection(struct evhttp_request *req)
4395 evhttp_connection_get_base(struct evhttp_connection *conn)
4401 evhttp_request_set_chunked_cb(struct evhttp_request *req,
4402 void (*cb)(struct evhttp_request *, void *))
4408 evhttp_request_set_header_cb(struct evhttp_request *req,
4409 int (*cb)(struct evhttp_request *, void *))
4411 req->header_cb = cb;
4415 evhttp_request_set_error_cb(struct evhttp_request *req,
4416 void (*cb)(enum evhttp_request_error, void *))
4422 evhttp_request_set_on_complete_cb(struct evhttp_request *req,
4423 void (*cb)(struct evhttp_request *, void *), void *cb_arg)
4425 req->on_complete_cb = cb;
4426 req->on_complete_cb_arg = cb_arg;
4430 * Allows for inspection of the request URI
4434 evhttp_request_get_uri(const struct evhttp_request *req) {
4435 if (req->uri == NULL)
4436 event_debug(("%s: request %p has no uri\n", __func__, req));
4440 const struct evhttp_uri *
4441 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
4442 if (req->uri_elems == NULL)
4443 event_debug(("%s: request %p has no uri elems\n",
4445 return (req->uri_elems);
4449 evhttp_request_get_host(struct evhttp_request *req)
4451 const char *host = NULL;
4453 if (req->host_cache)
4454 return req->host_cache;
4457 host = evhttp_uri_get_host(req->uri_elems);
4458 if (!host && req->input_headers) {
4462 host = evhttp_find_header(req->input_headers, "Host");
4463 /* The Host: header may include a port. Remove it here
4464 to be consistent with uri_elems case above. */
4466 p = host + strlen(host) - 1;
4467 while (p > host && EVUTIL_ISDIGIT_(*p))
4469 if (p > host && *p == ':') {
4471 req->host_cache = mm_malloc(len + 1);
4472 if (!req->host_cache) {
4473 event_warn("%s: malloc", __func__);
4476 memcpy(req->host_cache, host, len);
4477 req->host_cache[len] = '\0';
4478 host = req->host_cache;
4486 enum evhttp_cmd_type
4487 evhttp_request_get_command(const struct evhttp_request *req) {
4492 evhttp_request_get_response_code(const struct evhttp_request *req)
4494 return req->response_code;
4498 evhttp_request_get_response_code_line(const struct evhttp_request *req)
4500 return req->response_code_line;
4503 /** Returns the input headers */
4504 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
4506 return (req->input_headers);
4509 /** Returns the output headers */
4510 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
4512 return (req->output_headers);
4515 /** Returns the input buffer */
4516 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
4518 return (req->input_buffer);
4521 /** Returns the output buffer */
4522 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
4524 return (req->output_buffer);
4529 * Takes a file descriptor to read a request from.
4530 * The callback is executed once the whole request has been read.
4533 static struct evhttp_connection*
4534 evhttp_get_request_connection(
4535 struct evhttp* http,
4536 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen,
4537 struct bufferevent* bev)
4539 struct evhttp_connection *evcon;
4541 #ifdef EVENT__HAVE_STRUCT_SOCKADDR_UN
4542 if (sa->sa_family == AF_UNIX) {
4543 struct sockaddr_un *sa_un = (struct sockaddr_un *)sa;
4544 sa_un->sun_path[0] = '\0';
4549 if (sa->sa_family == AF_UNIX) {
4550 struct sockaddr_un *sockaddr = (struct sockaddr_un *)sa;
4552 event_debug(("%s: new request from unix socket on "
4553 EV_SOCK_FMT"\n", __func__, EV_SOCK_ARG(fd)));
4555 /* we need a connection object to put the http request on */
4556 if (!bev && http->bevcb != NULL) {
4557 bev = (*http->bevcb)(http->base, http->bevcbarg);
4560 evcon = evhttp_connection_base_bufferevent_unix_new(http->base,
4561 bev, sockaddr->sun_path);
4566 char *hostname = NULL, *portname = NULL;
4568 name_from_addr(sa, salen, &hostname, &portname);
4569 if (hostname == NULL || portname == NULL) {
4570 if (hostname) mm_free(hostname);
4571 if (portname) mm_free(portname);
4575 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
4576 __func__, hostname, portname, EV_SOCK_ARG(fd)));
4578 /* we need a connection object to put the http request on */
4579 if (!bev && http->bevcb != NULL) {
4580 bev = (*http->bevcb)(http->base, http->bevcbarg);
4582 evcon = evhttp_connection_base_bufferevent_new(
4583 http->base, NULL, bev, hostname, atoi(portname));
4590 evcon->max_headers_size = http->default_max_headers_size;
4591 evcon->max_body_size = http->default_max_body_size;
4592 if (http->flags & EVHTTP_SERVER_LINGERING_CLOSE)
4593 evcon->flags |= EVHTTP_CON_LINGERING_CLOSE;
4595 evcon->flags |= EVHTTP_CON_INCOMING;
4596 evcon->state = EVCON_READING_FIRSTLINE;
4598 if (bufferevent_replacefd(evcon->bufev, fd))
4600 if (bufferevent_enable(evcon->bufev, EV_READ))
4602 if (bufferevent_disable(evcon->bufev, EV_WRITE))
4604 bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen);
4609 evhttp_connection_free(evcon);
4614 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
4616 struct evhttp *http = evcon->http_server;
4617 struct evhttp_request *req;
4618 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
4621 if (evcon->address != NULL) {
4622 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
4623 event_warn("%s: strdup", __func__);
4624 evhttp_request_free(req);
4628 req->remote_port = evcon->port;
4630 req->evcon = evcon; /* the request ends up owning the connection */
4631 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4633 /* We did not present the request to the user yet, so treat it
4634 * as if the user was done with the request. This allows us
4635 * to free the request on a persistent connection if the
4636 * client drops it without sending a request.
4639 req->kind = EVHTTP_REQUEST;
4641 if (http->newreqcb && http->newreqcb(req, http->newreqcbarg) == -1) {
4642 evhttp_request_free(req);
4646 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4648 evhttp_start_read_(evcon);
4654 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
4655 struct sockaddr *sa, ev_socklen_t salen,
4656 struct bufferevent *bev)
4658 struct evhttp_connection *evcon;
4660 evcon = evhttp_get_request_connection(http, fd, sa, salen, bev);
4661 if (evcon == NULL) {
4662 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
4663 __func__, EV_SOCK_ARG(fd));
4664 evutil_closesocket(fd);
4668 /* the timeout can be used by the server to close idle connections */
4669 if (evutil_timerisset(&http->timeout_read))
4670 evhttp_connection_set_read_timeout_tv(evcon, &http->timeout_read);
4671 if (evutil_timerisset(&http->timeout_write))
4672 evhttp_connection_set_write_timeout_tv(evcon, &http->timeout_write);
4675 * if we want to accept more than one request on a connection,
4676 * we need to know which http server it belongs to.
4678 evcon->http_server = http;
4679 evcon->ext_method_cmp = http->ext_method_cmp;
4680 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
4681 http->connection_cnt++;
4683 /* send "service unavailable" if we've reached the connection limit */
4684 if (http->connection_max && http->connection_max < http->connection_cnt) {
4685 struct evhttp_request *req;
4687 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL) {
4688 evhttp_connection_free(evcon);
4692 req->evcon = evcon; /* the request owns the connection */
4693 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
4694 req->kind = EVHTTP_REQUEST;
4695 /* note, req->remote_host not needed since we don't read */
4697 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
4699 /* send error to client */
4700 evcon->state = EVCON_WRITING;
4701 bufferevent_enable(evcon->bufev, EV_READ); /* enable close events */
4702 evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL);
4704 } else if (evhttp_associate_new_request_with_connection(evcon) == -1)
4705 evhttp_connection_free(evcon);
4710 * Network helper functions that we do not want to export to the rest of
4715 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
4716 char **phost, char **pport)
4718 char ntop[NI_MAXHOST];
4719 char strport[NI_MAXSERV];
4722 #ifdef EVENT__HAVE_GETNAMEINFO
4723 ni_result = getnameinfo(sa, salen,
4724 ntop, sizeof(ntop), strport, sizeof(strport),
4725 NI_NUMERICHOST|NI_NUMERICSERV);
4727 if (ni_result != 0) {
4729 /* Windows doesn't have an EAI_SYSTEM. */
4730 if (ni_result == EAI_SYSTEM)
4731 event_err(1, "getnameinfo failed");
4734 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
4738 ni_result = fake_getnameinfo(sa, salen,
4739 ntop, sizeof(ntop), strport, sizeof(strport),
4740 NI_NUMERICHOST|NI_NUMERICSERV);
4745 *phost = mm_strdup(ntop);
4746 *pport = mm_strdup(strport);
4749 /* Create a non-blocking socket and bind it */
4750 static evutil_socket_t
4751 create_bind_socket_nonblock(struct evutil_addrinfo *ai, int reuse)
4758 /* Create listen socket */
4759 fd = evutil_socket_(ai ? ai->ai_family : AF_INET,
4760 SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
4762 event_sock_warn(-1, "socket");
4766 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
4769 if (evutil_make_listen_socket_reuseable(fd) < 0)
4774 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
4782 serrno = EVUTIL_SOCKET_ERROR();
4783 evutil_closesocket(fd);
4784 EVUTIL_SET_SOCKET_ERROR(serrno);
4788 static struct evutil_addrinfo *
4789 make_addrinfo(const char *address, ev_uint16_t port)
4791 struct evutil_addrinfo *ai = NULL;
4793 struct evutil_addrinfo hints;
4794 char strport[NI_MAXSERV];
4797 memset(&hints, 0, sizeof(hints));
4798 hints.ai_family = AF_UNSPEC;
4799 hints.ai_socktype = SOCK_STREAM;
4800 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
4801 * types we don't have an interface to connect to. */
4802 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
4803 evutil_snprintf(strport, sizeof(strport), "%d", port);
4804 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
4806 if (ai_result == EVUTIL_EAI_SYSTEM)
4807 event_warn("getaddrinfo");
4809 event_warnx("getaddrinfo: %s",
4810 evutil_gai_strerror(ai_result));
4817 static evutil_socket_t
4818 bind_socket(const char *address, ev_uint16_t port, int reuse)
4821 struct evutil_addrinfo *aitop = NULL;
4823 /* just create an unbound socket */
4824 if (address == NULL && port == 0)
4825 return create_bind_socket_nonblock(NULL, 0);
4827 aitop = make_addrinfo(address, port);
4832 fd = create_bind_socket_nonblock(aitop, reuse);
4834 evutil_freeaddrinfo(aitop);
4841 char *scheme; /* scheme; e.g http, ftp etc */
4842 char *userinfo; /* userinfo (typically username:pass), or NULL */
4843 char *host; /* hostname, IP address, or NULL */
4844 int port; /* port, or zero */
4846 char *unixsocket; /* unix domain socket or NULL */
4848 char *path; /* path, or "". */
4849 char *query; /* query, or NULL */
4850 char *fragment; /* fragment or NULL */
4854 evhttp_uri_new(void)
4856 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
4863 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
4868 /* Return true if the string starting at s and ending immediately before eos
4869 * is a valid URI scheme according to RFC3986
4872 scheme_ok(const char *s, const char *eos)
4874 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4875 EVUTIL_ASSERT(eos >= s);
4878 if (!EVUTIL_ISALPHA_(*s))
4881 if (! EVUTIL_ISALNUM_(*s) &&
4882 *s != '+' && *s != '-' && *s != '.')
4888 #define SUBDELIMS "!$&'()*+,;="
4890 /* Return true iff [s..eos) is a valid userinfo */
4892 userinfo_ok(const char *s, const char *eos)
4895 if (CHAR_IS_UNRESERVED(*s) ||
4896 strchr(SUBDELIMS, *s) ||
4899 else if (*s == '%' && s+2 < eos &&
4900 EVUTIL_ISXDIGIT_(s[1]) &&
4901 EVUTIL_ISXDIGIT_(s[2]))
4910 regname_ok(const char *s, const char *eos)
4912 while (s && s<eos) {
4913 if (CHAR_IS_UNRESERVED(*s) ||
4914 strchr(SUBDELIMS, *s))
4916 else if (*s == '%' &&
4917 EVUTIL_ISXDIGIT_(s[1]) &&
4918 EVUTIL_ISXDIGIT_(s[2]))
4927 parse_port(const char *s, const char *eos)
4931 if (! EVUTIL_ISDIGIT_(*s))
4933 portnum = (portnum * 10) + (*s - '0');
4936 if (portnum > 65535)
4943 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4945 bracket_addr_ok(const char *s, const char *eos)
4947 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4950 /* IPvFuture, or junk.
4951 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4953 s += 2; /* skip [v */
4955 if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/
4957 while (s < eos && *s != '.') {
4958 if (EVUTIL_ISXDIGIT_(*s))
4967 if (CHAR_IS_UNRESERVED(*s) ||
4968 strchr(SUBDELIMS, *s) ||
4978 ev_ssize_t n_chars = eos-s-2;
4979 struct in6_addr in6;
4980 if (n_chars >= 64) /* way too long */
4982 memcpy(buf, s+1, n_chars);
4984 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4989 parse_authority(struct evhttp_uri *uri, char *s, char *eos, unsigned *flags)
4996 uri->host = mm_strdup("");
4997 if (uri->host == NULL) {
4998 event_warn("%s: strdup", __func__);
5004 /* Optionally, we start with "userinfo@" */
5006 cp = strchr(s, '@');
5007 if (cp && cp < eos) {
5008 if (! userinfo_ok(s,cp))
5011 uri->userinfo = mm_strdup(s);
5012 if (uri->userinfo == NULL) {
5013 event_warn("%s: strdup", __func__);
5021 if (*flags & EVHTTP_URI_UNIX_SOCKET && !strncmp(cp, "unix:", 5)) {
5022 char *e = strchr(cp + 5, ':');
5025 uri->unixsocket = mm_strdup(cp + 5);
5033 /* Optionally, we end with ":port" */
5034 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port)
5036 if (port >= cp && *port == ':') {
5037 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
5040 else if ((uri->port = parse_port(port+1, eos))<0)
5044 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
5045 * an IP-Literal, or a reg-name */
5046 EVUTIL_ASSERT(eos >= cp);
5048 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
5049 /* IPv6address, IP-Literal, or junk. */
5050 if (! bracket_addr_ok(cp, eos))
5052 if (*flags & EVHTTP_URI_HOST_STRIP_BRACKETS)
5055 /* Make sure the host part is ok. */
5056 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
5060 uri->host = mm_malloc(len+1);
5061 if (uri->host == NULL) {
5062 event_warn("%s: malloc", __func__);
5065 if (*cp == '[' && *flags & EVHTTP_URI_HOST_STRIP_BRACKETS) {
5066 memcpy(uri->host, cp+1, len);
5067 *flags |= _EVHTTP_URI_HOST_HAS_BRACKETS;
5069 memcpy(uri->host, cp, len);
5071 uri->host[len] = '\0';
5077 end_of_authority(char *cp)
5080 if (*cp == '?' || *cp == '#' || *cp == '/')
5093 /* Return the character after the longest prefix of 'cp' that matches...
5094 * *pchar / "/" if allow_qchars is false, or
5095 * *(pchar / "/" / "?") if allow_qchars is true.
5098 end_of_path(char *cp, enum uri_part part, unsigned flags)
5100 if (flags & EVHTTP_URI_NONCONFORMANT) {
5101 /* If NONCONFORMANT:
5102 * Path is everything up to a # or ? or nul.
5103 * Query is everything up a # or nul
5104 * Fragment is everything up to a nul.
5108 while (*cp && *cp != '#' && *cp != '?')
5112 while (*cp && *cp != '#')
5123 if (CHAR_IS_UNRESERVED(*cp) ||
5124 strchr(SUBDELIMS, *cp) ||
5125 *cp == ':' || *cp == '@' || *cp == '/')
5127 else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) &&
5128 EVUTIL_ISXDIGIT_(cp[2]))
5130 else if (*cp == '?' && part != PART_PATH)
5139 path_matches_noscheme(const char *cp)
5144 else if (*cp == '/')
5152 evhttp_uri_parse(const char *source_uri)
5154 return evhttp_uri_parse_with_flags(source_uri, 0);
5158 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
5160 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
5161 char *path = NULL, *fragment = NULL;
5162 int got_authority = 0;
5164 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
5166 event_warn("%s: calloc", __func__);
5172 readbuf = mm_strdup(source_uri);
5173 if (readbuf == NULL) {
5174 event_warn("%s: strdup", __func__);
5181 /* We try to follow RFC3986 here as much as we can, and match
5184 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
5186 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
5190 token = strchr(readp, ':');
5191 if (token && scheme_ok(readp,token)) {
5193 uri->scheme = mm_strdup(readp);
5194 if (uri->scheme == NULL) {
5195 event_warn("%s: strdup", __func__);
5198 readp = token+1; /* eat : */
5201 /* 2. Optionally, "//" then an 'authority' part. */
5202 if (readp[0]=='/' && readp[1] == '/') {
5206 path = end_of_authority(readp);
5207 if (parse_authority(uri, authority, path, &uri->flags) < 0)
5213 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
5216 readp = end_of_path(path, PART_PATH, flags);
5219 if (*readp == '?') {
5223 readp = end_of_path(readp, PART_QUERY, flags);
5226 if (*readp == '#') {
5230 readp = end_of_path(readp, PART_FRAGMENT, flags);
5232 if (*readp != '\0') {
5236 /* These next two cases may be unreachable; I'm leaving them
5237 * in to be defensive. */
5238 /* If you didn't get an authority, the path can't begin with "//" */
5239 if (!got_authority && path[0]=='/' && path[1]=='/')
5241 /* If you did get an authority, the path must begin with "/" or be
5243 if (got_authority && path[0] != '/' && path[0] != '\0')
5245 /* (End of maybe-unreachable cases) */
5247 /* If there was no scheme, the first part of the path (if any) must
5248 * have no colon in it. */
5249 if (! uri->scheme && !path_matches_noscheme(path))
5252 EVUTIL_ASSERT(path);
5253 uri->path = mm_strdup(path);
5254 if (uri->path == NULL) {
5255 event_warn("%s: strdup", __func__);
5260 uri->query = mm_strdup(query);
5261 if (uri->query == NULL) {
5262 event_warn("%s: strdup", __func__);
5267 uri->fragment = mm_strdup(fragment);
5268 if (uri->fragment == NULL) {
5269 event_warn("%s: strdup", __func__);
5279 evhttp_uri_free(uri);
5285 static struct evhttp_uri *
5286 evhttp_uri_parse_authority(char *source_uri, unsigned flags)
5288 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
5292 event_warn("%s: calloc", __func__);
5298 end = end_of_authority(source_uri);
5299 if (parse_authority(uri, source_uri, end, &uri->flags) < 0)
5302 uri->path = mm_strdup("");
5303 if (uri->path == NULL) {
5304 event_warn("%s: strdup", __func__);
5311 evhttp_uri_free(uri);
5316 evhttp_uri_free(struct evhttp_uri *uri)
5318 #define URI_FREE_STR_(f) \
5323 URI_FREE_STR_(scheme);
5324 URI_FREE_STR_(userinfo);
5325 URI_FREE_STR_(host);
5327 URI_FREE_STR_(unixsocket);
5329 URI_FREE_STR_(path);
5330 URI_FREE_STR_(query);
5331 URI_FREE_STR_(fragment);
5334 #undef URI_FREE_STR_
5338 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
5340 struct evbuffer *tmp = 0;
5341 size_t joined_size = 0;
5342 char *output = NULL;
5344 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
5346 if (!uri || !buf || !limit)
5349 tmp = evbuffer_new();
5355 evbuffer_add(tmp, ":", 1);
5358 if (uri->unixsocket) {
5359 evbuffer_add(tmp, "//", 2);
5361 evbuffer_add_printf(tmp, "%s@", uri->userinfo);
5362 evbuffer_add_printf(tmp, "unix:%s:", uri->unixsocket);
5367 evbuffer_add(tmp, "//", 2);
5369 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
5370 if (uri->flags & _EVHTTP_URI_HOST_HAS_BRACKETS) {
5371 evbuffer_add(tmp, "[", 1);
5373 evbuffer_add(tmp, "]", 1);
5378 evbuffer_add_printf(tmp,":%d", uri->port);
5380 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
5388 evbuffer_add(tmp, "?", 1);
5392 if (uri->fragment) {
5393 evbuffer_add(tmp, "#", 1);
5397 evbuffer_add(tmp, "\0", 1); /* NUL */
5399 joined_size = evbuffer_get_length(tmp);
5401 if (joined_size > limit) {
5402 /* It doesn't fit. */
5406 evbuffer_remove(tmp, buf, joined_size);
5417 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
5422 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
5424 return uri->userinfo;
5427 evhttp_uri_get_host(const struct evhttp_uri *uri)
5433 evhttp_uri_get_unixsocket(const struct evhttp_uri *uri)
5435 return uri->unixsocket;
5439 evhttp_uri_get_port(const struct evhttp_uri *uri)
5444 evhttp_uri_get_path(const struct evhttp_uri *uri)
5449 evhttp_uri_get_query(const struct evhttp_uri *uri)
5454 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
5456 return uri->fragment;
5459 #define URI_SET_STR_(f) do { \
5463 if ((uri->f = mm_strdup(f)) == NULL) { \
5464 event_warn("%s: strdup()", __func__); \
5473 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
5475 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
5478 URI_SET_STR_(scheme);
5482 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
5484 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
5486 URI_SET_STR_(userinfo);
5490 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
5497 if (host[0] == '[') {
5498 if (! bracket_addr_ok(host, host+len))
5501 if (! regname_ok(host, host+len))
5506 if (host && host[0] == '[' && uri->flags & EVHTTP_URI_HOST_STRIP_BRACKETS) {
5510 new_host = mm_realloc(uri->host, len+1);
5515 memcpy(new_host, host+1, len);
5516 new_host[len] = '\0';
5517 uri->host = new_host;
5519 uri->flags |= _EVHTTP_URI_HOST_HAS_BRACKETS;
5522 uri->flags &= ~_EVHTTP_URI_HOST_HAS_BRACKETS;
5529 evhttp_uri_set_unixsocket(struct evhttp_uri *uri, const char *unixsocket)
5531 URI_SET_STR_(unixsocket);
5536 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
5543 #define end_of_cpath(cp,p,f) \
5544 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
5547 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
5549 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
5556 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
5558 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
5560 URI_SET_STR_(query);
5564 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
5566 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
5568 URI_SET_STR_(fragment);