Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / libevent / http.c
blob3994b917dc24353c41f39857722142eab84d7786
1 /*
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
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "event2/event-config.h"
30 #ifdef _EVENT_HAVE_SYS_PARAM_H
31 #include <sys/param.h>
32 #endif
33 #ifdef _EVENT_HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
37 #ifdef _EVENT_HAVE_SYS_TIME_H
38 #include <sys/time.h>
39 #endif
40 #ifdef HAVE_SYS_IOCCOM_H
41 #include <sys/ioccom.h>
42 #endif
44 #ifndef WIN32
45 #include <sys/resource.h>
46 #include <sys/socket.h>
47 #include <sys/stat.h>
48 #include <sys/wait.h>
49 #else
50 #include <winsock2.h>
51 #include <ws2tcpip.h>
52 #endif
54 #include <sys/queue.h>
56 #ifdef _EVENT_HAVE_NETINET_IN_H
57 #include <netinet/in.h>
58 #endif
59 #ifdef _EVENT_HAVE_ARPA_INET_H
60 #include <arpa/inet.h>
61 #endif
62 #ifdef _EVENT_HAVE_NETDB_H
63 #include <netdb.h>
64 #endif
66 #ifdef WIN32
67 #include <winsock2.h>
68 #endif
70 #include <errno.h>
71 #include <stdio.h>
72 #include <stdlib.h>
73 #include <string.h>
74 #ifndef WIN32
75 #include <syslog.h>
76 #endif
77 #include <signal.h>
78 #include <time.h>
79 #ifdef _EVENT_HAVE_UNISTD_H
80 #include <unistd.h>
81 #endif
82 #ifdef _EVENT_HAVE_FCNTL_H
83 #include <fcntl.h>
84 #endif
86 #undef timeout_pending
87 #undef timeout_initialized
89 #include "strlcpy-internal.h"
90 #include "event2/http.h"
91 #include "event2/event.h"
92 #include "event2/buffer.h"
93 #include "event2/bufferevent.h"
94 #include "event2/bufferevent_compat.h"
95 #include "event2/http_struct.h"
96 #include "event2/http_compat.h"
97 #include "event2/util.h"
98 #include "event2/listener.h"
99 #include "log-internal.h"
100 #include "util-internal.h"
101 #include "http-internal.h"
102 #include "mm-internal.h"
103 #include "bufferevent-internal.h"
105 #ifndef _EVENT_HAVE_GETNAMEINFO
106 #define NI_MAXSERV 32
107 #define NI_MAXHOST 1025
109 #ifndef NI_NUMERICHOST
110 #define NI_NUMERICHOST 1
111 #endif
113 #ifndef NI_NUMERICSERV
114 #define NI_NUMERICSERV 2
115 #endif
117 static int
118 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
119 size_t hostlen, char *serv, size_t servlen, int flags)
121 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
123 if (serv != NULL) {
124 char tmpserv[16];
125 evutil_snprintf(tmpserv, sizeof(tmpserv),
126 "%d", ntohs(sin->sin_port));
127 if (strlcpy(serv, tmpserv, servlen) >= servlen)
128 return (-1);
131 if (host != NULL) {
132 if (flags & NI_NUMERICHOST) {
133 if (strlcpy(host, inet_ntoa(sin->sin_addr),
134 hostlen) >= hostlen)
135 return (-1);
136 else
137 return (0);
138 } else {
139 struct hostent *hp;
140 hp = gethostbyaddr((char *)&sin->sin_addr,
141 sizeof(struct in_addr), AF_INET);
142 if (hp == NULL)
143 return (-2);
145 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
146 return (-1);
147 else
148 return (0);
151 return (0);
154 #endif
156 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \
157 ((req)->major < (major_v) || \
158 ((req)->major == (major_v) && (req)->minor < (minor_v)))
160 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \
161 ((req)->major > (major_v) || \
162 ((req)->major == (major_v) && (req)->minor >= (minor_v)))
164 #ifndef MIN
165 #define MIN(a,b) (((a)<(b))?(a):(b))
166 #endif
168 extern int debug;
170 static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse);
171 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse);
172 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **);
173 static int evhttp_associate_new_request_with_connection(
174 struct evhttp_connection *evcon);
175 static void evhttp_connection_start_detectclose(
176 struct evhttp_connection *evcon);
177 static void evhttp_connection_stop_detectclose(
178 struct evhttp_connection *evcon);
179 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
180 static void evhttp_read_firstline(struct evhttp_connection *evcon,
181 struct evhttp_request *req);
182 static void evhttp_read_header(struct evhttp_connection *evcon,
183 struct evhttp_request *req);
184 static int evhttp_add_header_internal(struct evkeyvalq *headers,
185 const char *key, const char *value);
186 static const char *evhttp_response_phrase_internal(int code);
187 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t);
188 static void evhttp_write_buffer(struct evhttp_connection *,
189 void (*)(struct evhttp_connection *, void *), void *);
190 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *);
192 /* callbacks for bufferevent */
193 static void evhttp_read_cb(struct bufferevent *, void *);
194 static void evhttp_write_cb(struct bufferevent *, void *);
195 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg);
196 static int evhttp_decode_uri_internal(const char *uri, size_t length,
197 char *ret, int decode_plus);
198 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
199 const char *hostname);
201 #ifndef _EVENT_HAVE_STRSEP
202 /* strsep replacement for platforms that lack it. Only works if
203 * del is one character long. */
204 static char *
205 strsep(char **s, const char *del)
207 char *d, *tok;
208 EVUTIL_ASSERT(strlen(del) == 1);
209 if (!s || !*s)
210 return NULL;
211 tok = *s;
212 d = strstr(tok, del);
213 if (d) {
214 *d = '\0';
215 *s = d + 1;
216 } else
217 *s = NULL;
218 return tok;
220 #endif
222 static size_t
223 html_replace(const char ch, const char **escaped)
225 switch (ch) {
226 case '<':
227 *escaped = "&lt;";
228 return 4;
229 case '>':
230 *escaped = "&gt;";
231 return 4;
232 case '"':
233 *escaped = "&quot;";
234 return 6;
235 case '\'':
236 *escaped = "&#039;";
237 return 6;
238 case '&':
239 *escaped = "&amp;";
240 return 5;
241 default:
242 break;
245 return 1;
249 * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
250 * &#039; and &amp; correspondingly.
252 * The returned string needs to be freed by the caller.
255 char *
256 evhttp_htmlescape(const char *html)
258 size_t i;
259 size_t new_size = 0, old_size = 0;
260 char *escaped_html, *p;
262 if (html == NULL)
263 return (NULL);
265 old_size = strlen(html);
266 for (i = 0; i < old_size; ++i) {
267 const char *replaced = NULL;
268 const size_t replace_size = html_replace(html[i], &replaced);
269 if (replace_size > EV_SIZE_MAX - new_size) {
270 event_warn("%s: html_replace overflow", __func__);
271 return (NULL);
273 new_size += replace_size;
276 if (new_size == EV_SIZE_MAX)
277 return (NULL);
278 p = escaped_html = mm_malloc(new_size + 1);
279 if (escaped_html == NULL) {
280 event_warn("%s: malloc(%lu)", __func__,
281 (unsigned long)(new_size + 1));
282 return (NULL);
284 for (i = 0; i < old_size; ++i) {
285 const char *replaced = &html[i];
286 const size_t len = html_replace(html[i], &replaced);
287 memcpy(p, replaced, len);
288 p += len;
291 *p = '\0';
293 return (escaped_html);
296 /** Given an evhttp_cmd_type, returns a constant string containing the
297 * equivalent HTTP command, or NULL if the evhttp_command_type is
298 * unrecognized. */
299 static const char *
300 evhttp_method(enum evhttp_cmd_type type)
302 const char *method;
304 switch (type) {
305 case EVHTTP_REQ_GET:
306 method = "GET";
307 break;
308 case EVHTTP_REQ_POST:
309 method = "POST";
310 break;
311 case EVHTTP_REQ_HEAD:
312 method = "HEAD";
313 break;
314 case EVHTTP_REQ_PUT:
315 method = "PUT";
316 break;
317 case EVHTTP_REQ_DELETE:
318 method = "DELETE";
319 break;
320 case EVHTTP_REQ_OPTIONS:
321 method = "OPTIONS";
322 break;
323 case EVHTTP_REQ_TRACE:
324 method = "TRACE";
325 break;
326 case EVHTTP_REQ_CONNECT:
327 method = "CONNECT";
328 break;
329 case EVHTTP_REQ_PATCH:
330 method = "PATCH";
331 break;
332 default:
333 method = NULL;
334 break;
337 return (method);
341 * Determines if a response should have a body.
342 * Follows the rules in RFC 2616 section 4.3.
343 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have
344 * a body.
346 static int
347 evhttp_response_needs_body(struct evhttp_request *req)
349 return (req->response_code != HTTP_NOCONTENT &&
350 req->response_code != HTTP_NOTMODIFIED &&
351 (req->response_code < 100 || req->response_code >= 200) &&
352 req->type != EVHTTP_REQ_HEAD);
355 /** Helper: adds the event 'ev' with the timeout 'timeout', or with
356 * default_timeout if timeout is -1.
358 static int
359 evhttp_add_event(struct event *ev, int timeout, int default_timeout)
361 if (timeout != 0) {
362 struct timeval tv;
364 evutil_timerclear(&tv);
365 tv.tv_sec = timeout != -1 ? timeout : default_timeout;
366 return event_add(ev, &tv);
367 } else {
368 return event_add(ev, NULL);
372 /** Helper: called after we've added some data to an evcon's bufferevent's
373 * output buffer. Sets the evconn's writing-is-done callback, and puts
374 * the bufferevent into writing mode.
376 static void
377 evhttp_write_buffer(struct evhttp_connection *evcon,
378 void (*cb)(struct evhttp_connection *, void *), void *arg)
380 event_debug(("%s: preparing to write buffer\n", __func__));
382 /* Set call back */
383 evcon->cb = cb;
384 evcon->cb_arg = arg;
386 bufferevent_enable(evcon->bufev, EV_WRITE);
388 /* Disable the read callback: we don't actually care about data;
389 * we only care about close detection. (We don't disable reading,
390 * since we *do* want to learn about any close events.) */
391 bufferevent_setcb(evcon->bufev,
392 NULL, /*read*/
393 evhttp_write_cb,
394 evhttp_error_cb,
395 evcon);
398 static void
399 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
401 bufferevent_disable(evcon->bufev, EV_WRITE);
404 static void
405 evhttp_send_continue(struct evhttp_connection *evcon,
406 struct evhttp_request *req)
408 bufferevent_enable(evcon->bufev, EV_WRITE);
409 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
410 "HTTP/%d.%d 100 Continue\r\n\r\n",
411 req->major, req->minor);
412 evcon->cb = evhttp_send_continue_done;
413 evcon->cb_arg = NULL;
414 bufferevent_setcb(evcon->bufev,
415 evhttp_read_cb,
416 evhttp_write_cb,
417 evhttp_error_cb,
418 evcon);
421 /** Helper: returns true iff evconn is in any connected state. */
422 static int
423 evhttp_connected(struct evhttp_connection *evcon)
425 switch (evcon->state) {
426 case EVCON_DISCONNECTED:
427 case EVCON_CONNECTING:
428 return (0);
429 case EVCON_IDLE:
430 case EVCON_READING_FIRSTLINE:
431 case EVCON_READING_HEADERS:
432 case EVCON_READING_BODY:
433 case EVCON_READING_TRAILER:
434 case EVCON_WRITING:
435 default:
436 return (1);
440 /* Create the headers needed for an outgoing HTTP request, adds them to
441 * the request's header list, and writes the request line to the
442 * connection's output buffer.
444 static void
445 evhttp_make_header_request(struct evhttp_connection *evcon,
446 struct evhttp_request *req)
448 const char *method;
450 evhttp_remove_header(req->output_headers, "Proxy-Connection");
452 /* Generate request line */
453 method = evhttp_method(req->type);
454 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
455 "%s %s HTTP/%d.%d\r\n",
456 method, req->uri, req->major, req->minor);
458 /* Add the content length on a post or put request if missing */
459 if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) &&
460 evhttp_find_header(req->output_headers, "Content-Length") == NULL){
461 char size[22];
462 evutil_snprintf(size, sizeof(size), EV_SIZE_FMT,
463 EV_SIZE_ARG(evbuffer_get_length(req->output_buffer)));
464 evhttp_add_header(req->output_headers, "Content-Length", size);
468 /** Return true if the list of headers in 'headers', intepreted with respect
469 * to flags, means that we should send a "connection: close" when the request
470 * is done. */
471 static int
472 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
474 if (flags & EVHTTP_PROXY_REQUEST) {
475 /* proxy connection */
476 const char *connection = evhttp_find_header(headers, "Proxy-Connection");
477 return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0);
478 } else {
479 const char *connection = evhttp_find_header(headers, "Connection");
480 return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0);
484 /* Return true iff 'headers' contains 'Connection: keep-alive' */
485 static int
486 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
488 const char *connection = evhttp_find_header(headers, "Connection");
489 return (connection != NULL
490 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
493 /* Add a correct "Date" header to headers, unless it already has one. */
494 static void
495 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
497 if (evhttp_find_header(headers, "Date") == NULL) {
498 char date[50];
499 #ifndef WIN32
500 struct tm cur;
501 #endif
502 struct tm *cur_p;
503 time_t t = time(NULL);
504 #ifdef WIN32
505 cur_p = gmtime(&t);
506 #else
507 gmtime_r(&t, &cur);
508 cur_p = &cur;
509 #endif
510 if (strftime(date, sizeof(date),
511 "%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) {
512 evhttp_add_header(headers, "Date", date);
517 /* Add a "Content-Length" header with value 'content_length' to headers,
518 * unless it already has a content-length or transfer-encoding header. */
519 static void
520 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
521 size_t content_length)
523 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
524 evhttp_find_header(headers, "Content-Length") == NULL) {
525 char len[22];
526 evutil_snprintf(len, sizeof(len), EV_SIZE_FMT,
527 EV_SIZE_ARG(content_length));
528 evhttp_add_header(headers, "Content-Length", len);
533 * Create the headers needed for an HTTP reply in req->output_headers,
534 * and write the first HTTP response for req line to evcon.
536 static void
537 evhttp_make_header_response(struct evhttp_connection *evcon,
538 struct evhttp_request *req)
540 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
541 evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
542 "HTTP/%d.%d %d %s\r\n",
543 req->major, req->minor, req->response_code,
544 req->response_code_line);
546 if (req->major == 1) {
547 if (req->minor >= 1)
548 evhttp_maybe_add_date_header(req->output_headers);
551 * if the protocol is 1.0; and the connection was keep-alive
552 * we need to add a keep-alive header, too.
554 if (req->minor == 0 && is_keepalive)
555 evhttp_add_header(req->output_headers,
556 "Connection", "keep-alive");
558 if ((req->minor >= 1 || is_keepalive) &&
559 evhttp_response_needs_body(req)) {
561 * we need to add the content length if the
562 * user did not give it, this is required for
563 * persistent connections to work.
565 evhttp_maybe_add_content_length_header(
566 req->output_headers,
567 evbuffer_get_length(req->output_buffer));
571 /* Potentially add headers for unidentified content. */
572 if (evhttp_response_needs_body(req)) {
573 if (evhttp_find_header(req->output_headers,
574 "Content-Type") == NULL) {
575 evhttp_add_header(req->output_headers,
576 "Content-Type", "text/html; charset=ISO-8859-1");
580 /* if the request asked for a close, we send a close, too */
581 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
582 evhttp_remove_header(req->output_headers, "Connection");
583 if (!(req->flags & EVHTTP_PROXY_REQUEST))
584 evhttp_add_header(req->output_headers, "Connection", "close");
585 evhttp_remove_header(req->output_headers, "Proxy-Connection");
589 /** Generate all headers appropriate for sending the http request in req (or
590 * the response, if we're sending a response), and write them to evcon's
591 * bufferevent. Also writes all data from req->output_buffer */
592 static void
593 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
595 struct evkeyval *header;
596 struct evbuffer *output = bufferevent_get_output(evcon->bufev);
599 * Depending if this is a HTTP request or response, we might need to
600 * add some new headers or remove existing headers.
602 if (req->kind == EVHTTP_REQUEST) {
603 evhttp_make_header_request(evcon, req);
604 } else {
605 evhttp_make_header_response(evcon, req);
608 TAILQ_FOREACH(header, req->output_headers, next) {
609 evbuffer_add_printf(output, "%s: %s\r\n",
610 header->key, header->value);
612 evbuffer_add(output, "\r\n", 2);
614 if (evbuffer_get_length(req->output_buffer) > 0) {
616 * For a request, we add the POST data, for a reply, this
617 * is the regular data.
619 /* XXX We might want to support waiting (a limited amount of
620 time) for a continue status line from the server before
621 sending POST/PUT message bodies. */
622 evbuffer_add_buffer(output, req->output_buffer);
626 void
627 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
628 ev_ssize_t new_max_headers_size)
630 if (new_max_headers_size<0)
631 evcon->max_headers_size = EV_SIZE_MAX;
632 else
633 evcon->max_headers_size = new_max_headers_size;
635 void
636 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
637 ev_ssize_t new_max_body_size)
639 if (new_max_body_size<0)
640 evcon->max_body_size = EV_UINT64_MAX;
641 else
642 evcon->max_body_size = new_max_body_size;
645 static int
646 evhttp_connection_incoming_fail(struct evhttp_request *req,
647 enum evhttp_connection_error error)
649 switch (error) {
650 case EVCON_HTTP_TIMEOUT:
651 case EVCON_HTTP_EOF:
653 * these are cases in which we probably should just
654 * close the connection and not send a reply. this
655 * case may happen when a browser keeps a persistent
656 * connection open and we timeout on the read. when
657 * the request is still being used for sending, we
658 * need to disassociated it from the connection here.
660 if (!req->userdone) {
661 /* remove it so that it will not be freed */
662 TAILQ_REMOVE(&req->evcon->requests, req, next);
663 /* indicate that this request no longer has a
664 * connection object
666 req->evcon = NULL;
668 return (-1);
669 case EVCON_HTTP_INVALID_HEADER:
670 case EVCON_HTTP_BUFFER_ERROR:
671 case EVCON_HTTP_REQUEST_CANCEL:
672 default: /* xxx: probably should just error on default */
673 /* the callback looks at the uri to determine errors */
674 if (req->uri) {
675 mm_free(req->uri);
676 req->uri = NULL;
678 if (req->uri_elems) {
679 evhttp_uri_free(req->uri_elems);
680 req->uri_elems = NULL;
684 * the callback needs to send a reply, once the reply has
685 * been send, the connection should get freed.
687 (*req->cb)(req, req->cb_arg);
690 return (0);
693 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
694 * given in error. If it's an outgoing connection, reset the connection,
695 * retry any pending requests, and inform the user. If it's incoming,
696 * delegates to evhttp_connection_incoming_fail(). */
697 void
698 evhttp_connection_fail(struct evhttp_connection *evcon,
699 enum evhttp_connection_error error)
701 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
702 void (*cb)(struct evhttp_request *, void *);
703 void *cb_arg;
704 EVUTIL_ASSERT(req != NULL);
706 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
708 if (evcon->flags & EVHTTP_CON_INCOMING) {
710 * for incoming requests, there are two different
711 * failure cases. it's either a network level error
712 * or an http layer error. for problems on the network
713 * layer like timeouts we just drop the connections.
714 * For HTTP problems, we might have to send back a
715 * reply before the connection can be freed.
717 if (evhttp_connection_incoming_fail(req, error) == -1)
718 evhttp_connection_free(evcon);
719 return;
722 /* when the request was canceled, the callback is not executed */
723 if (error != EVCON_HTTP_REQUEST_CANCEL) {
724 /* save the callback for later; the cb might free our object */
725 cb = req->cb;
726 cb_arg = req->cb_arg;
727 } else {
728 cb = NULL;
729 cb_arg = NULL;
732 /* do not fail all requests; the next request is going to get
733 * send over a new connection. when a user cancels a request,
734 * all other pending requests should be processed as normal
736 TAILQ_REMOVE(&evcon->requests, req, next);
737 evhttp_request_free(req);
739 /* reset the connection */
740 evhttp_connection_reset(evcon);
742 /* We are trying the next request that was queued on us */
743 if (TAILQ_FIRST(&evcon->requests) != NULL)
744 evhttp_connection_connect(evcon);
746 /* inform the user */
747 if (cb != NULL)
748 (*cb)(NULL, cb_arg);
751 /* Bufferevent callback: invoked when any data has been written from an
752 * http connection's bufferevent */
753 static void
754 evhttp_write_cb(struct bufferevent *bufev, void *arg)
756 struct evhttp_connection *evcon = arg;
758 /* Activate our call back */
759 if (evcon->cb != NULL)
760 (*evcon->cb)(evcon, evcon->cb_arg);
764 * Advance the connection state.
765 * - If this is an outgoing connection, we've just processed the response;
766 * idle or close the connection.
767 * - If this is an incoming connection, we've just processed the request;
768 * respond.
770 static void
771 evhttp_connection_done(struct evhttp_connection *evcon)
773 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
774 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
776 if (con_outgoing) {
777 /* idle or close the connection */
778 int need_close;
779 TAILQ_REMOVE(&evcon->requests, req, next);
780 req->evcon = NULL;
782 evcon->state = EVCON_IDLE;
784 need_close =
785 evhttp_is_connection_close(req->flags, req->input_headers)||
786 evhttp_is_connection_close(req->flags, req->output_headers);
788 /* check if we got asked to close the connection */
789 if (need_close)
790 evhttp_connection_reset(evcon);
792 if (TAILQ_FIRST(&evcon->requests) != NULL) {
794 * We have more requests; reset the connection
795 * and deal with the next request.
797 if (!evhttp_connected(evcon))
798 evhttp_connection_connect(evcon);
799 else
800 evhttp_request_dispatch(evcon);
801 } else if (!need_close) {
803 * The connection is going to be persistent, but we
804 * need to detect if the other side closes it.
806 evhttp_connection_start_detectclose(evcon);
808 } else {
810 * incoming connection - we need to leave the request on the
811 * connection so that we can reply to it.
813 evcon->state = EVCON_WRITING;
816 /* notify the user of the request */
817 (*req->cb)(req, req->cb_arg);
819 /* if this was an outgoing request, we own and it's done. so free it.
820 * unless the callback specifically requested to own the request.
822 if (con_outgoing && ((req->flags & EVHTTP_USER_OWNED) == 0)) {
823 evhttp_request_free(req);
828 * Handles reading from a chunked request.
829 * return ALL_DATA_READ:
830 * all data has been read
831 * return MORE_DATA_EXPECTED:
832 * more data is expected
833 * return DATA_CORRUPTED:
834 * data is corrupted
835 * return REQUEST_CANCELED:
836 * request was canceled by the user calling evhttp_cancel_request
837 * return DATA_TOO_LONG:
838 * ran over the maximum limit
841 static enum message_read_status
842 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
844 if (req == NULL || buf == NULL) {
845 return DATA_CORRUPTED;
848 while (1) {
849 size_t buflen;
851 if ((buflen = evbuffer_get_length(buf)) == 0) {
852 break;
855 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
856 * check for overflow conditions */
857 if (buflen > EV_SSIZE_MAX) {
858 return DATA_CORRUPTED;
861 if (req->ntoread < 0) {
862 /* Read chunk size */
863 ev_int64_t ntoread;
864 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
865 char *endp;
866 int error;
867 if (p == NULL)
868 break;
869 /* the last chunk is on a new line? */
870 if (strlen(p) == 0) {
871 mm_free(p);
872 continue;
874 ntoread = evutil_strtoll(p, &endp, 16);
875 error = (*p == '\0' ||
876 (*endp != '\0' && *endp != ' ') ||
877 ntoread < 0);
878 mm_free(p);
879 if (error) {
880 /* could not get chunk size */
881 return (DATA_CORRUPTED);
884 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
885 if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
886 return DATA_CORRUPTED;
889 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
890 /* failed body length test */
891 event_debug(("Request body is too long"));
892 return (DATA_TOO_LONG);
895 req->body_size += (size_t)ntoread;
896 req->ntoread = ntoread;
897 if (req->ntoread == 0) {
898 /* Last chunk */
899 return (ALL_DATA_READ);
901 continue;
904 /* req->ntoread is signed int64, len is ssize_t, based on arch,
905 * ssize_t could only be 32b, check for these conditions */
906 if (req->ntoread > EV_SSIZE_MAX) {
907 return DATA_CORRUPTED;
910 /* don't have enough to complete a chunk; wait for more */
911 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
912 return (MORE_DATA_EXPECTED);
914 /* Completed chunk */
915 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
916 req->ntoread = -1;
917 if (req->chunk_cb != NULL) {
918 req->flags |= EVHTTP_REQ_DEFER_FREE;
919 (*req->chunk_cb)(req, req->cb_arg);
920 evbuffer_drain(req->input_buffer,
921 evbuffer_get_length(req->input_buffer));
922 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
923 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
924 return (REQUEST_CANCELED);
929 return (MORE_DATA_EXPECTED);
932 static void
933 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
935 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
937 switch (evhttp_parse_headers(req, buf)) {
938 case DATA_CORRUPTED:
939 case DATA_TOO_LONG:
940 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
941 break;
942 case ALL_DATA_READ:
943 bufferevent_disable(evcon->bufev, EV_READ);
944 evhttp_connection_done(evcon);
945 break;
946 case MORE_DATA_EXPECTED:
947 case REQUEST_CANCELED: /* ??? */
948 default:
949 bufferevent_enable(evcon->bufev, EV_READ);
950 break;
954 static void
955 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
957 struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
959 if (req->chunked) {
960 switch (evhttp_handle_chunked_read(req, buf)) {
961 case ALL_DATA_READ:
962 /* finished last chunk */
963 evcon->state = EVCON_READING_TRAILER;
964 evhttp_read_trailer(evcon, req);
965 return;
966 case DATA_CORRUPTED:
967 case DATA_TOO_LONG:/*separate error for this? XXX */
968 /* corrupted data */
969 evhttp_connection_fail(evcon,
970 EVCON_HTTP_INVALID_HEADER);
971 return;
972 case REQUEST_CANCELED:
973 /* request canceled */
974 evhttp_request_free(req);
975 return;
976 case MORE_DATA_EXPECTED:
977 default:
978 break;
980 } else if (req->ntoread < 0) {
981 /* Read until connection close. */
982 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
983 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
984 return;
987 req->body_size += evbuffer_get_length(buf);
988 evbuffer_add_buffer(req->input_buffer, buf);
989 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
990 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
991 /* We've postponed moving the data until now, but we're
992 * about to use it. */
993 size_t n = evbuffer_get_length(buf);
995 if (n > (size_t) req->ntoread)
996 n = (size_t) req->ntoread;
997 req->ntoread -= n;
998 req->body_size += n;
999 evbuffer_remove_buffer(buf, req->input_buffer, n);
1002 if (req->body_size > req->evcon->max_body_size ||
1003 (!req->chunked && req->ntoread >= 0 &&
1004 (size_t)req->ntoread > req->evcon->max_body_size)) {
1005 /* XXX: The above casted comparison must checked for overflow */
1006 /* failed body length test */
1007 event_debug(("Request body is too long"));
1008 evhttp_connection_fail(evcon,
1009 EVCON_HTTP_INVALID_HEADER);
1010 return;
1013 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1014 req->flags |= EVHTTP_REQ_DEFER_FREE;
1015 (*req->chunk_cb)(req, req->cb_arg);
1016 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1017 evbuffer_drain(req->input_buffer,
1018 evbuffer_get_length(req->input_buffer));
1019 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1020 evhttp_request_free(req);
1021 return;
1025 if (req->ntoread == 0) {
1026 bufferevent_disable(evcon->bufev, EV_READ);
1027 /* Completed content length */
1028 evhttp_connection_done(evcon);
1029 return;
1032 /* Read more! */
1033 bufferevent_enable(evcon->bufev, EV_READ);
1036 #define get_deferred_queue(evcon) \
1037 (event_base_get_deferred_cb_queue((evcon)->base))
1040 * Gets called when more data becomes available
1043 static void
1044 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1046 struct evhttp_connection *evcon = arg;
1047 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1049 /* Cancel if it's pending. */
1050 event_deferred_cb_cancel(get_deferred_queue(evcon),
1051 &evcon->read_more_deferred_cb);
1053 switch (evcon->state) {
1054 case EVCON_READING_FIRSTLINE:
1055 evhttp_read_firstline(evcon, req);
1056 /* note the request may have been freed in
1057 * evhttp_read_body */
1058 break;
1059 case EVCON_READING_HEADERS:
1060 evhttp_read_header(evcon, req);
1061 /* note the request may have been freed in
1062 * evhttp_read_body */
1063 break;
1064 case EVCON_READING_BODY:
1065 evhttp_read_body(evcon, req);
1066 /* note the request may have been freed in
1067 * evhttp_read_body */
1068 break;
1069 case EVCON_READING_TRAILER:
1070 evhttp_read_trailer(evcon, req);
1071 break;
1072 case EVCON_IDLE:
1074 #ifdef USE_DEBUG
1075 struct evbuffer *input;
1076 size_t total_len;
1078 input = bufferevent_get_input(evcon->bufev);
1079 total_len = evbuffer_get_length(input);
1080 event_debug(("%s: read "EV_SIZE_FMT
1081 " bytes in EVCON_IDLE state,"
1082 " resetting connection",
1083 __func__, EV_SIZE_ARG(total_len)));
1084 #endif
1086 evhttp_connection_reset(evcon);
1088 break;
1089 case EVCON_DISCONNECTED:
1090 case EVCON_CONNECTING:
1091 case EVCON_WRITING:
1092 default:
1093 event_errx(1, "%s: illegal connection state %d",
1094 __func__, evcon->state);
1098 static void
1099 evhttp_deferred_read_cb(struct deferred_cb *cb, void *data)
1101 struct evhttp_connection *evcon = data;
1102 evhttp_read_cb(evcon->bufev, evcon);
1105 static void
1106 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1108 /* This is after writing the request to the server */
1109 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1110 EVUTIL_ASSERT(req != NULL);
1112 EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1114 /* We are done writing our header and are now expecting the response */
1115 req->kind = EVHTTP_RESPONSE;
1117 evhttp_start_read(evcon);
1121 * Clean up a connection object
1124 void
1125 evhttp_connection_free(struct evhttp_connection *evcon)
1127 struct evhttp_request *req;
1129 /* notify interested parties that this connection is going down */
1130 if (evcon->fd != -1) {
1131 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1132 (*evcon->closecb)(evcon, evcon->closecb_arg);
1135 /* remove all requests that might be queued on this
1136 * connection. for server connections, this should be empty.
1137 * because it gets dequeued either in evhttp_connection_done or
1138 * evhttp_connection_fail.
1140 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1141 TAILQ_REMOVE(&evcon->requests, req, next);
1142 evhttp_request_free(req);
1145 if (evcon->http_server != NULL) {
1146 struct evhttp *http = evcon->http_server;
1147 TAILQ_REMOVE(&http->connections, evcon, next);
1150 if (event_initialized(&evcon->retry_ev)) {
1151 event_del(&evcon->retry_ev);
1152 event_debug_unassign(&evcon->retry_ev);
1155 if (evcon->bufev != NULL)
1156 bufferevent_free(evcon->bufev);
1158 event_deferred_cb_cancel(get_deferred_queue(evcon),
1159 &evcon->read_more_deferred_cb);
1161 if (evcon->fd != -1) {
1162 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1163 evutil_closesocket(evcon->fd);
1166 if (evcon->bind_address != NULL)
1167 mm_free(evcon->bind_address);
1169 if (evcon->address != NULL)
1170 mm_free(evcon->address);
1172 mm_free(evcon);
1175 void
1176 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1177 const char *address)
1179 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1180 if (evcon->bind_address)
1181 mm_free(evcon->bind_address);
1182 if ((evcon->bind_address = mm_strdup(address)) == NULL)
1183 event_warn("%s: strdup", __func__);
1186 void
1187 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1188 ev_uint16_t port)
1190 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1191 evcon->bind_port = port;
1194 static void
1195 evhttp_request_dispatch(struct evhttp_connection* evcon)
1197 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1199 /* this should not usually happy but it's possible */
1200 if (req == NULL)
1201 return;
1203 /* delete possible close detection events */
1204 evhttp_connection_stop_detectclose(evcon);
1206 /* we assume that the connection is connected already */
1207 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1209 evcon->state = EVCON_WRITING;
1211 /* Create the header from the store arguments */
1212 evhttp_make_header(evcon, req);
1214 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1217 /* Reset our connection state: disables reading/writing, closes our fd (if
1218 * any), clears out buffers, and puts us in state DISCONNECTED. */
1219 void
1220 evhttp_connection_reset(struct evhttp_connection *evcon)
1222 struct evbuffer *tmp;
1224 /* XXXX This is not actually an optimal fix. Instead we ought to have
1225 an API for "stop connecting", or use bufferevent_setfd to turn off
1226 connecting. But for Libevent 2.0, this seems like a minimal change
1227 least likely to disrupt the rest of the bufferevent and http code.
1229 Why is this here? If the fd is set in the bufferevent, and the
1230 bufferevent is connecting, then you can't actually stop the
1231 bufferevent from trying to connect with bufferevent_disable(). The
1232 connect will never trigger, since we close the fd, but the timeout
1233 might. That caused an assertion failure in evhttp_connection_fail.
1235 bufferevent_disable_hard(evcon->bufev, EV_READ|EV_WRITE);
1237 if (evcon->fd != -1) {
1238 /* inform interested parties about connection close */
1239 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1240 (*evcon->closecb)(evcon, evcon->closecb_arg);
1242 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1243 evutil_closesocket(evcon->fd);
1244 evcon->fd = -1;
1247 /* we need to clean up any buffered data */
1248 tmp = bufferevent_get_output(evcon->bufev);
1249 evbuffer_drain(tmp, evbuffer_get_length(tmp));
1250 tmp = bufferevent_get_input(evcon->bufev);
1251 evbuffer_drain(tmp, evbuffer_get_length(tmp));
1253 evcon->state = EVCON_DISCONNECTED;
1256 static void
1257 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1259 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1261 bufferevent_enable(evcon->bufev, EV_READ);
1264 static void
1265 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1267 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1269 bufferevent_disable(evcon->bufev, EV_READ);
1272 static void
1273 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1275 struct evhttp_connection *evcon = arg;
1277 evcon->state = EVCON_DISCONNECTED;
1278 evhttp_connection_connect(evcon);
1281 static void
1282 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1284 struct evcon_requestq requests;
1286 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1287 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1288 /* XXXX handle failure from evhttp_add_event */
1289 evhttp_add_event(&evcon->retry_ev,
1290 MIN(3600, 2 << evcon->retry_cnt),
1291 HTTP_CONNECT_TIMEOUT);
1292 evcon->retry_cnt++;
1293 return;
1295 evhttp_connection_reset(evcon);
1298 * User callback can do evhttp_make_request() on the same
1299 * evcon so new request will be added to evcon->requests. To
1300 * avoid freeing it prematurely we iterate over the copy of
1301 * the queue.
1303 TAILQ_INIT(&requests);
1304 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1305 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1306 TAILQ_REMOVE(&evcon->requests, request, next);
1307 TAILQ_INSERT_TAIL(&requests, request, next);
1310 /* for now, we just signal all requests by executing their callbacks */
1311 while (TAILQ_FIRST(&requests) != NULL) {
1312 struct evhttp_request *request = TAILQ_FIRST(&requests);
1313 TAILQ_REMOVE(&requests, request, next);
1314 request->evcon = NULL;
1316 /* we might want to set an error here */
1317 request->cb(request, request->cb_arg);
1318 evhttp_request_free(request);
1322 static void
1323 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1325 struct evhttp_connection *evcon = arg;
1326 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1328 switch (evcon->state) {
1329 case EVCON_CONNECTING:
1330 if (what & BEV_EVENT_TIMEOUT) {
1331 event_debug(("%s: connection timeout for \"%s:%d\" on "
1332 EV_SOCK_FMT,
1333 __func__, evcon->address, evcon->port,
1334 EV_SOCK_ARG(evcon->fd)));
1335 evhttp_connection_cb_cleanup(evcon);
1336 return;
1338 break;
1340 case EVCON_READING_BODY:
1341 if (!req->chunked && req->ntoread < 0
1342 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1343 /* EOF on read can be benign */
1344 evhttp_connection_done(evcon);
1345 return;
1347 break;
1349 case EVCON_DISCONNECTED:
1350 case EVCON_IDLE:
1351 case EVCON_READING_FIRSTLINE:
1352 case EVCON_READING_HEADERS:
1353 case EVCON_READING_TRAILER:
1354 case EVCON_WRITING:
1355 default:
1356 break;
1359 /* when we are in close detect mode, a read error means that
1360 * the other side closed their connection.
1362 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1363 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1364 EVUTIL_ASSERT(evcon->http_server == NULL);
1365 /* For connections from the client, we just
1366 * reset the connection so that it becomes
1367 * disconnected.
1369 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1370 evhttp_connection_reset(evcon);
1371 return;
1374 if (what & BEV_EVENT_TIMEOUT) {
1375 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
1376 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1377 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
1378 } else {
1379 evhttp_connection_fail(evcon, EVCON_HTTP_BUFFER_ERROR);
1384 * Event callback for asynchronous connection attempt.
1386 static void
1387 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1389 struct evhttp_connection *evcon = arg;
1390 int error;
1391 ev_socklen_t errsz = sizeof(error);
1393 if (!(what & BEV_EVENT_CONNECTED)) {
1394 /* some operating systems return ECONNREFUSED immediately
1395 * when connecting to a local address. the cleanup is going
1396 * to reschedule this function call.
1398 #ifndef WIN32
1399 if (errno == ECONNREFUSED)
1400 goto cleanup;
1401 #endif
1402 evhttp_error_cb(bufev, what, arg);
1403 return;
1406 /* Check if the connection completed */
1407 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1408 &errsz) == -1) {
1409 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT,
1410 __func__, evcon->address, evcon->port,
1411 EV_SOCK_ARG(evcon->fd)));
1412 goto cleanup;
1415 if (error) {
1416 event_debug(("%s: connect failed for \"%s:%d\" on "
1417 EV_SOCK_FMT": %s",
1418 __func__, evcon->address, evcon->port,
1419 EV_SOCK_ARG(evcon->fd),
1420 evutil_socket_error_to_string(error)));
1421 goto cleanup;
1424 /* We are connected to the server now */
1425 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n",
1426 __func__, evcon->address, evcon->port,
1427 EV_SOCK_ARG(evcon->fd)));
1429 /* Reset the retry count as we were successful in connecting */
1430 evcon->retry_cnt = 0;
1431 evcon->state = EVCON_IDLE;
1433 /* reset the bufferevent cbs */
1434 bufferevent_setcb(evcon->bufev,
1435 evhttp_read_cb,
1436 evhttp_write_cb,
1437 evhttp_error_cb,
1438 evcon);
1440 if (evcon->timeout == -1)
1441 bufferevent_settimeout(evcon->bufev,
1442 HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
1443 else {
1444 struct timeval tv;
1445 tv.tv_sec = evcon->timeout;
1446 tv.tv_usec = 0;
1447 bufferevent_set_timeouts(evcon->bufev, &tv, &tv);
1450 /* try to start requests that have queued up on this connection */
1451 evhttp_request_dispatch(evcon);
1452 return;
1454 cleanup:
1455 evhttp_connection_cb_cleanup(evcon);
1459 * Check if we got a valid response code.
1462 static int
1463 evhttp_valid_response_code(int code)
1465 if (code == 0)
1466 return (0);
1468 return (1);
1471 static int
1472 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1474 int major, minor;
1475 char ch;
1476 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1477 if (n != 2 || major > 1) {
1478 event_debug(("%s: bad version %s on message %p from %s",
1479 __func__, version, req, req->remote_host));
1480 return (-1);
1482 req->major = major;
1483 req->minor = minor;
1484 return (0);
1487 /* Parses the status line of a web server */
1489 static int
1490 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1492 char *protocol;
1493 char *number;
1494 const char *readable = "";
1496 protocol = strsep(&line, " ");
1497 if (line == NULL)
1498 return (-1);
1499 number = strsep(&line, " ");
1500 if (line != NULL)
1501 readable = line;
1503 if (evhttp_parse_http_version(protocol, req) < 0)
1504 return (-1);
1506 req->response_code = atoi(number);
1507 if (!evhttp_valid_response_code(req->response_code)) {
1508 event_debug(("%s: bad response code \"%s\"",
1509 __func__, number));
1510 return (-1);
1513 if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1514 event_warn("%s: strdup", __func__);
1515 return (-1);
1518 return (0);
1521 /* Parse the first line of a HTTP request */
1523 static int
1524 evhttp_parse_request_line(struct evhttp_request *req, char *line)
1526 char *method;
1527 char *uri;
1528 char *version;
1529 const char *hostname;
1530 const char *scheme;
1532 /* Parse the request line */
1533 method = strsep(&line, " ");
1534 if (line == NULL)
1535 return (-1);
1536 uri = strsep(&line, " ");
1537 if (line == NULL)
1538 return (-1);
1539 version = strsep(&line, " ");
1540 if (line != NULL)
1541 return (-1);
1543 /* First line */
1544 if (strcmp(method, "GET") == 0) {
1545 req->type = EVHTTP_REQ_GET;
1546 } else if (strcmp(method, "POST") == 0) {
1547 req->type = EVHTTP_REQ_POST;
1548 } else if (strcmp(method, "HEAD") == 0) {
1549 req->type = EVHTTP_REQ_HEAD;
1550 } else if (strcmp(method, "PUT") == 0) {
1551 req->type = EVHTTP_REQ_PUT;
1552 } else if (strcmp(method, "DELETE") == 0) {
1553 req->type = EVHTTP_REQ_DELETE;
1554 } else if (strcmp(method, "OPTIONS") == 0) {
1555 req->type = EVHTTP_REQ_OPTIONS;
1556 } else if (strcmp(method, "TRACE") == 0) {
1557 req->type = EVHTTP_REQ_TRACE;
1558 } else if (strcmp(method, "PATCH") == 0) {
1559 req->type = EVHTTP_REQ_PATCH;
1560 } else {
1561 req->type = _EVHTTP_REQ_UNKNOWN;
1562 event_debug(("%s: bad method %s on request %p from %s",
1563 __func__, method, req, req->remote_host));
1564 /* No error yet; we'll give a better error later when
1565 * we see that req->type is unsupported. */
1568 if (evhttp_parse_http_version(version, req) < 0)
1569 return (-1);
1571 if ((req->uri = mm_strdup(uri)) == NULL) {
1572 event_debug(("%s: mm_strdup", __func__));
1573 return (-1);
1576 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
1577 EVHTTP_URI_NONCONFORMANT)) == NULL) {
1578 return -1;
1581 /* If we have an absolute-URI, check to see if it is an http request
1582 for a known vhost or server alias. If we don't know about this
1583 host, we consider it a proxy request. */
1584 scheme = evhttp_uri_get_scheme(req->uri_elems);
1585 hostname = evhttp_uri_get_host(req->uri_elems);
1586 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1587 !evutil_ascii_strcasecmp(scheme, "https")) &&
1588 hostname &&
1589 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1590 req->flags |= EVHTTP_PROXY_REQUEST;
1592 return (0);
1595 const char *
1596 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1598 struct evkeyval *header;
1600 TAILQ_FOREACH(header, headers, next) {
1601 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1602 return (header->value);
1605 return (NULL);
1608 void
1609 evhttp_clear_headers(struct evkeyvalq *headers)
1611 struct evkeyval *header;
1613 for (header = TAILQ_FIRST(headers);
1614 header != NULL;
1615 header = TAILQ_FIRST(headers)) {
1616 TAILQ_REMOVE(headers, header, next);
1617 mm_free(header->key);
1618 mm_free(header->value);
1619 mm_free(header);
1624 * Returns 0, if the header was successfully removed.
1625 * Returns -1, if the header could not be found.
1629 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1631 struct evkeyval *header;
1633 TAILQ_FOREACH(header, headers, next) {
1634 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1635 break;
1638 if (header == NULL)
1639 return (-1);
1641 /* Free and remove the header that we found */
1642 TAILQ_REMOVE(headers, header, next);
1643 mm_free(header->key);
1644 mm_free(header->value);
1645 mm_free(header);
1647 return (0);
1650 static int
1651 evhttp_header_is_valid_value(const char *value)
1653 const char *p = value;
1655 while ((p = strpbrk(p, "\r\n")) != NULL) {
1656 /* we really expect only one new line */
1657 p += strspn(p, "\r\n");
1658 /* we expect a space or tab for continuation */
1659 if (*p != ' ' && *p != '\t')
1660 return (0);
1662 return (1);
1666 evhttp_add_header(struct evkeyvalq *headers,
1667 const char *key, const char *value)
1669 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1671 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1672 /* drop illegal headers */
1673 event_debug(("%s: dropping illegal header key\n", __func__));
1674 return (-1);
1677 if (!evhttp_header_is_valid_value(value)) {
1678 event_debug(("%s: dropping illegal header value\n", __func__));
1679 return (-1);
1682 return (evhttp_add_header_internal(headers, key, value));
1685 static int
1686 evhttp_add_header_internal(struct evkeyvalq *headers,
1687 const char *key, const char *value)
1689 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
1690 if (header == NULL) {
1691 event_warn("%s: calloc", __func__);
1692 return (-1);
1694 if ((header->key = mm_strdup(key)) == NULL) {
1695 mm_free(header);
1696 event_warn("%s: strdup", __func__);
1697 return (-1);
1699 if ((header->value = mm_strdup(value)) == NULL) {
1700 mm_free(header->key);
1701 mm_free(header);
1702 event_warn("%s: strdup", __func__);
1703 return (-1);
1706 TAILQ_INSERT_TAIL(headers, header, next);
1708 return (0);
1712 * Parses header lines from a request or a response into the specified
1713 * request object given an event buffer.
1715 * Returns
1716 * DATA_CORRUPTED on error
1717 * MORE_DATA_EXPECTED when we need to read more headers
1718 * ALL_DATA_READ when all headers have been read.
1721 enum message_read_status
1722 evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
1724 char *line;
1725 enum message_read_status status = ALL_DATA_READ;
1727 size_t line_length;
1728 /* XXX try */
1729 line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF);
1730 if (line == NULL) {
1731 if (req->evcon != NULL &&
1732 evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1733 return (DATA_TOO_LONG);
1734 else
1735 return (MORE_DATA_EXPECTED);
1738 if (req->evcon != NULL &&
1739 line_length > req->evcon->max_headers_size) {
1740 mm_free(line);
1741 return (DATA_TOO_LONG);
1744 req->headers_size = line_length;
1746 switch (req->kind) {
1747 case EVHTTP_REQUEST:
1748 if (evhttp_parse_request_line(req, line) == -1)
1749 status = DATA_CORRUPTED;
1750 break;
1751 case EVHTTP_RESPONSE:
1752 if (evhttp_parse_response_line(req, line) == -1)
1753 status = DATA_CORRUPTED;
1754 break;
1755 default:
1756 status = DATA_CORRUPTED;
1759 mm_free(line);
1760 return (status);
1763 static int
1764 evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
1766 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
1767 char *newval;
1768 size_t old_len, line_len;
1770 if (header == NULL)
1771 return (-1);
1773 old_len = strlen(header->value);
1774 line_len = strlen(line);
1776 newval = mm_realloc(header->value, old_len + line_len + 1);
1777 if (newval == NULL)
1778 return (-1);
1780 memcpy(newval + old_len, line, line_len + 1);
1781 header->value = newval;
1783 return (0);
1786 enum message_read_status
1787 evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
1789 enum message_read_status errcode = DATA_CORRUPTED;
1790 char *line;
1791 enum message_read_status status = MORE_DATA_EXPECTED;
1793 struct evkeyvalq* headers = req->input_headers;
1794 size_t line_length;
1795 while ((line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF))
1796 != NULL) {
1797 char *skey, *svalue;
1799 req->headers_size += line_length;
1801 if (req->evcon != NULL &&
1802 req->headers_size > req->evcon->max_headers_size) {
1803 errcode = DATA_TOO_LONG;
1804 goto error;
1807 if (*line == '\0') { /* Last header - Done */
1808 status = ALL_DATA_READ;
1809 mm_free(line);
1810 break;
1813 /* Check if this is a continuation line */
1814 if (*line == ' ' || *line == '\t') {
1815 if (evhttp_append_to_last_header(headers, line) == -1)
1816 goto error;
1817 mm_free(line);
1818 continue;
1821 /* Processing of header lines */
1822 svalue = line;
1823 skey = strsep(&svalue, ":");
1824 if (svalue == NULL)
1825 goto error;
1827 svalue += strspn(svalue, " ");
1829 if (evhttp_add_header(headers, skey, svalue) == -1)
1830 goto error;
1832 mm_free(line);
1835 if (status == MORE_DATA_EXPECTED) {
1836 if (req->evcon != NULL &&
1837 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1838 return (DATA_TOO_LONG);
1841 return (status);
1843 error:
1844 mm_free(line);
1845 return (errcode);
1848 static int
1849 evhttp_get_body_length(struct evhttp_request *req)
1851 struct evkeyvalq *headers = req->input_headers;
1852 const char *content_length;
1853 const char *connection;
1855 content_length = evhttp_find_header(headers, "Content-Length");
1856 connection = evhttp_find_header(headers, "Connection");
1858 if (content_length == NULL && connection == NULL)
1859 req->ntoread = -1;
1860 else if (content_length == NULL &&
1861 evutil_ascii_strcasecmp(connection, "Close") != 0) {
1862 /* Bad combination, we don't know when it will end */
1863 event_warnx("%s: we got no content length, but the "
1864 "server wants to keep the connection open: %s.",
1865 __func__, connection);
1866 return (-1);
1867 } else if (content_length == NULL) {
1868 req->ntoread = -1;
1869 } else {
1870 char *endp;
1871 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
1872 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
1873 event_debug(("%s: illegal content length: %s",
1874 __func__, content_length));
1875 return (-1);
1877 req->ntoread = ntoread;
1880 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n",
1881 __func__, EV_I64_ARG(req->ntoread),
1882 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev)))));
1884 return (0);
1887 static int
1888 evhttp_method_may_have_body(enum evhttp_cmd_type type)
1890 switch (type) {
1891 case EVHTTP_REQ_POST:
1892 case EVHTTP_REQ_PUT:
1893 case EVHTTP_REQ_PATCH:
1894 return 1;
1895 case EVHTTP_REQ_TRACE:
1896 return 0;
1897 /* XXX May any of the below methods have a body? */
1898 case EVHTTP_REQ_GET:
1899 case EVHTTP_REQ_HEAD:
1900 case EVHTTP_REQ_DELETE:
1901 case EVHTTP_REQ_OPTIONS:
1902 case EVHTTP_REQ_CONNECT:
1903 return 0;
1904 default:
1905 return 0;
1909 static void
1910 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1912 const char *xfer_enc;
1914 /* If this is a request without a body, then we are done */
1915 if (req->kind == EVHTTP_REQUEST &&
1916 !evhttp_method_may_have_body(req->type)) {
1917 evhttp_connection_done(evcon);
1918 return;
1920 evcon->state = EVCON_READING_BODY;
1921 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
1922 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
1923 req->chunked = 1;
1924 req->ntoread = -1;
1925 } else {
1926 if (evhttp_get_body_length(req) == -1) {
1927 evhttp_connection_fail(evcon,
1928 EVCON_HTTP_INVALID_HEADER);
1929 return;
1931 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
1932 /* An incoming request with no content-length and no
1933 * transfer-encoding has no body. */
1934 evhttp_connection_done(evcon);
1935 return;
1939 /* Should we send a 100 Continue status line? */
1940 if (req->kind == EVHTTP_REQUEST && REQ_VERSION_ATLEAST(req, 1, 1)) {
1941 const char *expect;
1943 expect = evhttp_find_header(req->input_headers, "Expect");
1944 if (expect) {
1945 if (!evutil_ascii_strcasecmp(expect, "100-continue")) {
1946 /* XXX It would be nice to do some sanity
1947 checking here. Does the resource exist?
1948 Should the resource accept post requests? If
1949 no, we should respond with an error. For
1950 now, just optimistically tell the client to
1951 send their message body. */
1952 if (req->ntoread > 0) {
1953 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
1954 if ((req->evcon->max_body_size <= EV_INT64_MAX) && (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
1955 evhttp_send_error(req, HTTP_ENTITYTOOLARGE, NULL);
1956 return;
1959 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
1960 evhttp_send_continue(evcon, req);
1961 } else {
1962 evhttp_send_error(req, HTTP_EXPECTATIONFAILED,
1963 NULL);
1964 return;
1969 evhttp_read_body(evcon, req);
1970 /* note the request may have been freed in evhttp_read_body */
1973 static void
1974 evhttp_read_firstline(struct evhttp_connection *evcon,
1975 struct evhttp_request *req)
1977 enum message_read_status res;
1979 res = evhttp_parse_firstline(req, bufferevent_get_input(evcon->bufev));
1980 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
1981 /* Error while reading, terminate */
1982 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
1983 __func__, EV_SOCK_ARG(evcon->fd)));
1984 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1985 return;
1986 } else if (res == MORE_DATA_EXPECTED) {
1987 /* Need more header lines */
1988 return;
1991 evcon->state = EVCON_READING_HEADERS;
1992 evhttp_read_header(evcon, req);
1995 static void
1996 evhttp_read_header(struct evhttp_connection *evcon,
1997 struct evhttp_request *req)
1999 enum message_read_status res;
2000 evutil_socket_t fd = evcon->fd;
2002 res = evhttp_parse_headers(req, bufferevent_get_input(evcon->bufev));
2003 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
2004 /* Error while reading, terminate */
2005 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n",
2006 __func__, EV_SOCK_ARG(fd)));
2007 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
2008 return;
2009 } else if (res == MORE_DATA_EXPECTED) {
2010 /* Need more header lines */
2011 return;
2014 /* Disable reading for now */
2015 bufferevent_disable(evcon->bufev, EV_READ);
2017 /* Done reading headers, do the real work */
2018 switch (req->kind) {
2019 case EVHTTP_REQUEST:
2020 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n",
2021 __func__, EV_SOCK_ARG(fd)));
2022 evhttp_get_body(evcon, req);
2023 /* note the request may have been freed in evhttp_get_body */
2024 break;
2026 case EVHTTP_RESPONSE:
2027 /* Start over if we got a 100 Continue response. */
2028 if (req->response_code == 100) {
2029 evhttp_start_read(evcon);
2030 return;
2032 if (!evhttp_response_needs_body(req)) {
2033 event_debug(("%s: skipping body for code %d\n",
2034 __func__, req->response_code));
2035 evhttp_connection_done(evcon);
2036 } else {
2037 event_debug(("%s: start of read body for %s on "
2038 EV_SOCK_FMT"\n",
2039 __func__, req->remote_host, EV_SOCK_ARG(fd)));
2040 evhttp_get_body(evcon, req);
2041 /* note the request may have been freed in
2042 * evhttp_get_body */
2044 break;
2046 default:
2047 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__,
2048 EV_SOCK_ARG(fd));
2049 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
2050 break;
2052 /* request may have been freed above */
2056 * Creates a TCP connection to the specified port and executes a callback
2057 * when finished. Failure or success is indicate by the passed connection
2058 * object.
2060 * Although this interface accepts a hostname, it is intended to take
2061 * only numeric hostnames so that non-blocking DNS resolution can
2062 * happen elsewhere.
2065 struct evhttp_connection *
2066 evhttp_connection_new(const char *address, unsigned short port)
2068 return (evhttp_connection_base_new(NULL, NULL, address, port));
2071 struct evhttp_connection *
2072 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2073 const char *address, unsigned short port)
2075 struct evhttp_connection *evcon = NULL;
2077 event_debug(("Attempting connection to %s:%d\n", address, port));
2079 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2080 event_warn("%s: calloc failed", __func__);
2081 goto error;
2084 evcon->fd = -1;
2085 evcon->port = port;
2087 evcon->max_headers_size = EV_SIZE_MAX;
2088 evcon->max_body_size = EV_SIZE_MAX;
2090 evcon->timeout = -1;
2091 evcon->retry_cnt = evcon->retry_max = 0;
2093 if ((evcon->address = mm_strdup(address)) == NULL) {
2094 event_warn("%s: strdup failed", __func__);
2095 goto error;
2098 if ((evcon->bufev = bufferevent_new(-1,
2099 evhttp_read_cb,
2100 evhttp_write_cb,
2101 evhttp_error_cb, evcon)) == NULL) {
2102 event_warn("%s: bufferevent_new failed", __func__);
2103 goto error;
2106 evcon->state = EVCON_DISCONNECTED;
2107 TAILQ_INIT(&evcon->requests);
2109 if (base != NULL) {
2110 evcon->base = base;
2111 bufferevent_base_set(base, evcon->bufev);
2115 event_deferred_cb_init(&evcon->read_more_deferred_cb,
2116 evhttp_deferred_read_cb, evcon);
2118 evcon->dns_base = dnsbase;
2120 return (evcon);
2122 error:
2123 if (evcon != NULL)
2124 evhttp_connection_free(evcon);
2125 return (NULL);
2128 struct bufferevent *
2129 evhttp_connection_get_bufferevent(struct evhttp_connection *evcon)
2131 return evcon->bufev;
2134 void
2135 evhttp_connection_set_base(struct evhttp_connection *evcon,
2136 struct event_base *base)
2138 EVUTIL_ASSERT(evcon->base == NULL);
2139 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2140 evcon->base = base;
2141 bufferevent_base_set(base, evcon->bufev);
2144 void
2145 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2146 int timeout_in_secs)
2148 evcon->timeout = timeout_in_secs;
2150 if (evcon->timeout == -1)
2151 bufferevent_settimeout(evcon->bufev,
2152 HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
2153 else
2154 bufferevent_settimeout(evcon->bufev,
2155 evcon->timeout, evcon->timeout);
2158 void
2159 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2160 int retry_max)
2162 evcon->retry_max = retry_max;
2165 void
2166 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2167 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2169 evcon->closecb = cb;
2170 evcon->closecb_arg = cbarg;
2173 void
2174 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2175 char **address, ev_uint16_t *port)
2177 *address = evcon->address;
2178 *port = evcon->port;
2182 evhttp_connection_connect(struct evhttp_connection *evcon)
2184 if (evcon->state == EVCON_CONNECTING)
2185 return (0);
2187 evhttp_connection_reset(evcon);
2189 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2190 evcon->flags |= EVHTTP_CON_OUTGOING;
2192 evcon->fd = bind_socket(
2193 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2194 if (evcon->fd == -1) {
2195 event_debug(("%s: failed to bind to \"%s\"",
2196 __func__, evcon->bind_address));
2197 return (-1);
2200 /* Set up a callback for successful connection setup */
2201 bufferevent_setfd(evcon->bufev, evcon->fd);
2202 bufferevent_setcb(evcon->bufev,
2203 NULL /* evhttp_read_cb */,
2204 NULL /* evhttp_write_cb */,
2205 evhttp_connection_cb,
2206 evcon);
2207 bufferevent_settimeout(evcon->bufev, 0,
2208 evcon->timeout != -1 ? evcon->timeout : HTTP_CONNECT_TIMEOUT);
2209 /* make sure that we get a write callback */
2210 bufferevent_enable(evcon->bufev, EV_WRITE);
2212 if (bufferevent_socket_connect_hostname(evcon->bufev, evcon->dns_base,
2213 AF_UNSPEC, evcon->address, evcon->port) < 0) {
2214 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2215 __func__, evcon->address);
2216 /* some operating systems return ECONNREFUSED immediately
2217 * when connecting to a local address. the cleanup is going
2218 * to reschedule this function call.
2220 evhttp_connection_cb_cleanup(evcon);
2221 return (0);
2224 evcon->state = EVCON_CONNECTING;
2226 return (0);
2230 * Starts an HTTP request on the provided evhttp_connection object.
2231 * If the connection object is not connected to the web server already,
2232 * this will start the connection.
2236 evhttp_make_request(struct evhttp_connection *evcon,
2237 struct evhttp_request *req,
2238 enum evhttp_cmd_type type, const char *uri)
2240 /* We are making a request */
2241 req->kind = EVHTTP_REQUEST;
2242 req->type = type;
2243 if (req->uri != NULL)
2244 mm_free(req->uri);
2245 if ((req->uri = mm_strdup(uri)) == NULL) {
2246 event_warn("%s: strdup", __func__);
2247 evhttp_request_free(req);
2248 return (-1);
2251 /* Set the protocol version if it is not supplied */
2252 if (!req->major && !req->minor) {
2253 req->major = 1;
2254 req->minor = 1;
2257 EVUTIL_ASSERT(req->evcon == NULL);
2258 req->evcon = evcon;
2259 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2261 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2263 /* If the connection object is not connected; make it so */
2264 if (!evhttp_connected(evcon)) {
2265 int res = evhttp_connection_connect(evcon);
2266 /* evhttp_connection_fail(), which is called through
2267 * evhttp_connection_connect(), assumes that req lies in
2268 * evcon->requests. Thus, enqueue the request in advance and r
2269 * it in the error case. */
2270 if (res != 0)
2271 TAILQ_REMOVE(&evcon->requests, req, next);
2273 return res;
2277 * If it's connected already and we are the first in the queue,
2278 * then we can dispatch this request immediately. Otherwise, it
2279 * will be dispatched once the pending requests are completed.
2281 if (TAILQ_FIRST(&evcon->requests) == req)
2282 evhttp_request_dispatch(evcon);
2284 return (0);
2287 void
2288 evhttp_cancel_request(struct evhttp_request *req)
2290 struct evhttp_connection *evcon = req->evcon;
2291 if (evcon != NULL) {
2292 /* We need to remove it from the connection */
2293 if (TAILQ_FIRST(&evcon->requests) == req) {
2294 /* it's currently being worked on, so reset
2295 * the connection.
2297 evhttp_connection_fail(evcon,
2298 EVCON_HTTP_REQUEST_CANCEL);
2300 /* connection fail freed the request */
2301 return;
2302 } else {
2303 /* otherwise, we can just remove it from the
2304 * queue
2306 TAILQ_REMOVE(&evcon->requests, req, next);
2310 evhttp_request_free(req);
2314 * Reads data from file descriptor into request structure
2315 * Request structure needs to be set up correctly.
2318 void
2319 evhttp_start_read(struct evhttp_connection *evcon)
2321 /* Set up an event to read the headers */
2322 bufferevent_disable(evcon->bufev, EV_WRITE);
2323 bufferevent_enable(evcon->bufev, EV_READ);
2324 evcon->state = EVCON_READING_FIRSTLINE;
2325 /* Reset the bufferevent callbacks */
2326 bufferevent_setcb(evcon->bufev,
2327 evhttp_read_cb,
2328 evhttp_write_cb,
2329 evhttp_error_cb,
2330 evcon);
2332 /* If there's still data pending, process it next time through the
2333 * loop. Don't do it now; that could get recusive. */
2334 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2335 event_deferred_cb_schedule(get_deferred_queue(evcon),
2336 &evcon->read_more_deferred_cb);
2340 static void
2341 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2343 int need_close;
2344 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2345 TAILQ_REMOVE(&evcon->requests, req, next);
2347 need_close =
2348 (REQ_VERSION_BEFORE(req, 1, 1) &&
2349 !evhttp_is_connection_keepalive(req->input_headers))||
2350 evhttp_is_connection_close(req->flags, req->input_headers) ||
2351 evhttp_is_connection_close(req->flags, req->output_headers);
2353 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2354 evhttp_request_free(req);
2356 if (need_close) {
2357 evhttp_connection_free(evcon);
2358 return;
2361 /* we have a persistent connection; try to accept another request. */
2362 if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2363 evhttp_connection_free(evcon);
2368 * Returns an error page.
2371 void
2372 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2375 #define ERR_FORMAT "<HTML><HEAD>\n" \
2376 "<TITLE>%d %s</TITLE>\n" \
2377 "</HEAD><BODY>\n" \
2378 "<H1>%s</H1>\n" \
2379 "</BODY></HTML>\n"
2381 struct evbuffer *buf = evbuffer_new();
2382 if (buf == NULL) {
2383 /* if we cannot allocate memory; we just drop the connection */
2384 evhttp_connection_free(req->evcon);
2385 return;
2387 if (reason == NULL) {
2388 reason = evhttp_response_phrase_internal(error);
2391 evhttp_response_code(req, error, reason);
2393 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2395 evhttp_send_page(req, buf);
2397 evbuffer_free(buf);
2398 #undef ERR_FORMAT
2401 /* Requires that headers and response code are already set up */
2403 static inline void
2404 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2406 struct evhttp_connection *evcon = req->evcon;
2408 if (evcon == NULL) {
2409 evhttp_request_free(req);
2410 return;
2413 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2415 /* we expect no more calls form the user on this request */
2416 req->userdone = 1;
2418 /* xxx: not sure if we really should expose the data buffer this way */
2419 if (databuf != NULL)
2420 evbuffer_add_buffer(req->output_buffer, databuf);
2422 /* Adds headers to the response */
2423 evhttp_make_header(evcon, req);
2425 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2428 void
2429 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2430 struct evbuffer *databuf)
2432 evhttp_response_code(req, code, reason);
2434 evhttp_send(req, databuf);
2437 void
2438 evhttp_send_reply_start(struct evhttp_request *req, int code,
2439 const char *reason)
2441 evhttp_response_code(req, code, reason);
2442 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2443 REQ_VERSION_ATLEAST(req, 1, 1) &&
2444 evhttp_response_needs_body(req)) {
2446 * prefer HTTP/1.1 chunked encoding to closing the connection;
2447 * note RFC 2616 section 4.4 forbids it with Content-Length:
2448 * and it's not necessary then anyway.
2450 evhttp_add_header(req->output_headers, "Transfer-Encoding",
2451 "chunked");
2452 req->chunked = 1;
2453 } else {
2454 req->chunked = 0;
2456 evhttp_make_header(req->evcon, req);
2457 evhttp_write_buffer(req->evcon, NULL, NULL);
2460 void
2461 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
2463 struct evhttp_connection *evcon = req->evcon;
2464 struct evbuffer *output;
2466 if (evcon == NULL)
2467 return;
2469 output = bufferevent_get_output(evcon->bufev);
2471 if (evbuffer_get_length(databuf) == 0)
2472 return;
2473 if (!evhttp_response_needs_body(req))
2474 return;
2475 if (req->chunked) {
2476 evbuffer_add_printf(output, "%x\r\n",
2477 (unsigned)evbuffer_get_length(databuf));
2479 evbuffer_add_buffer(output, databuf);
2480 if (req->chunked) {
2481 evbuffer_add(output, "\r\n", 2);
2483 evhttp_write_buffer(evcon, NULL, NULL);
2486 void
2487 evhttp_send_reply_end(struct evhttp_request *req)
2489 struct evhttp_connection *evcon = req->evcon;
2490 struct evbuffer *output;
2492 if (evcon == NULL) {
2493 evhttp_request_free(req);
2494 return;
2497 output = bufferevent_get_output(evcon->bufev);
2499 /* we expect no more calls form the user on this request */
2500 req->userdone = 1;
2502 if (req->chunked) {
2503 evbuffer_add(output, "0\r\n\r\n", 5);
2504 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2505 req->chunked = 0;
2506 } else if (evbuffer_get_length(output) == 0) {
2507 /* let the connection know that we are done with the request */
2508 evhttp_send_done(evcon, NULL);
2509 } else {
2510 /* make the callback execute after all data has been written */
2511 evcon->cb = evhttp_send_done;
2512 evcon->cb_arg = NULL;
2516 static const char *informational_phrases[] = {
2517 /* 100 */ "Continue",
2518 /* 101 */ "Switching Protocols"
2521 static const char *success_phrases[] = {
2522 /* 200 */ "OK",
2523 /* 201 */ "Created",
2524 /* 202 */ "Accepted",
2525 /* 203 */ "Non-Authoritative Information",
2526 /* 204 */ "No Content",
2527 /* 205 */ "Reset Content",
2528 /* 206 */ "Partial Content"
2531 static const char *redirection_phrases[] = {
2532 /* 300 */ "Multiple Choices",
2533 /* 301 */ "Moved Permanently",
2534 /* 302 */ "Found",
2535 /* 303 */ "See Other",
2536 /* 304 */ "Not Modified",
2537 /* 305 */ "Use Proxy",
2538 /* 307 */ "Temporary Redirect"
2541 static const char *client_error_phrases[] = {
2542 /* 400 */ "Bad Request",
2543 /* 401 */ "Unauthorized",
2544 /* 402 */ "Payment Required",
2545 /* 403 */ "Forbidden",
2546 /* 404 */ "Not Found",
2547 /* 405 */ "Method Not Allowed",
2548 /* 406 */ "Not Acceptable",
2549 /* 407 */ "Proxy Authentication Required",
2550 /* 408 */ "Request Time-out",
2551 /* 409 */ "Conflict",
2552 /* 410 */ "Gone",
2553 /* 411 */ "Length Required",
2554 /* 412 */ "Precondition Failed",
2555 /* 413 */ "Request Entity Too Large",
2556 /* 414 */ "Request-URI Too Large",
2557 /* 415 */ "Unsupported Media Type",
2558 /* 416 */ "Requested range not satisfiable",
2559 /* 417 */ "Expectation Failed"
2562 static const char *server_error_phrases[] = {
2563 /* 500 */ "Internal Server Error",
2564 /* 501 */ "Not Implemented",
2565 /* 502 */ "Bad Gateway",
2566 /* 503 */ "Service Unavailable",
2567 /* 504 */ "Gateway Time-out",
2568 /* 505 */ "HTTP Version not supported"
2571 struct response_class {
2572 const char *name;
2573 size_t num_responses;
2574 const char **responses;
2577 #ifndef MEMBERSOF
2578 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
2579 #endif
2581 static const struct response_class response_classes[] = {
2582 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
2583 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
2584 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
2585 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
2586 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
2589 static const char *
2590 evhttp_response_phrase_internal(int code)
2592 int klass = code / 100 - 1;
2593 int subcode = code % 100;
2595 /* Unknown class - can't do any better here */
2596 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
2597 return "Unknown Status Class";
2599 /* Unknown sub-code, return class name at least */
2600 if (subcode >= (int) response_classes[klass].num_responses)
2601 return response_classes[klass].name;
2603 return response_classes[klass].responses[subcode];
2606 void
2607 evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
2609 req->kind = EVHTTP_RESPONSE;
2610 req->response_code = code;
2611 if (req->response_code_line != NULL)
2612 mm_free(req->response_code_line);
2613 if (reason == NULL)
2614 reason = evhttp_response_phrase_internal(code);
2615 req->response_code_line = mm_strdup(reason);
2616 if (req->response_code_line == NULL) {
2617 event_warn("%s: strdup", __func__);
2618 /* XXX what else can we do? */
2622 void
2623 evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
2625 if (!req->major || !req->minor) {
2626 req->major = 1;
2627 req->minor = 1;
2630 if (req->kind != EVHTTP_RESPONSE)
2631 evhttp_response_code(req, 200, "OK");
2633 evhttp_clear_headers(req->output_headers);
2634 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
2635 evhttp_add_header(req->output_headers, "Connection", "close");
2637 evhttp_send(req, databuf);
2640 static const char uri_chars[256] = {
2641 /* 0 */
2642 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2643 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2644 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
2645 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
2646 /* 64 */
2647 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2648 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
2649 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2650 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
2651 /* 128 */
2652 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2653 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2654 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2655 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2656 /* 192 */
2657 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2658 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2659 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2660 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2663 #define CHAR_IS_UNRESERVED(c) \
2664 (uri_chars[(unsigned char)(c)])
2667 * Helper functions to encode/decode a string for inclusion in a URI.
2668 * The returned string must be freed by the caller.
2670 char *
2671 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
2673 struct evbuffer *buf = evbuffer_new();
2674 const char *p, *end;
2675 char *result;
2677 if (buf == NULL)
2678 return (NULL);
2680 if (len >= 0)
2681 end = uri+len;
2682 else
2683 end = uri+strlen(uri);
2685 for (p = uri; p < end; p++) {
2686 if (CHAR_IS_UNRESERVED(*p)) {
2687 evbuffer_add(buf, p, 1);
2688 } else if (*p == ' ' && space_as_plus) {
2689 evbuffer_add(buf, "+", 1);
2690 } else {
2691 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
2694 evbuffer_add(buf, "", 1); /* NUL-terminator. */
2695 result = mm_malloc(evbuffer_get_length(buf));
2696 if (result)
2697 evbuffer_remove(buf, result, evbuffer_get_length(buf));
2698 evbuffer_free(buf);
2700 return (result);
2703 char *
2704 evhttp_encode_uri(const char *str)
2706 return evhttp_uriencode(str, -1, 0);
2710 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't.
2711 * If -1, when true we transform plus to space only after we've seen
2712 * a ?. -1 is deprecated.
2713 * @return the number of bytes written to 'ret'.
2715 static int
2716 evhttp_decode_uri_internal(
2717 const char *uri, size_t length, char *ret, int decode_plus_ctl)
2719 char c;
2720 int j;
2721 int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
2722 unsigned i;
2724 for (i = j = 0; i < length; i++) {
2725 c = uri[i];
2726 if (c == '?') {
2727 if (decode_plus_ctl < 0)
2728 decode_plus = 1;
2729 } else if (c == '+' && decode_plus) {
2730 c = ' ';
2731 } else if (c == '%' && EVUTIL_ISXDIGIT(uri[i+1]) &&
2732 EVUTIL_ISXDIGIT(uri[i+2])) {
2733 char tmp[3];
2734 tmp[0] = uri[i+1];
2735 tmp[1] = uri[i+2];
2736 tmp[2] = '\0';
2737 c = (char)strtol(tmp, NULL, 16);
2738 i += 2;
2740 ret[j++] = c;
2742 ret[j] = '\0';
2744 return (j);
2747 /* deprecated */
2748 char *
2749 evhttp_decode_uri(const char *uri)
2751 char *ret;
2753 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2754 event_warn("%s: malloc(%lu)", __func__,
2755 (unsigned long)(strlen(uri) + 1));
2756 return (NULL);
2759 evhttp_decode_uri_internal(uri, strlen(uri),
2760 ret, -1 /*always_decode_plus*/);
2762 return (ret);
2765 char *
2766 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
2768 char *ret;
2769 int n;
2771 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2772 event_warn("%s: malloc(%lu)", __func__,
2773 (unsigned long)(strlen(uri) + 1));
2774 return (NULL);
2777 n = evhttp_decode_uri_internal(uri, strlen(uri),
2778 ret, !!decode_plus/*always_decode_plus*/);
2780 if (size_out) {
2781 EVUTIL_ASSERT(n >= 0);
2782 *size_out = (size_t)n;
2785 return (ret);
2789 * Helper function to parse out arguments in a query.
2790 * The arguments are separated by key and value.
2793 static int
2794 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
2795 int is_whole_uri)
2797 char *line=NULL;
2798 char *argument;
2799 char *p;
2800 const char *query_part;
2801 int result = -1;
2802 struct evhttp_uri *uri=NULL;
2804 TAILQ_INIT(headers);
2806 if (is_whole_uri) {
2807 uri = evhttp_uri_parse(str);
2808 if (!uri)
2809 goto error;
2810 query_part = evhttp_uri_get_query(uri);
2811 } else {
2812 query_part = str;
2815 /* No arguments - we are done */
2816 if (!query_part || !strlen(query_part)) {
2817 result = 0;
2818 goto done;
2821 if ((line = mm_strdup(query_part)) == NULL) {
2822 event_warn("%s: strdup", __func__);
2823 goto error;
2826 p = argument = line;
2827 while (p != NULL && *p != '\0') {
2828 char *key, *value, *decoded_value;
2829 argument = strsep(&p, "&");
2831 value = argument;
2832 key = strsep(&value, "=");
2833 if (value == NULL || *key == '\0') {
2834 goto error;
2837 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
2838 event_warn("%s: mm_malloc", __func__);
2839 goto error;
2841 evhttp_decode_uri_internal(value, strlen(value),
2842 decoded_value, 1 /*always_decode_plus*/);
2843 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
2844 evhttp_add_header_internal(headers, key, decoded_value);
2845 mm_free(decoded_value);
2848 result = 0;
2849 goto done;
2850 error:
2851 evhttp_clear_headers(headers);
2852 done:
2853 if (line)
2854 mm_free(line);
2855 if (uri)
2856 evhttp_uri_free(uri);
2857 return result;
2861 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
2863 return evhttp_parse_query_impl(uri, headers, 1);
2866 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
2868 return evhttp_parse_query_impl(uri, headers, 0);
2871 static struct evhttp_cb *
2872 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
2874 struct evhttp_cb *cb;
2875 size_t offset = 0;
2876 char *translated;
2877 const char *path;
2879 /* Test for different URLs */
2880 path = evhttp_uri_get_path(req->uri_elems);
2881 offset = strlen(path);
2882 if ((translated = mm_malloc(offset + 1)) == NULL)
2883 return (NULL);
2884 evhttp_decode_uri_internal(path, offset, translated,
2885 0 /* decode_plus */);
2887 TAILQ_FOREACH(cb, callbacks, next) {
2888 if (!strcmp(cb->what, translated)) {
2889 mm_free(translated);
2890 return (cb);
2894 mm_free(translated);
2895 return (NULL);
2899 static int
2900 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
2902 char c;
2904 while (1) {
2905 switch (c = *pattern++) {
2906 case '\0':
2907 return *name == '\0';
2909 case '*':
2910 while (*name != '\0') {
2911 if (prefix_suffix_match(pattern, name,
2912 ignorecase))
2913 return (1);
2914 ++name;
2916 return (0);
2917 default:
2918 if (c != *name) {
2919 if (!ignorecase ||
2920 EVUTIL_TOLOWER(c) != EVUTIL_TOLOWER(*name))
2921 return (0);
2923 ++name;
2926 /* NOTREACHED */
2930 Search the vhost hierarchy beginning with http for a server alias
2931 matching hostname. If a match is found, and outhttp is non-null,
2932 outhttp is set to the matching http object and 1 is returned.
2935 static int
2936 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
2937 const char *hostname)
2939 struct evhttp_server_alias *alias;
2940 struct evhttp *vhost;
2942 TAILQ_FOREACH(alias, &http->aliases, next) {
2943 /* XXX Do we need to handle IP addresses? */
2944 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
2945 if (outhttp)
2946 *outhttp = http;
2947 return 1;
2951 /* XXX It might be good to avoid recursion here, but I don't
2952 see a way to do that w/o a list. */
2953 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
2954 if (evhttp_find_alias(vhost, outhttp, hostname))
2955 return 1;
2958 return 0;
2962 Attempts to find the best http object to handle a request for a hostname.
2963 All aliases for the root http object and vhosts are searched for an exact
2964 match. Then, the vhost hierarchy is traversed again for a matching
2965 pattern.
2967 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
2968 is set with the best matching http object. If there are no matches, the
2969 root http object is stored in outhttp and 0 is returned.
2972 static int
2973 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
2974 const char *hostname)
2976 struct evhttp *vhost;
2977 struct evhttp *oldhttp;
2978 int match_found = 0;
2980 if (evhttp_find_alias(http, outhttp, hostname))
2981 return 1;
2983 do {
2984 oldhttp = http;
2985 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
2986 if (prefix_suffix_match(vhost->vhost_pattern,
2987 hostname, 1 /* ignorecase */)) {
2988 http = vhost;
2989 match_found = 1;
2990 break;
2993 } while (oldhttp != http);
2995 if (outhttp)
2996 *outhttp = http;
2998 return match_found;
3001 static void
3002 evhttp_handle_request(struct evhttp_request *req, void *arg)
3004 struct evhttp *http = arg;
3005 struct evhttp_cb *cb = NULL;
3006 const char *hostname;
3008 /* we have a new request on which the user needs to take action */
3009 req->userdone = 0;
3011 if (req->type == 0 || req->uri == NULL) {
3012 evhttp_send_error(req, HTTP_BADREQUEST, NULL);
3013 return;
3016 if ((http->allowed_methods & req->type) == 0) {
3017 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3018 (unsigned)req->type, (unsigned)http->allowed_methods));
3019 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3020 return;
3023 /* handle potential virtual hosts */
3024 hostname = evhttp_request_get_host(req);
3025 if (hostname != NULL) {
3026 evhttp_find_vhost(http, &http, hostname);
3029 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3030 (*cb->cb)(req, cb->cbarg);
3031 return;
3034 /* Generic call back */
3035 if (http->gencb) {
3036 (*http->gencb)(req, http->gencbarg);
3037 return;
3038 } else {
3039 /* We need to send a 404 here */
3040 #define ERR_FORMAT "<html><head>" \
3041 "<title>404 Not Found</title>" \
3042 "</head><body>" \
3043 "<h1>Not Found</h1>" \
3044 "<p>The requested URL %s was not found on this server.</p>"\
3045 "</body></html>\n"
3047 char *escaped_html;
3048 struct evbuffer *buf;
3050 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3051 evhttp_connection_free(req->evcon);
3052 return;
3055 if ((buf = evbuffer_new()) == NULL) {
3056 mm_free(escaped_html);
3057 evhttp_connection_free(req->evcon);
3058 return;
3061 evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
3063 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3065 mm_free(escaped_html);
3067 evhttp_send_page(req, buf);
3069 evbuffer_free(buf);
3070 #undef ERR_FORMAT
3074 /* Listener callback when a connection arrives at a server. */
3075 static void
3076 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3078 struct evhttp *http = arg;
3080 evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3084 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3086 struct evhttp_bound_socket *bound =
3087 evhttp_bind_socket_with_handle(http, address, port);
3088 if (bound == NULL)
3089 return (-1);
3090 return (0);
3093 struct evhttp_bound_socket *
3094 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3096 evutil_socket_t fd;
3097 struct evhttp_bound_socket *bound;
3099 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3100 return (NULL);
3102 if (listen(fd, 128) == -1) {
3103 event_sock_warn(fd, "%s: listen", __func__);
3104 evutil_closesocket(fd);
3105 return (NULL);
3108 bound = evhttp_accept_socket_with_handle(http, fd);
3110 if (bound != NULL) {
3111 event_debug(("Bound to port %d - Awaiting connections ... ",
3112 port));
3113 return (bound);
3116 return (NULL);
3120 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3122 struct evhttp_bound_socket *bound =
3123 evhttp_accept_socket_with_handle(http, fd);
3124 if (bound == NULL)
3125 return (-1);
3126 return (0);
3130 struct evhttp_bound_socket *
3131 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3133 struct evhttp_bound_socket *bound;
3134 struct evconnlistener *listener;
3135 const int flags =
3136 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3138 listener = evconnlistener_new(http->base, NULL, NULL,
3139 flags,
3140 0, /* Backlog is '0' because we already said 'listen' */
3141 fd);
3142 if (!listener)
3143 return (NULL);
3145 bound = evhttp_bind_listener(http, listener);
3146 if (!bound) {
3147 evconnlistener_free(listener);
3148 return (NULL);
3150 return (bound);
3153 struct evhttp_bound_socket *
3154 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3156 struct evhttp_bound_socket *bound;
3158 bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3159 if (bound == NULL)
3160 return (NULL);
3162 bound->listener = listener;
3163 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3165 evconnlistener_set_cb(listener, accept_socket_cb, http);
3166 return bound;
3169 evutil_socket_t
3170 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3172 return evconnlistener_get_fd(bound->listener);
3175 struct evconnlistener *
3176 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3178 return bound->listener;
3181 void
3182 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3184 TAILQ_REMOVE(&http->sockets, bound, next);
3185 evconnlistener_free(bound->listener);
3186 mm_free(bound);
3189 static struct evhttp*
3190 evhttp_new_object(void)
3192 struct evhttp *http = NULL;
3194 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3195 event_warn("%s: calloc", __func__);
3196 return (NULL);
3199 http->timeout = -1;
3200 evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3201 evhttp_set_max_body_size(http, EV_SIZE_MAX);
3202 evhttp_set_allowed_methods(http,
3203 EVHTTP_REQ_GET |
3204 EVHTTP_REQ_POST |
3205 EVHTTP_REQ_HEAD |
3206 EVHTTP_REQ_PUT |
3207 EVHTTP_REQ_DELETE);
3209 TAILQ_INIT(&http->sockets);
3210 TAILQ_INIT(&http->callbacks);
3211 TAILQ_INIT(&http->connections);
3212 TAILQ_INIT(&http->virtualhosts);
3213 TAILQ_INIT(&http->aliases);
3215 return (http);
3218 struct evhttp *
3219 evhttp_new(struct event_base *base)
3221 struct evhttp *http = NULL;
3223 http = evhttp_new_object();
3224 if (http == NULL)
3225 return (NULL);
3226 http->base = base;
3228 return (http);
3232 * Start a web server on the specified address and port.
3235 struct evhttp *
3236 evhttp_start(const char *address, unsigned short port)
3238 struct evhttp *http = NULL;
3240 http = evhttp_new_object();
3241 if (http == NULL)
3242 return (NULL);
3243 if (evhttp_bind_socket(http, address, port) == -1) {
3244 mm_free(http);
3245 return (NULL);
3248 return (http);
3251 void
3252 evhttp_free(struct evhttp* http)
3254 struct evhttp_cb *http_cb;
3255 struct evhttp_connection *evcon;
3256 struct evhttp_bound_socket *bound;
3257 struct evhttp* vhost;
3258 struct evhttp_server_alias *alias;
3260 /* Remove the accepting part */
3261 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3262 TAILQ_REMOVE(&http->sockets, bound, next);
3264 evconnlistener_free(bound->listener);
3266 mm_free(bound);
3269 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3270 /* evhttp_connection_free removes the connection */
3271 evhttp_connection_free(evcon);
3274 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3275 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3276 mm_free(http_cb->what);
3277 mm_free(http_cb);
3280 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3281 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3283 evhttp_free(vhost);
3286 if (http->vhost_pattern != NULL)
3287 mm_free(http->vhost_pattern);
3289 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3290 TAILQ_REMOVE(&http->aliases, alias, next);
3291 mm_free(alias->alias);
3292 mm_free(alias);
3295 mm_free(http);
3299 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3300 struct evhttp* vhost)
3302 /* a vhost can only be a vhost once and should not have bound sockets */
3303 if (vhost->vhost_pattern != NULL ||
3304 TAILQ_FIRST(&vhost->sockets) != NULL)
3305 return (-1);
3307 vhost->vhost_pattern = mm_strdup(pattern);
3308 if (vhost->vhost_pattern == NULL)
3309 return (-1);
3311 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3313 return (0);
3317 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3319 if (vhost->vhost_pattern == NULL)
3320 return (-1);
3322 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3324 mm_free(vhost->vhost_pattern);
3325 vhost->vhost_pattern = NULL;
3327 return (0);
3331 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3333 struct evhttp_server_alias *evalias;
3335 evalias = mm_calloc(1, sizeof(*evalias));
3336 if (!evalias)
3337 return -1;
3339 evalias->alias = mm_strdup(alias);
3340 if (!evalias->alias) {
3341 mm_free(evalias);
3342 return -1;
3345 TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3347 return 0;
3351 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3353 struct evhttp_server_alias *evalias;
3355 TAILQ_FOREACH(evalias, &http->aliases, next) {
3356 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3357 TAILQ_REMOVE(&http->aliases, evalias, next);
3358 mm_free(evalias->alias);
3359 mm_free(evalias);
3360 return 0;
3364 return -1;
3367 void
3368 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
3370 http->timeout = timeout_in_secs;
3373 void
3374 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
3376 if (max_headers_size < 0)
3377 http->default_max_headers_size = EV_SIZE_MAX;
3378 else
3379 http->default_max_headers_size = max_headers_size;
3382 void
3383 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
3385 if (max_body_size < 0)
3386 http->default_max_body_size = EV_UINT64_MAX;
3387 else
3388 http->default_max_body_size = max_body_size;
3391 void
3392 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
3394 http->allowed_methods = methods;
3398 evhttp_set_cb(struct evhttp *http, const char *uri,
3399 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3401 struct evhttp_cb *http_cb;
3403 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3404 if (strcmp(http_cb->what, uri) == 0)
3405 return (-1);
3408 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
3409 event_warn("%s: calloc", __func__);
3410 return (-2);
3413 http_cb->what = mm_strdup(uri);
3414 if (http_cb->what == NULL) {
3415 event_warn("%s: strdup", __func__);
3416 mm_free(http_cb);
3417 return (-3);
3419 http_cb->cb = cb;
3420 http_cb->cbarg = cbarg;
3422 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
3424 return (0);
3428 evhttp_del_cb(struct evhttp *http, const char *uri)
3430 struct evhttp_cb *http_cb;
3432 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3433 if (strcmp(http_cb->what, uri) == 0)
3434 break;
3436 if (http_cb == NULL)
3437 return (-1);
3439 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3440 mm_free(http_cb->what);
3441 mm_free(http_cb);
3443 return (0);
3446 void
3447 evhttp_set_gencb(struct evhttp *http,
3448 void (*cb)(struct evhttp_request *, void *), void *cbarg)
3450 http->gencb = cb;
3451 http->gencbarg = cbarg;
3455 * Request related functions
3458 struct evhttp_request *
3459 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
3461 struct evhttp_request *req = NULL;
3463 /* Allocate request structure */
3464 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
3465 event_warn("%s: calloc", __func__);
3466 goto error;
3469 req->headers_size = 0;
3470 req->body_size = 0;
3472 req->kind = EVHTTP_RESPONSE;
3473 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3474 if (req->input_headers == NULL) {
3475 event_warn("%s: calloc", __func__);
3476 goto error;
3478 TAILQ_INIT(req->input_headers);
3480 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3481 if (req->output_headers == NULL) {
3482 event_warn("%s: calloc", __func__);
3483 goto error;
3485 TAILQ_INIT(req->output_headers);
3487 if ((req->input_buffer = evbuffer_new()) == NULL) {
3488 event_warn("%s: evbuffer_new", __func__);
3489 goto error;
3492 if ((req->output_buffer = evbuffer_new()) == NULL) {
3493 event_warn("%s: evbuffer_new", __func__);
3494 goto error;
3497 req->cb = cb;
3498 req->cb_arg = arg;
3500 return (req);
3502 error:
3503 if (req != NULL)
3504 evhttp_request_free(req);
3505 return (NULL);
3508 void
3509 evhttp_request_free(struct evhttp_request *req)
3511 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
3512 req->flags |= EVHTTP_REQ_NEEDS_FREE;
3513 return;
3516 if (req->remote_host != NULL)
3517 mm_free(req->remote_host);
3518 if (req->uri != NULL)
3519 mm_free(req->uri);
3520 if (req->uri_elems != NULL)
3521 evhttp_uri_free(req->uri_elems);
3522 if (req->response_code_line != NULL)
3523 mm_free(req->response_code_line);
3524 if (req->host_cache != NULL)
3525 mm_free(req->host_cache);
3527 evhttp_clear_headers(req->input_headers);
3528 mm_free(req->input_headers);
3530 evhttp_clear_headers(req->output_headers);
3531 mm_free(req->output_headers);
3533 if (req->input_buffer != NULL)
3534 evbuffer_free(req->input_buffer);
3536 if (req->output_buffer != NULL)
3537 evbuffer_free(req->output_buffer);
3539 mm_free(req);
3542 void
3543 evhttp_request_own(struct evhttp_request *req)
3545 req->flags |= EVHTTP_USER_OWNED;
3549 evhttp_request_is_owned(struct evhttp_request *req)
3551 return (req->flags & EVHTTP_USER_OWNED) != 0;
3554 struct evhttp_connection *
3555 evhttp_request_get_connection(struct evhttp_request *req)
3557 return req->evcon;
3560 struct event_base *
3561 evhttp_connection_get_base(struct evhttp_connection *conn)
3563 return conn->base;
3566 void
3567 evhttp_request_set_chunked_cb(struct evhttp_request *req,
3568 void (*cb)(struct evhttp_request *, void *))
3570 req->chunk_cb = cb;
3574 * Allows for inspection of the request URI
3577 const char *
3578 evhttp_request_get_uri(const struct evhttp_request *req) {
3579 if (req->uri == NULL)
3580 event_debug(("%s: request %p has no uri\n", __func__, req));
3581 return (req->uri);
3584 const struct evhttp_uri *
3585 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
3586 if (req->uri_elems == NULL)
3587 event_debug(("%s: request %p has no uri elems\n",
3588 __func__, req));
3589 return (req->uri_elems);
3592 const char *
3593 evhttp_request_get_host(struct evhttp_request *req)
3595 const char *host = NULL;
3597 if (req->host_cache)
3598 return req->host_cache;
3600 if (req->uri_elems)
3601 host = evhttp_uri_get_host(req->uri_elems);
3602 if (!host && req->input_headers) {
3603 const char *p;
3604 size_t len;
3606 host = evhttp_find_header(req->input_headers, "Host");
3607 /* The Host: header may include a port. Remove it here
3608 to be consistent with uri_elems case above. */
3609 if (host) {
3610 p = host + strlen(host) - 1;
3611 while (p > host && EVUTIL_ISDIGIT(*p))
3612 --p;
3613 if (p > host && *p == ':') {
3614 len = p - host;
3615 req->host_cache = mm_malloc(len + 1);
3616 if (!req->host_cache) {
3617 event_warn("%s: malloc", __func__);
3618 return NULL;
3620 memcpy(req->host_cache, host, len);
3621 req->host_cache[len] = '\0';
3622 host = req->host_cache;
3627 return host;
3630 enum evhttp_cmd_type
3631 evhttp_request_get_command(const struct evhttp_request *req) {
3632 return (req->type);
3636 evhttp_request_get_response_code(const struct evhttp_request *req)
3638 return req->response_code;
3641 /** Returns the input headers */
3642 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
3644 return (req->input_headers);
3647 /** Returns the output headers */
3648 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
3650 return (req->output_headers);
3653 /** Returns the input buffer */
3654 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
3656 return (req->input_buffer);
3659 /** Returns the output buffer */
3660 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
3662 return (req->output_buffer);
3667 * Takes a file descriptor to read a request from.
3668 * The callback is executed once the whole request has been read.
3671 static struct evhttp_connection*
3672 evhttp_get_request_connection(
3673 struct evhttp* http,
3674 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
3676 struct evhttp_connection *evcon;
3677 char *hostname = NULL, *portname = NULL;
3679 name_from_addr(sa, salen, &hostname, &portname);
3680 if (hostname == NULL || portname == NULL) {
3681 if (hostname) mm_free(hostname);
3682 if (portname) mm_free(portname);
3683 return (NULL);
3686 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n",
3687 __func__, hostname, portname, EV_SOCK_ARG(fd)));
3689 /* we need a connection object to put the http request on */
3690 evcon = evhttp_connection_base_new(
3691 http->base, NULL, hostname, atoi(portname));
3692 mm_free(hostname);
3693 mm_free(portname);
3694 if (evcon == NULL)
3695 return (NULL);
3697 evcon->max_headers_size = http->default_max_headers_size;
3698 evcon->max_body_size = http->default_max_body_size;
3700 evcon->flags |= EVHTTP_CON_INCOMING;
3701 evcon->state = EVCON_READING_FIRSTLINE;
3703 evcon->fd = fd;
3705 bufferevent_setfd(evcon->bufev, fd);
3707 return (evcon);
3710 static int
3711 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
3713 struct evhttp *http = evcon->http_server;
3714 struct evhttp_request *req;
3715 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
3716 return (-1);
3718 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
3719 event_warn("%s: strdup", __func__);
3720 evhttp_request_free(req);
3721 return (-1);
3723 req->remote_port = evcon->port;
3725 req->evcon = evcon; /* the request ends up owning the connection */
3726 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
3728 /* We did not present the request to the user user yet, so treat it as
3729 * if the user was done with the request. This allows us to free the
3730 * request on a persistent connection if the client drops it without
3731 * sending a request.
3733 req->userdone = 1;
3735 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
3737 req->kind = EVHTTP_REQUEST;
3740 evhttp_start_read(evcon);
3742 return (0);
3745 static void
3746 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
3747 struct sockaddr *sa, ev_socklen_t salen)
3749 struct evhttp_connection *evcon;
3751 evcon = evhttp_get_request_connection(http, fd, sa, salen);
3752 if (evcon == NULL) {
3753 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT,
3754 __func__, EV_SOCK_ARG(fd));
3755 evutil_closesocket(fd);
3756 return;
3759 /* the timeout can be used by the server to close idle connections */
3760 if (http->timeout != -1)
3761 evhttp_connection_set_timeout(evcon, http->timeout);
3764 * if we want to accept more than one request on a connection,
3765 * we need to know which http server it belongs to.
3767 evcon->http_server = http;
3768 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
3770 if (evhttp_associate_new_request_with_connection(evcon) == -1)
3771 evhttp_connection_free(evcon);
3776 * Network helper functions that we do not want to export to the rest of
3777 * the world.
3780 static void
3781 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
3782 char **phost, char **pport)
3784 char ntop[NI_MAXHOST];
3785 char strport[NI_MAXSERV];
3786 int ni_result;
3788 #ifdef _EVENT_HAVE_GETNAMEINFO
3789 ni_result = getnameinfo(sa, salen,
3790 ntop, sizeof(ntop), strport, sizeof(strport),
3791 NI_NUMERICHOST|NI_NUMERICSERV);
3793 if (ni_result != 0) {
3794 #ifdef EAI_SYSTEM
3795 /* Windows doesn't have an EAI_SYSTEM. */
3796 if (ni_result == EAI_SYSTEM)
3797 event_err(1, "getnameinfo failed");
3798 else
3799 #endif
3800 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
3801 return;
3803 #else
3804 ni_result = fake_getnameinfo(sa, salen,
3805 ntop, sizeof(ntop), strport, sizeof(strport),
3806 NI_NUMERICHOST|NI_NUMERICSERV);
3807 if (ni_result != 0)
3808 return;
3809 #endif
3811 *phost = mm_strdup(ntop);
3812 *pport = mm_strdup(strport);
3815 /* Create a non-blocking socket and bind it */
3816 /* todo: rename this function */
3817 static evutil_socket_t
3818 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
3820 evutil_socket_t fd;
3822 int on = 1, r;
3823 int serrno;
3825 /* Create listen socket */
3826 fd = socket(ai ? ai->ai_family : AF_INET, SOCK_STREAM, 0);
3827 if (fd == -1) {
3828 event_sock_warn(-1, "socket");
3829 return (-1);
3832 if (evutil_make_socket_nonblocking(fd) < 0)
3833 goto out;
3834 if (evutil_make_socket_closeonexec(fd) < 0)
3835 goto out;
3837 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0)
3838 goto out;
3839 if (reuse) {
3840 if (evutil_make_listen_socket_reuseable(fd) < 0)
3841 goto out;
3844 if (ai != NULL) {
3845 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
3846 if (r == -1)
3847 goto out;
3850 return (fd);
3852 out:
3853 serrno = EVUTIL_SOCKET_ERROR();
3854 evutil_closesocket(fd);
3855 EVUTIL_SET_SOCKET_ERROR(serrno);
3856 return (-1);
3859 static struct evutil_addrinfo *
3860 make_addrinfo(const char *address, ev_uint16_t port)
3862 struct evutil_addrinfo *ai = NULL;
3864 struct evutil_addrinfo hints;
3865 char strport[NI_MAXSERV];
3866 int ai_result;
3868 memset(&hints, 0, sizeof(hints));
3869 hints.ai_family = AF_UNSPEC;
3870 hints.ai_socktype = SOCK_STREAM;
3871 /* turn NULL hostname into INADDR_ANY, and skip looking up any address
3872 * types we don't have an interface to connect to. */
3873 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
3874 evutil_snprintf(strport, sizeof(strport), "%d", port);
3875 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
3876 != 0) {
3877 if (ai_result == EVUTIL_EAI_SYSTEM)
3878 event_warn("getaddrinfo");
3879 else
3880 event_warnx("getaddrinfo: %s",
3881 evutil_gai_strerror(ai_result));
3882 return (NULL);
3885 return (ai);
3888 static evutil_socket_t
3889 bind_socket(const char *address, ev_uint16_t port, int reuse)
3891 evutil_socket_t fd;
3892 struct evutil_addrinfo *aitop = NULL;
3894 /* just create an unbound socket */
3895 if (address == NULL && port == 0)
3896 return bind_socket_ai(NULL, 0);
3898 aitop = make_addrinfo(address, port);
3900 if (aitop == NULL)
3901 return (-1);
3903 fd = bind_socket_ai(aitop, reuse);
3905 evutil_freeaddrinfo(aitop);
3907 return (fd);
3910 struct evhttp_uri {
3911 unsigned flags;
3912 char *scheme; /* scheme; e.g http, ftp etc */
3913 char *userinfo; /* userinfo (typically username:pass), or NULL */
3914 char *host; /* hostname, IP address, or NULL */
3915 int port; /* port, or zero */
3916 char *path; /* path, or "". */
3917 char *query; /* query, or NULL */
3918 char *fragment; /* fragment or NULL */
3921 struct evhttp_uri *
3922 evhttp_uri_new(void)
3924 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
3925 if (uri)
3926 uri->port = -1;
3927 return uri;
3930 void
3931 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
3933 uri->flags = flags;
3936 /* Return true if the string starting at s and ending immediately before eos
3937 * is a valid URI scheme according to RFC3986
3939 static int
3940 scheme_ok(const char *s, const char *eos)
3942 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
3943 EVUTIL_ASSERT(eos >= s);
3944 if (s == eos)
3945 return 0;
3946 if (!EVUTIL_ISALPHA(*s))
3947 return 0;
3948 while (++s < eos) {
3949 if (! EVUTIL_ISALNUM(*s) &&
3950 *s != '+' && *s != '-' && *s != '.')
3951 return 0;
3953 return 1;
3956 #define SUBDELIMS "!$&'()*+,;="
3958 /* Return true iff [s..eos) is a valid userinfo */
3959 static int
3960 userinfo_ok(const char *s, const char *eos)
3962 while (s < eos) {
3963 if (CHAR_IS_UNRESERVED(*s) ||
3964 strchr(SUBDELIMS, *s) ||
3965 *s == ':')
3966 ++s;
3967 else if (*s == '%' && s+2 < eos &&
3968 EVUTIL_ISXDIGIT(s[1]) &&
3969 EVUTIL_ISXDIGIT(s[2]))
3970 s += 3;
3971 else
3972 return 0;
3974 return 1;
3977 static int
3978 regname_ok(const char *s, const char *eos)
3980 while (s && s<eos) {
3981 if (CHAR_IS_UNRESERVED(*s) ||
3982 strchr(SUBDELIMS, *s))
3983 ++s;
3984 else if (*s == '%' &&
3985 EVUTIL_ISXDIGIT(s[1]) &&
3986 EVUTIL_ISXDIGIT(s[2]))
3987 s += 3;
3988 else
3989 return 0;
3991 return 1;
3994 static int
3995 parse_port(const char *s, const char *eos)
3997 int portnum = 0;
3998 while (s < eos) {
3999 if (! EVUTIL_ISDIGIT(*s))
4000 return -1;
4001 portnum = (portnum * 10) + (*s - '0');
4002 if (portnum < 0)
4003 return -1;
4004 ++s;
4006 return portnum;
4009 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
4010 static int
4011 bracket_addr_ok(const char *s, const char *eos)
4013 if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
4014 return 0;
4015 if (s[1] == 'v') {
4016 /* IPvFuture, or junk.
4017 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
4019 s += 2; /* skip [v */
4020 --eos;
4021 if (!EVUTIL_ISXDIGIT(*s)) /*require at least one*/
4022 return 0;
4023 while (s < eos && *s != '.') {
4024 if (EVUTIL_ISXDIGIT(*s))
4025 ++s;
4026 else
4027 return 0;
4029 if (*s != '.')
4030 return 0;
4031 ++s;
4032 while (s < eos) {
4033 if (CHAR_IS_UNRESERVED(*s) ||
4034 strchr(SUBDELIMS, *s) ||
4035 *s == ':')
4036 ++s;
4037 else
4038 return 0;
4040 return 2;
4041 } else {
4042 /* IPv6, or junk */
4043 char buf[64];
4044 ev_ssize_t n_chars = eos-s-2;
4045 struct in6_addr in6;
4046 if (n_chars >= 64) /* way too long */
4047 return 0;
4048 memcpy(buf, s+1, n_chars);
4049 buf[n_chars]='\0';
4050 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4054 static int
4055 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4057 char *cp, *port;
4058 EVUTIL_ASSERT(eos);
4059 if (eos == s) {
4060 uri->host = mm_strdup("");
4061 if (uri->host == NULL) {
4062 event_warn("%s: strdup", __func__);
4063 return -1;
4065 return 0;
4068 /* Optionally, we start with "userinfo@" */
4070 cp = strchr(s, '@');
4071 if (cp && cp < eos) {
4072 if (! userinfo_ok(s,cp))
4073 return -1;
4074 *cp++ = '\0';
4075 uri->userinfo = mm_strdup(s);
4076 if (uri->userinfo == NULL) {
4077 event_warn("%s: strdup", __func__);
4078 return -1;
4080 } else {
4081 cp = s;
4083 /* Optionally, we end with ":port" */
4084 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT(*port); --port)
4086 if (port >= cp && *port == ':') {
4087 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4088 * nil port */
4089 uri->port = -1;
4090 else if ((uri->port = parse_port(port+1, eos))<0)
4091 return -1;
4092 eos = port;
4094 /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4095 * an IP-Literal, or a reg-name */
4096 EVUTIL_ASSERT(eos >= cp);
4097 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4098 /* IPv6address, IP-Literal, or junk. */
4099 if (! bracket_addr_ok(cp, eos))
4100 return -1;
4101 } else {
4102 /* Make sure the host part is ok. */
4103 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4104 return -1;
4106 uri->host = mm_malloc(eos-cp+1);
4107 if (uri->host == NULL) {
4108 event_warn("%s: malloc", __func__);
4109 return -1;
4111 memcpy(uri->host, cp, eos-cp);
4112 uri->host[eos-cp] = '\0';
4113 return 0;
4117 static char *
4118 end_of_authority(char *cp)
4120 while (*cp) {
4121 if (*cp == '?' || *cp == '#' || *cp == '/')
4122 return cp;
4123 ++cp;
4125 return cp;
4128 enum uri_part {
4129 PART_PATH,
4130 PART_QUERY,
4131 PART_FRAGMENT
4134 /* Return the character after the longest prefix of 'cp' that matches...
4135 * *pchar / "/" if allow_qchars is false, or
4136 * *(pchar / "/" / "?") if allow_qchars is true.
4138 static char *
4139 end_of_path(char *cp, enum uri_part part, unsigned flags)
4141 if (flags & EVHTTP_URI_NONCONFORMANT) {
4142 /* If NONCONFORMANT:
4143 * Path is everything up to a # or ? or nul.
4144 * Query is everything up a # or nul
4145 * Fragment is everything up to a nul.
4147 switch (part) {
4148 case PART_PATH:
4149 while (*cp && *cp != '#' && *cp != '?')
4150 ++cp;
4151 break;
4152 case PART_QUERY:
4153 while (*cp && *cp != '#')
4154 ++cp;
4155 break;
4156 case PART_FRAGMENT:
4157 cp += strlen(cp);
4158 break;
4160 return cp;
4163 while (*cp) {
4164 if (CHAR_IS_UNRESERVED(*cp) ||
4165 strchr(SUBDELIMS, *cp) ||
4166 *cp == ':' || *cp == '@' || *cp == '/')
4167 ++cp;
4168 else if (*cp == '%' && EVUTIL_ISXDIGIT(cp[1]) &&
4169 EVUTIL_ISXDIGIT(cp[2]))
4170 cp += 3;
4171 else if (*cp == '?' && part != PART_PATH)
4172 ++cp;
4173 else
4174 return cp;
4176 return cp;
4179 static int
4180 path_matches_noscheme(const char *cp)
4182 while (*cp) {
4183 if (*cp == ':')
4184 return 0;
4185 else if (*cp == '/')
4186 return 1;
4187 ++cp;
4189 return 1;
4192 struct evhttp_uri *
4193 evhttp_uri_parse(const char *source_uri)
4195 return evhttp_uri_parse_with_flags(source_uri, 0);
4198 struct evhttp_uri *
4199 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4201 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4202 char *path = NULL, *fragment = NULL;
4203 int got_authority = 0;
4205 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4206 if (uri == NULL) {
4207 event_warn("%s: calloc", __func__);
4208 goto err;
4210 uri->port = -1;
4211 uri->flags = flags;
4213 readbuf = mm_strdup(source_uri);
4214 if (readbuf == NULL) {
4215 event_warn("%s: strdup", __func__);
4216 goto err;
4219 readp = readbuf;
4220 token = NULL;
4222 /* We try to follow RFC3986 here as much as we can, and match
4223 the productions
4225 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4227 relative-ref = relative-part [ "?" query ] [ "#" fragment ]
4230 /* 1. scheme: */
4231 token = strchr(readp, ':');
4232 if (token && scheme_ok(readp,token)) {
4233 *token = '\0';
4234 uri->scheme = mm_strdup(readp);
4235 if (uri->scheme == NULL) {
4236 event_warn("%s: strdup", __func__);
4237 goto err;
4239 readp = token+1; /* eat : */
4242 /* 2. Optionally, "//" then an 'authority' part. */
4243 if (readp[0]=='/' && readp[1] == '/') {
4244 char *authority;
4245 readp += 2;
4246 authority = readp;
4247 path = end_of_authority(readp);
4248 if (parse_authority(uri, authority, path) < 0)
4249 goto err;
4250 readp = path;
4251 got_authority = 1;
4254 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4256 path = readp;
4257 readp = end_of_path(path, PART_PATH, flags);
4259 /* Query */
4260 if (*readp == '?') {
4261 *readp = '\0';
4262 ++readp;
4263 query = readp;
4264 readp = end_of_path(readp, PART_QUERY, flags);
4266 /* fragment */
4267 if (*readp == '#') {
4268 *readp = '\0';
4269 ++readp;
4270 fragment = readp;
4271 readp = end_of_path(readp, PART_FRAGMENT, flags);
4273 if (*readp != '\0') {
4274 goto err;
4277 /* These next two cases may be unreachable; I'm leaving them
4278 * in to be defensive. */
4279 /* If you didn't get an authority, the path can't begin with "//" */
4280 if (!got_authority && path[0]=='/' && path[1]=='/')
4281 goto err;
4282 /* If you did get an authority, the path must begin with "/" or be
4283 * empty. */
4284 if (got_authority && path[0] != '/' && path[0] != '\0')
4285 goto err;
4286 /* (End of maybe-unreachable cases) */
4288 /* If there was no scheme, the first part of the path (if any) must
4289 * have no colon in it. */
4290 if (! uri->scheme && !path_matches_noscheme(path))
4291 goto err;
4293 EVUTIL_ASSERT(path);
4294 uri->path = mm_strdup(path);
4295 if (uri->path == NULL) {
4296 event_warn("%s: strdup", __func__);
4297 goto err;
4300 if (query) {
4301 uri->query = mm_strdup(query);
4302 if (uri->query == NULL) {
4303 event_warn("%s: strdup", __func__);
4304 goto err;
4307 if (fragment) {
4308 uri->fragment = mm_strdup(fragment);
4309 if (uri->fragment == NULL) {
4310 event_warn("%s: strdup", __func__);
4311 goto err;
4315 mm_free(readbuf);
4317 return uri;
4318 err:
4319 if (uri)
4320 evhttp_uri_free(uri);
4321 if (readbuf)
4322 mm_free(readbuf);
4323 return NULL;
4326 void
4327 evhttp_uri_free(struct evhttp_uri *uri)
4329 #define _URI_FREE_STR(f) \
4330 if (uri->f) { \
4331 mm_free(uri->f); \
4334 _URI_FREE_STR(scheme);
4335 _URI_FREE_STR(userinfo);
4336 _URI_FREE_STR(host);
4337 _URI_FREE_STR(path);
4338 _URI_FREE_STR(query);
4339 _URI_FREE_STR(fragment);
4341 mm_free(uri);
4342 #undef _URI_FREE_STR
4345 char *
4346 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
4348 struct evbuffer *tmp = 0;
4349 size_t joined_size = 0;
4350 char *output = NULL;
4352 #define _URI_ADD(f) evbuffer_add(tmp, uri->f, strlen(uri->f))
4354 if (!uri || !buf || !limit)
4355 return NULL;
4357 tmp = evbuffer_new();
4358 if (!tmp)
4359 return NULL;
4361 if (uri->scheme) {
4362 _URI_ADD(scheme);
4363 evbuffer_add(tmp, ":", 1);
4365 if (uri->host) {
4366 evbuffer_add(tmp, "//", 2);
4367 if (uri->userinfo)
4368 evbuffer_add_printf(tmp,"%s@", uri->userinfo);
4369 _URI_ADD(host);
4370 if (uri->port >= 0)
4371 evbuffer_add_printf(tmp,":%d", uri->port);
4373 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
4374 goto err;
4377 if (uri->path)
4378 _URI_ADD(path);
4380 if (uri->query) {
4381 evbuffer_add(tmp, "?", 1);
4382 _URI_ADD(query);
4385 if (uri->fragment) {
4386 evbuffer_add(tmp, "#", 1);
4387 _URI_ADD(fragment);
4390 evbuffer_add(tmp, "\0", 1); /* NUL */
4392 joined_size = evbuffer_get_length(tmp);
4394 if (joined_size > limit) {
4395 /* It doesn't fit. */
4396 evbuffer_free(tmp);
4397 return NULL;
4399 evbuffer_remove(tmp, buf, joined_size);
4401 output = buf;
4402 err:
4403 evbuffer_free(tmp);
4405 return output;
4406 #undef _URI_ADD
4409 const char *
4410 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
4412 return uri->scheme;
4414 const char *
4415 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
4417 return uri->userinfo;
4419 const char *
4420 evhttp_uri_get_host(const struct evhttp_uri *uri)
4422 return uri->host;
4425 evhttp_uri_get_port(const struct evhttp_uri *uri)
4427 return uri->port;
4429 const char *
4430 evhttp_uri_get_path(const struct evhttp_uri *uri)
4432 return uri->path;
4434 const char *
4435 evhttp_uri_get_query(const struct evhttp_uri *uri)
4437 return uri->query;
4439 const char *
4440 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
4442 return uri->fragment;
4445 #define _URI_SET_STR(f) do { \
4446 if (uri->f) \
4447 mm_free(uri->f); \
4448 if (f) { \
4449 if ((uri->f = mm_strdup(f)) == NULL) { \
4450 event_warn("%s: strdup()", __func__); \
4451 return -1; \
4453 } else { \
4454 uri->f = NULL; \
4456 } while(0)
4459 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
4461 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
4462 return -1;
4464 _URI_SET_STR(scheme);
4465 return 0;
4468 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
4470 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
4471 return -1;
4472 _URI_SET_STR(userinfo);
4473 return 0;
4476 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
4478 if (host) {
4479 if (host[0] == '[') {
4480 if (! bracket_addr_ok(host, host+strlen(host)))
4481 return -1;
4482 } else {
4483 if (! regname_ok(host, host+strlen(host)))
4484 return -1;
4488 _URI_SET_STR(host);
4489 return 0;
4492 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
4494 if (port < -1)
4495 return -1;
4496 uri->port = port;
4497 return 0;
4499 #define end_of_cpath(cp,p,f) \
4500 ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
4503 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
4505 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
4506 return -1;
4508 _URI_SET_STR(path);
4509 return 0;
4512 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
4514 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
4515 return -1;
4516 _URI_SET_STR(query);
4517 return 0;
4520 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
4522 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
4523 return -1;
4524 _URI_SET_STR(fragment);
4525 return 0;