2 * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
3 * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "event2/event-config.h"
30 #ifdef _EVENT_HAVE_SYS_PARAM_H
31 #include <sys/param.h>
33 #ifdef _EVENT_HAVE_SYS_TYPES_H
34 #include <sys/types.h>
37 #ifdef _EVENT_HAVE_SYS_TIME_H
40 #ifdef HAVE_SYS_IOCCOM_H
41 #include <sys/ioccom.h>
45 #include <sys/resource.h>
46 #include <sys/socket.h>
54 #include <sys/queue.h>
56 #ifdef _EVENT_HAVE_NETINET_IN_H
57 #include <netinet/in.h>
59 #ifdef _EVENT_HAVE_NETDB_H
76 #ifdef _EVENT_HAVE_UNISTD_H
79 #ifdef _EVENT_HAVE_FCNTL_H
83 #undef timeout_pending
84 #undef timeout_initialized
86 #include "strlcpy-internal.h"
87 #include "event2/http.h"
88 #include "event2/event.h"
89 #include "event2/buffer.h"
90 #include "event2/bufferevent.h"
91 #include "event2/bufferevent_compat.h"
92 #include "event2/http_struct.h"
93 #include "event2/http_compat.h"
94 #include "event2/util.h"
95 #include "event2/listener.h"
96 #include "log-internal.h"
97 #include "util-internal.h"
98 #include "http-internal.h"
99 #include "mm-internal.h"
101 #ifndef _EVENT_HAVE_GETNAMEINFO
102 #define NI_MAXSERV 32
103 #define NI_MAXHOST 1025
105 #ifndef NI_NUMERICHOST
106 #define NI_NUMERICHOST 1
109 #ifndef NI_NUMERICSERV
110 #define NI_NUMERICSERV 2
114 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
115 size_t hostlen, char *serv, size_t servlen, int flags)
117 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
121 evutil_snprintf(tmpserv, sizeof(tmpserv),
122 "%d", ntohs(sin->sin_port));
123 if (strlcpy(serv, tmpserv, servlen) >= servlen)
128 if (flags & NI_NUMERICHOST) {
129 if (strlcpy(host, inet_ntoa(sin->sin_addr),
136 hp = gethostbyaddr((char *)&sin->sin_addr,
137 sizeof(struct in_addr), AF_INET);
141 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
152 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \
153 ((req)->major < (major_v) || \
154 ((req)->major == (major_v) && (req)->minor < (minor_v)))
156 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \
157 ((req)->major > (major_v) || \
158 ((req)->major == (major_v) && (req)->minor >= (minor_v)))
161 #define MIN(a,b) (((a)<(b))?(a):(b))
166 static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse);
167 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
168 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
169 static int evhttp_associate_new_request_with_connection(
170 struct evhttp_connection *evcon);
171 static void evhttp_connection_start_detectclose(
172 struct evhttp_connection *evcon);
173 static void evhttp_connection_stop_detectclose(
174 struct evhttp_connection *evcon);
175 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
176 static void evhttp_read_firstline(struct evhttp_connection *evcon,
177 struct evhttp_request *req);
178 static void evhttp_read_header(struct evhttp_connection *evcon,
179 struct evhttp_request *req);
180 static int evhttp_add_header_internal(struct evkeyvalq *headers,
181 const char *key, const char *value);
182 static const char *evhttp_response_phrase_internal(int code);
183 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t);
184 static void evhttp_write_buffer(struct evhttp_connection *,
185 void (*)(struct evhttp_connection *, void *), void *);
186 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
188 /* callbacks for bufferevent */
189 static void evhttp_read_cb(struct bufferevent *, void *);
190 static void evhttp_write_cb(struct bufferevent *, void *);
191 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
192 static int evhttp_decode_uri_internal(const char *uri, size_t length,
193 char *ret, int decode_plus);
194 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
195 const char *hostname);
197 #ifndef _EVENT_HAVE_STRSEP
198 /* strsep replacement for platforms that lack it. Only works if
199 * del is one character long. */
201 strsep(char **s, const char *del)
204 EVUTIL_ASSERT(strlen(del) == 1);
208 d = strstr(tok, del);
219 html_replace(char ch, char *buf)
236 /* Echo the character back */
244 * Replaces <, >, ", ' and & with <, >, ",
245 * ' and & correspondingly.
247 * The returned string needs to be freed by the caller.
251 evhttp_htmlescape(const char *html)
254 size_t new_size = 0, old_size = strlen(html);
255 char *escaped_html, *p;
256 char scratch_space[2];
258 for (i = 0; i < old_size; ++i)
259 new_size += strlen(html_replace(html[i], scratch_space));
261 p = escaped_html = mm_malloc(new_size + 1);
262 if (escaped_html == NULL) {
263 event_warn("%s: malloc(%ld)", __func__, (long)(new_size + 1));
266 for (i = 0; i < old_size; ++i) {
267 const char *replaced = html_replace(html[i], scratch_space);
268 size_t len = strlen(replaced);
269 memcpy(p, replaced, len);
275 return (escaped_html);
278 /** Given an evhttp_cmd_type, returns a constant string containing the
279 * equivalent HTTP command, or NULL if the evhttp_command_type is
282 evhttp_method(enum evhttp_cmd_type type)
290 case EVHTTP_REQ_POST:
293 case EVHTTP_REQ_HEAD:
299 case EVHTTP_REQ_DELETE:
302 case EVHTTP_REQ_OPTIONS:
305 case EVHTTP_REQ_TRACE:
308 case EVHTTP_REQ_CONNECT:
311 case EVHTTP_REQ_PATCH:
323 * Determines if a response should have a body.
324 * Follows the rules in RFC 2616 section 4.3.
325 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
329 evhttp_response_needs_body(struct evhttp_request *req)
331 return (req->response_code != HTTP_NOCONTENT &&
332 req->response_code != HTTP_NOTMODIFIED &&
333 (req->response_code < 100 || req->response_code >= 200) &&
334 req->type != EVHTTP_REQ_HEAD);
337 /** Helper: adds the event 'ev' with the timeout 'timeout', or with
338 * default_timeout if timeout is -1.
341 evhttp_add_event(struct event *ev, int timeout, int default_timeout)
346 evutil_timerclear(&tv);
347 tv.tv_sec = timeout != -1 ? timeout : default_timeout;
348 return event_add(ev, &tv);
350 return event_add(ev, NULL);
354 /** Helper: called after we've added some data to an evcon's bufferevent's
355 * output buffer. Sets the evconn's writing-is-done callback, and puts
356 * the bufferevent into writing mode.
359 evhttp_write_buffer(struct evhttp_connection *evcon,
360 void (*cb)(struct evhttp_connection *, void *), void *arg)
362 event_debug(("%s: preparing to write buffer\n", __func__));
368 bufferevent_enable(evcon->bufev, EV_WRITE);
370 /* Disable the read callback: we don't actually care about data;
371 * we only care about close detection. (We don't disable reading,
372 * since we *do* want to learn about any close events.) */
373 bufferevent_setcb(evcon->bufev,
381 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
383 bufferevent_disable(evcon->bufev, EV_WRITE);
387 evhttp_send_continue(struct evhttp_connection *evcon,
388 struct evhttp_request *req)
390 bufferevent_enable(evcon->bufev, EV_WRITE);
391 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
392 "HTTP/%d.%d 100 Continue\r\n\r\n",
393 req->major, req->minor);
394 evcon->cb = evhttp_send_continue_done;
395 evcon->cb_arg = NULL;
396 bufferevent_setcb(evcon->bufev,
403 /** Helper: returns true iff evconn is in any connected state. */
405 evhttp_connected(struct evhttp_connection *evcon)
407 switch (evcon->state) {
408 case EVCON_DISCONNECTED:
409 case EVCON_CONNECTING:
412 case EVCON_READING_FIRSTLINE:
413 case EVCON_READING_HEADERS:
414 case EVCON_READING_BODY:
415 case EVCON_READING_TRAILER:
422 /* Create the headers needed for an outgoing HTTP request, adds them to
423 * the request's header list, and writes the request line to the
424 * connection's output buffer.
427 evhttp_make_header_request(struct evhttp_connection *evcon,
428 struct evhttp_request *req)
432 evhttp_remove_header(req->output_headers, "Proxy-Connection");
434 /* Generate request line */
435 method = evhttp_method(req->type);
436 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
437 "%s %s HTTP/%d.%d\r\n",
438 method, req->uri, req->major, req->minor);
440 /* Add the content length on a post or put request if missing */
441 if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
442 evhttp_find_header(req->output_headers, "Content-Length") == NULL){
444 evutil_snprintf(size, sizeof(size), "%ld",
445 (long)evbuffer_get_length(req->output_buffer));
446 evhttp_add_header(req->output_headers, "Content-Length", size);
450 /** Return true if the list of headers in 'headers', intepreted with respect
451 * to flags, means that we should send a "connection: close" when the request
454 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
456 if (flags & EVHTTP_PROXY_REQUEST) {
457 /* proxy connection */
458 const char *connection = evhttp_find_header(headers, "Proxy-Connection");
459 return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
461 const char *connection = evhttp_find_header(headers, "Connection");
462 return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
466 /* Return true iff 'headers' contains 'Connection: keep-alive' */
468 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
470 const char *connection = evhttp_find_header(headers, "Connection");
471 return (connection != NULL
472 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
475 /* Add a correct "Date" header to headers, unless it already has one. */
477 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
479 if (evhttp_find_header(headers, "Date") == NULL) {
485 time_t t = time(NULL);
492 if (strftime(date, sizeof(date),
493 "%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) {
494 evhttp_add_header(headers, "Date", date);
499 /* Add a "Content-Length" header with value 'content_length' to headers,
500 * unless it already has a content-length or transfer-encoding header. */
502 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
503 long content_length) /* XXX use size_t or int64, not long. */
505 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
506 evhttp_find_header(headers, "Content-Length") == NULL) {
508 evutil_snprintf(len, sizeof(len), "%ld", content_length);
509 evhttp_add_header(headers, "Content-Length", len);
514 * Create the headers needed for an HTTP reply in req->output_headers,
515 * and write the first HTTP response for req line to evcon.
518 evhttp_make_header_response(struct evhttp_connection *evcon,
519 struct evhttp_request *req)
521 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
522 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
523 "HTTP/%d.%d %d %s\r\n",
524 req->major, req->minor, req->response_code,
525 req->response_code_line);
527 if (req->major == 1) {
529 evhttp_maybe_add_date_header(req->output_headers);
532 * if the protocol is 1.0; and the connection was keep-alive
533 * we need to add a keep-alive header, too.
535 if (req->minor == 0 && is_keepalive)
536 evhttp_add_header(req->output_headers,
537 "Connection", "keep-alive");
539 if ((req->minor >= 1 || is_keepalive) &&
540 evhttp_response_needs_body(req)) {
542 * we need to add the content length if the
543 * user did not give it, this is required for
544 * persistent connections to work.
546 evhttp_maybe_add_content_length_header(
548 (long)evbuffer_get_length(req->output_buffer));
552 /* Potentially add headers for unidentified content. */
553 if (evhttp_response_needs_body(req)) {
554 if (evhttp_find_header(req->output_headers,
555 "Content-Type") == NULL) {
556 evhttp_add_header(req->output_headers,
557 "Content-Type", "text/html; charset=ISO-8859-1");
561 /* if the request asked for a close, we send a close, too */
562 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
563 evhttp_remove_header(req->output_headers, "Connection");
564 if (!(req->flags & EVHTTP_PROXY_REQUEST))
565 evhttp_add_header(req->output_headers, "Connection", "close");
566 evhttp_remove_header(req->output_headers, "Proxy-Connection");
570 /** Generate all headers appropriate for sending the http request in req (or
571 * the response, if we're sending a response), and write them to evcon's
572 * bufferevent. Also writes all data from req->output_buffer */
574 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
576 struct evkeyval *header;
577 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
580 * Depending if this is a HTTP request or response, we might need to
581 * add some new headers or remove existing headers.
583 if (req->kind == EVHTTP_REQUEST) {
584 evhttp_make_header_request(evcon, req);
586 evhttp_make_header_response(evcon, req);
589 TAILQ_FOREACH(header, req->output_headers, next) {
590 evbuffer_add_printf(output, "%s: %s\r\n",
591 header->key, header->value);
593 evbuffer_add(output, "\r\n", 2);
595 if (evbuffer_get_length(req->output_buffer) > 0) {
597 * For a request, we add the POST data, for a reply, this
598 * is the regular data.
600 /* XXX We might want to support waiting (a limited amount of
601 time) for a continue status line from the server before
602 sending POST/PUT message bodies. */
603 evbuffer_add_buffer(output, req->output_buffer);
608 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
609 ev_ssize_t new_max_headers_size)
611 if (new_max_headers_size<0)
612 evcon->max_headers_size = EV_SIZE_MAX;
614 evcon->max_headers_size = new_max_headers_size;
617 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
618 ev_ssize_t new_max_body_size)
620 if (new_max_body_size<0)
621 evcon->max_body_size = EV_UINT64_MAX;
623 evcon->max_body_size = new_max_body_size;
627 evhttp_connection_incoming_fail(struct evhttp_request *req,
628 enum evhttp_connection_error error)
631 case EVCON_HTTP_TIMEOUT:
634 * these are cases in which we probably should just
635 * close the connection and not send a reply. this
636 * case may happen when a browser keeps a persistent
637 * connection open and we timeout on the read. when
638 * the request is still being used for sending, we
639 * need to disassociated it from the connection here.
641 if (!req->userdone) {
642 /* remove it so that it will not be freed */
643 TAILQ_REMOVE(&req->evcon->requests, req, next);
644 /* indicate that this request no longer has a
650 case EVCON_HTTP_INVALID_HEADER:
651 case EVCON_HTTP_BUFFER_ERROR:
652 case EVCON_HTTP_REQUEST_CANCEL:
653 default: /* xxx: probably should just error on default */
654 /* the callback looks at the uri to determine errors */
659 if (req->uri_elems) {
660 evhttp_uri_free(req->uri_elems);
661 req->uri_elems = NULL;
665 * the callback needs to send a reply, once the reply has
666 * been send, the connection should get freed.
668 (*req->cb)(req, req->cb_arg);
674 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
675 * given in error. If it's an outgoing connection, reset the connection,
676 * retry any pending requests, and inform the user. If it's incoming,
677 * delegates to evhttp_connection_incoming_fail(). */
679 evhttp_connection_fail(struct evhttp_connection *evcon,
680 enum evhttp_connection_error error)
682 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
683 void (*cb)(struct evhttp_request *, void *);
685 EVUTIL_ASSERT(req != NULL);
687 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
689 if (evcon->flags & EVHTTP_CON_INCOMING) {
691 * for incoming requests, there are two different
692 * failure cases. it's either a network level error
693 * or an http layer error. for problems on the network
694 * layer like timeouts we just drop the connections.
695 * For HTTP problems, we might have to send back a
696 * reply before the connection can be freed.
698 if (evhttp_connection_incoming_fail(req, error) == -1)
699 evhttp_connection_free(evcon);
703 /* when the request was canceled, the callback is not executed */
704 if (error != EVCON_HTTP_REQUEST_CANCEL) {
705 /* save the callback for later; the cb might free our object */
707 cb_arg = req->cb_arg;
713 /* do not fail all requests; the next request is going to get
714 * send over a new connection. when a user cancels a request,
715 * all other pending requests should be processed as normal
717 TAILQ_REMOVE(&evcon->requests, req, next);
718 evhttp_request_free(req);
720 /* reset the connection */
721 evhttp_connection_reset(evcon);
723 /* We are trying the next request that was queued on us */
724 if (TAILQ_FIRST(&evcon->requests) != NULL)
725 evhttp_connection_connect(evcon);
727 /* inform the user */
732 /* Bufferevent callback: invoked when any data has been written from an
733 * http connection's bufferevent */
735 evhttp_write_cb(struct bufferevent *bufev, void *arg)
737 struct evhttp_connection *evcon = arg;
739 /* Activate our call back */
740 if (evcon->cb != NULL)
741 (*evcon->cb)(evcon, evcon->cb_arg);
745 * Advance the connection state.
746 * - If this is an outgoing connection, we've just processed the response;
747 * idle or close the connection.
748 * - If this is an incoming connection, we've just processed the request;
752 evhttp_connection_done(struct evhttp_connection *evcon)
754 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
755 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
758 /* idle or close the connection */
760 TAILQ_REMOVE(&evcon->requests, req, next);
763 evcon->state = EVCON_IDLE;
766 evhttp_is_connection_close(req->flags, req->input_headers)||
767 evhttp_is_connection_close(req->flags, req->output_headers);
769 /* check if we got asked to close the connection */
771 evhttp_connection_reset(evcon);
773 if (TAILQ_FIRST(&evcon->requests) != NULL) {
775 * We have more requests; reset the connection
776 * and deal with the next request.
778 if (!evhttp_connected(evcon))
779 evhttp_connection_connect(evcon);
781 evhttp_request_dispatch(evcon);
782 } else if (!need_close) {
784 * The connection is going to be persistent, but we
785 * need to detect if the other side closes it.
787 evhttp_connection_start_detectclose(evcon);
791 * incoming connection - we need to leave the request on the
792 * connection so that we can reply to it.
794 evcon->state = EVCON_WRITING;
797 /* notify the user of the request */
798 (*req->cb)(req, req->cb_arg);
800 /* if this was an outgoing request, we own and it's done. so free it.
801 * unless the callback specifically requested to own the request.
803 if (con_outgoing && ((req->flags & EVHTTP_USER_OWNED) == 0)) {
804 evhttp_request_free(req);
809 * Handles reading from a chunked request.
810 * return ALL_DATA_READ:
811 * all data has been read
812 * return MORE_DATA_EXPECTED:
813 * more data is expected
814 * return DATA_CORRUPTED:
816 * return REQUEST_CANCELED:
817 * request was canceled by the user calling evhttp_cancel_request
818 * return DATA_TOO_LONG:
819 * ran over the maximum limit
822 static enum message_read_status
823 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
827 while ((len = evbuffer_get_length(buf)) > 0) {
828 if (req->ntoread < 0) {
829 /* Read chunk size */
831 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
836 /* the last chunk is on a new line? */
837 if (strlen(p) == 0) {
841 ntoread = evutil_strtoll(p, &endp, 16);
842 error = (*p == '\0' ||
843 (*endp != '\0' && *endp != ' ') ||
847 /* could not get chunk size */
848 return (DATA_CORRUPTED);
850 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
851 /* failed body length test */
852 event_debug(("Request body is too long"));
853 return (DATA_TOO_LONG);
855 req->body_size += (size_t)ntoread;
856 req->ntoread = ntoread;
857 if (req->ntoread == 0) {
859 return (ALL_DATA_READ);
864 /* don't have enough to complete a chunk; wait for more */
865 if (len < req->ntoread)
866 return (MORE_DATA_EXPECTED);
868 /* Completed chunk */
869 /* XXXX fixme: what if req->ntoread is > SIZE_T_MAX? */
870 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
872 if (req->chunk_cb != NULL) {
873 req->flags |= EVHTTP_REQ_DEFER_FREE;
874 (*req->chunk_cb)(req, req->cb_arg);
875 evbuffer_drain(req->input_buffer,
876 evbuffer_get_length(req->input_buffer));
877 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
878 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
879 return (REQUEST_CANCELED);
884 return (MORE_DATA_EXPECTED);
888 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
890 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
892 switch (evhttp_parse_headers(req, buf)) {
895 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
898 bufferevent_disable(evcon->bufev, EV_READ);
899 evhttp_connection_done(evcon);
901 case MORE_DATA_EXPECTED:
902 case REQUEST_CANCELED: /* ??? */
904 bufferevent_enable(evcon->bufev, EV_READ);
910 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
912 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
915 switch (evhttp_handle_chunked_read(req, buf)) {
917 /* finished last chunk */
918 evcon->state = EVCON_READING_TRAILER;
919 evhttp_read_trailer(evcon, req);
922 case DATA_TOO_LONG:/*separate error for this? XXX */
924 evhttp_connection_fail(evcon,
925 EVCON_HTTP_INVALID_HEADER);
927 case REQUEST_CANCELED:
928 /* request canceled */
929 evhttp_request_free(req);
931 case MORE_DATA_EXPECTED:
935 } else if (req->ntoread < 0) {
936 /* Read until connection close. */
937 req->body_size += evbuffer_get_length(buf);
938 evbuffer_add_buffer(req->input_buffer, buf);
939 } else if (req->chunk_cb != NULL ||
940 evbuffer_get_length(buf) >= (size_t)req->ntoread) {
941 /* We've postponed moving the data until now, but we're
942 * about to use it. */
943 size_t n = evbuffer_get_length(buf);
944 if (n > (size_t) req->ntoread)
945 n = (size_t) req->ntoread;
948 evbuffer_remove_buffer(buf, req->input_buffer, n);
951 if (req->body_size > req->evcon->max_body_size) {
952 /* failed body length test */
953 event_debug(("Request body is too long"));
954 evhttp_connection_fail(evcon,
955 EVCON_HTTP_INVALID_HEADER);
959 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
960 req->flags |= EVHTTP_REQ_DEFER_FREE;
961 (*req->chunk_cb)(req, req->cb_arg);
962 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
963 evbuffer_drain(req->input_buffer,
964 evbuffer_get_length(req->input_buffer));
965 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
966 evhttp_request_free(req);
971 if (req->ntoread == 0) {
972 bufferevent_disable(evcon->bufev, EV_READ);
973 /* Completed content length */
974 evhttp_connection_done(evcon);
979 bufferevent_enable(evcon->bufev, EV_READ);
982 #define get_deferred_queue(evcon) \
983 (event_base_get_deferred_cb_queue((evcon)->base))
986 * Gets called when more data becomes available
990 evhttp_read_cb(struct bufferevent *bufev, void *arg)
992 struct evhttp_connection *evcon = arg;
993 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
995 /* Cancel if it's pending. */
996 event_deferred_cb_cancel(get_deferred_queue(evcon),
997 &evcon->read_more_deferred_cb);
999 switch (evcon->state) {
1000 case EVCON_READING_FIRSTLINE:
1001 evhttp_read_firstline(evcon, req);
1002 /* note the request may have been freed in
1003 * evhttp_read_body */
1005 case EVCON_READING_HEADERS:
1006 evhttp_read_header(evcon, req);
1007 /* note the request may have been freed in
1008 * evhttp_read_body */
1010 case EVCON_READING_BODY:
1011 evhttp_read_body(evcon, req);
1012 /* note the request may have been freed in
1013 * evhttp_read_body */
1015 case EVCON_READING_TRAILER:
1016 evhttp_read_trailer(evcon, req);
1018 case EVCON_DISCONNECTED:
1019 case EVCON_CONNECTING:
1023 event_errx(1, "%s: illegal connection state %d",
1024 __func__, evcon->state);
1029 evhttp_deferred_read_cb(struct deferred_cb *cb, void *data)
1031 struct evhttp_connection *evcon = data;
1032 evhttp_read_cb(evcon->bufev, evcon);
1036 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1038 /* This is after writing the request to the server */
1039 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1040 EVUTIL_ASSERT(req != NULL);
1042 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1044 /* We are done writing our header and are now expecting the response */
1045 req->kind = EVHTTP_RESPONSE;
1047 evhttp_start_read(evcon);
1051 * Clean up a connection object
1055 evhttp_connection_free(struct evhttp_connection *evcon)
1057 struct evhttp_request *req;
1059 /* notify interested parties that this connection is going down */
1060 if (evcon->fd != -1) {
1061 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1062 (*evcon->closecb)(evcon, evcon->closecb_arg);
1065 /* remove all requests that might be queued on this
1066 * connection. for server connections, this should be empty.
1067 * because it gets dequeued either in evhttp_connection_done or
1068 * evhttp_connection_fail.
1070 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1071 TAILQ_REMOVE(&evcon->requests, req, next);
1072 evhttp_request_free(req);
1075 if (evcon->http_server != NULL) {
1076 struct evhttp *http = evcon->http_server;
1077 TAILQ_REMOVE(&http->connections, evcon, next);
1080 if (event_initialized(&evcon->retry_ev)) {
1081 event_del(&evcon->retry_ev);
1082 event_debug_unassign(&evcon->retry_ev);
1085 if (evcon->bufev != NULL)
1086 bufferevent_free(evcon->bufev);
1088 event_deferred_cb_cancel(get_deferred_queue(evcon),
1089 &evcon->read_more_deferred_cb);
1091 if (evcon->fd != -1) {
1092 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1093 evutil_closesocket(evcon->fd);
1096 if (evcon->bind_address != NULL)
1097 mm_free(evcon->bind_address);
1099 if (evcon->address != NULL)
1100 mm_free(evcon->address);
1106 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1107 const char *address)
1109 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1110 if (evcon->bind_address)
1111 mm_free(evcon->bind_address);
1112 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1113 event_err(1, "%s: strdup", __func__);
1117 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1120 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1121 evcon->bind_port = port;
1125 evhttp_request_dispatch(struct evhttp_connection* evcon)
1127 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1129 /* this should not usually happy but it's possible */
1133 /* delete possible close detection events */
1134 evhttp_connection_stop_detectclose(evcon);
1136 /* we assume that the connection is connected already */
1137 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1139 evcon->state = EVCON_WRITING;
1141 /* Create the header from the store arguments */
1142 evhttp_make_header(evcon, req);
1144 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1147 /* Reset our connection state: disables reading/writing, closes our fd (if
1148 * any), clears out buffers, and puts us in state DISCONNECTED. */
1150 evhttp_connection_reset(struct evhttp_connection *evcon)
1152 struct evbuffer *tmp;
1154 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
1156 if (evcon->fd != -1) {
1157 /* inform interested parties about connection close */
1158 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1159 (*evcon->closecb)(evcon, evcon->closecb_arg);
1161 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1162 evutil_closesocket(evcon->fd);
1166 /* we need to clean up any buffered data */
1167 tmp = bufferevent_get_output(evcon->bufev);
1168 evbuffer_drain(tmp, evbuffer_get_length(tmp));
1169 tmp = bufferevent_get_input(evcon->bufev);
1170 evbuffer_drain(tmp, evbuffer_get_length(tmp));
1172 evcon->state = EVCON_DISCONNECTED;
1176 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1178 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1180 bufferevent_enable(evcon->bufev, EV_READ);
1184 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1186 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1188 bufferevent_disable(evcon->bufev, EV_READ);
1192 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1194 struct evhttp_connection *evcon = arg;
1196 evcon->state = EVCON_DISCONNECTED;
1197 evhttp_connection_connect(evcon);
1201 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1203 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1204 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1205 /* XXXX handle failure from evhttp_add_event */
1206 evhttp_add_event(&evcon->retry_ev,
1207 MIN(3600, 2 << evcon->retry_cnt),
1208 HTTP_CONNECT_TIMEOUT);
1212 evhttp_connection_reset(evcon);
1214 /* for now, we just signal all requests by executing their callbacks */
1215 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1216 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1217 TAILQ_REMOVE(&evcon->requests, request, next);
1218 request->evcon = NULL;
1220 /* we might want to set an error here */
1221 request->cb(request, request->cb_arg);
1222 evhttp_request_free(request);
1227 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1229 struct evhttp_connection *evcon = arg;
1230 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1232 switch (evcon->state) {
1233 case EVCON_CONNECTING:
1234 if (what & BEV_EVENT_TIMEOUT) {
1235 event_debug(("%s: connection timeout for \"%s:%d\" on %d",
1236 __func__, evcon->address, evcon->port,
1238 evhttp_connection_cb_cleanup(evcon);
1243 case EVCON_READING_BODY:
1244 if (!req->chunked && req->ntoread < 0
1245 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1246 /* EOF on read can be benign */
1247 evhttp_connection_done(evcon);
1252 case EVCON_DISCONNECTED:
1254 case EVCON_READING_FIRSTLINE:
1255 case EVCON_READING_HEADERS:
1256 case EVCON_READING_TRAILER:
1262 /* when we are in close detect mode, a read error means that
1263 * the other side closed their connection.
1265 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1266 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1267 EVUTIL_ASSERT(evcon->http_server == NULL);
1268 /* For connections from the client, we just
1269 * reset the connection so that it becomes
1272 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1273 evhttp_connection_reset(evcon);
1277 if (what & BEV_EVENT_TIMEOUT) {
1278 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
1279 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1280 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
1282 evhttp_connection_fail(evcon, EVCON_HTTP_BUFFER_ERROR);
1287 * Event callback for asynchronous connection attempt.
1290 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1292 struct evhttp_connection *evcon = arg;
1294 ev_socklen_t errsz = sizeof(error);
1296 if (!(what & BEV_EVENT_CONNECTED)) {
1297 /* some operating systems return ECONNREFUSED immediately
1298 * when connecting to a local address. the cleanup is going
1299 * to reschedule this function call.
1302 if (errno == ECONNREFUSED)
1305 evhttp_error_cb(bufev, what, arg);
1309 /* Check if the connection completed */
1310 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1312 event_debug(("%s: getsockopt for \"%s:%d\" on %d",
1313 __func__, evcon->address, evcon->port, evcon->fd));
1318 event_debug(("%s: connect failed for \"%s:%d\" on %d: %s",
1319 __func__, evcon->address, evcon->port, evcon->fd,
1320 evutil_socket_error_to_string(error)));
1324 /* We are connected to the server now */
1325 event_debug(("%s: connected to \"%s:%d\" on %d\n",
1326 __func__, evcon->address, evcon->port, evcon->fd));
1328 /* Reset the retry count as we were successful in connecting */
1329 evcon->retry_cnt = 0;
1330 evcon->state = EVCON_IDLE;
1332 /* reset the bufferevent cbs */
1333 bufferevent_setcb(evcon->bufev,
1339 if (evcon->timeout == -1)
1340 bufferevent_settimeout(evcon->bufev,
1341 HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
1344 tv.tv_sec = evcon->timeout;
1346 bufferevent_set_timeouts(evcon->bufev, &tv, &tv);
1349 /* try to start requests that have queued up on this connection */
1350 evhttp_request_dispatch(evcon);
1354 evhttp_connection_cb_cleanup(evcon);
1358 * Check if we got a valid response code.
1362 evhttp_valid_response_code(int code)
1371 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1375 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1376 if (n > 2 || major > 1) {
1377 event_debug(("%s: bad version %s on message %p from %s",
1378 __func__, version, req, req->remote_host));
1386 /* Parses the status line of a web server */
1389 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1393 const char *readable = "";
1395 protocol = strsep(&line, " ");
1398 number = strsep(&line, " ");
1402 if (evhttp_parse_http_version(protocol, req) < 0)
1405 req->response_code = atoi(number);
1406 if (!evhttp_valid_response_code(req->response_code)) {
1407 event_debug(("%s: bad response code \"%s\"",
1412 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1413 event_warn("%s: strdup", __func__);
1420 /* Parse the first line of a HTTP request */
1423 evhttp_parse_request_line(struct evhttp_request *req, char *line)
1428 const char *hostname;
1431 /* Parse the request line */
1432 method = strsep(&line, " ");
1435 uri = strsep(&line, " ");
1438 version = strsep(&line, " ");
1443 if (strcmp(method, "GET") == 0) {
1444 req->type = EVHTTP_REQ_GET;
1445 } else if (strcmp(method, "POST") == 0) {
1446 req->type = EVHTTP_REQ_POST;
1447 } else if (strcmp(method, "HEAD") == 0) {
1448 req->type = EVHTTP_REQ_HEAD;
1449 } else if (strcmp(method, "PUT") == 0) {
1450 req->type = EVHTTP_REQ_PUT;
1451 } else if (strcmp(method, "DELETE") == 0) {
1452 req->type = EVHTTP_REQ_DELETE;
1453 } else if (strcmp(method, "OPTIONS") == 0) {
1454 req->type = EVHTTP_REQ_OPTIONS;
1455 } else if (strcmp(method, "TRACE") == 0) {
1456 req->type = EVHTTP_REQ_TRACE;
1457 } else if (strcmp(method, "PATCH") == 0) {
1458 req->type = EVHTTP_REQ_PATCH;
1460 req->type = _EVHTTP_REQ_UNKNOWN;
1461 event_debug(("%s: bad method %s on request %p from %s",
1462 __func__, method, req, req->remote_host));
1463 /* No error yet; we'll give a better error later when
1464 * we see that req->type is unsupported. */
1467 if (evhttp_parse_http_version(version, req) < 0)
1470 if ((req->uri = mm_strdup(uri)) == NULL) {
1471 event_debug(("%s: mm_strdup", __func__));
1475 if ((req->uri_elems = evhttp_uri_parse(req->uri)) == NULL) {
1479 /* If we have an absolute-URI, check to see if it is an http request
1480 for a known vhost or server alias. If we don't know about this
1481 host, we consider it a proxy request. */
1482 scheme = evhttp_uri_get_scheme(req->uri_elems);
1483 hostname = evhttp_uri_get_host(req->uri_elems);
1484 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1485 !evutil_ascii_strcasecmp(scheme, "https")) &&
1487 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1488 req->flags |= EVHTTP_PROXY_REQUEST;
1494 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1496 struct evkeyval *header;
1498 TAILQ_FOREACH(header, headers, next) {
1499 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1500 return (header->value);
1507 evhttp_clear_headers(struct evkeyvalq *headers)
1509 struct evkeyval *header;
1511 for (header = TAILQ_FIRST(headers);
1513 header = TAILQ_FIRST(headers)) {
1514 TAILQ_REMOVE(headers, header, next);
1515 mm_free(header->key);
1516 mm_free(header->value);
1522 * Returns 0, if the header was successfully removed.
1523 * Returns -1, if the header could not be found.
1527 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1529 struct evkeyval *header;
1531 TAILQ_FOREACH(header, headers, next) {
1532 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1539 /* Free and remove the header that we found */
1540 TAILQ_REMOVE(headers, header, next);
1541 mm_free(header->key);
1542 mm_free(header->value);
1549 evhttp_header_is_valid_value(const char *value)
1551 const char *p = value;
1553 while ((p = strpbrk(p, "\r\n")) != NULL) {
1554 /* we really expect only one new line */
1555 p += strspn(p, "\r\n");
1556 /* we expect a space or tab for continuation */
1557 if (*p != ' ' && *p != '\t')
1564 evhttp_add_header(struct evkeyvalq *headers,
1565 const char *key, const char *value)
1567 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1569 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1570 /* drop illegal headers */
1571 event_debug(("%s: dropping illegal header key\n", __func__));
1575 if (!evhttp_header_is_valid_value(value)) {
1576 event_debug(("%s: dropping illegal header value\n", __func__));
1580 return (evhttp_add_header_internal(headers, key, value));
1584 evhttp_add_header_internal(struct evkeyvalq *headers,
1585 const char *key, const char *value)
1587 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
1588 if (header == NULL) {
1589 event_warn("%s: calloc", __func__);
1592 if ((header->key = mm_strdup(key)) == NULL) {
1594 event_warn("%s: strdup", __func__);
1597 if ((header->value = mm_strdup(value)) == NULL) {
1598 mm_free(header->key);
1600 event_warn("%s: strdup", __func__);
1604 TAILQ_INSERT_TAIL(headers, header, next);
1610 * Parses header lines from a request or a response into the specified
1611 * request object given an event buffer.
1614 * DATA_CORRUPTED on error
1615 * MORE_DATA_EXPECTED when we need to read more headers
1616 * ALL_DATA_READ when all headers have been read.
1619 enum message_read_status
1620 evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
1623 enum message_read_status status = ALL_DATA_READ;
1627 line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF);
1629 if (req->evcon != NULL &&
1630 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1631 return (DATA_TOO_LONG);
1633 return (MORE_DATA_EXPECTED);
1636 if (req->evcon != NULL &&
1637 line_length > req->evcon->max_headers_size) {
1639 return (DATA_TOO_LONG);
1642 req->headers_size = line_length;
1644 switch (req->kind) {
1645 case EVHTTP_REQUEST:
1646 if (evhttp_parse_request_line(req, line) == -1)
1647 status = DATA_CORRUPTED;
1649 case EVHTTP_RESPONSE:
1650 if (evhttp_parse_response_line(req, line) == -1)
1651 status = DATA_CORRUPTED;
1654 status = DATA_CORRUPTED;
1662 evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
1664 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
1666 size_t old_len, line_len;
1671 old_len = strlen(header->value);
1672 line_len = strlen(line);
1674 newval = mm_realloc(header->value, old_len + line_len + 1);
1678 memcpy(newval + old_len, line, line_len + 1);
1679 header->value = newval;
1684 enum message_read_status
1685 evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
1687 enum message_read_status errcode = DATA_CORRUPTED;
1689 enum message_read_status status = MORE_DATA_EXPECTED;
1691 struct evkeyvalq* headers = req->input_headers;
1693 while ((line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF))
1695 char *skey, *svalue;
1697 req->headers_size += line_length;
1699 if (req->evcon != NULL &&
1700 req->headers_size > req->evcon->max_headers_size) {
1701 errcode = DATA_TOO_LONG;
1705 if (*line == '\0') { /* Last header - Done */
1706 status = ALL_DATA_READ;
1711 /* Check if this is a continuation line */
1712 if (*line == ' ' || *line == '\t') {
1713 if (evhttp_append_to_last_header(headers, line) == -1)
1719 /* Processing of header lines */
1721 skey = strsep(&svalue, ":");
1725 svalue += strspn(svalue, " ");
1727 if (evhttp_add_header(headers, skey, svalue) == -1)
1733 if (status == MORE_DATA_EXPECTED) {
1734 if (req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1735 return (DATA_TOO_LONG);
1746 evhttp_get_body_length(struct evhttp_request *req)
1748 struct evkeyvalq *headers = req->input_headers;
1749 const char *content_length;
1750 const char *connection;
1752 content_length = evhttp_find_header(headers, "Content-Length");
1753 connection = evhttp_find_header(headers, "Connection");
1755 if (content_length == NULL && connection == NULL)
1757 else if (content_length == NULL &&
1758 evutil_ascii_strcasecmp(connection, "Close") != 0) {
1759 /* Bad combination, we don't know when it will end */
1760 event_warnx("%s: we got no content length, but the "
1761 "server wants to keep the connection open: %s.",
1762 __func__, connection);
1764 } else if (content_length == NULL) {
1768 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
1769 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
1770 event_debug(("%s: illegal content length: %s",
1771 __func__, content_length));
1774 req->ntoread = ntoread;
1777 event_debug(("%s: bytes to read: %ld (in buffer %ld)\n",
1778 __func__, (long)req->ntoread,
1779 evbuffer_get_length(bufferevent_get_input(req->evcon->bufev))));
1785 evhttp_method_may_have_body(enum evhttp_cmd_type type)
1788 case EVHTTP_REQ_POST:
1789 case EVHTTP_REQ_PUT:
1790 case EVHTTP_REQ_PATCH:
1792 case EVHTTP_REQ_TRACE:
1794 /* XXX May any of the below methods have a body? */
1795 case EVHTTP_REQ_GET:
1796 case EVHTTP_REQ_HEAD:
1797 case EVHTTP_REQ_DELETE:
1798 case EVHTTP_REQ_OPTIONS:
1799 case EVHTTP_REQ_CONNECT:
1807 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1809 const char *xfer_enc;
1811 /* If this is a request without a body, then we are done */
1812 if (req->kind == EVHTTP_REQUEST &&
1813 !evhttp_method_may_have_body(req->type)) {
1814 evhttp_connection_done(evcon);
1817 evcon->state = EVCON_READING_BODY;
1818 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
1819 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
1823 if (evhttp_get_body_length(req) == -1) {
1824 evhttp_connection_fail(evcon,
1825 EVCON_HTTP_INVALID_HEADER);
1828 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
1829 /* An incoming request with no content-length and no
1830 * transfer-encoding has no body. */
1831 evhttp_connection_done(evcon);
1836 /* Should we send a 100 Continue status line? */
1837 if (req->kind == EVHTTP_REQUEST && REQ_VERSION_ATLEAST(req, 1, 1)) {
1840 expect = evhttp_find_header(req->input_headers, "Expect");
1842 if (!evutil_ascii_strcasecmp(expect, "100-continue")) {
1843 /* XXX It would be nice to do some sanity
1844 checking here. Does the resource exist?
1845 Should the resource accept post requests? If
1846 no, we should respond with an error. For
1847 now, just optimistically tell the client to
1848 send their message body. */
1849 if (req->ntoread > 0 &&
1850 (size_t)req->ntoread > req->evcon->max_body_size) {
1851 evhttp_send_error(req, HTTP_ENTITYTOOLARGE,
1855 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
1856 evhttp_send_continue(evcon, req);
1858 evhttp_send_error(req, HTTP_EXPECTATIONFAILED,
1865 evhttp_read_body(evcon, req);
1866 /* note the request may have been freed in evhttp_read_body */
1870 evhttp_read_firstline(struct evhttp_connection *evcon,
1871 struct evhttp_request *req)
1873 enum message_read_status res;
1875 res = evhttp_parse_firstline(req, bufferevent_get_input(evcon->bufev));
1876 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
1877 /* Error while reading, terminate */
1878 event_debug(("%s: bad header lines on %d\n",
1879 __func__, evcon->fd));
1880 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1882 } else if (res == MORE_DATA_EXPECTED) {
1883 /* Need more header lines */
1887 evcon->state = EVCON_READING_HEADERS;
1888 evhttp_read_header(evcon, req);
1892 evhttp_read_header(struct evhttp_connection *evcon,
1893 struct evhttp_request *req)
1895 enum message_read_status res;
1896 evutil_socket_t fd = evcon->fd;
1898 res = evhttp_parse_headers(req, bufferevent_get_input(evcon->bufev));
1899 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
1900 /* Error while reading, terminate */
1901 event_debug(("%s: bad header lines on %d\n", __func__, fd));
1902 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1904 } else if (res == MORE_DATA_EXPECTED) {
1905 /* Need more header lines */
1909 /* Disable reading for now */
1910 bufferevent_disable(evcon->bufev, EV_READ);
1912 /* Done reading headers, do the real work */
1913 switch (req->kind) {
1914 case EVHTTP_REQUEST:
1915 event_debug(("%s: checking for post data on %d\n",
1917 evhttp_get_body(evcon, req);
1918 /* note the request may have been freed in evhttp_get_body */
1921 case EVHTTP_RESPONSE:
1922 /* Start over if we got a 100 Continue response. */
1923 if (req->response_code == 100) {
1924 evhttp_start_read(evcon);
1927 if (!evhttp_response_needs_body(req)) {
1928 event_debug(("%s: skipping body for code %d\n",
1929 __func__, req->response_code));
1930 evhttp_connection_done(evcon);
1932 event_debug(("%s: start of read body for %s on %d\n",
1933 __func__, req->remote_host, fd));
1934 evhttp_get_body(evcon, req);
1935 /* note the request may have been freed in
1936 * evhttp_get_body */
1941 event_warnx("%s: bad header on %d", __func__, fd);
1942 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1945 /* request may have been freed above */
1949 * Creates a TCP connection to the specified port and executes a callback
1950 * when finished. Failure or success is indicate by the passed connection
1953 * Although this interface accepts a hostname, it is intended to take
1954 * only numeric hostnames so that non-blocking DNS resolution can
1958 struct evhttp_connection *
1959 evhttp_connection_new(const char *address, unsigned short port)
1961 return (evhttp_connection_base_new(NULL, NULL, address, port));
1964 struct evhttp_connection *
1965 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
1966 const char *address, unsigned short port)
1968 struct evhttp_connection *evcon = NULL;
1970 event_debug(("Attempting connection to %s:%d\n", address, port));
1972 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
1973 event_warn("%s: calloc failed", __func__);
1980 evcon->max_headers_size = EV_SIZE_MAX;
1981 evcon->max_body_size = EV_SIZE_MAX;
1983 evcon->timeout = -1;
1984 evcon->retry_cnt = evcon->retry_max = 0;
1986 if ((evcon->address = mm_strdup(address)) == NULL) {
1987 event_warn("%s: strdup failed", __func__);
1991 if ((evcon->bufev = bufferevent_new(-1,
1994 evhttp_error_cb, evcon)) == NULL) {
1995 event_warn("%s: bufferevent_new failed", __func__);
1999 evcon->state = EVCON_DISCONNECTED;
2000 TAILQ_INIT(&evcon->requests);
2004 bufferevent_base_set(base, evcon->bufev);
2008 event_deferred_cb_init(&evcon->read_more_deferred_cb,
2009 evhttp_deferred_read_cb, evcon);
2011 evcon->dns_base = dnsbase;
2017 evhttp_connection_free(evcon);
2022 evhttp_connection_set_base(struct evhttp_connection *evcon,
2023 struct event_base *base)
2025 EVUTIL_ASSERT(evcon->base == NULL);
2026 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2028 bufferevent_base_set(base, evcon->bufev);
2032 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2033 int timeout_in_secs)
2035 evcon->timeout = timeout_in_secs;
2037 if (evcon->timeout == -1)
2038 bufferevent_settimeout(evcon->bufev,
2039 HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
2041 bufferevent_settimeout(evcon->bufev,
2042 evcon->timeout, evcon->timeout);
2046 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2049 evcon->retry_max = retry_max;
2053 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2054 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2056 evcon->closecb = cb;
2057 evcon->closecb_arg = cbarg;
2061 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2062 char **address, ev_uint16_t *port)
2064 *address = evcon->address;
2065 *port = evcon->port;
2069 evhttp_connection_connect(struct evhttp_connection *evcon)
2071 if (evcon->state == EVCON_CONNECTING)
2074 evhttp_connection_reset(evcon);
2076 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2077 evcon->flags |= EVHTTP_CON_OUTGOING;
2079 evcon->fd = bind_socket(
2080 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2081 if (evcon->fd == -1) {
2082 event_debug(("%s: failed to bind to \"%s\"",
2083 __func__, evcon->bind_address));
2087 /* Set up a callback for successful connection setup */
2088 bufferevent_setfd(evcon->bufev, evcon->fd);
2089 bufferevent_setcb(evcon->bufev,
2090 NULL /* evhttp_read_cb */,
2091 NULL /* evhttp_write_cb */,
2092 evhttp_connection_cb,
2094 bufferevent_settimeout(evcon->bufev, 0,
2095 evcon->timeout != -1 ? evcon->timeout : HTTP_CONNECT_TIMEOUT);
2096 /* make sure that we get a write callback */
2097 bufferevent_enable(evcon->bufev, EV_WRITE);
2099 if (bufferevent_socket_connect_hostname(evcon->bufev, evcon->dns_base,
2100 AF_UNSPEC, evcon->address, evcon->port) < 0) {
2101 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2102 __func__, evcon->address);
2103 /* some operating systems return ECONNREFUSED immediately
2104 * when connecting to a local address. the cleanup is going
2105 * to reschedule this function call.
2107 evhttp_connection_cb_cleanup(evcon);
2111 evcon->state = EVCON_CONNECTING;
2117 * Starts an HTTP request on the provided evhttp_connection object.
2118 * If the connection object is not connected to the web server already,
2119 * this will start the connection.
2123 evhttp_make_request(struct evhttp_connection *evcon,
2124 struct evhttp_request *req,
2125 enum evhttp_cmd_type type, const char *uri)
2127 /* We are making a request */
2128 req->kind = EVHTTP_REQUEST;
2130 if (req->uri != NULL)
2132 if ((req->uri = mm_strdup(uri)) == NULL) {
2133 event_warn("%s: strdup", __func__);
2134 evhttp_request_free(req);
2138 /* Set the protocol version if it is not supplied */
2139 if (!req->major && !req->minor) {
2144 EVUTIL_ASSERT(req->evcon == NULL);
2146 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2148 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2150 /* If the connection object is not connected; make it so */
2151 if (!evhttp_connected(evcon))
2152 return (evhttp_connection_connect(evcon));
2155 * If it's connected already and we are the first in the queue,
2156 * then we can dispatch this request immediately. Otherwise, it
2157 * will be dispatched once the pending requests are completed.
2159 if (TAILQ_FIRST(&evcon->requests) == req)
2160 evhttp_request_dispatch(evcon);
2166 evhttp_cancel_request(struct evhttp_request *req)
2168 struct evhttp_connection *evcon = req->evcon;
2169 if (evcon != NULL) {
2170 /* We need to remove it from the connection */
2171 if (TAILQ_FIRST(&evcon->requests) == req) {
2172 /* it's currently being worked on, so reset
2175 evhttp_connection_fail(evcon,
2176 EVCON_HTTP_REQUEST_CANCEL);
2178 /* connection fail freed the request */
2181 /* otherwise, we can just remove it from the
2184 TAILQ_REMOVE(&evcon->requests, req, next);
2188 evhttp_request_free(req);
2192 * Reads data from file descriptor into request structure
2193 * Request structure needs to be set up correctly.
2197 evhttp_start_read(struct evhttp_connection *evcon)
2199 /* Set up an event to read the headers */
2200 bufferevent_disable(evcon->bufev, EV_WRITE);
2201 bufferevent_enable(evcon->bufev, EV_READ);
2202 evcon->state = EVCON_READING_FIRSTLINE;
2203 /* Reset the bufferevent callbacks */
2204 bufferevent_setcb(evcon->bufev,
2210 /* If there's still data pending, process it next time through the
2211 * loop. Don't do it now; that could get recusive. */
2212 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2213 event_deferred_cb_schedule(get_deferred_queue(evcon),
2214 &evcon->read_more_deferred_cb);
2219 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2222 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2223 TAILQ_REMOVE(&evcon->requests, req, next);
2226 (REQ_VERSION_BEFORE(req, 1, 1) &&
2227 !evhttp_is_connection_keepalive(req->input_headers))||
2228 evhttp_is_connection_close(req->flags, req->input_headers) ||
2229 evhttp_is_connection_close(req->flags, req->output_headers);
2231 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2232 evhttp_request_free(req);
2235 evhttp_connection_free(evcon);
2239 /* we have a persistent connection; try to accept another request. */
2240 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2241 evhttp_connection_free(evcon);
2246 * Returns an error page.
2250 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2253 #define ERR_FORMAT "<HTML><HEAD>\n" \
2254 "<TITLE>%d %s</TITLE>\n" \
2259 struct evbuffer *buf = evbuffer_new();
2261 /* if we cannot allocate memory; we just drop the connection */
2262 evhttp_connection_free(req->evcon);
2265 if (reason == NULL) {
2266 reason = evhttp_response_phrase_internal(error);
2269 evhttp_response_code(req, error, reason);
2271 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2273 evhttp_send_page(req, buf);
2279 /* Requires that headers and response code are already set up */
2282 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2284 struct evhttp_connection *evcon = req->evcon;
2286 if (evcon == NULL) {
2287 evhttp_request_free(req);
2291 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2293 /* we expect no more calls form the user on this request */
2296 /* xxx: not sure if we really should expose the data buffer this way */
2297 if (databuf != NULL)
2298 evbuffer_add_buffer(req->output_buffer, databuf);
2300 /* Adds headers to the response */
2301 evhttp_make_header(evcon, req);
2303 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2307 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2308 struct evbuffer *databuf)
2310 evhttp_response_code(req, code, reason);
2312 evhttp_send(req, databuf);
2316 evhttp_send_reply_start(struct evhttp_request *req, int code,
2319 evhttp_response_code(req, code, reason);
2320 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2321 REQ_VERSION_ATLEAST(req, 1, 1) &&
2322 evhttp_response_needs_body(req)) {
2324 * prefer HTTP/1.1 chunked encoding to closing the connection;
2325 * note RFC 2616 section 4.4 forbids it with Content-Length:
2326 * and it's not necessary then anyway.
2328 evhttp_add_header(req->output_headers, "Transfer-Encoding",
2334 evhttp_make_header(req->evcon, req);
2335 evhttp_write_buffer(req->evcon, NULL, NULL);
2339 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
2341 struct evhttp_connection *evcon = req->evcon;
2342 struct evbuffer *output;
2347 output = bufferevent_get_output(evcon->bufev);
2349 if (evbuffer_get_length(databuf) == 0)
2351 if (!evhttp_response_needs_body(req))
2354 evbuffer_add_printf(output, "%x\r\n",
2355 (unsigned)evbuffer_get_length(databuf));
2357 evbuffer_add_buffer(output, databuf);
2359 evbuffer_add(output, "\r\n", 2);
2361 evhttp_write_buffer(evcon, NULL, NULL);
2365 evhttp_send_reply_end(struct evhttp_request *req)
2367 struct evhttp_connection *evcon = req->evcon;
2368 struct evbuffer *output;
2370 if (evcon == NULL) {
2371 evhttp_request_free(req);
2375 output = bufferevent_get_output(evcon->bufev);
2377 /* we expect no more calls form the user on this request */
2381 evbuffer_add(output, "0\r\n\r\n", 5);
2382 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2384 } else if (evbuffer_get_length(output) == 0) {
2385 /* let the connection know that we are done with the request */
2386 evhttp_send_done(evcon, NULL);
2388 /* make the callback execute after all data has been written */
2389 evcon->cb = evhttp_send_done;
2390 evcon->cb_arg = NULL;
2394 static const char *informational_phrases[] = {
2395 /* 100 */ "Continue",
2396 /* 101 */ "Switching Protocols"
2399 static const char *success_phrases[] = {
2401 /* 201 */ "Created",
2402 /* 202 */ "Accepted",
2403 /* 203 */ "Non-Authoritative Information",
2404 /* 204 */ "No Content",
2405 /* 205 */ "Reset Content",
2406 /* 206 */ "Partial Content"
2409 static const char *redirection_phrases[] = {
2410 /* 300 */ "Multiple Choices",
2411 /* 301 */ "Moved Permanently",
2413 /* 303 */ "See Other",
2414 /* 304 */ "Not Modified",
2415 /* 305 */ "Use Proxy",
2416 /* 307 */ "Temporary Redirect"
2419 static const char *client_error_phrases[] = {
2420 /* 400 */ "Bad Request",
2421 /* 401 */ "Unauthorized",
2422 /* 402 */ "Payment Required",
2423 /* 403 */ "Forbidden",
2424 /* 404 */ "Not Found",
2425 /* 405 */ "Method Not Allowed",
2426 /* 406 */ "Not Acceptable",
2427 /* 407 */ "Proxy Authentication Required",
2428 /* 408 */ "Request Time-out",
2429 /* 409 */ "Conflict",
2431 /* 411 */ "Length Required",
2432 /* 412 */ "Precondition Failed",
2433 /* 413 */ "Request Entity Too Large",
2434 /* 414 */ "Request-URI Too Large",
2435 /* 415 */ "Unsupported Media Type",
2436 /* 416 */ "Requested range not satisfiable",
2437 /* 417 */ "Expectation Failed"
2440 static const char *server_error_phrases[] = {
2441 /* 500 */ "Internal Server Error",
2442 /* 501 */ "Not Implemented",
2443 /* 502 */ "Bad Gateway",
2444 /* 503 */ "Service Unavailable",
2445 /* 504 */ "Gateway Time-out",
2446 /* 505 */ "HTTP Version not supported"
2449 struct response_class {
2451 size_t num_responses;
2452 const char **responses;
2456 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
2459 static const struct response_class response_classes[] = {
2460 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
2461 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
2462 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
2463 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
2464 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
2468 evhttp_response_phrase_internal(int code)
2470 int klass = code / 100 - 1;
2471 int subcode = code % 100;
2473 /* Unknown class - can't do any better here */
2474 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
2475 return "Unknown Status Class";
2477 /* Unknown sub-code, return class name at least */
2478 if (subcode >= (int) response_classes[klass].num_responses)
2479 return response_classes[klass].name;
2481 return response_classes[klass].responses[subcode];
2485 evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
2487 req->kind = EVHTTP_RESPONSE;
2488 req->response_code = code;
2489 if (req->response_code_line != NULL)
2490 mm_free(req->response_code_line);
2492 reason = evhttp_response_phrase_internal(code);
2493 req->response_code_line = mm_strdup(reason);
2497 evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
2499 if (!req->major || !req->minor) {
2504 if (req->kind != EVHTTP_RESPONSE)
2505 evhttp_response_code(req, 200, "OK");
2507 evhttp_clear_headers(req->output_headers);
2508 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
2509 evhttp_add_header(req->output_headers, "Connection", "close");
2511 evhttp_send(req, databuf);
2514 static const char uri_chars[256] = {
2516 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2517 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2518 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
2519 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
2521 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2522 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
2523 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2524 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
2526 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2527 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2528 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2529 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2531 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2532 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2533 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2534 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2537 #define CHAR_IS_UNRESERVED(c) \
2538 (uri_chars[(unsigned char)(c)])
2541 * Helper functions to encode/decode a string for inclusion in a URI.
2542 * The returned string must be freed by the caller.
2545 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
2547 struct evbuffer *buf = evbuffer_new();
2548 const char *p, *end;
2557 end = uri+strlen(uri);
2559 for (p = uri; p < end; p++) {
2560 if (CHAR_IS_UNRESERVED(*p)) {
2561 evbuffer_add(buf, p, 1);
2562 } else if (*p == ' ' && space_as_plus) {
2563 evbuffer_add(buf, "+", 1);
2565 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
2568 evbuffer_add(buf, "", 1); /* NUL-terminator. */
2569 result = mm_malloc(evbuffer_get_length(buf));
2572 evbuffer_remove(buf, result, evbuffer_get_length(buf));
2579 evhttp_encode_uri(const char *str)
2581 return evhttp_uriencode(str, -1, 0);
2585 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
2586 * If -1, when true we transform plus to space only after we've seen
2587 * a ?. -1 is deprecated.
2588 * @return the number of bytes written to 'ret'.
2591 evhttp_decode_uri_internal(
2592 const char *uri, size_t length, char *ret, int decode_plus_ctl)
2596 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
2599 for (i = j = 0; i < length; i++) {
2602 if (decode_plus_ctl < 0)
2604 } else if (c == '+' && decode_plus) {
2606 } else if (c == '%' && EVUTIL_ISXDIGIT(uri[i+1]) &&
2607 EVUTIL_ISXDIGIT(uri[i+2])) {
2612 c = (char)strtol(tmp, NULL, 16);
2624 evhttp_decode_uri(const char *uri)
2628 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2629 event_warn("%s: malloc(%lu)", __func__,
2630 (unsigned long)(strlen(uri) + 1));
2634 evhttp_decode_uri_internal(uri, strlen(uri),
2635 ret, -1 /*always_decode_plus*/);
2641 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
2646 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2647 event_warn("%s: malloc(%lu)", __func__,
2648 (unsigned long)(strlen(uri) + 1));
2652 n = evhttp_decode_uri_internal(uri, strlen(uri),
2653 ret, !!decode_plus/*always_decode_plus*/);
2656 EVUTIL_ASSERT(n >= 0);
2657 *size_out = (size_t)n;
2664 * Helper function to parse out arguments in a query.
2665 * The arguments are separated by key and value.
2669 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
2675 const char *query_part;
2677 struct evhttp_uri *uri=NULL;
2679 TAILQ_INIT(headers);
2682 uri = evhttp_uri_parse(str);
2685 query_part = evhttp_uri_get_query(uri);
2690 /* No arguments - we are done */
2691 if (!query_part || !strlen(query_part)) {
2696 if ((line = mm_strdup(query_part)) == NULL) {
2697 event_warn("%s: strdup", __func__);
2701 p = argument = line;
2702 while (p != NULL && *p != '\0') {
2703 char *key, *value, *decoded_value;
2704 argument = strsep(&p, "&");
2707 key = strsep(&value, "=");
2708 if (value == NULL || *key == '\0') {
2712 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
2713 event_warn("%s: mm_malloc", __func__);
2716 evhttp_decode_uri_internal(value, strlen(value),
2717 decoded_value, 1 /*always_decode_plus*/);
2718 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
2719 evhttp_add_header_internal(headers, key, decoded_value);
2720 mm_free(decoded_value);
2726 evhttp_clear_headers(headers);
2731 evhttp_uri_free(uri);
2736 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
2738 return evhttp_parse_query_impl(uri, headers, 1);
2741 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
2743 return evhttp_parse_query_impl(uri, headers, 0);
2746 static struct evhttp_cb *
2747 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
2749 struct evhttp_cb *cb;
2754 /* Test for different URLs */
2755 path = evhttp_uri_get_path(req->uri_elems);
2756 offset = strlen(path);
2757 if ((translated = mm_malloc(offset + 1)) == NULL)
2759 evhttp_decode_uri_internal(path, offset, translated,
2760 0 /* decode_plus */);
2762 TAILQ_FOREACH(cb, callbacks, next) {
2763 if (!strcmp(cb->what, translated)) {
2764 mm_free(translated);
2769 mm_free(translated);
2775 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
2780 switch (c = *pattern++) {
2782 return *name == '\0';
2785 while (*name != '\0') {
2786 if (prefix_suffix_match(pattern, name,
2795 EVUTIL_TOLOWER(c) != EVUTIL_TOLOWER(*name))
2805 Search the vhost hierarchy beginning with http for a server alias
2806 matching hostname. If a match is found, and outhttp is non-null,
2807 outhttp is set to the matching http object and 1 is returned.
2811 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
2812 const char *hostname)
2814 struct evhttp_server_alias *alias;
2815 struct evhttp *vhost;
2817 TAILQ_FOREACH(alias, &http->aliases, next) {
2818 /* XXX Do we need to handle IP addresses? */
2819 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
2826 /* XXX It might be good to avoid recursion here, but I don't
2827 see a way to do that w/o a list. */
2828 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
2829 if (evhttp_find_alias(vhost, outhttp, hostname))
2837 Attempts to find the best http object to handle a request for a hostname.
2838 All aliases for the root http object and vhosts are searched for an exact
2839 match. Then, the vhost hierarchy is traversed again for a matching
2842 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
2843 is set with the best matching http object. If there are no matches, the
2844 root http object is stored in outhttp and 0 is returned.
2848 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
2849 const char *hostname)
2851 struct evhttp *vhost;
2852 struct evhttp *oldhttp;
2853 int match_found = 0;
2855 if (evhttp_find_alias(http, outhttp, hostname))
2860 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
2861 if (prefix_suffix_match(vhost->vhost_pattern,
2862 hostname, 1 /* ignorecase */)) {
2868 } while (oldhttp != http);
2877 evhttp_handle_request(struct evhttp_request *req, void *arg)
2879 struct evhttp *http = arg;
2880 struct evhttp_cb *cb = NULL;
2881 const char *hostname;
2883 /* we have a new request on which the user needs to take action */
2886 if (req->type == 0 || req->uri == NULL) {
2887 evhttp_send_error(req, HTTP_BADREQUEST, NULL);
2891 if ((http->allowed_methods & req->type) == 0) {
2892 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
2893 (unsigned)req->type, (unsigned)http->allowed_methods));
2894 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
2898 /* handle potential virtual hosts */
2899 hostname = evhttp_request_get_host(req);
2900 if (hostname != NULL) {
2901 evhttp_find_vhost(http, &http, hostname);
2904 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
2905 (*cb->cb)(req, cb->cbarg);
2909 /* Generic call back */
2911 (*http->gencb)(req, http->gencbarg);
2914 /* We need to send a 404 here */
2915 #define ERR_FORMAT "<html><head>" \
2916 "<title>404 Not Found</title>" \
2918 "<h1>Not Found</h1>" \
2919 "<p>The requested URL %s was not found on this server.</p>"\
2923 struct evbuffer *buf;
2925 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
2926 evhttp_connection_free(req->evcon);
2930 if ((buf = evbuffer_new()) == NULL) {
2931 mm_free(escaped_html);
2932 evhttp_connection_free(req->evcon);
2936 evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
2938 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
2940 mm_free(escaped_html);
2942 evhttp_send_page(req, buf);
2949 /* Listener callback when a connection arrives at a server. */
2951 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
2953 struct evhttp *http = arg;
2955 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
2959 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
2961 struct evhttp_bound_socket *bound =
2962 evhttp_bind_socket_with_handle(http, address, port);
2968 struct evhttp_bound_socket *
2969 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
2972 struct evhttp_bound_socket *bound;
2974 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
2977 if (listen(fd, 128) == -1) {
2978 event_sock_warn(fd, "%s: listen", __func__);
2979 evutil_closesocket(fd);
2983 bound = evhttp_accept_socket_with_handle(http, fd);
2985 if (bound != NULL) {
2986 event_debug(("Bound to port %d - Awaiting connections ... ",
2995 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
2997 struct evhttp_bound_socket *bound =
2998 evhttp_accept_socket_with_handle(http, fd);
3005 struct evhttp_bound_socket *
3006 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3008 struct evhttp_bound_socket *bound;
3009 struct evconnlistener *listener;
3011 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3013 listener = evconnlistener_new(http->base, NULL, NULL,
3015 0, /* Backlog is '0' because we already said 'listen' */
3020 bound = evhttp_bind_listener(http, listener);
3022 evconnlistener_free(listener);
3028 struct evhttp_bound_socket *
3029 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3031 struct evhttp_bound_socket *bound;
3033 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3037 bound->listener = listener;
3038 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3040 evconnlistener_set_cb(listener, accept_socket_cb, http);
3045 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3047 return evconnlistener_get_fd(bound->listener);
3050 struct evconnlistener *
3051 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3053 return bound->listener;
3057 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3059 TAILQ_REMOVE(&http->sockets, bound, next);
3060 evconnlistener_free(bound->listener);
3064 static struct evhttp*
3065 evhttp_new_object(void)
3067 struct evhttp *http = NULL;
3069 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3070 event_warn("%s: calloc", __func__);
3075 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3076 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3077 evhttp_set_allowed_methods(http,
3084 TAILQ_INIT(&http->sockets);
3085 TAILQ_INIT(&http->callbacks);
3086 TAILQ_INIT(&http->connections);
3087 TAILQ_INIT(&http->virtualhosts);
3088 TAILQ_INIT(&http->aliases);
3094 evhttp_new(struct event_base *base)
3096 struct evhttp *http = evhttp_new_object();
3104 * Start a web server on the specified address and port.
3108 evhttp_start(const char *address, unsigned short port)
3110 struct evhttp *http = evhttp_new_object();
3112 if (evhttp_bind_socket(http, address, port) == -1) {
3121 evhttp_free(struct evhttp* http)
3123 struct evhttp_cb *http_cb;
3124 struct evhttp_connection *evcon;
3125 struct evhttp_bound_socket *bound;
3126 struct evhttp* vhost;
3127 struct evhttp_server_alias *alias;
3129 /* Remove the accepting part */
3130 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3131 TAILQ_REMOVE(&http->sockets, bound, next);
3133 evconnlistener_free(bound->listener);
3138 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3139 /* evhttp_connection_free removes the connection */
3140 evhttp_connection_free(evcon);
3143 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3144 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3145 mm_free(http_cb->what);
3149 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3150 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3155 if (http->vhost_pattern != NULL)
3156 mm_free(http->vhost_pattern);
3158 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3159 TAILQ_REMOVE(&http->aliases, alias, next);
3160 mm_free(alias->alias);
3168 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3169 struct evhttp* vhost)
3171 /* a vhost can only be a vhost once and should not have bound sockets */
3172 if (vhost->vhost_pattern != NULL ||
3173 TAILQ_FIRST(&vhost->sockets) != NULL)
3176 vhost->vhost_pattern = mm_strdup(pattern);
3177 if (vhost->vhost_pattern == NULL)
3180 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3186 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3188 if (vhost->vhost_pattern == NULL)
3191 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3193 mm_free(vhost->vhost_pattern);
3194 vhost->vhost_pattern = NULL;
3200 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3202 struct evhttp_server_alias *evalias;
3204 evalias = mm_calloc(1, sizeof(*evalias));
3208 evalias->alias = mm_strdup(alias);
3209 if (!evalias->alias) {
3214 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3220 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3222 struct evhttp_server_alias *evalias;
3224 TAILQ_FOREACH(evalias, &http->aliases, next) {
3225 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3226 TAILQ_REMOVE(&http->aliases, evalias, next);
3227 mm_free(evalias->alias);
3237 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
3239 http->timeout = timeout_in_secs;
3243 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
3245 if (max_headers_size < 0)
3246 http->default_max_headers_size = EV_SIZE_MAX;
3248 http->default_max_headers_size = max_headers_size;
3252 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
3254 if (max_body_size < 0)
3255 http->default_max_body_size = EV_UINT64_MAX;
3257 http->default_max_body_size = max_body_size;
3261 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
3263 http->allowed_methods = methods;
3267 evhttp_set_cb(struct evhttp *http, const char *uri,
3268 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3270 struct evhttp_cb *http_cb;
3272 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3273 if (strcmp(http_cb->what, uri) == 0)
3277 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
3278 event_warn("%s: calloc", __func__);
3282 http_cb->what = mm_strdup(uri);
3284 http_cb->cbarg = cbarg;
3286 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
3292 evhttp_del_cb(struct evhttp *http, const char *uri)
3294 struct evhttp_cb *http_cb;
3296 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3297 if (strcmp(http_cb->what, uri) == 0)
3300 if (http_cb == NULL)
3303 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3304 mm_free(http_cb->what);
3311 evhttp_set_gencb(struct evhttp *http,
3312 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3315 http->gencbarg = cbarg;
3319 * Request related functions
3322 struct evhttp_request *
3323 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
3325 struct evhttp_request *req = NULL;
3327 /* Allocate request structure */
3328 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
3329 event_warn("%s: calloc", __func__);
3333 req->headers_size = 0;
3336 req->kind = EVHTTP_RESPONSE;
3337 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3338 if (req->input_headers == NULL) {
3339 event_warn("%s: calloc", __func__);
3342 TAILQ_INIT(req->input_headers);
3344 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3345 if (req->output_headers == NULL) {
3346 event_warn("%s: calloc", __func__);
3349 TAILQ_INIT(req->output_headers);
3351 if ((req->input_buffer = evbuffer_new()) == NULL) {
3352 event_warn("%s: evbuffer_new", __func__);
3356 if ((req->output_buffer = evbuffer_new()) == NULL) {
3357 event_warn("%s: evbuffer_new", __func__);
3368 evhttp_request_free(req);
3373 evhttp_request_free(struct evhttp_request *req)
3375 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
3376 req->flags |= EVHTTP_REQ_NEEDS_FREE;
3380 if (req->remote_host != NULL)
3381 mm_free(req->remote_host);
3382 if (req->uri != NULL)
3384 if (req->uri_elems != NULL)
3385 evhttp_uri_free(req->uri_elems);
3386 if (req->response_code_line != NULL)
3387 mm_free(req->response_code_line);
3388 if (req->host_cache != NULL)
3389 mm_free(req->host_cache);
3391 evhttp_clear_headers(req->input_headers);
3392 mm_free(req->input_headers);
3394 evhttp_clear_headers(req->output_headers);
3395 mm_free(req->output_headers);
3397 if (req->input_buffer != NULL)
3398 evbuffer_free(req->input_buffer);
3400 if (req->output_buffer != NULL)
3401 evbuffer_free(req->output_buffer);
3407 evhttp_request_own(struct evhttp_request *req)
3409 req->flags |= EVHTTP_USER_OWNED;
3413 evhttp_request_is_owned(struct evhttp_request *req)
3415 return (req->flags & EVHTTP_USER_OWNED) != 0;
3418 struct evhttp_connection *
3419 evhttp_request_get_connection(struct evhttp_request *req)
3425 evhttp_connection_get_base(struct evhttp_connection *conn)
3431 evhttp_request_set_chunked_cb(struct evhttp_request *req,
3432 void (*cb)(struct evhttp_request *, void *))
3438 * Allows for inspection of the request URI
3442 evhttp_request_get_uri(const struct evhttp_request *req) {
3443 if (req->uri == NULL)
3444 event_debug(("%s: request %p has no uri\n", __func__, req));
3448 const struct evhttp_uri *
3449 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
3450 if (req->uri_elems == NULL)
3451 event_debug(("%s: request %p has no uri elems\n",
3453 return (req->uri_elems);
3457 evhttp_request_get_host(struct evhttp_request *req)
3459 const char *host = NULL;
3461 if (req->host_cache)
3462 return req->host_cache;
3465 host = evhttp_uri_get_host(req->uri_elems);
3466 if (!host && req->input_headers) {
3470 host = evhttp_find_header(req->input_headers, "Host");
3471 /* The Host: header may include a port. Remove it here
3472 to be consistent with uri_elems case above. */
3474 p = host + strlen(host) - 1;
3475 while (p > host && EVUTIL_ISDIGIT(*p))
3477 if (p > host && *p == ':') {
3479 req->host_cache = mm_malloc(len + 1);
3480 if (!req->host_cache) {
3481 event_warn("%s: malloc", __func__);
3484 memcpy(req->host_cache, host, len);
3485 req->host_cache[len] = '\0';
3486 host = req->host_cache;
3494 enum evhttp_cmd_type
3495 evhttp_request_get_command(const struct evhttp_request *req) {
3500 evhttp_request_get_response_code(const struct evhttp_request *req)
3502 return req->response_code;
3505 /** Returns the input headers */
3506 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
3508 return (req->input_headers);
3511 /** Returns the output headers */
3512 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
3514 return (req->output_headers);
3517 /** Returns the input buffer */
3518 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
3520 return (req->input_buffer);
3523 /** Returns the output buffer */
3524 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
3526 return (req->output_buffer);
3531 * Takes a file descriptor to read a request from.
3532 * The callback is executed once the whole request has been read.
3535 static struct evhttp_connection*
3536 evhttp_get_request_connection(
3537 struct evhttp* http,
3538 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
3540 struct evhttp_connection *evcon;
3541 char *hostname = NULL, *portname = NULL;
3543 name_from_addr(sa, salen, &hostname, &portname);
3544 if (hostname == NULL || portname == NULL) {
3545 if (hostname) mm_free(hostname);
3546 if (portname) mm_free(portname);
3550 event_debug(("%s: new request from %s:%s on %d\n",
3551 __func__, hostname, portname, fd));
3553 /* we need a connection object to put the http request on */
3554 evcon = evhttp_connection_base_new(
3555 http->base, NULL, hostname, atoi(portname));
3561 evcon->max_headers_size = http->default_max_headers_size;
3562 evcon->max_body_size = http->default_max_body_size;
3564 evcon->flags |= EVHTTP_CON_INCOMING;
3565 evcon->state = EVCON_READING_FIRSTLINE;
3569 bufferevent_setfd(evcon->bufev, fd);
3575 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
3577 struct evhttp *http = evcon->http_server;
3578 struct evhttp_request *req;
3579 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
3582 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
3583 event_warn("%s: strdup", __func__);
3584 evhttp_request_free(req);
3587 req->remote_port = evcon->port;
3589 req->evcon = evcon; /* the request ends up owning the connection */
3590 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
3592 /* We did not present the request to the user user yet, so treat it as
3593 * if the user was done with the request. This allows us to free the
3594 * request on a persistent connection if the client drops it without
3595 * sending a request.
3599 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
3601 req->kind = EVHTTP_REQUEST;
3604 evhttp_start_read(evcon);
3610 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
3611 struct sockaddr *sa, ev_socklen_t salen)
3613 struct evhttp_connection *evcon;
3615 evcon = evhttp_get_request_connection(http, fd, sa, salen);
3616 if (evcon == NULL) {
3617 event_sock_warn(fd, "%s: cannot get connection on %d", __func__, fd);
3618 evutil_closesocket(fd);
3622 /* the timeout can be used by the server to close idle connections */
3623 if (http->timeout != -1)
3624 evhttp_connection_set_timeout(evcon, http->timeout);
3627 * if we want to accept more than one request on a connection,
3628 * we need to know which http server it belongs to.
3630 evcon->http_server = http;
3631 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
3633 if (evhttp_associate_new_request_with_connection(evcon) == -1)
3634 evhttp_connection_free(evcon);
3639 * Network helper functions that we do not want to export to the rest of
3644 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
3645 char **phost, char **pport)
3647 char ntop[NI_MAXHOST];
3648 char strport[NI_MAXSERV];
3651 #ifdef _EVENT_HAVE_GETNAMEINFO
3652 ni_result = getnameinfo(sa, salen,
3653 ntop, sizeof(ntop), strport, sizeof(strport),
3654 NI_NUMERICHOST|NI_NUMERICSERV);
3656 if (ni_result != 0) {
3658 /* Windows doesn't have an EAI_SYSTEM. */
3659 if (ni_result == EAI_SYSTEM)
3660 event_err(1, "getnameinfo failed");
3663 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
3667 ni_result = fake_getnameinfo(sa, salen,
3668 ntop, sizeof(ntop), strport, sizeof(strport),
3669 NI_NUMERICHOST|NI_NUMERICSERV);
3674 *phost = mm_strdup(ntop);
3675 *pport = mm_strdup(strport);
3678 /* Create a non-blocking socket and bind it */
3679 /* todo: rename this function */
3680 static evutil_socket_t
3681 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
3688 /* Create listen socket */
3689 fd = socket(ai ? ai->ai_family : AF_INET, SOCK_STREAM, 0);
3691 event_sock_warn(-1, "socket");
3695 if (evutil_make_socket_nonblocking(fd) < 0)
3697 if (evutil_make_socket_closeonexec(fd) < 0)
3700 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
3702 evutil_make_listen_socket_reuseable(fd);
3705 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
3713 serrno = EVUTIL_SOCKET_ERROR();
3714 evutil_closesocket(fd);
3715 EVUTIL_SET_SOCKET_ERROR(serrno);
3719 static struct evutil_addrinfo *
3720 make_addrinfo(const char *address, ev_uint16_t port)
3722 struct evutil_addrinfo *ai = NULL;
3724 struct evutil_addrinfo hints;
3725 char strport[NI_MAXSERV];
3728 memset(&hints, 0, sizeof(hints));
3729 hints.ai_family = AF_UNSPEC;
3730 hints.ai_socktype = SOCK_STREAM;
3731 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
3732 * types we don't have an interface to connect to. */
3733 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
3734 evutil_snprintf(strport, sizeof(strport), "%d", port);
3735 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
3737 if (ai_result == EVUTIL_EAI_SYSTEM)
3738 event_warn("getaddrinfo");
3740 event_warnx("getaddrinfo: %s",
3741 evutil_gai_strerror(ai_result));
3748 static evutil_socket_t
3749 bind_socket(const char *address, ev_uint16_t port, int reuse)
3752 struct evutil_addrinfo *aitop = NULL;
3754 /* just create an unbound socket */
3755 if (address == NULL && port == 0)
3756 return bind_socket_ai(NULL, 0);
3758 aitop = make_addrinfo(address, port);
3763 fd = bind_socket_ai(aitop, reuse);
3765 evutil_freeaddrinfo(aitop);
3771 char *scheme; /* scheme; e.g http, ftp etc */
3772 char *userinfo; /* userinfo (typically username:pass), or NULL */
3773 char *host; /* hostname, IP address, or NULL */
3774 int port; /* port, or zero */
3775 char *path; /* path, or "". */
3776 char *query; /* query, or NULL */
3777 char *fragment; /* fragment or NULL */
3781 evhttp_uri_new(void)
3783 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
3789 /* Return true of the string starting at s and ending immediately before eos
3790 * is a valid URI scheme according to RFC3986
3793 scheme_ok(const char *s, const char *eos)
3795 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
3796 EVUTIL_ASSERT(eos >= s);
3799 if (!EVUTIL_ISALPHA(*s))
3802 if (! EVUTIL_ISALNUM(*s) &&
3803 *s != '+' && *s != '-' && *s != '.')
3809 #define SUBDELIMS "!$&'()*+,;="
3811 /* Return true iff [s..eos) is a valid userinfo */
3813 userinfo_ok(const char *s, const char *eos)
3816 if (CHAR_IS_UNRESERVED(*s) ||
3817 strchr(SUBDELIMS, *s) ||
3820 else if (*s == '%' && s+2 < eos &&
3821 EVUTIL_ISXDIGIT(s[1]) &&
3822 EVUTIL_ISXDIGIT(s[2]))
3831 regname_ok(const char *s, const char *eos)
3833 while (s && s<eos) {
3834 if (CHAR_IS_UNRESERVED(*s) ||
3835 strchr(SUBDELIMS, *s))
3837 else if (*s == '%' &&
3838 EVUTIL_ISXDIGIT(s[1]) &&
3839 EVUTIL_ISXDIGIT(s[2]))
3848 parse_port(const char *s, const char *eos)
3852 if (! EVUTIL_ISDIGIT(*s))
3854 portnum = (portnum * 10) + (*s - '0');
3862 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
3864 bracket_addr_ok(const char *s, const char *eos)
3866 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
3869 /* IPvFuture, or junk.
3870 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
3872 s += 2; /* skip [v */
3874 if (!EVUTIL_ISXDIGIT(*s)) /*require at least one*/
3876 while (s < eos && *s != '.') {
3877 if (EVUTIL_ISXDIGIT(*s))
3886 if (CHAR_IS_UNRESERVED(*s) ||
3887 strchr(SUBDELIMS, *s) ||
3897 ev_ssize_t n_chars = eos-s-2;
3898 struct in6_addr in6;
3899 if (n_chars >= 64) /* way too long */
3901 memcpy(buf, s+1, n_chars);
3903 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
3908 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
3913 uri->host = mm_strdup("");
3917 /* Optionally, we start with "userinfo@" */
3919 cp = strchr(s, '@');
3920 if (cp && cp < eos) {
3921 if (! userinfo_ok(s,cp))
3924 uri->userinfo = mm_strdup(s);
3928 /* Optionally, we end with ":port" */
3929 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT(*port); --port)
3931 if (port >= cp && *port == ':') {
3932 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
3935 else if ((uri->port = parse_port(port+1, eos))<0)
3939 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
3940 * an IP-Literal, or a reg-name */
3941 EVUTIL_ASSERT(eos >= cp);
3942 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
3943 /* IPv6address, IP-Literal, or junk. */
3944 if (! bracket_addr_ok(cp, eos))
3947 /* Make sure the host part is ok. */
3948 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
3951 uri->host = mm_malloc(eos-cp+1);
3952 memcpy(uri->host, cp, eos-cp);
3953 uri->host[eos-cp] = '\0';
3959 end_of_authority(char *cp)
3962 if (*cp == '?' || *cp == '#' || *cp == '/')
3969 /* Return the character after the longest prefix of 'cp' that matches...
3970 * *pchar / "/" if allow_qchars is false, or
3971 * *(pchar / "/" / "?") if allow_chars is true.
3974 end_of_path(char *cp, int allow_qchars)
3977 if (CHAR_IS_UNRESERVED(*cp) ||
3978 strchr(SUBDELIMS, *cp) ||
3979 *cp == ':' || *cp == '@' || *cp == '/')
3981 else if (*cp == '%' && EVUTIL_ISXDIGIT(cp[1]) &&
3982 EVUTIL_ISXDIGIT(cp[2]))
3984 else if (*cp == '?' && allow_qchars)
3993 path_matches_noscheme(const char *cp)
3998 else if (*cp == '/')
4006 evhttp_uri_parse(const char *source_uri)
4008 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4009 char *path = NULL, *fragment = NULL;
4010 int got_authority = 0;
4012 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4014 event_err(1, "%s: calloc", __func__);
4019 readbuf = mm_strdup(source_uri);
4020 if (readbuf == NULL) {
4021 event_err(1, "%s: strdup", __func__);
4028 /* We try to follow RFC3986 here as much as we can, and match
4031 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4033 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
4038 token = strchr(readp, ':');
4039 if (token && scheme_ok(readp,token)) {
4041 uri->scheme = mm_strdup(readp);
4043 readp = token+1; /* eat : */
4046 /* 2. Optionally, "//" then an 'authority' part. */
4047 if (readp[0]=='/' && readp[1] == '/') {
4051 path = end_of_authority(readp);
4052 if (parse_authority(uri, authority, path) < 0)
4058 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4061 readp = end_of_path(path, 0);
4064 if (*readp == '?') {
4068 readp = end_of_path(readp, 1);
4071 if (*readp == '#') {
4075 readp = end_of_path(readp, 1);
4077 if (*readp != '\0') {
4081 /* These next two cases may be unreachable; I'm leaving them
4082 * in to be defensive. */
4083 /* If you didn't get an authority, the path can't begin with "//" */
4084 if (!got_authority && path[0]=='/' && path[1]=='/')
4086 /* If you did get an authority, the path must begin with "/" or be
4088 if (got_authority && path[0] != '/' && path[0] != '\0')
4090 /* (End of maybe-unreachable cases) */
4092 /* If there was no scheme, the first part of the path (if any) must
4093 * have no colon in it. */
4094 if (! uri->scheme && !path_matches_noscheme(path))
4097 EVUTIL_ASSERT(path);
4098 uri->path = mm_strdup(path);
4101 uri->query = mm_strdup(query);
4103 uri->fragment = mm_strdup(fragment);
4110 evhttp_uri_free(uri);
4117 evhttp_uri_free(struct evhttp_uri *uri)
4119 #define _URI_FREE_STR(f) \
4124 _URI_FREE_STR(scheme);
4125 _URI_FREE_STR(userinfo);
4126 _URI_FREE_STR(host);
4127 _URI_FREE_STR(path);
4128 _URI_FREE_STR(query);
4129 _URI_FREE_STR(fragment);
4132 #undef _URI_FREE_STR
4136 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
4138 struct evbuffer *tmp = 0;
4139 size_t joined_size = 0;
4140 char *output = NULL;
4142 #define _URI_ADD(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
4144 if (!uri || !buf || !limit)
4147 tmp = evbuffer_new();
4153 evbuffer_add(tmp, ":", 1);
4156 evbuffer_add(tmp, "//", 2);
4158 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
4161 evbuffer_add_printf(tmp,":%d", uri->port);
4163 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
4171 evbuffer_add(tmp, "?", 1);
4175 if (uri->fragment) {
4176 evbuffer_add(tmp, "#", 1);
4180 evbuffer_add(tmp, "\0", 1); /* NUL */
4182 joined_size = evbuffer_get_length(tmp);
4184 if (joined_size > limit) {
4185 /* It doesn't fit. */
4189 evbuffer_remove(tmp, buf, joined_size);
4200 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
4205 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
4207 return uri->userinfo;
4210 evhttp_uri_get_host(const struct evhttp_uri *uri)
4215 evhttp_uri_get_port(const struct evhttp_uri *uri)
4220 evhttp_uri_get_path(const struct evhttp_uri *uri)
4225 evhttp_uri_get_query(const struct evhttp_uri *uri)
4230 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
4232 return uri->fragment;
4235 #define _URI_SET_STR(f) do { \
4239 if ((uri->f = mm_strdup(f)) == NULL) { \
4240 event_warn("%s: strdup()", __func__); \
4249 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
4251 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
4254 _URI_SET_STR(scheme);
4258 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
4260 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
4262 _URI_SET_STR(userinfo);
4266 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
4269 if (host[0] == '[') {
4270 if (! bracket_addr_ok(host, host+strlen(host)))
4273 if (! regname_ok(host, host+strlen(host)))
4282 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
4289 #define end_of_cpath(cp,aq) ((const char*)(end_of_path(((char*)(cp)), (aq))))
4292 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
4294 if (path && end_of_cpath(path, 0) != path+strlen(path))
4301 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
4303 if (query && end_of_cpath(query, 1) != query+strlen(query))
4305 _URI_SET_STR(query);
4309 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
4311 if (fragment && end_of_cpath(fragment, 1) != fragment+strlen(fragment))
4313 _URI_SET_STR(fragment);