2 * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
3 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "event2/event-config.h"
29 #include "evconfig-private.h"
31 #ifdef EVENT__HAVE_SYS_PARAM_H
32 #include <sys/param.h>
34 #ifdef EVENT__HAVE_SYS_TYPES_H
35 #include <sys/types.h>
38 #ifdef HAVE_SYS_IOCCOM_H
39 #include <sys/ioccom.h>
41 #ifdef EVENT__HAVE_SYS_RESOURCE_H
42 #include <sys/resource.h>
44 #ifdef EVENT__HAVE_SYS_TIME_H
47 #ifdef EVENT__HAVE_SYS_WAIT_H
52 #include <sys/socket.h>
59 #include <sys/queue.h>
61 #ifdef EVENT__HAVE_NETINET_IN_H
62 #include <netinet/in.h>
64 #ifdef EVENT__HAVE_ARPA_INET_H
65 #include <arpa/inet.h>
67 #ifdef EVENT__HAVE_NETDB_H
84 #ifdef EVENT__HAVE_UNISTD_H
87 #ifdef EVENT__HAVE_FCNTL_H
91 #undef timeout_pending
92 #undef timeout_initialized
94 #include "strlcpy-internal.h"
95 #include "event2/http.h"
96 #include "event2/event.h"
97 #include "event2/buffer.h"
98 #include "event2/bufferevent.h"
99 #include "event2/http_struct.h"
100 #include "event2/http_compat.h"
101 #include "event2/util.h"
102 #include "event2/listener.h"
103 #include "log-internal.h"
104 #include "util-internal.h"
105 #include "http-internal.h"
106 #include "mm-internal.h"
107 #include "bufferevent-internal.h"
109 #ifndef EVENT__HAVE_GETNAMEINFO
110 #define NI_MAXSERV 32
111 #define NI_MAXHOST 1025
113 #ifndef NI_NUMERICHOST
114 #define NI_NUMERICHOST 1
117 #ifndef NI_NUMERICSERV
118 #define NI_NUMERICSERV 2
122 fake_getnameinfo(const struct sockaddr
*sa
, size_t salen
, char *host
,
123 size_t hostlen
, char *serv
, size_t servlen
, int flags
)
125 struct sockaddr_in
*sin
= (struct sockaddr_in
*)sa
;
129 evutil_snprintf(tmpserv
, sizeof(tmpserv
),
130 "%d", ntohs(sin
->sin_port
));
131 if (strlcpy(serv
, tmpserv
, servlen
) >= servlen
)
136 if (flags
& NI_NUMERICHOST
) {
137 if (strlcpy(host
, inet_ntoa(sin
->sin_addr
),
144 hp
= gethostbyaddr((char *)&sin
->sin_addr
,
145 sizeof(struct in_addr
), AF_INET
);
149 if (strlcpy(host
, hp
->h_name
, hostlen
) >= hostlen
)
160 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \
161 ((req)->major < (major_v) || \
162 ((req)->major == (major_v) && (req)->minor < (minor_v)))
164 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \
165 ((req)->major > (major_v) || \
166 ((req)->major == (major_v) && (req)->minor >= (minor_v)))
169 #define MIN(a,b) (((a)<(b))?(a):(b))
174 static evutil_socket_t
bind_socket_ai(struct evutil_addrinfo
*, int reuse
);
175 static evutil_socket_t
bind_socket(const char *, ev_uint16_t
, int reuse
);
176 static void name_from_addr(struct sockaddr
*, ev_socklen_t
, char **, char **);
177 static int evhttp_associate_new_request_with_connection(
178 struct evhttp_connection
*evcon
);
179 static void evhttp_connection_start_detectclose(
180 struct evhttp_connection
*evcon
);
181 static void evhttp_connection_stop_detectclose(
182 struct evhttp_connection
*evcon
);
183 static void evhttp_request_dispatch(struct evhttp_connection
* evcon
);
184 static void evhttp_read_firstline(struct evhttp_connection
*evcon
,
185 struct evhttp_request
*req
);
186 static void evhttp_read_header(struct evhttp_connection
*evcon
,
187 struct evhttp_request
*req
);
188 static int evhttp_add_header_internal(struct evkeyvalq
*headers
,
189 const char *key
, const char *value
);
190 static const char *evhttp_response_phrase_internal(int code
);
191 static void evhttp_get_request(struct evhttp
*, evutil_socket_t
, struct sockaddr
*, ev_socklen_t
);
192 static void evhttp_write_buffer(struct evhttp_connection
*,
193 void (*)(struct evhttp_connection
*, void *), void *);
194 static void evhttp_make_header(struct evhttp_connection
*, struct evhttp_request
*);
196 /* callbacks for bufferevent */
197 static void evhttp_read_cb(struct bufferevent
*, void *);
198 static void evhttp_write_cb(struct bufferevent
*, void *);
199 static void evhttp_error_cb(struct bufferevent
*bufev
, short what
, void *arg
);
200 static int evhttp_find_vhost(struct evhttp
*http
, struct evhttp
**outhttp
,
201 const char *hostname
);
203 #ifndef EVENT__HAVE_STRSEP
204 /* strsep replacement for platforms that lack it. Only works if
205 * del is one character long. */
207 strsep(char **s
, const char *del
)
210 EVUTIL_ASSERT(strlen(del
) == 1);
214 d
= strstr(tok
, del
);
225 html_replace(const char ch
, const char **escaped
)
251 * Replaces <, >, ", ' and & with <, >, ",
252 * ' and & correspondingly.
254 * The returned string needs to be freed by the caller.
258 evhttp_htmlescape(const char *html
)
261 size_t new_size
= 0, old_size
= 0;
262 char *escaped_html
, *p
;
267 old_size
= strlen(html
);
268 for (i
= 0; i
< old_size
; ++i
) {
269 const char *replaced
= NULL
;
270 const size_t replace_size
= html_replace(html
[i
], &replaced
);
271 if (replace_size
> EV_SIZE_MAX
- new_size
) {
272 event_warn("%s: html_replace overflow", __func__
);
275 new_size
+= replace_size
;
278 if (new_size
== EV_SIZE_MAX
)
280 p
= escaped_html
= mm_malloc(new_size
+ 1);
281 if (escaped_html
== NULL
) {
282 event_warn("%s: malloc(%lu)", __func__
,
283 (unsigned long)(new_size
+ 1));
286 for (i
= 0; i
< old_size
; ++i
) {
287 const char *replaced
= &html
[i
];
288 const size_t len
= html_replace(html
[i
], &replaced
);
289 memcpy(p
, replaced
, len
);
295 return (escaped_html
);
298 /** Given an evhttp_cmd_type, returns a constant string containing the
299 * equivalent HTTP command, or NULL if the evhttp_command_type is
302 evhttp_method(enum evhttp_cmd_type type
)
310 case EVHTTP_REQ_POST
:
313 case EVHTTP_REQ_HEAD
:
319 case EVHTTP_REQ_DELETE
:
322 case EVHTTP_REQ_OPTIONS
:
325 case EVHTTP_REQ_TRACE
:
328 case EVHTTP_REQ_CONNECT
:
331 case EVHTTP_REQ_PATCH
:
343 * Determines if a response should have a body.
344 * Follows the rules in RFC 2616 section 4.3.
345 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
349 evhttp_response_needs_body(struct evhttp_request
*req
)
351 return (req
->response_code
!= HTTP_NOCONTENT
&&
352 req
->response_code
!= HTTP_NOTMODIFIED
&&
353 (req
->response_code
< 100 || req
->response_code
>= 200) &&
354 req
->type
!= EVHTTP_REQ_HEAD
);
357 /** Helper: called after we've added some data to an evcon's bufferevent's
358 * output buffer. Sets the evconn's writing-is-done callback, and puts
359 * the bufferevent into writing mode.
362 evhttp_write_buffer(struct evhttp_connection
*evcon
,
363 void (*cb
)(struct evhttp_connection
*, void *), void *arg
)
365 event_debug(("%s: preparing to write buffer\n", __func__
));
371 /* Disable the read callback: we don't actually care about data;
372 * we only care about close detection. (We don't disable reading,
373 * since we *do* want to learn about any close events.) */
374 bufferevent_setcb(evcon
->bufev
,
380 bufferevent_enable(evcon
->bufev
, EV_WRITE
);
384 evhttp_send_continue_done(struct evhttp_connection
*evcon
, void *arg
)
386 bufferevent_disable(evcon
->bufev
, EV_WRITE
);
390 evhttp_send_continue(struct evhttp_connection
*evcon
,
391 struct evhttp_request
*req
)
393 bufferevent_enable(evcon
->bufev
, EV_WRITE
);
394 evbuffer_add_printf(bufferevent_get_output(evcon
->bufev
),
395 "HTTP/%d.%d 100 Continue\r\n\r\n",
396 req
->major
, req
->minor
);
397 evcon
->cb
= evhttp_send_continue_done
;
398 evcon
->cb_arg
= NULL
;
399 bufferevent_setcb(evcon
->bufev
,
406 /** Helper: returns true iff evconn is in any connected state. */
408 evhttp_connected(struct evhttp_connection
*evcon
)
410 switch (evcon
->state
) {
411 case EVCON_DISCONNECTED
:
412 case EVCON_CONNECTING
:
415 case EVCON_READING_FIRSTLINE
:
416 case EVCON_READING_HEADERS
:
417 case EVCON_READING_BODY
:
418 case EVCON_READING_TRAILER
:
425 /* Create the headers needed for an outgoing HTTP request, adds them to
426 * the request's header list, and writes the request line to the
427 * connection's output buffer.
430 evhttp_make_header_request(struct evhttp_connection
*evcon
,
431 struct evhttp_request
*req
)
435 evhttp_remove_header(req
->output_headers
, "Proxy-Connection");
437 /* Generate request line */
438 method
= evhttp_method(req
->type
);
439 evbuffer_add_printf(bufferevent_get_output(evcon
->bufev
),
440 "%s %s HTTP/%d.%d\r\n",
441 method
, req
->uri
, req
->major
, req
->minor
);
443 /* Add the content length on a post or put request if missing */
444 if ((req
->type
== EVHTTP_REQ_POST
|| req
->type
== EVHTTP_REQ_PUT
) &&
445 evhttp_find_header(req
->output_headers
, "Content-Length") == NULL
){
447 evutil_snprintf(size
, sizeof(size
), EV_SIZE_FMT
,
448 EV_SIZE_ARG(evbuffer_get_length(req
->output_buffer
)));
449 evhttp_add_header(req
->output_headers
, "Content-Length", size
);
453 /** Return true if the list of headers in 'headers', intepreted with respect
454 * to flags, means that we should send a "connection: close" when the request
457 evhttp_is_connection_close(int flags
, struct evkeyvalq
* headers
)
459 if (flags
& EVHTTP_PROXY_REQUEST
) {
460 /* proxy connection */
461 const char *connection
= evhttp_find_header(headers
, "Proxy-Connection");
462 return (connection
== NULL
|| evutil_ascii_strcasecmp(connection
, "keep-alive") != 0);
464 const char *connection
= evhttp_find_header(headers
, "Connection");
465 return (connection
!= NULL
&& evutil_ascii_strcasecmp(connection
, "close") == 0);
469 evhttp_is_request_connection_close(struct evhttp_request
*req
)
472 evhttp_is_connection_close(req
->flags
, req
->input_headers
) ||
473 evhttp_is_connection_close(req
->flags
, req
->output_headers
);
476 /* Return true iff 'headers' contains 'Connection: keep-alive' */
478 evhttp_is_connection_keepalive(struct evkeyvalq
* headers
)
480 const char *connection
= evhttp_find_header(headers
, "Connection");
481 return (connection
!= NULL
482 && evutil_ascii_strncasecmp(connection
, "keep-alive", 10) == 0);
485 /* Add a correct "Date" header to headers, unless it already has one. */
487 evhttp_maybe_add_date_header(struct evkeyvalq
*headers
)
489 if (evhttp_find_header(headers
, "Date") == NULL
) {
495 time_t t
= time(NULL
);
502 if (strftime(date
, sizeof(date
),
503 "%a, %d %b %Y %H:%M:%S GMT", cur_p
) != 0) {
504 evhttp_add_header(headers
, "Date", date
);
509 /* Add a "Content-Length" header with value 'content_length' to headers,
510 * unless it already has a content-length or transfer-encoding header. */
512 evhttp_maybe_add_content_length_header(struct evkeyvalq
*headers
,
513 size_t content_length
)
515 if (evhttp_find_header(headers
, "Transfer-Encoding") == NULL
&&
516 evhttp_find_header(headers
, "Content-Length") == NULL
) {
518 evutil_snprintf(len
, sizeof(len
), EV_SIZE_FMT
,
519 EV_SIZE_ARG(content_length
));
520 evhttp_add_header(headers
, "Content-Length", len
);
525 * Create the headers needed for an HTTP reply in req->output_headers,
526 * and write the first HTTP response for req line to evcon.
529 evhttp_make_header_response(struct evhttp_connection
*evcon
,
530 struct evhttp_request
*req
)
532 int is_keepalive
= evhttp_is_connection_keepalive(req
->input_headers
);
533 evbuffer_add_printf(bufferevent_get_output(evcon
->bufev
),
534 "HTTP/%d.%d %d %s\r\n",
535 req
->major
, req
->minor
, req
->response_code
,
536 req
->response_code_line
);
538 if (req
->major
== 1) {
540 evhttp_maybe_add_date_header(req
->output_headers
);
543 * if the protocol is 1.0; and the connection was keep-alive
544 * we need to add a keep-alive header, too.
546 if (req
->minor
== 0 && is_keepalive
)
547 evhttp_add_header(req
->output_headers
,
548 "Connection", "keep-alive");
550 if ((req
->minor
>= 1 || is_keepalive
) &&
551 evhttp_response_needs_body(req
)) {
553 * we need to add the content length if the
554 * user did not give it, this is required for
555 * persistent connections to work.
557 evhttp_maybe_add_content_length_header(
559 evbuffer_get_length(req
->output_buffer
));
563 /* Potentially add headers for unidentified content. */
564 if (evhttp_response_needs_body(req
)) {
565 if (evhttp_find_header(req
->output_headers
,
566 "Content-Type") == NULL
567 && evcon
->http_server
->default_content_type
) {
568 evhttp_add_header(req
->output_headers
,
570 evcon
->http_server
->default_content_type
);
574 /* if the request asked for a close, we send a close, too */
575 if (evhttp_is_connection_close(req
->flags
, req
->input_headers
)) {
576 evhttp_remove_header(req
->output_headers
, "Connection");
577 if (!(req
->flags
& EVHTTP_PROXY_REQUEST
))
578 evhttp_add_header(req
->output_headers
, "Connection", "close");
579 evhttp_remove_header(req
->output_headers
, "Proxy-Connection");
583 /** Generate all headers appropriate for sending the http request in req (or
584 * the response, if we're sending a response), and write them to evcon's
585 * bufferevent. Also writes all data from req->output_buffer */
587 evhttp_make_header(struct evhttp_connection
*evcon
, struct evhttp_request
*req
)
589 struct evkeyval
*header
;
590 struct evbuffer
*output
= bufferevent_get_output(evcon
->bufev
);
593 * Depending if this is a HTTP request or response, we might need to
594 * add some new headers or remove existing headers.
596 if (req
->kind
== EVHTTP_REQUEST
) {
597 evhttp_make_header_request(evcon
, req
);
599 evhttp_make_header_response(evcon
, req
);
602 TAILQ_FOREACH(header
, req
->output_headers
, next
) {
603 evbuffer_add_printf(output
, "%s: %s\r\n",
604 header
->key
, header
->value
);
606 evbuffer_add(output
, "\r\n", 2);
608 if (evbuffer_get_length(req
->output_buffer
) > 0) {
610 * For a request, we add the POST data, for a reply, this
611 * is the regular data.
613 /* XXX We might want to support waiting (a limited amount of
614 time) for a continue status line from the server before
615 sending POST/PUT message bodies. */
616 evbuffer_add_buffer(output
, req
->output_buffer
);
621 evhttp_connection_set_max_headers_size(struct evhttp_connection
*evcon
,
622 ev_ssize_t new_max_headers_size
)
624 if (new_max_headers_size
<0)
625 evcon
->max_headers_size
= EV_SIZE_MAX
;
627 evcon
->max_headers_size
= new_max_headers_size
;
630 evhttp_connection_set_max_body_size(struct evhttp_connection
* evcon
,
631 ev_ssize_t new_max_body_size
)
633 if (new_max_body_size
<0)
634 evcon
->max_body_size
= EV_UINT64_MAX
;
636 evcon
->max_body_size
= new_max_body_size
;
640 evhttp_connection_incoming_fail(struct evhttp_request
*req
,
641 enum evhttp_request_error error
)
644 case EVREQ_HTTP_TIMEOUT
:
647 * these are cases in which we probably should just
648 * close the connection and not send a reply. this
649 * case may happen when a browser keeps a persistent
650 * connection open and we timeout on the read. when
651 * the request is still being used for sending, we
652 * need to disassociated it from the connection here.
654 if (!req
->userdone
) {
655 /* remove it so that it will not be freed */
656 TAILQ_REMOVE(&req
->evcon
->requests
, req
, next
);
657 /* indicate that this request no longer has a
663 case EVREQ_HTTP_INVALID_HEADER
:
664 case EVREQ_HTTP_BUFFER_ERROR
:
665 case EVREQ_HTTP_REQUEST_CANCEL
:
666 case EVREQ_HTTP_DATA_TOO_LONG
:
667 default: /* xxx: probably should just error on default */
668 /* the callback looks at the uri to determine errors */
673 if (req
->uri_elems
) {
674 evhttp_uri_free(req
->uri_elems
);
675 req
->uri_elems
= NULL
;
679 * the callback needs to send a reply, once the reply has
680 * been send, the connection should get freed.
682 (*req
->cb
)(req
, req
->cb_arg
);
688 /* Free connection ownership of which can be acquired by user using
689 * evhttp_request_own(). */
691 evhttp_request_free_auto(struct evhttp_request
*req
)
693 if (!(req
->flags
& EVHTTP_USER_OWNED
)) {
694 evhttp_request_free(req
);
699 evhttp_request_free_(struct evhttp_connection
*evcon
, struct evhttp_request
*req
)
701 TAILQ_REMOVE(&evcon
->requests
, req
, next
);
702 evhttp_request_free_auto(req
);
705 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
706 * given in error. If it's an outgoing connection, reset the connection,
707 * retry any pending requests, and inform the user. If it's incoming,
708 * delegates to evhttp_connection_incoming_fail(). */
710 evhttp_connection_fail_(struct evhttp_connection
*evcon
,
711 enum evhttp_request_error error
)
713 const int errsave
= EVUTIL_SOCKET_ERROR();
714 struct evhttp_request
* req
= TAILQ_FIRST(&evcon
->requests
);
715 void (*cb
)(struct evhttp_request
*, void *);
717 void (*error_cb
)(enum evhttp_request_error
, void *);
719 EVUTIL_ASSERT(req
!= NULL
);
721 bufferevent_disable(evcon
->bufev
, EV_READ
|EV_WRITE
);
723 if (evcon
->flags
& EVHTTP_CON_INCOMING
) {
725 * for incoming requests, there are two different
726 * failure cases. it's either a network level error
727 * or an http layer error. for problems on the network
728 * layer like timeouts we just drop the connections.
729 * For HTTP problems, we might have to send back a
730 * reply before the connection can be freed.
732 if (evhttp_connection_incoming_fail(req
, error
) == -1)
733 evhttp_connection_free(evcon
);
737 error_cb
= req
->error_cb
;
738 error_cb_arg
= req
->cb_arg
;
739 /* when the request was canceled, the callback is not executed */
740 if (error
!= EVREQ_HTTP_REQUEST_CANCEL
) {
741 /* save the callback for later; the cb might free our object */
743 cb_arg
= req
->cb_arg
;
749 /* do not fail all requests; the next request is going to get
750 * send over a new connection. when a user cancels a request,
751 * all other pending requests should be processed as normal
753 evhttp_request_free_(evcon
, req
);
755 /* reset the connection */
756 evhttp_connection_reset_(evcon
);
758 /* We are trying the next request that was queued on us */
759 if (TAILQ_FIRST(&evcon
->requests
) != NULL
)
760 evhttp_connection_connect_(evcon
);
762 /* The call to evhttp_connection_reset_ overwrote errno.
763 * Let's restore the original errno, so that the user's
764 * callback can have a better idea of what the error was.
766 EVUTIL_SET_SOCKET_ERROR(errsave
);
768 /* inform the user */
769 if (error_cb
!= NULL
)
770 error_cb(error
, error_cb_arg
);
775 /* Bufferevent callback: invoked when any data has been written from an
776 * http connection's bufferevent */
778 evhttp_write_cb(struct bufferevent
*bufev
, void *arg
)
780 struct evhttp_connection
*evcon
= arg
;
782 /* Activate our call back */
783 if (evcon
->cb
!= NULL
)
784 (*evcon
->cb
)(evcon
, evcon
->cb_arg
);
788 * Advance the connection state.
789 * - If this is an outgoing connection, we've just processed the response;
790 * idle or close the connection.
791 * - If this is an incoming connection, we've just processed the request;
795 evhttp_connection_done(struct evhttp_connection
*evcon
)
797 struct evhttp_request
*req
= TAILQ_FIRST(&evcon
->requests
);
798 int con_outgoing
= evcon
->flags
& EVHTTP_CON_OUTGOING
;
802 /* idle or close the connection */
803 int need_close
= evhttp_is_request_connection_close(req
);
804 TAILQ_REMOVE(&evcon
->requests
, req
, next
);
807 evcon
->state
= EVCON_IDLE
;
809 /* check if we got asked to close the connection */
811 evhttp_connection_reset_(evcon
);
813 if (TAILQ_FIRST(&evcon
->requests
) != NULL
) {
815 * We have more requests; reset the connection
816 * and deal with the next request.
818 if (!evhttp_connected(evcon
))
819 evhttp_connection_connect_(evcon
);
821 evhttp_request_dispatch(evcon
);
822 } else if (!need_close
) {
824 * The connection is going to be persistent, but we
825 * need to detect if the other side closes it.
827 evhttp_connection_start_detectclose(evcon
);
828 } else if ((evcon
->flags
& EVHTTP_CON_AUTOFREE
)) {
830 * If we have no more requests that need completion
831 * and we're not waiting for the connection to close
837 * incoming connection - we need to leave the request on the
838 * connection so that we can reply to it.
840 evcon
->state
= EVCON_WRITING
;
843 /* notify the user of the request */
844 (*req
->cb
)(req
, req
->cb_arg
);
846 /* if this was an outgoing request, we own and it's done. so free it. */
848 evhttp_request_free_auto(req
);
851 /* If this was the last request of an outgoing connection and we're
852 * not waiting to receive a connection close event and we want to
853 * automatically free the connection. We check to ensure our request
854 * list is empty one last time just in case our callback added a
857 if (free_evcon
&& TAILQ_FIRST(&evcon
->requests
) == NULL
) {
858 evhttp_connection_free(evcon
);
863 * Handles reading from a chunked request.
864 * return ALL_DATA_READ:
865 * all data has been read
866 * return MORE_DATA_EXPECTED:
867 * more data is expected
868 * return DATA_CORRUPTED:
870 * return REQUEST_CANCELED:
871 * request was canceled by the user calling evhttp_cancel_request
872 * return DATA_TOO_LONG:
873 * ran over the maximum limit
876 static enum message_read_status
877 evhttp_handle_chunked_read(struct evhttp_request
*req
, struct evbuffer
*buf
)
879 if (req
== NULL
|| buf
== NULL
) {
880 return DATA_CORRUPTED
;
886 if ((buflen
= evbuffer_get_length(buf
)) == 0) {
890 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
891 * check for overflow conditions */
892 if (buflen
> EV_SSIZE_MAX
) {
893 return DATA_CORRUPTED
;
896 if (req
->ntoread
< 0) {
897 /* Read chunk size */
899 char *p
= evbuffer_readln(buf
, NULL
, EVBUFFER_EOL_CRLF
);
904 /* the last chunk is on a new line? */
905 if (strlen(p
) == 0) {
909 ntoread
= evutil_strtoll(p
, &endp
, 16);
910 error
= (*p
== '\0' ||
911 (*endp
!= '\0' && *endp
!= ' ') ||
915 /* could not get chunk size */
916 return (DATA_CORRUPTED
);
919 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
920 if ((ev_uint64_t
)ntoread
> EV_SIZE_MAX
- req
->body_size
) {
921 return DATA_CORRUPTED
;
924 if (req
->body_size
+ (size_t)ntoread
> req
->evcon
->max_body_size
) {
925 /* failed body length test */
926 event_debug(("Request body is too long"));
927 return (DATA_TOO_LONG
);
930 req
->body_size
+= (size_t)ntoread
;
931 req
->ntoread
= ntoread
;
932 if (req
->ntoread
== 0) {
934 return (ALL_DATA_READ
);
939 /* req->ntoread is signed int64, len is ssize_t, based on arch,
940 * ssize_t could only be 32b, check for these conditions */
941 if (req
->ntoread
> EV_SSIZE_MAX
) {
942 return DATA_CORRUPTED
;
945 /* don't have enough to complete a chunk; wait for more */
946 if (req
->ntoread
> 0 && buflen
< (ev_uint64_t
)req
->ntoread
)
947 return (MORE_DATA_EXPECTED
);
949 /* Completed chunk */
950 evbuffer_remove_buffer(buf
, req
->input_buffer
, (size_t)req
->ntoread
);
952 if (req
->chunk_cb
!= NULL
) {
953 req
->flags
|= EVHTTP_REQ_DEFER_FREE
;
954 (*req
->chunk_cb
)(req
, req
->cb_arg
);
955 evbuffer_drain(req
->input_buffer
,
956 evbuffer_get_length(req
->input_buffer
));
957 req
->flags
&= ~EVHTTP_REQ_DEFER_FREE
;
958 if ((req
->flags
& EVHTTP_REQ_NEEDS_FREE
) != 0) {
959 return (REQUEST_CANCELED
);
964 return (MORE_DATA_EXPECTED
);
968 evhttp_read_trailer(struct evhttp_connection
*evcon
, struct evhttp_request
*req
)
970 struct evbuffer
*buf
= bufferevent_get_input(evcon
->bufev
);
972 switch (evhttp_parse_headers_(req
, buf
)) {
975 evhttp_connection_fail_(evcon
, EVREQ_HTTP_DATA_TOO_LONG
);
978 bufferevent_disable(evcon
->bufev
, EV_READ
);
979 evhttp_connection_done(evcon
);
981 case MORE_DATA_EXPECTED
:
982 case REQUEST_CANCELED
: /* ??? */
989 evhttp_read_body(struct evhttp_connection
*evcon
, struct evhttp_request
*req
)
991 struct evbuffer
*buf
= bufferevent_get_input(evcon
->bufev
);
994 switch (evhttp_handle_chunked_read(req
, buf
)) {
996 /* finished last chunk */
997 evcon
->state
= EVCON_READING_TRAILER
;
998 evhttp_read_trailer(evcon
, req
);
1000 case DATA_CORRUPTED
:
1002 /* corrupted data */
1003 evhttp_connection_fail_(evcon
,
1004 EVREQ_HTTP_DATA_TOO_LONG
);
1006 case REQUEST_CANCELED
:
1007 /* request canceled */
1008 evhttp_request_free_auto(req
);
1010 case MORE_DATA_EXPECTED
:
1014 } else if (req
->ntoread
< 0) {
1015 /* Read until connection close. */
1016 if ((size_t)(req
->body_size
+ evbuffer_get_length(buf
)) < req
->body_size
) {
1017 evhttp_connection_fail_(evcon
, EVREQ_HTTP_INVALID_HEADER
);
1021 req
->body_size
+= evbuffer_get_length(buf
);
1022 evbuffer_add_buffer(req
->input_buffer
, buf
);
1023 } else if (req
->chunk_cb
!= NULL
|| evbuffer_get_length(buf
) >= (size_t)req
->ntoread
) {
1024 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
1025 /* We've postponed moving the data until now, but we're
1026 * about to use it. */
1027 size_t n
= evbuffer_get_length(buf
);
1029 if (n
> (size_t) req
->ntoread
)
1030 n
= (size_t) req
->ntoread
;
1032 req
->body_size
+= n
;
1033 evbuffer_remove_buffer(buf
, req
->input_buffer
, n
);
1036 if (req
->body_size
> req
->evcon
->max_body_size
||
1037 (!req
->chunked
&& req
->ntoread
>= 0 &&
1038 (size_t)req
->ntoread
> req
->evcon
->max_body_size
)) {
1039 /* XXX: The above casted comparison must checked for overflow */
1040 /* failed body length test */
1041 event_debug(("Request body is too long"));
1042 evhttp_connection_fail_(evcon
,
1043 EVREQ_HTTP_DATA_TOO_LONG
);
1047 if (evbuffer_get_length(req
->input_buffer
) > 0 && req
->chunk_cb
!= NULL
) {
1048 req
->flags
|= EVHTTP_REQ_DEFER_FREE
;
1049 (*req
->chunk_cb
)(req
, req
->cb_arg
);
1050 req
->flags
&= ~EVHTTP_REQ_DEFER_FREE
;
1051 evbuffer_drain(req
->input_buffer
,
1052 evbuffer_get_length(req
->input_buffer
));
1053 if ((req
->flags
& EVHTTP_REQ_NEEDS_FREE
) != 0) {
1054 evhttp_request_free_auto(req
);
1059 if (req
->ntoread
== 0) {
1060 bufferevent_disable(evcon
->bufev
, EV_READ
);
1061 /* Completed content length */
1062 evhttp_connection_done(evcon
);
1067 #define get_deferred_queue(evcon) \
1071 * Gets called when more data becomes available
1075 evhttp_read_cb(struct bufferevent
*bufev
, void *arg
)
1077 struct evhttp_connection
*evcon
= arg
;
1078 struct evhttp_request
*req
= TAILQ_FIRST(&evcon
->requests
);
1080 /* Cancel if it's pending. */
1081 event_deferred_cb_cancel_(get_deferred_queue(evcon
),
1082 &evcon
->read_more_deferred_cb
);
1084 switch (evcon
->state
) {
1085 case EVCON_READING_FIRSTLINE
:
1086 evhttp_read_firstline(evcon
, req
);
1087 /* note the request may have been freed in
1088 * evhttp_read_body */
1090 case EVCON_READING_HEADERS
:
1091 evhttp_read_header(evcon
, req
);
1092 /* note the request may have been freed in
1093 * evhttp_read_body */
1095 case EVCON_READING_BODY
:
1096 evhttp_read_body(evcon
, req
);
1097 /* note the request may have been freed in
1098 * evhttp_read_body */
1100 case EVCON_READING_TRAILER
:
1101 evhttp_read_trailer(evcon
, req
);
1106 struct evbuffer
*input
;
1109 input
= bufferevent_get_input(evcon
->bufev
);
1110 total_len
= evbuffer_get_length(input
);
1111 event_debug(("%s: read "EV_SIZE_FMT
1112 " bytes in EVCON_IDLE state,"
1113 " resetting connection",
1114 __func__
, EV_SIZE_ARG(total_len
)));
1117 evhttp_connection_reset_(evcon
);
1120 case EVCON_DISCONNECTED
:
1121 case EVCON_CONNECTING
:
1124 event_errx(1, "%s: illegal connection state %d",
1125 __func__
, evcon
->state
);
1130 evhttp_deferred_read_cb(struct event_callback
*cb
, void *data
)
1132 struct evhttp_connection
*evcon
= data
;
1133 evhttp_read_cb(evcon
->bufev
, evcon
);
1137 evhttp_write_connectioncb(struct evhttp_connection
*evcon
, void *arg
)
1139 /* This is after writing the request to the server */
1140 struct evhttp_request
*req
= TAILQ_FIRST(&evcon
->requests
);
1141 EVUTIL_ASSERT(req
!= NULL
);
1143 EVUTIL_ASSERT(evcon
->state
== EVCON_WRITING
);
1145 /* We need to wait until we've written all of our output data before we can continue */
1146 if (evbuffer_get_length(bufferevent_get_output(evcon
->bufev
)) > 0) { return; }
1148 /* We are done writing our header and are now expecting the response */
1149 req
->kind
= EVHTTP_RESPONSE
;
1151 evhttp_start_read_(evcon
);
1155 * Clean up a connection object
1159 evhttp_connection_free(struct evhttp_connection
*evcon
)
1161 struct evhttp_request
*req
;
1163 /* notify interested parties that this connection is going down */
1164 if (evcon
->fd
!= -1) {
1165 if (evhttp_connected(evcon
) && evcon
->closecb
!= NULL
)
1166 (*evcon
->closecb
)(evcon
, evcon
->closecb_arg
);
1169 /* remove all requests that might be queued on this
1170 * connection. for server connections, this should be empty.
1171 * because it gets dequeued either in evhttp_connection_done or
1172 * evhttp_connection_fail_.
1174 while ((req
= TAILQ_FIRST(&evcon
->requests
)) != NULL
) {
1175 evhttp_request_free_(evcon
, req
);
1178 if (evcon
->http_server
!= NULL
) {
1179 struct evhttp
*http
= evcon
->http_server
;
1180 TAILQ_REMOVE(&http
->connections
, evcon
, next
);
1183 if (event_initialized(&evcon
->retry_ev
)) {
1184 event_del(&evcon
->retry_ev
);
1185 event_debug_unassign(&evcon
->retry_ev
);
1188 if (evcon
->bufev
!= NULL
)
1189 bufferevent_free(evcon
->bufev
);
1191 event_deferred_cb_cancel_(get_deferred_queue(evcon
),
1192 &evcon
->read_more_deferred_cb
);
1194 if (evcon
->fd
!= -1) {
1195 bufferevent_disable(evcon
->bufev
, EV_READ
|EV_WRITE
);
1196 shutdown(evcon
->fd
, EVUTIL_SHUT_WR
);
1197 if (!(bufferevent_get_options_(evcon
->bufev
) & BEV_OPT_CLOSE_ON_FREE
)) {
1198 evutil_closesocket(evcon
->fd
);
1202 if (evcon
->bind_address
!= NULL
)
1203 mm_free(evcon
->bind_address
);
1205 if (evcon
->address
!= NULL
)
1206 mm_free(evcon
->address
);
1212 evhttp_connection_free_on_completion(struct evhttp_connection
*evcon
) {
1213 evcon
->flags
|= EVHTTP_CON_AUTOFREE
;
1217 evhttp_connection_set_local_address(struct evhttp_connection
*evcon
,
1218 const char *address
)
1220 EVUTIL_ASSERT(evcon
->state
== EVCON_DISCONNECTED
);
1221 if (evcon
->bind_address
)
1222 mm_free(evcon
->bind_address
);
1223 if ((evcon
->bind_address
= mm_strdup(address
)) == NULL
)
1224 event_warn("%s: strdup", __func__
);
1228 evhttp_connection_set_local_port(struct evhttp_connection
*evcon
,
1231 EVUTIL_ASSERT(evcon
->state
== EVCON_DISCONNECTED
);
1232 evcon
->bind_port
= port
;
1236 evhttp_request_dispatch(struct evhttp_connection
* evcon
)
1238 struct evhttp_request
*req
= TAILQ_FIRST(&evcon
->requests
);
1240 /* this should not usually happy but it's possible */
1244 /* delete possible close detection events */
1245 evhttp_connection_stop_detectclose(evcon
);
1247 /* we assume that the connection is connected already */
1248 EVUTIL_ASSERT(evcon
->state
== EVCON_IDLE
);
1250 evcon
->state
= EVCON_WRITING
;
1252 /* Create the header from the store arguments */
1253 evhttp_make_header(evcon
, req
);
1255 evhttp_write_buffer(evcon
, evhttp_write_connectioncb
, NULL
);
1258 /* Reset our connection state: disables reading/writing, closes our fd (if
1259 * any), clears out buffers, and puts us in state DISCONNECTED. */
1261 evhttp_connection_reset_(struct evhttp_connection
*evcon
)
1263 struct evbuffer
*tmp
;
1265 /* XXXX This is not actually an optimal fix. Instead we ought to have
1266 an API for "stop connecting", or use bufferevent_setfd to turn off
1267 connecting. But for Libevent 2.0, this seems like a minimal change
1268 least likely to disrupt the rest of the bufferevent and http code.
1270 Why is this here? If the fd is set in the bufferevent, and the
1271 bufferevent is connecting, then you can't actually stop the
1272 bufferevent from trying to connect with bufferevent_disable(). The
1273 connect will never trigger, since we close the fd, but the timeout
1274 might. That caused an assertion failure in evhttp_connection_fail_.
1276 bufferevent_disable_hard_(evcon
->bufev
, EV_READ
|EV_WRITE
);
1278 if (evcon
->fd
!= -1) {
1279 /* inform interested parties about connection close */
1280 if (evhttp_connected(evcon
) && evcon
->closecb
!= NULL
)
1281 (*evcon
->closecb
)(evcon
, evcon
->closecb_arg
);
1283 shutdown(evcon
->fd
, EVUTIL_SHUT_WR
);
1284 evutil_closesocket(evcon
->fd
);
1285 bufferevent_setfd(evcon
->bufev
, -1);
1289 /* we need to clean up any buffered data */
1290 tmp
= bufferevent_get_output(evcon
->bufev
);
1291 evbuffer_drain(tmp
, evbuffer_get_length(tmp
));
1292 tmp
= bufferevent_get_input(evcon
->bufev
);
1293 evbuffer_drain(tmp
, evbuffer_get_length(tmp
));
1295 evcon
->state
= EVCON_DISCONNECTED
;
1299 evhttp_connection_start_detectclose(struct evhttp_connection
*evcon
)
1301 evcon
->flags
|= EVHTTP_CON_CLOSEDETECT
;
1303 bufferevent_enable(evcon
->bufev
, EV_READ
);
1307 evhttp_connection_stop_detectclose(struct evhttp_connection
*evcon
)
1309 evcon
->flags
&= ~EVHTTP_CON_CLOSEDETECT
;
1311 bufferevent_disable(evcon
->bufev
, EV_READ
);
1315 evhttp_connection_retry(evutil_socket_t fd
, short what
, void *arg
)
1317 struct evhttp_connection
*evcon
= arg
;
1319 evcon
->state
= EVCON_DISCONNECTED
;
1320 evhttp_connection_connect_(evcon
);
1324 evhttp_connection_cb_cleanup(struct evhttp_connection
*evcon
)
1326 struct evcon_requestq requests
;
1328 evhttp_connection_reset_(evcon
);
1329 if (evcon
->retry_max
< 0 || evcon
->retry_cnt
< evcon
->retry_max
) {
1330 struct timeval tv_retry
= evcon
->initial_retry_timeout
;
1332 evtimer_assign(&evcon
->retry_ev
, evcon
->base
, evhttp_connection_retry
, evcon
);
1333 /* XXXX handle failure from evhttp_add_event */
1334 for (i
=0; i
< evcon
->retry_cnt
; ++i
) {
1335 tv_retry
.tv_usec
*= 2;
1336 if (tv_retry
.tv_usec
> 1000000) {
1337 tv_retry
.tv_usec
-= 1000000;
1338 tv_retry
.tv_sec
+= 1;
1340 tv_retry
.tv_sec
*= 2;
1341 if (tv_retry
.tv_sec
> 3600) {
1342 tv_retry
.tv_sec
= 3600;
1343 tv_retry
.tv_usec
= 0;
1346 event_add(&evcon
->retry_ev
, &tv_retry
);
1352 * User callback can do evhttp_make_request() on the same
1353 * evcon so new request will be added to evcon->requests. To
1354 * avoid freeing it prematurely we iterate over the copy of
1357 TAILQ_INIT(&requests
);
1358 while (TAILQ_FIRST(&evcon
->requests
) != NULL
) {
1359 struct evhttp_request
*request
= TAILQ_FIRST(&evcon
->requests
);
1360 TAILQ_REMOVE(&evcon
->requests
, request
, next
);
1361 TAILQ_INSERT_TAIL(&requests
, request
, next
);
1364 /* for now, we just signal all requests by executing their callbacks */
1365 while (TAILQ_FIRST(&requests
) != NULL
) {
1366 struct evhttp_request
*request
= TAILQ_FIRST(&requests
);
1367 TAILQ_REMOVE(&requests
, request
, next
);
1368 request
->evcon
= NULL
;
1370 /* we might want to set an error here */
1371 request
->cb(request
, request
->cb_arg
);
1372 evhttp_request_free_auto(request
);
1377 evhttp_error_cb(struct bufferevent
*bufev
, short what
, void *arg
)
1379 struct evhttp_connection
*evcon
= arg
;
1380 struct evhttp_request
*req
= TAILQ_FIRST(&evcon
->requests
);
1382 if (evcon
->fd
== -1)
1383 evcon
->fd
= bufferevent_getfd(bufev
);
1385 switch (evcon
->state
) {
1386 case EVCON_CONNECTING
:
1387 if (what
& BEV_EVENT_TIMEOUT
) {
1388 event_debug(("%s: connection timeout for \"%s:%d\" on "
1390 __func__
, evcon
->address
, evcon
->port
,
1391 EV_SOCK_ARG(evcon
->fd
)));
1392 evhttp_connection_cb_cleanup(evcon
);
1397 case EVCON_READING_BODY
:
1398 if (!req
->chunked
&& req
->ntoread
< 0
1399 && what
== (BEV_EVENT_READING
|BEV_EVENT_EOF
)) {
1400 /* EOF on read can be benign */
1401 evhttp_connection_done(evcon
);
1406 case EVCON_DISCONNECTED
:
1408 case EVCON_READING_FIRSTLINE
:
1409 case EVCON_READING_HEADERS
:
1410 case EVCON_READING_TRAILER
:
1416 /* when we are in close detect mode, a read error means that
1417 * the other side closed their connection.
1419 if (evcon
->flags
& EVHTTP_CON_CLOSEDETECT
) {
1420 evcon
->flags
&= ~EVHTTP_CON_CLOSEDETECT
;
1421 EVUTIL_ASSERT(evcon
->http_server
== NULL
);
1422 /* For connections from the client, we just
1423 * reset the connection so that it becomes
1426 EVUTIL_ASSERT(evcon
->state
== EVCON_IDLE
);
1427 evhttp_connection_reset_(evcon
);
1430 * If we have no more requests that need completion
1431 * and we want to auto-free the connection when all
1432 * requests have been completed.
1434 if (TAILQ_FIRST(&evcon
->requests
) == NULL
1435 && (evcon
->flags
& EVHTTP_CON_OUTGOING
)
1436 && (evcon
->flags
& EVHTTP_CON_AUTOFREE
)) {
1437 evhttp_connection_free(evcon
);
1442 if (what
& BEV_EVENT_TIMEOUT
) {
1443 evhttp_connection_fail_(evcon
, EVREQ_HTTP_TIMEOUT
);
1444 } else if (what
& (BEV_EVENT_EOF
|BEV_EVENT_ERROR
)) {
1445 evhttp_connection_fail_(evcon
, EVREQ_HTTP_EOF
);
1446 } else if (what
== BEV_EVENT_CONNECTED
) {
1448 evhttp_connection_fail_(evcon
, EVREQ_HTTP_BUFFER_ERROR
);
1453 * Event callback for asynchronous connection attempt.
1456 evhttp_connection_cb(struct bufferevent
*bufev
, short what
, void *arg
)
1458 struct evhttp_connection
*evcon
= arg
;
1460 ev_socklen_t errsz
= sizeof(error
);
1462 if (evcon
->fd
== -1)
1463 evcon
->fd
= bufferevent_getfd(bufev
);
1465 if (!(what
& BEV_EVENT_CONNECTED
)) {
1466 /* some operating systems return ECONNREFUSED immediately
1467 * when connecting to a local address. the cleanup is going
1468 * to reschedule this function call.
1471 if (errno
== ECONNREFUSED
)
1474 evhttp_error_cb(bufev
, what
, arg
);
1478 if (evcon
->fd
== -1) {
1479 event_debug(("%s: bufferevent_getfd returned -1",
1484 /* Check if the connection completed */
1485 if (getsockopt(evcon
->fd
, SOL_SOCKET
, SO_ERROR
, (void*)&error
,
1487 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT
,
1488 __func__
, evcon
->address
, evcon
->port
,
1489 EV_SOCK_ARG(evcon
->fd
)));
1494 event_debug(("%s: connect failed for \"%s:%d\" on "
1496 __func__
, evcon
->address
, evcon
->port
,
1497 EV_SOCK_ARG(evcon
->fd
),
1498 evutil_socket_error_to_string(error
)));
1502 /* We are connected to the server now */
1503 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT
"\n",
1504 __func__
, evcon
->address
, evcon
->port
,
1505 EV_SOCK_ARG(evcon
->fd
)));
1507 /* Reset the retry count as we were successful in connecting */
1508 evcon
->retry_cnt
= 0;
1509 evcon
->state
= EVCON_IDLE
;
1511 /* reset the bufferevent cbs */
1512 bufferevent_setcb(evcon
->bufev
,
1518 if (!evutil_timerisset(&evcon
->timeout
)) {
1519 const struct timeval read_tv
= { HTTP_READ_TIMEOUT
, 0 };
1520 const struct timeval write_tv
= { HTTP_WRITE_TIMEOUT
, 0 };
1521 bufferevent_set_timeouts(evcon
->bufev
, &read_tv
, &write_tv
);
1523 bufferevent_set_timeouts(evcon
->bufev
, &evcon
->timeout
, &evcon
->timeout
);
1526 /* try to start requests that have queued up on this connection */
1527 evhttp_request_dispatch(evcon
);
1531 evhttp_connection_cb_cleanup(evcon
);
1535 * Check if we got a valid response code.
1539 evhttp_valid_response_code(int code
)
1548 evhttp_parse_http_version(const char *version
, struct evhttp_request
*req
)
1552 int n
= sscanf(version
, "HTTP/%d.%d%c", &major
, &minor
, &ch
);
1553 if (n
!= 2 || major
> 1) {
1554 event_debug(("%s: bad version %s on message %p from %s",
1555 __func__
, version
, req
, req
->remote_host
));
1563 /* Parses the status line of a web server */
1566 evhttp_parse_response_line(struct evhttp_request
*req
, char *line
)
1570 const char *readable
= "";
1572 protocol
= strsep(&line
, " ");
1575 number
= strsep(&line
, " ");
1579 if (evhttp_parse_http_version(protocol
, req
) < 0)
1582 req
->response_code
= atoi(number
);
1583 if (!evhttp_valid_response_code(req
->response_code
)) {
1584 event_debug(("%s: bad response code \"%s\"",
1589 if ((req
->response_code_line
= mm_strdup(readable
)) == NULL
) {
1590 event_warn("%s: strdup", __func__
);
1597 /* Parse the first line of a HTTP request */
1600 evhttp_parse_request_line(struct evhttp_request
*req
, char *line
)
1605 const char *hostname
;
1608 enum evhttp_cmd_type type
;
1610 /* Parse the request line */
1611 method
= strsep(&line
, " ");
1614 uri
= strsep(&line
, " ");
1617 version
= strsep(&line
, " ");
1621 method_len
= (uri
- method
) - 1;
1622 type
= EVHTTP_REQ_UNKNOWN_
;
1625 switch (method_len
) {
1627 /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */
1629 /* Since both GET and PUT share the same character 'T' at the end,
1630 * if the string doesn't have 'T', we can immediately determine this
1631 * is an invalid HTTP method */
1633 if (method
[2] != 'T') {
1639 /* This first byte is 'G', so make sure the next byte is
1640 * 'E', if it isn't then this isn't a valid method */
1642 if (method
[1] == 'E') {
1643 type
= EVHTTP_REQ_GET
;
1648 /* First byte is P, check second byte for 'U', if not,
1649 * we know it's an invalid method */
1650 if (method
[1] == 'U') {
1651 type
= EVHTTP_REQ_PUT
;
1659 /* The method length is 4 bytes, leaving only the methods "POST" and "HEAD" */
1662 if (method
[3] == 'T' && method
[2] == 'S' && method
[1] == 'O') {
1663 type
= EVHTTP_REQ_POST
;
1667 if (method
[3] == 'D' && method
[2] == 'A' && method
[1] == 'E') {
1668 type
= EVHTTP_REQ_HEAD
;
1676 /* Method length is 5 bytes, which can only encompass PATCH and TRACE */
1679 if (method
[4] == 'H' && method
[3] == 'C' && method
[2] == 'T' && method
[1] == 'A') {
1680 type
= EVHTTP_REQ_PATCH
;
1684 if (method
[4] == 'E' && method
[3] == 'C' && method
[2] == 'A' && method
[1] == 'R') {
1685 type
= EVHTTP_REQ_TRACE
;
1694 /* Method length is 6, only valid method 6 bytes in length is DELEte */
1696 /* If the first byte isn't 'D' then it's invalid */
1697 if (*method
!= 'D') {
1701 if (method
[5] == 'E' && method
[4] == 'T' && method
[3] == 'E' && method
[2] == 'L' && method
[1] == 'E') {
1702 type
= EVHTTP_REQ_DELETE
;
1707 /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */
1710 if (method
[6] == 'S' && method
[5] == 'N' && method
[4] == 'O' &&
1711 method
[3] == 'I' && method
[2] == 'T' && method
[1] == 'P') {
1712 type
= EVHTTP_REQ_OPTIONS
;
1717 if (method
[6] == 'T' && method
[5] == 'C' && method
[4] == 'E' &&
1718 method
[3] == 'N' && method
[2] == 'N' && method
[1] == 'O') {
1719 type
= EVHTTP_REQ_CONNECT
;
1729 if ((int)type
== EVHTTP_REQ_UNKNOWN_
) {
1730 event_debug(("%s: bad method %s on request %p from %s",
1731 __func__
, method
, req
, req
->remote_host
));
1732 /* No error yet; we'll give a better error later when
1733 * we see that req->type is unsupported. */
1738 if (evhttp_parse_http_version(version
, req
) < 0)
1741 if ((req
->uri
= mm_strdup(uri
)) == NULL
) {
1742 event_debug(("%s: mm_strdup", __func__
));
1746 if ((req
->uri_elems
= evhttp_uri_parse_with_flags(req
->uri
,
1747 EVHTTP_URI_NONCONFORMANT
)) == NULL
) {
1751 /* If we have an absolute-URI, check to see if it is an http request
1752 for a known vhost or server alias. If we don't know about this
1753 host, we consider it a proxy request. */
1754 scheme
= evhttp_uri_get_scheme(req
->uri_elems
);
1755 hostname
= evhttp_uri_get_host(req
->uri_elems
);
1756 if (scheme
&& (!evutil_ascii_strcasecmp(scheme
, "http") ||
1757 !evutil_ascii_strcasecmp(scheme
, "https")) &&
1759 !evhttp_find_vhost(req
->evcon
->http_server
, NULL
, hostname
))
1760 req
->flags
|= EVHTTP_PROXY_REQUEST
;
1766 evhttp_find_header(const struct evkeyvalq
*headers
, const char *key
)
1768 struct evkeyval
*header
;
1770 TAILQ_FOREACH(header
, headers
, next
) {
1771 if (evutil_ascii_strcasecmp(header
->key
, key
) == 0)
1772 return (header
->value
);
1779 evhttp_clear_headers(struct evkeyvalq
*headers
)
1781 struct evkeyval
*header
;
1783 for (header
= TAILQ_FIRST(headers
);
1785 header
= TAILQ_FIRST(headers
)) {
1786 TAILQ_REMOVE(headers
, header
, next
);
1787 mm_free(header
->key
);
1788 mm_free(header
->value
);
1794 * Returns 0, if the header was successfully removed.
1795 * Returns -1, if the header could not be found.
1799 evhttp_remove_header(struct evkeyvalq
*headers
, const char *key
)
1801 struct evkeyval
*header
;
1803 TAILQ_FOREACH(header
, headers
, next
) {
1804 if (evutil_ascii_strcasecmp(header
->key
, key
) == 0)
1811 /* Free and remove the header that we found */
1812 TAILQ_REMOVE(headers
, header
, next
);
1813 mm_free(header
->key
);
1814 mm_free(header
->value
);
1821 evhttp_header_is_valid_value(const char *value
)
1823 const char *p
= value
;
1825 while ((p
= strpbrk(p
, "\r\n")) != NULL
) {
1826 /* we really expect only one new line */
1827 p
+= strspn(p
, "\r\n");
1828 /* we expect a space or tab for continuation */
1829 if (*p
!= ' ' && *p
!= '\t')
1836 evhttp_add_header(struct evkeyvalq
*headers
,
1837 const char *key
, const char *value
)
1839 event_debug(("%s: key: %s val: %s\n", __func__
, key
, value
));
1841 if (strchr(key
, '\r') != NULL
|| strchr(key
, '\n') != NULL
) {
1842 /* drop illegal headers */
1843 event_debug(("%s: dropping illegal header key\n", __func__
));
1847 if (!evhttp_header_is_valid_value(value
)) {
1848 event_debug(("%s: dropping illegal header value\n", __func__
));
1852 return (evhttp_add_header_internal(headers
, key
, value
));
1856 evhttp_add_header_internal(struct evkeyvalq
*headers
,
1857 const char *key
, const char *value
)
1859 struct evkeyval
*header
= mm_calloc(1, sizeof(struct evkeyval
));
1860 if (header
== NULL
) {
1861 event_warn("%s: calloc", __func__
);
1864 if ((header
->key
= mm_strdup(key
)) == NULL
) {
1866 event_warn("%s: strdup", __func__
);
1869 if ((header
->value
= mm_strdup(value
)) == NULL
) {
1870 mm_free(header
->key
);
1872 event_warn("%s: strdup", __func__
);
1876 TAILQ_INSERT_TAIL(headers
, header
, next
);
1882 * Parses header lines from a request or a response into the specified
1883 * request object given an event buffer.
1886 * DATA_CORRUPTED on error
1887 * MORE_DATA_EXPECTED when we need to read more headers
1888 * ALL_DATA_READ when all headers have been read.
1891 enum message_read_status
1892 evhttp_parse_firstline_(struct evhttp_request
*req
, struct evbuffer
*buffer
)
1895 enum message_read_status status
= ALL_DATA_READ
;
1899 line
= evbuffer_readln(buffer
, &line_length
, EVBUFFER_EOL_CRLF
);
1901 if (req
->evcon
!= NULL
&&
1902 evbuffer_get_length(buffer
) > req
->evcon
->max_headers_size
)
1903 return (DATA_TOO_LONG
);
1905 return (MORE_DATA_EXPECTED
);
1908 if (req
->evcon
!= NULL
&&
1909 line_length
> req
->evcon
->max_headers_size
) {
1911 return (DATA_TOO_LONG
);
1914 req
->headers_size
= line_length
;
1916 switch (req
->kind
) {
1917 case EVHTTP_REQUEST
:
1918 if (evhttp_parse_request_line(req
, line
) == -1)
1919 status
= DATA_CORRUPTED
;
1921 case EVHTTP_RESPONSE
:
1922 if (evhttp_parse_response_line(req
, line
) == -1)
1923 status
= DATA_CORRUPTED
;
1926 status
= DATA_CORRUPTED
;
1934 evhttp_append_to_last_header(struct evkeyvalq
*headers
, char *line
)
1936 struct evkeyval
*header
= TAILQ_LAST(headers
, evkeyvalq
);
1938 size_t old_len
, line_len
;
1943 old_len
= strlen(header
->value
);
1945 /* Strip space from start and end of line. */
1946 while (*line
== ' ' || *line
== '\t')
1948 evutil_rtrim_lws_(line
);
1950 line_len
= strlen(line
);
1952 newval
= mm_realloc(header
->value
, old_len
+ line_len
+ 2);
1956 newval
[old_len
] = ' ';
1957 memcpy(newval
+ old_len
+ 1, line
, line_len
+ 1);
1958 header
->value
= newval
;
1963 enum message_read_status
1964 evhttp_parse_headers_(struct evhttp_request
*req
, struct evbuffer
* buffer
)
1966 enum message_read_status errcode
= DATA_CORRUPTED
;
1968 enum message_read_status status
= MORE_DATA_EXPECTED
;
1970 struct evkeyvalq
* headers
= req
->input_headers
;
1972 while ((line
= evbuffer_readln(buffer
, &line_length
, EVBUFFER_EOL_CRLF
))
1974 char *skey
, *svalue
;
1976 req
->headers_size
+= line_length
;
1978 if (req
->evcon
!= NULL
&&
1979 req
->headers_size
> req
->evcon
->max_headers_size
) {
1980 errcode
= DATA_TOO_LONG
;
1984 if (*line
== '\0') { /* Last header - Done */
1985 status
= ALL_DATA_READ
;
1990 /* Check if this is a continuation line */
1991 if (*line
== ' ' || *line
== '\t') {
1992 if (evhttp_append_to_last_header(headers
, line
) == -1)
1998 /* Processing of header lines */
2000 skey
= strsep(&svalue
, ":");
2004 svalue
+= strspn(svalue
, " ");
2005 evutil_rtrim_lws_(svalue
);
2007 if (evhttp_add_header(headers
, skey
, svalue
) == -1)
2013 if (status
== MORE_DATA_EXPECTED
) {
2014 if (req
->evcon
!= NULL
&&
2015 req
->headers_size
+ evbuffer_get_length(buffer
) > req
->evcon
->max_headers_size
)
2016 return (DATA_TOO_LONG
);
2027 evhttp_get_body_length(struct evhttp_request
*req
)
2029 struct evkeyvalq
*headers
= req
->input_headers
;
2030 const char *content_length
;
2031 const char *connection
;
2033 content_length
= evhttp_find_header(headers
, "Content-Length");
2034 connection
= evhttp_find_header(headers
, "Connection");
2036 if (content_length
== NULL
&& connection
== NULL
)
2038 else if (content_length
== NULL
&&
2039 evutil_ascii_strcasecmp(connection
, "Close") != 0) {
2040 /* Bad combination, we don't know when it will end */
2041 event_warnx("%s: we got no content length, but the "
2042 "server wants to keep the connection open: %s.",
2043 __func__
, connection
);
2045 } else if (content_length
== NULL
) {
2049 ev_int64_t ntoread
= evutil_strtoll(content_length
, &endp
, 10);
2050 if (*content_length
== '\0' || *endp
!= '\0' || ntoread
< 0) {
2051 event_debug(("%s: illegal content length: %s",
2052 __func__
, content_length
));
2055 req
->ntoread
= ntoread
;
2058 event_debug(("%s: bytes to read: "EV_I64_FMT
" (in buffer "EV_SIZE_FMT
")\n",
2059 __func__
, EV_I64_ARG(req
->ntoread
),
2060 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req
->evcon
->bufev
)))));
2066 evhttp_method_may_have_body(enum evhttp_cmd_type type
)
2069 case EVHTTP_REQ_POST
:
2070 case EVHTTP_REQ_PUT
:
2071 case EVHTTP_REQ_PATCH
:
2073 case EVHTTP_REQ_TRACE
:
2075 /* XXX May any of the below methods have a body? */
2076 case EVHTTP_REQ_GET
:
2077 case EVHTTP_REQ_HEAD
:
2078 case EVHTTP_REQ_DELETE
:
2079 case EVHTTP_REQ_OPTIONS
:
2080 case EVHTTP_REQ_CONNECT
:
2088 evhttp_get_body(struct evhttp_connection
*evcon
, struct evhttp_request
*req
)
2090 const char *xfer_enc
;
2092 /* If this is a request without a body, then we are done */
2093 if (req
->kind
== EVHTTP_REQUEST
&&
2094 !evhttp_method_may_have_body(req
->type
)) {
2095 evhttp_connection_done(evcon
);
2098 evcon
->state
= EVCON_READING_BODY
;
2099 xfer_enc
= evhttp_find_header(req
->input_headers
, "Transfer-Encoding");
2100 if (xfer_enc
!= NULL
&& evutil_ascii_strcasecmp(xfer_enc
, "chunked") == 0) {
2104 if (evhttp_get_body_length(req
) == -1) {
2105 evhttp_connection_fail_(evcon
,
2106 EVREQ_HTTP_INVALID_HEADER
);
2109 if (req
->kind
== EVHTTP_REQUEST
&& req
->ntoread
< 1) {
2110 /* An incoming request with no content-length and no
2111 * transfer-encoding has no body. */
2112 evhttp_connection_done(evcon
);
2117 /* Should we send a 100 Continue status line? */
2118 if (req
->kind
== EVHTTP_REQUEST
&& REQ_VERSION_ATLEAST(req
, 1, 1)) {
2121 expect
= evhttp_find_header(req
->input_headers
, "Expect");
2123 if (!evutil_ascii_strcasecmp(expect
, "100-continue")) {
2124 /* XXX It would be nice to do some sanity
2125 checking here. Does the resource exist?
2126 Should the resource accept post requests? If
2127 no, we should respond with an error. For
2128 now, just optimistically tell the client to
2129 send their message body. */
2130 if (req
->ntoread
> 0) {
2131 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
2132 if ((req
->evcon
->max_body_size
<= EV_INT64_MAX
) && (ev_uint64_t
)req
->ntoread
> req
->evcon
->max_body_size
) {
2133 evhttp_send_error(req
, HTTP_ENTITYTOOLARGE
, NULL
);
2137 if (!evbuffer_get_length(bufferevent_get_input(evcon
->bufev
)))
2138 evhttp_send_continue(evcon
, req
);
2140 evhttp_send_error(req
, HTTP_EXPECTATIONFAILED
,
2147 evhttp_read_body(evcon
, req
);
2148 /* note the request may have been freed in evhttp_read_body */
2152 evhttp_read_firstline(struct evhttp_connection
*evcon
,
2153 struct evhttp_request
*req
)
2155 enum message_read_status res
;
2157 res
= evhttp_parse_firstline_(req
, bufferevent_get_input(evcon
->bufev
));
2158 if (res
== DATA_CORRUPTED
|| res
== DATA_TOO_LONG
) {
2159 /* Error while reading, terminate */
2160 event_debug(("%s: bad header lines on "EV_SOCK_FMT
"\n",
2161 __func__
, EV_SOCK_ARG(evcon
->fd
)));
2162 evhttp_connection_fail_(evcon
, EVREQ_HTTP_INVALID_HEADER
);
2164 } else if (res
== MORE_DATA_EXPECTED
) {
2165 /* Need more header lines */
2169 evcon
->state
= EVCON_READING_HEADERS
;
2170 evhttp_read_header(evcon
, req
);
2174 evhttp_read_header(struct evhttp_connection
*evcon
,
2175 struct evhttp_request
*req
)
2177 enum message_read_status res
;
2178 evutil_socket_t fd
= evcon
->fd
;
2180 res
= evhttp_parse_headers_(req
, bufferevent_get_input(evcon
->bufev
));
2181 if (res
== DATA_CORRUPTED
|| res
== DATA_TOO_LONG
) {
2182 /* Error while reading, terminate */
2183 event_debug(("%s: bad header lines on "EV_SOCK_FMT
"\n",
2184 __func__
, EV_SOCK_ARG(fd
)));
2185 evhttp_connection_fail_(evcon
, EVREQ_HTTP_INVALID_HEADER
);
2187 } else if (res
== MORE_DATA_EXPECTED
) {
2188 /* Need more header lines */
2192 /* Callback can shut down connection with negative return value */
2193 if (req
->header_cb
!= NULL
) {
2194 if ((*req
->header_cb
)(req
, req
->cb_arg
) < 0) {
2195 evhttp_connection_fail_(evcon
, EVREQ_HTTP_EOF
);
2200 /* Done reading headers, do the real work */
2201 switch (req
->kind
) {
2202 case EVHTTP_REQUEST
:
2203 event_debug(("%s: checking for post data on "EV_SOCK_FMT
"\n",
2204 __func__
, EV_SOCK_ARG(fd
)));
2205 evhttp_get_body(evcon
, req
);
2206 /* note the request may have been freed in evhttp_get_body */
2209 case EVHTTP_RESPONSE
:
2210 /* Start over if we got a 100 Continue response. */
2211 if (req
->response_code
== 100) {
2212 evhttp_start_read_(evcon
);
2215 if (!evhttp_response_needs_body(req
)) {
2216 event_debug(("%s: skipping body for code %d\n",
2217 __func__
, req
->response_code
));
2218 evhttp_connection_done(evcon
);
2220 event_debug(("%s: start of read body for %s on "
2222 __func__
, req
->remote_host
, EV_SOCK_ARG(fd
)));
2223 evhttp_get_body(evcon
, req
);
2224 /* note the request may have been freed in
2225 * evhttp_get_body */
2230 event_warnx("%s: bad header on "EV_SOCK_FMT
, __func__
,
2232 evhttp_connection_fail_(evcon
, EVREQ_HTTP_INVALID_HEADER
);
2235 /* request may have been freed above */
2239 * Creates a TCP connection to the specified port and executes a callback
2240 * when finished. Failure or success is indicate by the passed connection
2243 * Although this interface accepts a hostname, it is intended to take
2244 * only numeric hostnames so that non-blocking DNS resolution can
2248 struct evhttp_connection
*
2249 evhttp_connection_new(const char *address
, unsigned short port
)
2251 return (evhttp_connection_base_new(NULL
, NULL
, address
, port
));
2254 struct evhttp_connection
*
2255 evhttp_connection_base_bufferevent_new(struct event_base
*base
, struct evdns_base
*dnsbase
, struct bufferevent
* bev
,
2256 const char *address
, unsigned short port
)
2258 struct evhttp_connection
*evcon
= NULL
;
2260 event_debug(("Attempting connection to %s:%d\n", address
, port
));
2262 if ((evcon
= mm_calloc(1, sizeof(struct evhttp_connection
))) == NULL
) {
2263 event_warn("%s: calloc failed", __func__
);
2270 evcon
->max_headers_size
= EV_SIZE_MAX
;
2271 evcon
->max_body_size
= EV_SIZE_MAX
;
2273 evutil_timerclear(&evcon
->timeout
);
2274 evcon
->retry_cnt
= evcon
->retry_max
= 0;
2276 if ((evcon
->address
= mm_strdup(address
)) == NULL
) {
2277 event_warn("%s: strdup failed", __func__
);
2282 if (!(bev
= bufferevent_socket_new(base
, -1, 0))) {
2283 event_warn("%s: bufferevent_socket_new failed", __func__
);
2288 bufferevent_setcb(bev
, evhttp_read_cb
, evhttp_write_cb
, evhttp_error_cb
, evcon
);
2291 evcon
->state
= EVCON_DISCONNECTED
;
2292 TAILQ_INIT(&evcon
->requests
);
2294 evcon
->initial_retry_timeout
.tv_sec
= 2;
2295 evcon
->initial_retry_timeout
.tv_usec
= 0;
2299 if (bufferevent_get_base(bev
) != base
)
2300 bufferevent_base_set(base
, evcon
->bufev
);
2303 event_deferred_cb_init_(
2304 &evcon
->read_more_deferred_cb
,
2305 bufferevent_get_priority(bev
),
2306 evhttp_deferred_read_cb
, evcon
);
2308 evcon
->dns_base
= dnsbase
;
2309 evcon
->ai_family
= AF_UNSPEC
;
2315 evhttp_connection_free(evcon
);
2319 struct bufferevent
* evhttp_connection_get_bufferevent(struct evhttp_connection
*evcon
)
2321 return evcon
->bufev
;
2325 evhttp_connection_get_server(struct evhttp_connection
*evcon
)
2327 return evcon
->http_server
;
2330 struct evhttp_connection
*
2331 evhttp_connection_base_new(struct event_base
*base
, struct evdns_base
*dnsbase
,
2332 const char *address
, unsigned short port
)
2334 return evhttp_connection_base_bufferevent_new(base
, dnsbase
, NULL
, address
, port
);
2337 void evhttp_connection_set_family(struct evhttp_connection
*evcon
,
2340 evcon
->ai_family
= family
;
2343 int evhttp_connection_set_flags(struct evhttp_connection
*evcon
,
2346 if (flags
& ~(EVHTTP_CON_REUSE_CONNECTED_ADDR
)) {
2350 evcon
->flags
&= ~(EVHTTP_CON_REUSE_CONNECTED_ADDR
);
2352 evcon
->flags
|= EVHTTP_CON_REUSE_CONNECTED_ADDR
;
2358 evhttp_connection_set_base(struct evhttp_connection
*evcon
,
2359 struct event_base
*base
)
2361 EVUTIL_ASSERT(evcon
->base
== NULL
);
2362 EVUTIL_ASSERT(evcon
->state
== EVCON_DISCONNECTED
);
2364 bufferevent_base_set(base
, evcon
->bufev
);
2368 evhttp_connection_set_timeout(struct evhttp_connection
*evcon
,
2369 int timeout_in_secs
)
2371 if (timeout_in_secs
== -1)
2372 evhttp_connection_set_timeout_tv(evcon
, NULL
);
2375 tv
.tv_sec
= timeout_in_secs
;
2377 evhttp_connection_set_timeout_tv(evcon
, &tv
);
2382 evhttp_connection_set_timeout_tv(struct evhttp_connection
*evcon
,
2383 const struct timeval
* tv
)
2386 evcon
->timeout
= *tv
;
2387 bufferevent_set_timeouts(evcon
->bufev
, &evcon
->timeout
, &evcon
->timeout
);
2389 const struct timeval read_tv
= { HTTP_READ_TIMEOUT
, 0 };
2390 const struct timeval write_tv
= { HTTP_WRITE_TIMEOUT
, 0 };
2391 evutil_timerclear(&evcon
->timeout
);
2392 bufferevent_set_timeouts(evcon
->bufev
, &read_tv
, &write_tv
);
2397 evhttp_connection_set_initial_retry_tv(struct evhttp_connection
*evcon
,
2398 const struct timeval
*tv
)
2401 evcon
->initial_retry_timeout
= *tv
;
2403 evutil_timerclear(&evcon
->initial_retry_timeout
);
2404 evcon
->initial_retry_timeout
.tv_sec
= 2;
2409 evhttp_connection_set_retries(struct evhttp_connection
*evcon
,
2412 evcon
->retry_max
= retry_max
;
2416 evhttp_connection_set_closecb(struct evhttp_connection
*evcon
,
2417 void (*cb
)(struct evhttp_connection
*, void *), void *cbarg
)
2419 evcon
->closecb
= cb
;
2420 evcon
->closecb_arg
= cbarg
;
2424 evhttp_connection_get_peer(struct evhttp_connection
*evcon
,
2425 char **address
, ev_uint16_t
*port
)
2427 *address
= evcon
->address
;
2428 *port
= evcon
->port
;
2431 const struct sockaddr
*
2432 evhttp_connection_get_addr(struct evhttp_connection
*evcon
)
2434 return bufferevent_socket_get_conn_address_(evcon
->bufev
);
2438 evhttp_connection_connect_(struct evhttp_connection
*evcon
)
2440 int old_state
= evcon
->state
;
2441 const char *address
= evcon
->address
;
2442 const struct sockaddr
*sa
= evhttp_connection_get_addr(evcon
);
2445 if (evcon
->state
== EVCON_CONNECTING
)
2448 evhttp_connection_reset_(evcon
);
2450 EVUTIL_ASSERT(!(evcon
->flags
& EVHTTP_CON_INCOMING
));
2451 evcon
->flags
|= EVHTTP_CON_OUTGOING
;
2453 if (evcon
->bind_address
|| evcon
->bind_port
) {
2454 evcon
->fd
= bind_socket(
2455 evcon
->bind_address
, evcon
->bind_port
, 0 /*reuse*/);
2456 if (evcon
->fd
== -1) {
2457 event_debug(("%s: failed to bind to \"%s\"",
2458 __func__
, evcon
->bind_address
));
2462 bufferevent_setfd(evcon
->bufev
, evcon
->fd
);
2464 bufferevent_setfd(evcon
->bufev
, -1);
2467 /* Set up a callback for successful connection setup */
2468 bufferevent_setcb(evcon
->bufev
,
2469 NULL
/* evhttp_read_cb */,
2470 NULL
/* evhttp_write_cb */,
2471 evhttp_connection_cb
,
2473 if (!evutil_timerisset(&evcon
->timeout
)) {
2474 const struct timeval conn_tv
= { HTTP_CONNECT_TIMEOUT
, 0 };
2475 bufferevent_set_timeouts(evcon
->bufev
, &conn_tv
, &conn_tv
);
2477 bufferevent_set_timeouts(evcon
->bufev
, &evcon
->timeout
, &evcon
->timeout
);
2479 /* make sure that we get a write callback */
2480 bufferevent_enable(evcon
->bufev
, EV_WRITE
);
2482 evcon
->state
= EVCON_CONNECTING
;
2484 if (evcon
->flags
& EVHTTP_CON_REUSE_CONNECTED_ADDR
&&
2486 (sa
->sa_family
== AF_INET
|| sa
->sa_family
== AF_INET6
)) {
2487 int socklen
= sizeof(struct sockaddr_in
);
2488 if (sa
->sa_family
== AF_INET6
) {
2489 socklen
= sizeof(struct sockaddr_in6
);
2491 ret
= bufferevent_socket_connect(evcon
->bufev
, sa
, socklen
);
2493 ret
= bufferevent_socket_connect_hostname(evcon
->bufev
,
2494 evcon
->dns_base
, evcon
->ai_family
, address
, evcon
->port
);
2498 evcon
->state
= old_state
;
2499 event_sock_warn(evcon
->fd
, "%s: connection to \"%s\" failed",
2500 __func__
, evcon
->address
);
2501 /* some operating systems return ECONNREFUSED immediately
2502 * when connecting to a local address. the cleanup is going
2503 * to reschedule this function call.
2505 evhttp_connection_cb_cleanup(evcon
);
2513 * Starts an HTTP request on the provided evhttp_connection object.
2514 * If the connection object is not connected to the web server already,
2515 * this will start the connection.
2519 evhttp_make_request(struct evhttp_connection
*evcon
,
2520 struct evhttp_request
*req
,
2521 enum evhttp_cmd_type type
, const char *uri
)
2523 /* We are making a request */
2524 req
->kind
= EVHTTP_REQUEST
;
2526 if (req
->uri
!= NULL
)
2528 if ((req
->uri
= mm_strdup(uri
)) == NULL
) {
2529 event_warn("%s: strdup", __func__
);
2530 evhttp_request_free_auto(req
);
2534 /* Set the protocol version if it is not supplied */
2535 if (!req
->major
&& !req
->minor
) {
2540 EVUTIL_ASSERT(req
->evcon
== NULL
);
2542 EVUTIL_ASSERT(!(req
->flags
& EVHTTP_REQ_OWN_CONNECTION
));
2544 TAILQ_INSERT_TAIL(&evcon
->requests
, req
, next
);
2546 /* If the connection object is not connected; make it so */
2547 if (!evhttp_connected(evcon
)) {
2548 int res
= evhttp_connection_connect_(evcon
);
2549 /* evhttp_connection_fail_(), which is called through
2550 * evhttp_connection_connect_(), assumes that req lies in
2551 * evcon->requests. Thus, enqueue the request in advance and
2552 * remove it in the error case. */
2554 TAILQ_REMOVE(&evcon
->requests
, req
, next
);
2560 * If it's connected already and we are the first in the queue,
2561 * then we can dispatch this request immediately. Otherwise, it
2562 * will be dispatched once the pending requests are completed.
2564 if (TAILQ_FIRST(&evcon
->requests
) == req
)
2565 evhttp_request_dispatch(evcon
);
2571 evhttp_cancel_request(struct evhttp_request
*req
)
2573 struct evhttp_connection
*evcon
= req
->evcon
;
2574 if (evcon
!= NULL
) {
2575 /* We need to remove it from the connection */
2576 if (TAILQ_FIRST(&evcon
->requests
) == req
) {
2577 /* it's currently being worked on, so reset
2580 evhttp_connection_fail_(evcon
,
2581 EVREQ_HTTP_REQUEST_CANCEL
);
2583 /* connection fail freed the request */
2586 /* otherwise, we can just remove it from the
2589 TAILQ_REMOVE(&evcon
->requests
, req
, next
);
2593 evhttp_request_free_auto(req
);
2597 * Reads data from file descriptor into request structure
2598 * Request structure needs to be set up correctly.
2602 evhttp_start_read_(struct evhttp_connection
*evcon
)
2604 bufferevent_disable(evcon
->bufev
, EV_WRITE
);
2605 bufferevent_enable(evcon
->bufev
, EV_READ
);
2607 evcon
->state
= EVCON_READING_FIRSTLINE
;
2608 /* Reset the bufferevent callbacks */
2609 bufferevent_setcb(evcon
->bufev
,
2615 /* If there's still data pending, process it next time through the
2616 * loop. Don't do it now; that could get recusive. */
2617 if (evbuffer_get_length(bufferevent_get_input(evcon
->bufev
))) {
2618 event_deferred_cb_schedule_(get_deferred_queue(evcon
),
2619 &evcon
->read_more_deferred_cb
);
2624 evhttp_send_done(struct evhttp_connection
*evcon
, void *arg
)
2627 struct evhttp_request
*req
= TAILQ_FIRST(&evcon
->requests
);
2628 TAILQ_REMOVE(&evcon
->requests
, req
, next
);
2630 if (req
->on_complete_cb
!= NULL
) {
2631 req
->on_complete_cb(req
, req
->on_complete_cb_arg
);
2635 (REQ_VERSION_BEFORE(req
, 1, 1) &&
2636 !evhttp_is_connection_keepalive(req
->input_headers
)) ||
2637 evhttp_is_request_connection_close(req
);
2639 EVUTIL_ASSERT(req
->flags
& EVHTTP_REQ_OWN_CONNECTION
);
2640 evhttp_request_free(req
);
2643 evhttp_connection_free(evcon
);
2647 /* we have a persistent connection; try to accept another request. */
2648 if (evhttp_associate_new_request_with_connection(evcon
) == -1) {
2649 evhttp_connection_free(evcon
);
2654 * Returns an error page.
2658 evhttp_send_error(struct evhttp_request
*req
, int error
, const char *reason
)
2661 #define ERR_FORMAT "<HTML><HEAD>\n" \
2662 "<TITLE>%d %s</TITLE>\n" \
2667 struct evbuffer
*buf
= evbuffer_new();
2669 /* if we cannot allocate memory; we just drop the connection */
2670 evhttp_connection_free(req
->evcon
);
2673 if (reason
== NULL
) {
2674 reason
= evhttp_response_phrase_internal(error
);
2677 evhttp_response_code_(req
, error
, reason
);
2679 evbuffer_add_printf(buf
, ERR_FORMAT
, error
, reason
, reason
);
2681 evhttp_send_page_(req
, buf
);
2687 /* Requires that headers and response code are already set up */
2690 evhttp_send(struct evhttp_request
*req
, struct evbuffer
*databuf
)
2692 struct evhttp_connection
*evcon
= req
->evcon
;
2694 if (evcon
== NULL
) {
2695 evhttp_request_free(req
);
2699 EVUTIL_ASSERT(TAILQ_FIRST(&evcon
->requests
) == req
);
2701 /* we expect no more calls form the user on this request */
2704 /* xxx: not sure if we really should expose the data buffer this way */
2705 if (databuf
!= NULL
)
2706 evbuffer_add_buffer(req
->output_buffer
, databuf
);
2708 /* Adds headers to the response */
2709 evhttp_make_header(evcon
, req
);
2711 evhttp_write_buffer(evcon
, evhttp_send_done
, NULL
);
2715 evhttp_send_reply(struct evhttp_request
*req
, int code
, const char *reason
,
2716 struct evbuffer
*databuf
)
2718 evhttp_response_code_(req
, code
, reason
);
2720 evhttp_send(req
, databuf
);
2724 evhttp_send_reply_start(struct evhttp_request
*req
, int code
,
2727 evhttp_response_code_(req
, code
, reason
);
2728 if (evhttp_find_header(req
->output_headers
, "Content-Length") == NULL
&&
2729 REQ_VERSION_ATLEAST(req
, 1, 1) &&
2730 evhttp_response_needs_body(req
)) {
2732 * prefer HTTP/1.1 chunked encoding to closing the connection;
2733 * note RFC 2616 section 4.4 forbids it with Content-Length:
2734 * and it's not necessary then anyway.
2736 evhttp_add_header(req
->output_headers
, "Transfer-Encoding",
2742 evhttp_make_header(req
->evcon
, req
);
2743 evhttp_write_buffer(req
->evcon
, NULL
, NULL
);
2747 evhttp_send_reply_chunk_with_cb(struct evhttp_request
*req
, struct evbuffer
*databuf
,
2748 void (*cb
)(struct evhttp_connection
*, void *), void *arg
)
2750 struct evhttp_connection
*evcon
= req
->evcon
;
2751 struct evbuffer
*output
;
2756 output
= bufferevent_get_output(evcon
->bufev
);
2758 if (evbuffer_get_length(databuf
) == 0)
2760 if (!evhttp_response_needs_body(req
))
2763 evbuffer_add_printf(output
, "%x\r\n",
2764 (unsigned)evbuffer_get_length(databuf
));
2766 evbuffer_add_buffer(output
, databuf
);
2768 evbuffer_add(output
, "\r\n", 2);
2770 evhttp_write_buffer(evcon
, cb
, arg
);
2774 evhttp_send_reply_chunk(struct evhttp_request
*req
, struct evbuffer
*databuf
)
2776 evhttp_send_reply_chunk_with_cb(req
, databuf
, NULL
, NULL
);
2779 evhttp_send_reply_end(struct evhttp_request
*req
)
2781 struct evhttp_connection
*evcon
= req
->evcon
;
2782 struct evbuffer
*output
;
2784 if (evcon
== NULL
) {
2785 evhttp_request_free(req
);
2789 output
= bufferevent_get_output(evcon
->bufev
);
2791 /* we expect no more calls form the user on this request */
2795 evbuffer_add(output
, "0\r\n\r\n", 5);
2796 evhttp_write_buffer(req
->evcon
, evhttp_send_done
, NULL
);
2798 } else if (evbuffer_get_length(output
) == 0) {
2799 /* let the connection know that we are done with the request */
2800 evhttp_send_done(evcon
, NULL
);
2802 /* make the callback execute after all data has been written */
2803 evcon
->cb
= evhttp_send_done
;
2804 evcon
->cb_arg
= NULL
;
2808 static const char *informational_phrases
[] = {
2809 /* 100 */ "Continue",
2810 /* 101 */ "Switching Protocols"
2813 static const char *success_phrases
[] = {
2815 /* 201 */ "Created",
2816 /* 202 */ "Accepted",
2817 /* 203 */ "Non-Authoritative Information",
2818 /* 204 */ "No Content",
2819 /* 205 */ "Reset Content",
2820 /* 206 */ "Partial Content"
2823 static const char *redirection_phrases
[] = {
2824 /* 300 */ "Multiple Choices",
2825 /* 301 */ "Moved Permanently",
2827 /* 303 */ "See Other",
2828 /* 304 */ "Not Modified",
2829 /* 305 */ "Use Proxy",
2830 /* 307 */ "Temporary Redirect"
2833 static const char *client_error_phrases
[] = {
2834 /* 400 */ "Bad Request",
2835 /* 401 */ "Unauthorized",
2836 /* 402 */ "Payment Required",
2837 /* 403 */ "Forbidden",
2838 /* 404 */ "Not Found",
2839 /* 405 */ "Method Not Allowed",
2840 /* 406 */ "Not Acceptable",
2841 /* 407 */ "Proxy Authentication Required",
2842 /* 408 */ "Request Time-out",
2843 /* 409 */ "Conflict",
2845 /* 411 */ "Length Required",
2846 /* 412 */ "Precondition Failed",
2847 /* 413 */ "Request Entity Too Large",
2848 /* 414 */ "Request-URI Too Large",
2849 /* 415 */ "Unsupported Media Type",
2850 /* 416 */ "Requested range not satisfiable",
2851 /* 417 */ "Expectation Failed"
2854 static const char *server_error_phrases
[] = {
2855 /* 500 */ "Internal Server Error",
2856 /* 501 */ "Not Implemented",
2857 /* 502 */ "Bad Gateway",
2858 /* 503 */ "Service Unavailable",
2859 /* 504 */ "Gateway Time-out",
2860 /* 505 */ "HTTP Version not supported"
2863 struct response_class
{
2865 size_t num_responses
;
2866 const char **responses
;
2870 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
2873 static const struct response_class response_classes
[] = {
2874 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases
), informational_phrases
},
2875 /* 2xx */ { "Success", MEMBERSOF(success_phrases
), success_phrases
},
2876 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases
), redirection_phrases
},
2877 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases
), client_error_phrases
},
2878 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases
), server_error_phrases
}
2882 evhttp_response_phrase_internal(int code
)
2884 int klass
= code
/ 100 - 1;
2885 int subcode
= code
% 100;
2887 /* Unknown class - can't do any better here */
2888 if (klass
< 0 || klass
>= (int) MEMBERSOF(response_classes
))
2889 return "Unknown Status Class";
2891 /* Unknown sub-code, return class name at least */
2892 if (subcode
>= (int) response_classes
[klass
].num_responses
)
2893 return response_classes
[klass
].name
;
2895 return response_classes
[klass
].responses
[subcode
];
2899 evhttp_response_code_(struct evhttp_request
*req
, int code
, const char *reason
)
2901 req
->kind
= EVHTTP_RESPONSE
;
2902 req
->response_code
= code
;
2903 if (req
->response_code_line
!= NULL
)
2904 mm_free(req
->response_code_line
);
2906 reason
= evhttp_response_phrase_internal(code
);
2907 req
->response_code_line
= mm_strdup(reason
);
2908 if (req
->response_code_line
== NULL
) {
2909 event_warn("%s: strdup", __func__
);
2910 /* XXX what else can we do? */
2915 evhttp_send_page_(struct evhttp_request
*req
, struct evbuffer
*databuf
)
2917 if (!req
->major
|| !req
->minor
) {
2922 if (req
->kind
!= EVHTTP_RESPONSE
)
2923 evhttp_response_code_(req
, 200, "OK");
2925 evhttp_clear_headers(req
->output_headers
);
2926 evhttp_add_header(req
->output_headers
, "Content-Type", "text/html");
2927 evhttp_add_header(req
->output_headers
, "Connection", "close");
2929 evhttp_send(req
, databuf
);
2932 static const char uri_chars
[256] = {
2934 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2935 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2936 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
2937 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
2939 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2940 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
2941 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2942 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
2944 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2945 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2946 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2947 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2949 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2950 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2951 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2952 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2955 #define CHAR_IS_UNRESERVED(c) \
2956 (uri_chars[(unsigned char)(c)])
2959 * Helper functions to encode/decode a string for inclusion in a URI.
2960 * The returned string must be freed by the caller.
2963 evhttp_uriencode(const char *uri
, ev_ssize_t len
, int space_as_plus
)
2965 struct evbuffer
*buf
= evbuffer_new();
2966 const char *p
, *end
;
2975 end
= uri
+strlen(uri
);
2977 for (p
= uri
; p
< end
; p
++) {
2978 if (CHAR_IS_UNRESERVED(*p
)) {
2979 evbuffer_add(buf
, p
, 1);
2980 } else if (*p
== ' ' && space_as_plus
) {
2981 evbuffer_add(buf
, "+", 1);
2983 evbuffer_add_printf(buf
, "%%%02X", (unsigned char)(*p
));
2986 evbuffer_add(buf
, "", 1); /* NUL-terminator. */
2987 result
= mm_malloc(evbuffer_get_length(buf
));
2989 evbuffer_remove(buf
, result
, evbuffer_get_length(buf
));
2996 evhttp_encode_uri(const char *str
)
2998 return evhttp_uriencode(str
, -1, 0);
3002 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
3003 * If -1, when true we transform plus to space only after we've seen
3004 * a ?. -1 is deprecated.
3005 * @return the number of bytes written to 'ret'.
3008 evhttp_decode_uri_internal(
3009 const char *uri
, size_t length
, char *ret
, int decode_plus_ctl
)
3013 int decode_plus
= (decode_plus_ctl
== 1) ? 1: 0;
3016 for (i
= j
= 0; i
< length
; i
++) {
3019 if (decode_plus_ctl
< 0)
3021 } else if (c
== '+' && decode_plus
) {
3023 } else if ((i
+ 2) < length
&& c
== '%' &&
3024 EVUTIL_ISXDIGIT_(uri
[i
+1]) && EVUTIL_ISXDIGIT_(uri
[i
+2])) {
3029 c
= (char)strtol(tmp
, NULL
, 16);
3041 evhttp_decode_uri(const char *uri
)
3045 if ((ret
= mm_malloc(strlen(uri
) + 1)) == NULL
) {
3046 event_warn("%s: malloc(%lu)", __func__
,
3047 (unsigned long)(strlen(uri
) + 1));
3051 evhttp_decode_uri_internal(uri
, strlen(uri
),
3052 ret
, -1 /*always_decode_plus*/);
3058 evhttp_uridecode(const char *uri
, int decode_plus
, size_t *size_out
)
3063 if ((ret
= mm_malloc(strlen(uri
) + 1)) == NULL
) {
3064 event_warn("%s: malloc(%lu)", __func__
,
3065 (unsigned long)(strlen(uri
) + 1));
3069 n
= evhttp_decode_uri_internal(uri
, strlen(uri
),
3070 ret
, !!decode_plus
/*always_decode_plus*/);
3073 EVUTIL_ASSERT(n
>= 0);
3074 *size_out
= (size_t)n
;
3081 * Helper function to parse out arguments in a query.
3082 * The arguments are separated by key and value.
3086 evhttp_parse_query_impl(const char *str
, struct evkeyvalq
*headers
,
3092 const char *query_part
;
3094 struct evhttp_uri
*uri
=NULL
;
3096 TAILQ_INIT(headers
);
3099 uri
= evhttp_uri_parse(str
);
3102 query_part
= evhttp_uri_get_query(uri
);
3107 /* No arguments - we are done */
3108 if (!query_part
|| !strlen(query_part
)) {
3113 if ((line
= mm_strdup(query_part
)) == NULL
) {
3114 event_warn("%s: strdup", __func__
);
3118 p
= argument
= line
;
3119 while (p
!= NULL
&& *p
!= '\0') {
3120 char *key
, *value
, *decoded_value
;
3121 argument
= strsep(&p
, "&");
3124 key
= strsep(&value
, "=");
3125 if (value
== NULL
|| *key
== '\0') {
3129 if ((decoded_value
= mm_malloc(strlen(value
) + 1)) == NULL
) {
3130 event_warn("%s: mm_malloc", __func__
);
3133 evhttp_decode_uri_internal(value
, strlen(value
),
3134 decoded_value
, 1 /*always_decode_plus*/);
3135 event_debug(("Query Param: %s -> %s\n", key
, decoded_value
));
3136 evhttp_add_header_internal(headers
, key
, decoded_value
);
3137 mm_free(decoded_value
);
3143 evhttp_clear_headers(headers
);
3148 evhttp_uri_free(uri
);
3153 evhttp_parse_query(const char *uri
, struct evkeyvalq
*headers
)
3155 return evhttp_parse_query_impl(uri
, headers
, 1);
3158 evhttp_parse_query_str(const char *uri
, struct evkeyvalq
*headers
)
3160 return evhttp_parse_query_impl(uri
, headers
, 0);
3163 static struct evhttp_cb
*
3164 evhttp_dispatch_callback(struct httpcbq
*callbacks
, struct evhttp_request
*req
)
3166 struct evhttp_cb
*cb
;
3171 /* Test for different URLs */
3172 path
= evhttp_uri_get_path(req
->uri_elems
);
3173 offset
= strlen(path
);
3174 if ((translated
= mm_malloc(offset
+ 1)) == NULL
)
3176 evhttp_decode_uri_internal(path
, offset
, translated
,
3177 0 /* decode_plus */);
3179 TAILQ_FOREACH(cb
, callbacks
, next
) {
3180 if (!strcmp(cb
->what
, translated
)) {
3181 mm_free(translated
);
3186 mm_free(translated
);
3192 prefix_suffix_match(const char *pattern
, const char *name
, int ignorecase
)
3197 switch (c
= *pattern
++) {
3199 return *name
== '\0';
3202 while (*name
!= '\0') {
3203 if (prefix_suffix_match(pattern
, name
,
3212 EVUTIL_TOLOWER_(c
) != EVUTIL_TOLOWER_(*name
))
3222 Search the vhost hierarchy beginning with http for a server alias
3223 matching hostname. If a match is found, and outhttp is non-null,
3224 outhttp is set to the matching http object and 1 is returned.
3228 evhttp_find_alias(struct evhttp
*http
, struct evhttp
**outhttp
,
3229 const char *hostname
)
3231 struct evhttp_server_alias
*alias
;
3232 struct evhttp
*vhost
;
3234 TAILQ_FOREACH(alias
, &http
->aliases
, next
) {
3235 /* XXX Do we need to handle IP addresses? */
3236 if (!evutil_ascii_strcasecmp(alias
->alias
, hostname
)) {
3243 /* XXX It might be good to avoid recursion here, but I don't
3244 see a way to do that w/o a list. */
3245 TAILQ_FOREACH(vhost
, &http
->virtualhosts
, next_vhost
) {
3246 if (evhttp_find_alias(vhost
, outhttp
, hostname
))
3254 Attempts to find the best http object to handle a request for a hostname.
3255 All aliases for the root http object and vhosts are searched for an exact
3256 match. Then, the vhost hierarchy is traversed again for a matching
3259 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
3260 is set with the best matching http object. If there are no matches, the
3261 root http object is stored in outhttp and 0 is returned.
3265 evhttp_find_vhost(struct evhttp
*http
, struct evhttp
**outhttp
,
3266 const char *hostname
)
3268 struct evhttp
*vhost
;
3269 struct evhttp
*oldhttp
;
3270 int match_found
= 0;
3272 if (evhttp_find_alias(http
, outhttp
, hostname
))
3277 TAILQ_FOREACH(vhost
, &http
->virtualhosts
, next_vhost
) {
3278 if (prefix_suffix_match(vhost
->vhost_pattern
,
3279 hostname
, 1 /* ignorecase */)) {
3285 } while (oldhttp
!= http
);
3294 evhttp_handle_request(struct evhttp_request
*req
, void *arg
)
3296 struct evhttp
*http
= arg
;
3297 struct evhttp_cb
*cb
= NULL
;
3298 const char *hostname
;
3300 /* we have a new request on which the user needs to take action */
3303 if (req
->type
== 0 || req
->uri
== NULL
) {
3304 evhttp_send_error(req
, HTTP_BADREQUEST
, NULL
);
3308 if ((http
->allowed_methods
& req
->type
) == 0) {
3309 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3310 (unsigned)req
->type
, (unsigned)http
->allowed_methods
));
3311 evhttp_send_error(req
, HTTP_NOTIMPLEMENTED
, NULL
);
3315 /* handle potential virtual hosts */
3316 hostname
= evhttp_request_get_host(req
);
3317 if (hostname
!= NULL
) {
3318 evhttp_find_vhost(http
, &http
, hostname
);
3321 if ((cb
= evhttp_dispatch_callback(&http
->callbacks
, req
)) != NULL
) {
3322 (*cb
->cb
)(req
, cb
->cbarg
);
3326 /* Generic call back */
3328 (*http
->gencb
)(req
, http
->gencbarg
);
3331 /* We need to send a 404 here */
3332 #define ERR_FORMAT "<html><head>" \
3333 "<title>404 Not Found</title>" \
3335 "<h1>Not Found</h1>" \
3336 "<p>The requested URL %s was not found on this server.</p>"\
3340 struct evbuffer
*buf
;
3342 if ((escaped_html
= evhttp_htmlescape(req
->uri
)) == NULL
) {
3343 evhttp_connection_free(req
->evcon
);
3347 if ((buf
= evbuffer_new()) == NULL
) {
3348 mm_free(escaped_html
);
3349 evhttp_connection_free(req
->evcon
);
3353 evhttp_response_code_(req
, HTTP_NOTFOUND
, "Not Found");
3355 evbuffer_add_printf(buf
, ERR_FORMAT
, escaped_html
);
3357 mm_free(escaped_html
);
3359 evhttp_send_page_(req
, buf
);
3366 /* Listener callback when a connection arrives at a server. */
3368 accept_socket_cb(struct evconnlistener
*listener
, evutil_socket_t nfd
, struct sockaddr
*peer_sa
, int peer_socklen
, void *arg
)
3370 struct evhttp
*http
= arg
;
3372 evhttp_get_request(http
, nfd
, peer_sa
, peer_socklen
);
3376 evhttp_bind_socket(struct evhttp
*http
, const char *address
, ev_uint16_t port
)
3378 struct evhttp_bound_socket
*bound
=
3379 evhttp_bind_socket_with_handle(http
, address
, port
);
3385 struct evhttp_bound_socket
*
3386 evhttp_bind_socket_with_handle(struct evhttp
*http
, const char *address
, ev_uint16_t port
)
3389 struct evhttp_bound_socket
*bound
;
3391 if ((fd
= bind_socket(address
, port
, 1 /*reuse*/)) == -1)
3394 if (listen(fd
, 128) == -1) {
3395 event_sock_warn(fd
, "%s: listen", __func__
);
3396 evutil_closesocket(fd
);
3400 bound
= evhttp_accept_socket_with_handle(http
, fd
);
3402 if (bound
!= NULL
) {
3403 event_debug(("Bound to port %d - Awaiting connections ... ",
3412 evhttp_accept_socket(struct evhttp
*http
, evutil_socket_t fd
)
3414 struct evhttp_bound_socket
*bound
=
3415 evhttp_accept_socket_with_handle(http
, fd
);
3422 evhttp_foreach_bound_socket(struct evhttp
*http
,
3423 evhttp_bound_socket_foreach_fn
*function
,
3426 struct evhttp_bound_socket
*bound
;
3428 TAILQ_FOREACH(bound
, &http
->sockets
, next
)
3429 function(bound
, argument
);
3432 struct evhttp_bound_socket
*
3433 evhttp_accept_socket_with_handle(struct evhttp
*http
, evutil_socket_t fd
)
3435 struct evhttp_bound_socket
*bound
;
3436 struct evconnlistener
*listener
;
3438 LEV_OPT_REUSEABLE
|LEV_OPT_CLOSE_ON_EXEC
|LEV_OPT_CLOSE_ON_FREE
;
3440 listener
= evconnlistener_new(http
->base
, NULL
, NULL
,
3442 0, /* Backlog is '0' because we already said 'listen' */
3447 bound
= evhttp_bind_listener(http
, listener
);
3449 evconnlistener_free(listener
);
3455 struct evhttp_bound_socket
*
3456 evhttp_bind_listener(struct evhttp
*http
, struct evconnlistener
*listener
)
3458 struct evhttp_bound_socket
*bound
;
3460 bound
= mm_malloc(sizeof(struct evhttp_bound_socket
));
3464 bound
->listener
= listener
;
3465 TAILQ_INSERT_TAIL(&http
->sockets
, bound
, next
);
3467 evconnlistener_set_cb(listener
, accept_socket_cb
, http
);
3472 evhttp_bound_socket_get_fd(struct evhttp_bound_socket
*bound
)
3474 return evconnlistener_get_fd(bound
->listener
);
3477 struct evconnlistener
*
3478 evhttp_bound_socket_get_listener(struct evhttp_bound_socket
*bound
)
3480 return bound
->listener
;
3484 evhttp_del_accept_socket(struct evhttp
*http
, struct evhttp_bound_socket
*bound
)
3486 TAILQ_REMOVE(&http
->sockets
, bound
, next
);
3487 evconnlistener_free(bound
->listener
);
3491 static struct evhttp
*
3492 evhttp_new_object(void)
3494 struct evhttp
*http
= NULL
;
3496 if ((http
= mm_calloc(1, sizeof(struct evhttp
))) == NULL
) {
3497 event_warn("%s: calloc", __func__
);
3501 evutil_timerclear(&http
->timeout
);
3502 evhttp_set_max_headers_size(http
, EV_SIZE_MAX
);
3503 evhttp_set_max_body_size(http
, EV_SIZE_MAX
);
3504 evhttp_set_default_content_type(http
, "text/html; charset=ISO-8859-1");
3505 evhttp_set_allowed_methods(http
,
3512 TAILQ_INIT(&http
->sockets
);
3513 TAILQ_INIT(&http
->callbacks
);
3514 TAILQ_INIT(&http
->connections
);
3515 TAILQ_INIT(&http
->virtualhosts
);
3516 TAILQ_INIT(&http
->aliases
);
3522 evhttp_new(struct event_base
*base
)
3524 struct evhttp
*http
= NULL
;
3526 http
= evhttp_new_object();
3535 * Start a web server on the specified address and port.
3539 evhttp_start(const char *address
, unsigned short port
)
3541 struct evhttp
*http
= NULL
;
3543 http
= evhttp_new_object();
3546 if (evhttp_bind_socket(http
, address
, port
) == -1) {
3555 evhttp_free(struct evhttp
* http
)
3557 struct evhttp_cb
*http_cb
;
3558 struct evhttp_connection
*evcon
;
3559 struct evhttp_bound_socket
*bound
;
3560 struct evhttp
* vhost
;
3561 struct evhttp_server_alias
*alias
;
3563 /* Remove the accepting part */
3564 while ((bound
= TAILQ_FIRST(&http
->sockets
)) != NULL
) {
3565 TAILQ_REMOVE(&http
->sockets
, bound
, next
);
3567 evconnlistener_free(bound
->listener
);
3572 while ((evcon
= TAILQ_FIRST(&http
->connections
)) != NULL
) {
3573 /* evhttp_connection_free removes the connection */
3574 evhttp_connection_free(evcon
);
3577 while ((http_cb
= TAILQ_FIRST(&http
->callbacks
)) != NULL
) {
3578 TAILQ_REMOVE(&http
->callbacks
, http_cb
, next
);
3579 mm_free(http_cb
->what
);
3583 while ((vhost
= TAILQ_FIRST(&http
->virtualhosts
)) != NULL
) {
3584 TAILQ_REMOVE(&http
->virtualhosts
, vhost
, next_vhost
);
3589 if (http
->vhost_pattern
!= NULL
)
3590 mm_free(http
->vhost_pattern
);
3592 while ((alias
= TAILQ_FIRST(&http
->aliases
)) != NULL
) {
3593 TAILQ_REMOVE(&http
->aliases
, alias
, next
);
3594 mm_free(alias
->alias
);
3602 evhttp_add_virtual_host(struct evhttp
* http
, const char *pattern
,
3603 struct evhttp
* vhost
)
3605 /* a vhost can only be a vhost once and should not have bound sockets */
3606 if (vhost
->vhost_pattern
!= NULL
||
3607 TAILQ_FIRST(&vhost
->sockets
) != NULL
)
3610 vhost
->vhost_pattern
= mm_strdup(pattern
);
3611 if (vhost
->vhost_pattern
== NULL
)
3614 TAILQ_INSERT_TAIL(&http
->virtualhosts
, vhost
, next_vhost
);
3620 evhttp_remove_virtual_host(struct evhttp
* http
, struct evhttp
* vhost
)
3622 if (vhost
->vhost_pattern
== NULL
)
3625 TAILQ_REMOVE(&http
->virtualhosts
, vhost
, next_vhost
);
3627 mm_free(vhost
->vhost_pattern
);
3628 vhost
->vhost_pattern
= NULL
;
3634 evhttp_add_server_alias(struct evhttp
*http
, const char *alias
)
3636 struct evhttp_server_alias
*evalias
;
3638 evalias
= mm_calloc(1, sizeof(*evalias
));
3642 evalias
->alias
= mm_strdup(alias
);
3643 if (!evalias
->alias
) {
3648 TAILQ_INSERT_TAIL(&http
->aliases
, evalias
, next
);
3654 evhttp_remove_server_alias(struct evhttp
*http
, const char *alias
)
3656 struct evhttp_server_alias
*evalias
;
3658 TAILQ_FOREACH(evalias
, &http
->aliases
, next
) {
3659 if (evutil_ascii_strcasecmp(evalias
->alias
, alias
) == 0) {
3660 TAILQ_REMOVE(&http
->aliases
, evalias
, next
);
3661 mm_free(evalias
->alias
);
3671 evhttp_set_timeout(struct evhttp
* http
, int timeout_in_secs
)
3673 if (timeout_in_secs
== -1) {
3674 evhttp_set_timeout_tv(http
, NULL
);
3677 tv
.tv_sec
= timeout_in_secs
;
3679 evhttp_set_timeout_tv(http
, &tv
);
3684 evhttp_set_timeout_tv(struct evhttp
* http
, const struct timeval
* tv
)
3687 http
->timeout
= *tv
;
3689 evutil_timerclear(&http
->timeout
);
3694 evhttp_set_max_headers_size(struct evhttp
* http
, ev_ssize_t max_headers_size
)
3696 if (max_headers_size
< 0)
3697 http
->default_max_headers_size
= EV_SIZE_MAX
;
3699 http
->default_max_headers_size
= max_headers_size
;
3703 evhttp_set_max_body_size(struct evhttp
* http
, ev_ssize_t max_body_size
)
3705 if (max_body_size
< 0)
3706 http
->default_max_body_size
= EV_UINT64_MAX
;
3708 http
->default_max_body_size
= max_body_size
;
3712 evhttp_set_default_content_type(struct evhttp
*http
,
3713 const char *content_type
) {
3714 http
->default_content_type
= content_type
;
3718 evhttp_set_allowed_methods(struct evhttp
* http
, ev_uint16_t methods
)
3720 http
->allowed_methods
= methods
;
3724 evhttp_set_cb(struct evhttp
*http
, const char *uri
,
3725 void (*cb
)(struct evhttp_request
*, void *), void *cbarg
)
3727 struct evhttp_cb
*http_cb
;
3729 TAILQ_FOREACH(http_cb
, &http
->callbacks
, next
) {
3730 if (strcmp(http_cb
->what
, uri
) == 0)
3734 if ((http_cb
= mm_calloc(1, sizeof(struct evhttp_cb
))) == NULL
) {
3735 event_warn("%s: calloc", __func__
);
3739 http_cb
->what
= mm_strdup(uri
);
3740 if (http_cb
->what
== NULL
) {
3741 event_warn("%s: strdup", __func__
);
3746 http_cb
->cbarg
= cbarg
;
3748 TAILQ_INSERT_TAIL(&http
->callbacks
, http_cb
, next
);
3754 evhttp_del_cb(struct evhttp
*http
, const char *uri
)
3756 struct evhttp_cb
*http_cb
;
3758 TAILQ_FOREACH(http_cb
, &http
->callbacks
, next
) {
3759 if (strcmp(http_cb
->what
, uri
) == 0)
3762 if (http_cb
== NULL
)
3765 TAILQ_REMOVE(&http
->callbacks
, http_cb
, next
);
3766 mm_free(http_cb
->what
);
3773 evhttp_set_gencb(struct evhttp
*http
,
3774 void (*cb
)(struct evhttp_request
*, void *), void *cbarg
)
3777 http
->gencbarg
= cbarg
;
3781 evhttp_set_bevcb(struct evhttp
*http
,
3782 struct bufferevent
* (*cb
)(struct event_base
*, void *), void *cbarg
)
3785 http
->bevcbarg
= cbarg
;
3789 * Request related functions
3792 struct evhttp_request
*
3793 evhttp_request_new(void (*cb
)(struct evhttp_request
*, void *), void *arg
)
3795 struct evhttp_request
*req
= NULL
;
3797 /* Allocate request structure */
3798 if ((req
= mm_calloc(1, sizeof(struct evhttp_request
))) == NULL
) {
3799 event_warn("%s: calloc", __func__
);
3803 req
->headers_size
= 0;
3806 req
->kind
= EVHTTP_RESPONSE
;
3807 req
->input_headers
= mm_calloc(1, sizeof(struct evkeyvalq
));
3808 if (req
->input_headers
== NULL
) {
3809 event_warn("%s: calloc", __func__
);
3812 TAILQ_INIT(req
->input_headers
);
3814 req
->output_headers
= mm_calloc(1, sizeof(struct evkeyvalq
));
3815 if (req
->output_headers
== NULL
) {
3816 event_warn("%s: calloc", __func__
);
3819 TAILQ_INIT(req
->output_headers
);
3821 if ((req
->input_buffer
= evbuffer_new()) == NULL
) {
3822 event_warn("%s: evbuffer_new", __func__
);
3826 if ((req
->output_buffer
= evbuffer_new()) == NULL
) {
3827 event_warn("%s: evbuffer_new", __func__
);
3838 evhttp_request_free(req
);
3843 evhttp_request_free(struct evhttp_request
*req
)
3845 if ((req
->flags
& EVHTTP_REQ_DEFER_FREE
) != 0) {
3846 req
->flags
|= EVHTTP_REQ_NEEDS_FREE
;
3850 if (req
->remote_host
!= NULL
)
3851 mm_free(req
->remote_host
);
3852 if (req
->uri
!= NULL
)
3854 if (req
->uri_elems
!= NULL
)
3855 evhttp_uri_free(req
->uri_elems
);
3856 if (req
->response_code_line
!= NULL
)
3857 mm_free(req
->response_code_line
);
3858 if (req
->host_cache
!= NULL
)
3859 mm_free(req
->host_cache
);
3861 evhttp_clear_headers(req
->input_headers
);
3862 mm_free(req
->input_headers
);
3864 evhttp_clear_headers(req
->output_headers
);
3865 mm_free(req
->output_headers
);
3867 if (req
->input_buffer
!= NULL
)
3868 evbuffer_free(req
->input_buffer
);
3870 if (req
->output_buffer
!= NULL
)
3871 evbuffer_free(req
->output_buffer
);
3877 evhttp_request_own(struct evhttp_request
*req
)
3879 req
->flags
|= EVHTTP_USER_OWNED
;
3883 evhttp_request_is_owned(struct evhttp_request
*req
)
3885 return (req
->flags
& EVHTTP_USER_OWNED
) != 0;
3888 struct evhttp_connection
*
3889 evhttp_request_get_connection(struct evhttp_request
*req
)
3895 evhttp_connection_get_base(struct evhttp_connection
*conn
)
3901 evhttp_request_set_chunked_cb(struct evhttp_request
*req
,
3902 void (*cb
)(struct evhttp_request
*, void *))
3908 evhttp_request_set_header_cb(struct evhttp_request
*req
,
3909 int (*cb
)(struct evhttp_request
*, void *))
3911 req
->header_cb
= cb
;
3915 evhttp_request_set_error_cb(struct evhttp_request
*req
,
3916 void (*cb
)(enum evhttp_request_error
, void *))
3922 evhttp_request_set_on_complete_cb(struct evhttp_request
*req
,
3923 void (*cb
)(struct evhttp_request
*, void *), void *cb_arg
)
3925 req
->on_complete_cb
= cb
;
3926 req
->on_complete_cb_arg
= cb_arg
;
3930 * Allows for inspection of the request URI
3934 evhttp_request_get_uri(const struct evhttp_request
*req
) {
3935 if (req
->uri
== NULL
)
3936 event_debug(("%s: request %p has no uri\n", __func__
, req
));
3940 const struct evhttp_uri
*
3941 evhttp_request_get_evhttp_uri(const struct evhttp_request
*req
) {
3942 if (req
->uri_elems
== NULL
)
3943 event_debug(("%s: request %p has no uri elems\n",
3945 return (req
->uri_elems
);
3949 evhttp_request_get_host(struct evhttp_request
*req
)
3951 const char *host
= NULL
;
3953 if (req
->host_cache
)
3954 return req
->host_cache
;
3957 host
= evhttp_uri_get_host(req
->uri_elems
);
3958 if (!host
&& req
->input_headers
) {
3962 host
= evhttp_find_header(req
->input_headers
, "Host");
3963 /* The Host: header may include a port. Remove it here
3964 to be consistent with uri_elems case above. */
3966 p
= host
+ strlen(host
) - 1;
3967 while (p
> host
&& EVUTIL_ISDIGIT_(*p
))
3969 if (p
> host
&& *p
== ':') {
3971 req
->host_cache
= mm_malloc(len
+ 1);
3972 if (!req
->host_cache
) {
3973 event_warn("%s: malloc", __func__
);
3976 memcpy(req
->host_cache
, host
, len
);
3977 req
->host_cache
[len
] = '\0';
3978 host
= req
->host_cache
;
3986 enum evhttp_cmd_type
3987 evhttp_request_get_command(const struct evhttp_request
*req
) {
3992 evhttp_request_get_response_code(const struct evhttp_request
*req
)
3994 return req
->response_code
;
3998 evhttp_request_get_response_code_line(const struct evhttp_request
*req
)
4000 return req
->response_code_line
;
4003 /** Returns the input headers */
4004 struct evkeyvalq
*evhttp_request_get_input_headers(struct evhttp_request
*req
)
4006 return (req
->input_headers
);
4009 /** Returns the output headers */
4010 struct evkeyvalq
*evhttp_request_get_output_headers(struct evhttp_request
*req
)
4012 return (req
->output_headers
);
4015 /** Returns the input buffer */
4016 struct evbuffer
*evhttp_request_get_input_buffer(struct evhttp_request
*req
)
4018 return (req
->input_buffer
);
4021 /** Returns the output buffer */
4022 struct evbuffer
*evhttp_request_get_output_buffer(struct evhttp_request
*req
)
4024 return (req
->output_buffer
);
4029 * Takes a file descriptor to read a request from.
4030 * The callback is executed once the whole request has been read.
4033 static struct evhttp_connection
*
4034 evhttp_get_request_connection(
4035 struct evhttp
* http
,
4036 evutil_socket_t fd
, struct sockaddr
*sa
, ev_socklen_t salen
)
4038 struct evhttp_connection
*evcon
;
4039 char *hostname
= NULL
, *portname
= NULL
;
4040 struct bufferevent
* bev
= NULL
;
4042 name_from_addr(sa
, salen
, &hostname
, &portname
);
4043 if (hostname
== NULL
|| portname
== NULL
) {
4044 if (hostname
) mm_free(hostname
);
4045 if (portname
) mm_free(portname
);
4049 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT
"\n",
4050 __func__
, hostname
, portname
, EV_SOCK_ARG(fd
)));
4052 /* we need a connection object to put the http request on */
4053 if (http
->bevcb
!= NULL
) {
4054 bev
= (*http
->bevcb
)(http
->base
, http
->bevcbarg
);
4056 evcon
= evhttp_connection_base_bufferevent_new(
4057 http
->base
, NULL
, bev
, hostname
, atoi(portname
));
4063 evcon
->max_headers_size
= http
->default_max_headers_size
;
4064 evcon
->max_body_size
= http
->default_max_body_size
;
4066 evcon
->flags
|= EVHTTP_CON_INCOMING
;
4067 evcon
->state
= EVCON_READING_FIRSTLINE
;
4071 bufferevent_enable(evcon
->bufev
, EV_READ
);
4072 bufferevent_disable(evcon
->bufev
, EV_WRITE
);
4073 bufferevent_setfd(evcon
->bufev
, fd
);
4079 evhttp_associate_new_request_with_connection(struct evhttp_connection
*evcon
)
4081 struct evhttp
*http
= evcon
->http_server
;
4082 struct evhttp_request
*req
;
4083 if ((req
= evhttp_request_new(evhttp_handle_request
, http
)) == NULL
)
4086 if ((req
->remote_host
= mm_strdup(evcon
->address
)) == NULL
) {
4087 event_warn("%s: strdup", __func__
);
4088 evhttp_request_free(req
);
4091 req
->remote_port
= evcon
->port
;
4093 req
->evcon
= evcon
; /* the request ends up owning the connection */
4094 req
->flags
|= EVHTTP_REQ_OWN_CONNECTION
;
4096 /* We did not present the request to the user user yet, so treat it as
4097 * if the user was done with the request. This allows us to free the
4098 * request on a persistent connection if the client drops it without
4099 * sending a request.
4103 TAILQ_INSERT_TAIL(&evcon
->requests
, req
, next
);
4105 req
->kind
= EVHTTP_REQUEST
;
4108 evhttp_start_read_(evcon
);
4114 evhttp_get_request(struct evhttp
*http
, evutil_socket_t fd
,
4115 struct sockaddr
*sa
, ev_socklen_t salen
)
4117 struct evhttp_connection
*evcon
;
4119 evcon
= evhttp_get_request_connection(http
, fd
, sa
, salen
);
4120 if (evcon
== NULL
) {
4121 event_sock_warn(fd
, "%s: cannot get connection on "EV_SOCK_FMT
,
4122 __func__
, EV_SOCK_ARG(fd
));
4123 evutil_closesocket(fd
);
4127 /* the timeout can be used by the server to close idle connections */
4128 if (evutil_timerisset(&http
->timeout
))
4129 evhttp_connection_set_timeout_tv(evcon
, &http
->timeout
);
4132 * if we want to accept more than one request on a connection,
4133 * we need to know which http server it belongs to.
4135 evcon
->http_server
= http
;
4136 TAILQ_INSERT_TAIL(&http
->connections
, evcon
, next
);
4138 if (evhttp_associate_new_request_with_connection(evcon
) == -1)
4139 evhttp_connection_free(evcon
);
4144 * Network helper functions that we do not want to export to the rest of
4149 name_from_addr(struct sockaddr
*sa
, ev_socklen_t salen
,
4150 char **phost
, char **pport
)
4152 char ntop
[NI_MAXHOST
];
4153 char strport
[NI_MAXSERV
];
4156 #ifdef EVENT__HAVE_GETNAMEINFO
4157 ni_result
= getnameinfo(sa
, salen
,
4158 ntop
, sizeof(ntop
), strport
, sizeof(strport
),
4159 NI_NUMERICHOST
|NI_NUMERICSERV
);
4161 if (ni_result
!= 0) {
4163 /* Windows doesn't have an EAI_SYSTEM. */
4164 if (ni_result
== EAI_SYSTEM
)
4165 event_err(1, "getnameinfo failed");
4168 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result
));
4172 ni_result
= fake_getnameinfo(sa
, salen
,
4173 ntop
, sizeof(ntop
), strport
, sizeof(strport
),
4174 NI_NUMERICHOST
|NI_NUMERICSERV
);
4179 *phost
= mm_strdup(ntop
);
4180 *pport
= mm_strdup(strport
);
4183 /* Create a non-blocking socket and bind it */
4184 /* todo: rename this function */
4185 static evutil_socket_t
4186 bind_socket_ai(struct evutil_addrinfo
*ai
, int reuse
)
4193 /* Create listen socket */
4194 fd
= evutil_socket_(ai
? ai
->ai_family
: AF_INET
,
4195 SOCK_STREAM
|EVUTIL_SOCK_NONBLOCK
|EVUTIL_SOCK_CLOEXEC
, 0);
4197 event_sock_warn(-1, "socket");
4201 if (setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&on
, sizeof(on
))<0)
4204 if (evutil_make_listen_socket_reuseable(fd
) < 0)
4209 r
= bind(fd
, ai
->ai_addr
, (ev_socklen_t
)ai
->ai_addrlen
);
4217 serrno
= EVUTIL_SOCKET_ERROR();
4218 evutil_closesocket(fd
);
4219 EVUTIL_SET_SOCKET_ERROR(serrno
);
4223 static struct evutil_addrinfo
*
4224 make_addrinfo(const char *address
, ev_uint16_t port
)
4226 struct evutil_addrinfo
*ai
= NULL
;
4228 struct evutil_addrinfo hints
;
4229 char strport
[NI_MAXSERV
];
4232 memset(&hints
, 0, sizeof(hints
));
4233 hints
.ai_family
= AF_UNSPEC
;
4234 hints
.ai_socktype
= SOCK_STREAM
;
4235 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
4236 * types we don't have an interface to connect to. */
4237 hints
.ai_flags
= EVUTIL_AI_PASSIVE
|EVUTIL_AI_ADDRCONFIG
;
4238 evutil_snprintf(strport
, sizeof(strport
), "%d", port
);
4239 if ((ai_result
= evutil_getaddrinfo(address
, strport
, &hints
, &ai
))
4241 if (ai_result
== EVUTIL_EAI_SYSTEM
)
4242 event_warn("getaddrinfo");
4244 event_warnx("getaddrinfo: %s",
4245 evutil_gai_strerror(ai_result
));
4252 static evutil_socket_t
4253 bind_socket(const char *address
, ev_uint16_t port
, int reuse
)
4256 struct evutil_addrinfo
*aitop
= NULL
;
4258 /* just create an unbound socket */
4259 if (address
== NULL
&& port
== 0)
4260 return bind_socket_ai(NULL
, 0);
4262 aitop
= make_addrinfo(address
, port
);
4267 fd
= bind_socket_ai(aitop
, reuse
);
4269 evutil_freeaddrinfo(aitop
);
4276 char *scheme
; /* scheme; e.g http, ftp etc */
4277 char *userinfo
; /* userinfo (typically username:pass), or NULL */
4278 char *host
; /* hostname, IP address, or NULL */
4279 int port
; /* port, or zero */
4280 char *path
; /* path, or "". */
4281 char *query
; /* query, or NULL */
4282 char *fragment
; /* fragment or NULL */
4286 evhttp_uri_new(void)
4288 struct evhttp_uri
*uri
= mm_calloc(sizeof(struct evhttp_uri
), 1);
4295 evhttp_uri_set_flags(struct evhttp_uri
*uri
, unsigned flags
)
4300 /* Return true if the string starting at s and ending immediately before eos
4301 * is a valid URI scheme according to RFC3986
4304 scheme_ok(const char *s
, const char *eos
)
4306 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
4307 EVUTIL_ASSERT(eos
>= s
);
4310 if (!EVUTIL_ISALPHA_(*s
))
4313 if (! EVUTIL_ISALNUM_(*s
) &&
4314 *s
!= '+' && *s
!= '-' && *s
!= '.')
4320 #define SUBDELIMS "!$&'()*+,;="
4322 /* Return true iff [s..eos) is a valid userinfo */
4324 userinfo_ok(const char *s
, const char *eos
)
4327 if (CHAR_IS_UNRESERVED(*s
) ||
4328 strchr(SUBDELIMS
, *s
) ||
4331 else if (*s
== '%' && s
+2 < eos
&&
4332 EVUTIL_ISXDIGIT_(s
[1]) &&
4333 EVUTIL_ISXDIGIT_(s
[2]))
4342 regname_ok(const char *s
, const char *eos
)
4344 while (s
&& s
<eos
) {
4345 if (CHAR_IS_UNRESERVED(*s
) ||
4346 strchr(SUBDELIMS
, *s
))
4348 else if (*s
== '%' &&
4349 EVUTIL_ISXDIGIT_(s
[1]) &&
4350 EVUTIL_ISXDIGIT_(s
[2]))
4359 parse_port(const char *s
, const char *eos
)
4363 if (! EVUTIL_ISDIGIT_(*s
))
4365 portnum
= (portnum
* 10) + (*s
- '0');
4368 if (portnum
> 65535)
4375 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4377 bracket_addr_ok(const char *s
, const char *eos
)
4379 if (s
+ 3 > eos
|| *s
!= '[' || *(eos
-1) != ']')
4382 /* IPvFuture, or junk.
4383 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4385 s
+= 2; /* skip [v */
4387 if (!EVUTIL_ISXDIGIT_(*s
)) /*require at least one*/
4389 while (s
< eos
&& *s
!= '.') {
4390 if (EVUTIL_ISXDIGIT_(*s
))
4399 if (CHAR_IS_UNRESERVED(*s
) ||
4400 strchr(SUBDELIMS
, *s
) ||
4410 ev_ssize_t n_chars
= eos
-s
-2;
4411 struct in6_addr in6
;
4412 if (n_chars
>= 64) /* way too long */
4414 memcpy(buf
, s
+1, n_chars
);
4416 return (evutil_inet_pton(AF_INET6
,buf
,&in6
)==1) ? 1 : 0;
4421 parse_authority(struct evhttp_uri
*uri
, char *s
, char *eos
)
4426 uri
->host
= mm_strdup("");
4427 if (uri
->host
== NULL
) {
4428 event_warn("%s: strdup", __func__
);
4434 /* Optionally, we start with "userinfo@" */
4436 cp
= strchr(s
, '@');
4437 if (cp
&& cp
< eos
) {
4438 if (! userinfo_ok(s
,cp
))
4441 uri
->userinfo
= mm_strdup(s
);
4442 if (uri
->userinfo
== NULL
) {
4443 event_warn("%s: strdup", __func__
);
4449 /* Optionally, we end with ":port" */
4450 for (port
=eos
-1; port
>= cp
&& EVUTIL_ISDIGIT_(*port
); --port
)
4452 if (port
>= cp
&& *port
== ':') {
4453 if (port
+1 == eos
) /* Leave port unspecified; the RFC allows a
4456 else if ((uri
->port
= parse_port(port
+1, eos
))<0)
4460 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4461 * an IP-Literal, or a reg-name */
4462 EVUTIL_ASSERT(eos
>= cp
);
4463 if (*cp
== '[' && eos
>= cp
+2 && *(eos
-1) == ']') {
4464 /* IPv6address, IP-Literal, or junk. */
4465 if (! bracket_addr_ok(cp
, eos
))
4468 /* Make sure the host part is ok. */
4469 if (! regname_ok(cp
,eos
)) /* Match IPv4Address or reg-name */
4472 uri
->host
= mm_malloc(eos
-cp
+1);
4473 if (uri
->host
== NULL
) {
4474 event_warn("%s: malloc", __func__
);
4477 memcpy(uri
->host
, cp
, eos
-cp
);
4478 uri
->host
[eos
-cp
] = '\0';
4484 end_of_authority(char *cp
)
4487 if (*cp
== '?' || *cp
== '#' || *cp
== '/')
4500 /* Return the character after the longest prefix of 'cp' that matches...
4501 * *pchar / "/" if allow_qchars is false, or
4502 * *(pchar / "/" / "?") if allow_qchars is true.
4505 end_of_path(char *cp
, enum uri_part part
, unsigned flags
)
4507 if (flags
& EVHTTP_URI_NONCONFORMANT
) {
4508 /* If NONCONFORMANT:
4509 * Path is everything up to a # or ? or nul.
4510 * Query is everything up a # or nul
4511 * Fragment is everything up to a nul.
4515 while (*cp
&& *cp
!= '#' && *cp
!= '?')
4519 while (*cp
&& *cp
!= '#')
4530 if (CHAR_IS_UNRESERVED(*cp
) ||
4531 strchr(SUBDELIMS
, *cp
) ||
4532 *cp
== ':' || *cp
== '@' || *cp
== '/')
4534 else if (*cp
== '%' && EVUTIL_ISXDIGIT_(cp
[1]) &&
4535 EVUTIL_ISXDIGIT_(cp
[2]))
4537 else if (*cp
== '?' && part
!= PART_PATH
)
4546 path_matches_noscheme(const char *cp
)
4551 else if (*cp
== '/')
4559 evhttp_uri_parse(const char *source_uri
)
4561 return evhttp_uri_parse_with_flags(source_uri
, 0);
4565 evhttp_uri_parse_with_flags(const char *source_uri
, unsigned flags
)
4567 char *readbuf
= NULL
, *readp
= NULL
, *token
= NULL
, *query
= NULL
;
4568 char *path
= NULL
, *fragment
= NULL
;
4569 int got_authority
= 0;
4571 struct evhttp_uri
*uri
= mm_calloc(1, sizeof(struct evhttp_uri
));
4573 event_warn("%s: calloc", __func__
);
4579 readbuf
= mm_strdup(source_uri
);
4580 if (readbuf
== NULL
) {
4581 event_warn("%s: strdup", __func__
);
4588 /* We try to follow RFC3986 here as much as we can, and match
4591 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4593 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
4597 token
= strchr(readp
, ':');
4598 if (token
&& scheme_ok(readp
,token
)) {
4600 uri
->scheme
= mm_strdup(readp
);
4601 if (uri
->scheme
== NULL
) {
4602 event_warn("%s: strdup", __func__
);
4605 readp
= token
+1; /* eat : */
4608 /* 2. Optionally, "//" then an 'authority' part. */
4609 if (readp
[0]=='/' && readp
[1] == '/') {
4613 path
= end_of_authority(readp
);
4614 if (parse_authority(uri
, authority
, path
) < 0)
4620 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4623 readp
= end_of_path(path
, PART_PATH
, flags
);
4626 if (*readp
== '?') {
4630 readp
= end_of_path(readp
, PART_QUERY
, flags
);
4633 if (*readp
== '#') {
4637 readp
= end_of_path(readp
, PART_FRAGMENT
, flags
);
4639 if (*readp
!= '\0') {
4643 /* These next two cases may be unreachable; I'm leaving them
4644 * in to be defensive. */
4645 /* If you didn't get an authority, the path can't begin with "//" */
4646 if (!got_authority
&& path
[0]=='/' && path
[1]=='/')
4648 /* If you did get an authority, the path must begin with "/" or be
4650 if (got_authority
&& path
[0] != '/' && path
[0] != '\0')
4652 /* (End of maybe-unreachable cases) */
4654 /* If there was no scheme, the first part of the path (if any) must
4655 * have no colon in it. */
4656 if (! uri
->scheme
&& !path_matches_noscheme(path
))
4659 EVUTIL_ASSERT(path
);
4660 uri
->path
= mm_strdup(path
);
4661 if (uri
->path
== NULL
) {
4662 event_warn("%s: strdup", __func__
);
4667 uri
->query
= mm_strdup(query
);
4668 if (uri
->query
== NULL
) {
4669 event_warn("%s: strdup", __func__
);
4674 uri
->fragment
= mm_strdup(fragment
);
4675 if (uri
->fragment
== NULL
) {
4676 event_warn("%s: strdup", __func__
);
4686 evhttp_uri_free(uri
);
4693 evhttp_uri_free(struct evhttp_uri
*uri
)
4695 #define URI_FREE_STR_(f) \
4700 URI_FREE_STR_(scheme
);
4701 URI_FREE_STR_(userinfo
);
4702 URI_FREE_STR_(host
);
4703 URI_FREE_STR_(path
);
4704 URI_FREE_STR_(query
);
4705 URI_FREE_STR_(fragment
);
4708 #undef URI_FREE_STR_
4712 evhttp_uri_join(struct evhttp_uri
*uri
, char *buf
, size_t limit
)
4714 struct evbuffer
*tmp
= 0;
4715 size_t joined_size
= 0;
4716 char *output
= NULL
;
4718 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
4720 if (!uri
|| !buf
|| !limit
)
4723 tmp
= evbuffer_new();
4729 evbuffer_add(tmp
, ":", 1);
4732 evbuffer_add(tmp
, "//", 2);
4734 evbuffer_add_printf(tmp
,"%s@", uri
->userinfo
);
4737 evbuffer_add_printf(tmp
,":%d", uri
->port
);
4739 if (uri
->path
&& uri
->path
[0] != '/' && uri
->path
[0] != '\0')
4747 evbuffer_add(tmp
, "?", 1);
4751 if (uri
->fragment
) {
4752 evbuffer_add(tmp
, "#", 1);
4756 evbuffer_add(tmp
, "\0", 1); /* NUL */
4758 joined_size
= evbuffer_get_length(tmp
);
4760 if (joined_size
> limit
) {
4761 /* It doesn't fit. */
4765 evbuffer_remove(tmp
, buf
, joined_size
);
4776 evhttp_uri_get_scheme(const struct evhttp_uri
*uri
)
4781 evhttp_uri_get_userinfo(const struct evhttp_uri
*uri
)
4783 return uri
->userinfo
;
4786 evhttp_uri_get_host(const struct evhttp_uri
*uri
)
4791 evhttp_uri_get_port(const struct evhttp_uri
*uri
)
4796 evhttp_uri_get_path(const struct evhttp_uri
*uri
)
4801 evhttp_uri_get_query(const struct evhttp_uri
*uri
)
4806 evhttp_uri_get_fragment(const struct evhttp_uri
*uri
)
4808 return uri
->fragment
;
4811 #define URI_SET_STR_(f) do { \
4815 if ((uri->f = mm_strdup(f)) == NULL) { \
4816 event_warn("%s: strdup()", __func__); \
4825 evhttp_uri_set_scheme(struct evhttp_uri
*uri
, const char *scheme
)
4827 if (scheme
&& !scheme_ok(scheme
, scheme
+strlen(scheme
)))
4830 URI_SET_STR_(scheme
);
4834 evhttp_uri_set_userinfo(struct evhttp_uri
*uri
, const char *userinfo
)
4836 if (userinfo
&& !userinfo_ok(userinfo
, userinfo
+strlen(userinfo
)))
4838 URI_SET_STR_(userinfo
);
4842 evhttp_uri_set_host(struct evhttp_uri
*uri
, const char *host
)
4845 if (host
[0] == '[') {
4846 if (! bracket_addr_ok(host
, host
+strlen(host
)))
4849 if (! regname_ok(host
, host
+strlen(host
)))
4858 evhttp_uri_set_port(struct evhttp_uri
*uri
, int port
)
4865 #define end_of_cpath(cp,p,f) \
4866 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
4869 evhttp_uri_set_path(struct evhttp_uri
*uri
, const char *path
)
4871 if (path
&& end_of_cpath(path
, PART_PATH
, uri
->flags
) != path
+strlen(path
))
4878 evhttp_uri_set_query(struct evhttp_uri
*uri
, const char *query
)
4880 if (query
&& end_of_cpath(query
, PART_QUERY
, uri
->flags
) != query
+strlen(query
))
4882 URI_SET_STR_(query
);
4886 evhttp_uri_set_fragment(struct evhttp_uri
*uri
, const char *fragment
)
4888 if (fragment
&& end_of_cpath(fragment
, PART_FRAGMENT
, uri
->flags
) != fragment
+strlen(fragment
))
4890 URI_SET_STR_(fragment
);