]> arthur.barton.de Git - netatalk.git/blob - libevent/http.c
Update libevent to 2.0.12
[netatalk.git] / libevent / http.c
1 /*
2  * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu>
3  * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson
4  *
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.
15  *
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.
26  */
27
28 #include "event2/event-config.h"
29
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
36
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
43
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
53
54 #include <sys/queue.h>
55
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
65
66 #ifdef WIN32
67 #include <winsock2.h>
68 #endif
69
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
85
86 #undef timeout_pending
87 #undef timeout_initialized
88
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"
104
105 #ifndef _EVENT_HAVE_GETNAMEINFO
106 #define NI_MAXSERV 32
107 #define NI_MAXHOST 1025
108
109 #ifndef NI_NUMERICHOST
110 #define NI_NUMERICHOST 1
111 #endif
112
113 #ifndef NI_NUMERICSERV
114 #define NI_NUMERICSERV 2
115 #endif
116
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)
120 {
121         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
122
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);
129         }
130
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);
144
145                         if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
146                                 return (-1);
147                         else
148                                 return (0);
149                 }
150         }
151         return (0);
152 }
153
154 #endif
155
156 #define REQ_VERSION_BEFORE(req, major_v, minor_v)                       \
157         ((req)->major < (major_v) ||                                    \
158             ((req)->major == (major_v) && (req)->minor < (minor_v)))
159
160 #define REQ_VERSION_ATLEAST(req, major_v, minor_v)                      \
161         ((req)->major > (major_v) ||                                    \
162             ((req)->major == (major_v) && (req)->minor >= (minor_v)))
163
164 #ifndef MIN
165 #define MIN(a,b) (((a)<(b))?(a):(b))
166 #endif
167
168 extern int debug;
169
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 *);
191
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);
200
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)
206 {
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;
219 }
220 #endif
221
222 static size_t
223 html_replace(const char ch, const char **escaped)
224 {
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;
243         }
244
245         return 1;
246 }
247
248 /*
249  * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
250  * &#039; and &amp; correspondingly.
251  *
252  * The returned string needs to be freed by the caller.
253  */
254
255 char *
256 evhttp_htmlescape(const char *html)
257 {
258         size_t i;
259         size_t new_size = 0, old_size = 0;
260         char *escaped_html, *p;
261
262         if (html == NULL)
263                 return (NULL);
264
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);
272                 }
273                 new_size += replace_size;
274         }
275
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);
283         }
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;
289         }
290
291         *p = '\0';
292
293         return (escaped_html);
294 }
295
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)
301 {
302         const char *method;
303
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;
335         }
336
337         return (method);
338 }
339
340 /**
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.
345  */
346 static int
347 evhttp_response_needs_body(struct evhttp_request *req)
348 {
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);
353 }
354
355 /** Helper: adds the event 'ev' with the timeout 'timeout', or with
356  * default_timeout if timeout is -1.
357  */
358 static int
359 evhttp_add_event(struct event *ev, int timeout, int default_timeout)
360 {
361         if (timeout != 0) {
362                 struct timeval tv;
363
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);
369         }
370 }
371
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.
375  */
376 static void
377 evhttp_write_buffer(struct evhttp_connection *evcon,
378     void (*cb)(struct evhttp_connection *, void *), void *arg)
379 {
380         event_debug(("%s: preparing to write buffer\n", __func__));
381
382         /* Set call back */
383         evcon->cb = cb;
384         evcon->cb_arg = arg;
385
386         bufferevent_enable(evcon->bufev, EV_WRITE);
387
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);
396 }
397
398 static void
399 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
400 {
401         bufferevent_disable(evcon->bufev, EV_WRITE);
402 }
403
404 static void
405 evhttp_send_continue(struct evhttp_connection *evcon,
406                         struct evhttp_request *req)
407 {
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);
419 }
420
421 /** Helper: returns true iff evconn is in any connected state. */
422 static int
423 evhttp_connected(struct evhttp_connection *evcon)
424 {
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);
437         }
438 }
439
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.
443  */
444 static void
445 evhttp_make_header_request(struct evhttp_connection *evcon,
446     struct evhttp_request *req)
447 {
448         const char *method;
449
450         evhttp_remove_header(req->output_headers, "Proxy-Connection");
451
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);
457
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), "%ld",
463                     (long)evbuffer_get_length(req->output_buffer));
464                 evhttp_add_header(req->output_headers, "Content-Length", size);
465         }
466 }
467
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)
473 {
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);
481         }
482 }
483
484 /* Return true iff 'headers' contains 'Connection: keep-alive' */
485 static int
486 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
487 {
488         const char *connection = evhttp_find_header(headers, "Connection");
489         return (connection != NULL
490             && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0);
491 }
492
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)
496 {
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);
513                 }
514         }
515 }
516
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     long content_length) /* XXX use size_t or int64, not long. */
522 {
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), "%ld", content_length);
527                 evhttp_add_header(headers, "Content-Length", len);
528         }
529 }
530
531 /*
532  * Create the headers needed for an HTTP reply in req->output_headers,
533  * and write the first HTTP response for req line to evcon.
534  */
535 static void
536 evhttp_make_header_response(struct evhttp_connection *evcon,
537     struct evhttp_request *req)
538 {
539         int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
540         evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
541             "HTTP/%d.%d %d %s\r\n",
542             req->major, req->minor, req->response_code,
543             req->response_code_line);
544
545         if (req->major == 1) {
546                 if (req->minor >= 1)
547                         evhttp_maybe_add_date_header(req->output_headers);
548
549                 /*
550                  * if the protocol is 1.0; and the connection was keep-alive
551                  * we need to add a keep-alive header, too.
552                  */
553                 if (req->minor == 0 && is_keepalive)
554                         evhttp_add_header(req->output_headers,
555                             "Connection", "keep-alive");
556
557                 if ((req->minor >= 1 || is_keepalive) &&
558                     evhttp_response_needs_body(req)) {
559                         /*
560                          * we need to add the content length if the
561                          * user did not give it, this is required for
562                          * persistent connections to work.
563                          */
564                         evhttp_maybe_add_content_length_header(
565                                 req->output_headers,
566                                 (long)evbuffer_get_length(req->output_buffer));
567                 }
568         }
569
570         /* Potentially add headers for unidentified content. */
571         if (evhttp_response_needs_body(req)) {
572                 if (evhttp_find_header(req->output_headers,
573                         "Content-Type") == NULL) {
574                         evhttp_add_header(req->output_headers,
575                             "Content-Type", "text/html; charset=ISO-8859-1");
576                 }
577         }
578
579         /* if the request asked for a close, we send a close, too */
580         if (evhttp_is_connection_close(req->flags, req->input_headers)) {
581                 evhttp_remove_header(req->output_headers, "Connection");
582                 if (!(req->flags & EVHTTP_PROXY_REQUEST))
583                     evhttp_add_header(req->output_headers, "Connection", "close");
584                 evhttp_remove_header(req->output_headers, "Proxy-Connection");
585         }
586 }
587
588 /** Generate all headers appropriate for sending the http request in req (or
589  * the response, if we're sending a response), and write them to evcon's
590  * bufferevent. Also writes all data from req->output_buffer */
591 static void
592 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
593 {
594         struct evkeyval *header;
595         struct evbuffer *output = bufferevent_get_output(evcon->bufev);
596
597         /*
598          * Depending if this is a HTTP request or response, we might need to
599          * add some new headers or remove existing headers.
600          */
601         if (req->kind == EVHTTP_REQUEST) {
602                 evhttp_make_header_request(evcon, req);
603         } else {
604                 evhttp_make_header_response(evcon, req);
605         }
606
607         TAILQ_FOREACH(header, req->output_headers, next) {
608                 evbuffer_add_printf(output, "%s: %s\r\n",
609                     header->key, header->value);
610         }
611         evbuffer_add(output, "\r\n", 2);
612
613         if (evbuffer_get_length(req->output_buffer) > 0) {
614                 /*
615                  * For a request, we add the POST data, for a reply, this
616                  * is the regular data.
617                  */
618                 /* XXX We might want to support waiting (a limited amount of
619                    time) for a continue status line from the server before
620                    sending POST/PUT message bodies. */
621                 evbuffer_add_buffer(output, req->output_buffer);
622         }
623 }
624
625 void
626 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon,
627     ev_ssize_t new_max_headers_size)
628 {
629         if (new_max_headers_size<0)
630                 evcon->max_headers_size = EV_SIZE_MAX;
631         else
632                 evcon->max_headers_size = new_max_headers_size;
633 }
634 void
635 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon,
636     ev_ssize_t new_max_body_size)
637 {
638         if (new_max_body_size<0)
639                 evcon->max_body_size = EV_UINT64_MAX;
640         else
641                 evcon->max_body_size = new_max_body_size;
642 }
643
644 static int
645 evhttp_connection_incoming_fail(struct evhttp_request *req,
646     enum evhttp_connection_error error)
647 {
648         switch (error) {
649         case EVCON_HTTP_TIMEOUT:
650         case EVCON_HTTP_EOF:
651                 /*
652                  * these are cases in which we probably should just
653                  * close the connection and not send a reply.  this
654                  * case may happen when a browser keeps a persistent
655                  * connection open and we timeout on the read.  when
656                  * the request is still being used for sending, we
657                  * need to disassociated it from the connection here.
658                  */
659                 if (!req->userdone) {
660                         /* remove it so that it will not be freed */
661                         TAILQ_REMOVE(&req->evcon->requests, req, next);
662                         /* indicate that this request no longer has a
663                          * connection object
664                          */
665                         req->evcon = NULL;
666                 }
667                 return (-1);
668         case EVCON_HTTP_INVALID_HEADER:
669         case EVCON_HTTP_BUFFER_ERROR:
670         case EVCON_HTTP_REQUEST_CANCEL:
671         default:        /* xxx: probably should just error on default */
672                 /* the callback looks at the uri to determine errors */
673                 if (req->uri) {
674                         mm_free(req->uri);
675                         req->uri = NULL;
676                 }
677                 if (req->uri_elems) {
678                         evhttp_uri_free(req->uri_elems);
679                         req->uri_elems = NULL;
680                 }
681
682                 /*
683                  * the callback needs to send a reply, once the reply has
684                  * been send, the connection should get freed.
685                  */
686                 (*req->cb)(req, req->cb_arg);
687         }
688
689         return (0);
690 }
691
692 /* Called when evcon has experienced a (non-recoverable? -NM) error, as
693  * given in error. If it's an outgoing connection, reset the connection,
694  * retry any pending requests, and inform the user.  If it's incoming,
695  * delegates to evhttp_connection_incoming_fail(). */
696 void
697 evhttp_connection_fail(struct evhttp_connection *evcon,
698     enum evhttp_connection_error error)
699 {
700         struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
701         void (*cb)(struct evhttp_request *, void *);
702         void *cb_arg;
703         EVUTIL_ASSERT(req != NULL);
704
705         bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE);
706
707         if (evcon->flags & EVHTTP_CON_INCOMING) {
708                 /*
709                  * for incoming requests, there are two different
710                  * failure cases.  it's either a network level error
711                  * or an http layer error. for problems on the network
712                  * layer like timeouts we just drop the connections.
713                  * For HTTP problems, we might have to send back a
714                  * reply before the connection can be freed.
715                  */
716                 if (evhttp_connection_incoming_fail(req, error) == -1)
717                         evhttp_connection_free(evcon);
718                 return;
719         }
720
721         /* when the request was canceled, the callback is not executed */
722         if (error != EVCON_HTTP_REQUEST_CANCEL) {
723                 /* save the callback for later; the cb might free our object */
724                 cb = req->cb;
725                 cb_arg = req->cb_arg;
726         } else {
727                 cb = NULL;
728                 cb_arg = NULL;
729         }
730
731         /* do not fail all requests; the next request is going to get
732          * send over a new connection.   when a user cancels a request,
733          * all other pending requests should be processed as normal
734          */
735         TAILQ_REMOVE(&evcon->requests, req, next);
736         evhttp_request_free(req);
737
738         /* reset the connection */
739         evhttp_connection_reset(evcon);
740
741         /* We are trying the next request that was queued on us */
742         if (TAILQ_FIRST(&evcon->requests) != NULL)
743                 evhttp_connection_connect(evcon);
744
745         /* inform the user */
746         if (cb != NULL)
747                 (*cb)(NULL, cb_arg);
748 }
749
750 /* Bufferevent callback: invoked when any data has been written from an
751  * http connection's bufferevent */
752 static void
753 evhttp_write_cb(struct bufferevent *bufev, void *arg)
754 {
755         struct evhttp_connection *evcon = arg;
756
757         /* Activate our call back */
758         if (evcon->cb != NULL)
759                 (*evcon->cb)(evcon, evcon->cb_arg);
760 }
761
762 /**
763  * Advance the connection state.
764  * - If this is an outgoing connection, we've just processed the response;
765  *   idle or close the connection.
766  * - If this is an incoming connection, we've just processed the request;
767  *   respond.
768  */
769 static void
770 evhttp_connection_done(struct evhttp_connection *evcon)
771 {
772         struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
773         int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
774
775         if (con_outgoing) {
776                 /* idle or close the connection */
777                 int need_close;
778                 TAILQ_REMOVE(&evcon->requests, req, next);
779                 req->evcon = NULL;
780
781                 evcon->state = EVCON_IDLE;
782
783                 need_close =
784                     evhttp_is_connection_close(req->flags, req->input_headers)||
785                     evhttp_is_connection_close(req->flags, req->output_headers);
786
787                 /* check if we got asked to close the connection */
788                 if (need_close)
789                         evhttp_connection_reset(evcon);
790
791                 if (TAILQ_FIRST(&evcon->requests) != NULL) {
792                         /*
793                          * We have more requests; reset the connection
794                          * and deal with the next request.
795                          */
796                         if (!evhttp_connected(evcon))
797                                 evhttp_connection_connect(evcon);
798                         else
799                                 evhttp_request_dispatch(evcon);
800                 } else if (!need_close) {
801                         /*
802                          * The connection is going to be persistent, but we
803                          * need to detect if the other side closes it.
804                          */
805                         evhttp_connection_start_detectclose(evcon);
806                 }
807         } else {
808                 /*
809                  * incoming connection - we need to leave the request on the
810                  * connection so that we can reply to it.
811                  */
812                 evcon->state = EVCON_WRITING;
813         }
814
815         /* notify the user of the request */
816         (*req->cb)(req, req->cb_arg);
817
818         /* if this was an outgoing request, we own and it's done. so free it.
819          * unless the callback specifically requested to own the request.
820          */
821         if (con_outgoing && ((req->flags & EVHTTP_USER_OWNED) == 0)) {
822                 evhttp_request_free(req);
823         }
824 }
825
826 /*
827  * Handles reading from a chunked request.
828  *   return ALL_DATA_READ:
829  *     all data has been read
830  *   return MORE_DATA_EXPECTED:
831  *     more data is expected
832  *   return DATA_CORRUPTED:
833  *     data is corrupted
834  *   return REQUEST_CANCELED:
835  *     request was canceled by the user calling evhttp_cancel_request
836  *   return DATA_TOO_LONG:
837  *     ran over the maximum limit
838  */
839
840 static enum message_read_status
841 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
842 {
843         if (req == NULL || buf == NULL) {
844             return DATA_CORRUPTED;
845         }
846
847         while (1) {
848                 size_t buflen;
849
850                 if ((buflen = evbuffer_get_length(buf)) == 0) {
851                         break;
852                 }
853
854                 /* evbuffer_get_length returns size_t, but len variable is ssize_t,
855                  * check for overflow conditions */
856                 if (buflen > EV_SSIZE_MAX) {
857                         return DATA_CORRUPTED;
858                 }
859
860                 if (req->ntoread < 0) {
861                         /* Read chunk size */
862                         ev_int64_t ntoread;
863                         char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF);
864                         char *endp;
865                         int error;
866                         if (p == NULL)
867                                 break;
868                         /* the last chunk is on a new line? */
869                         if (strlen(p) == 0) {
870                                 mm_free(p);
871                                 continue;
872                         }
873                         ntoread = evutil_strtoll(p, &endp, 16);
874                         error = (*p == '\0' ||
875                             (*endp != '\0' && *endp != ' ') ||
876                             ntoread < 0);
877                         mm_free(p);
878                         if (error) {
879                                 /* could not get chunk size */
880                                 return (DATA_CORRUPTED);
881                         }
882
883                         /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
884                         if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
885                             return DATA_CORRUPTED;
886                         }
887
888                         if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
889                                 /* failed body length test */
890                                 event_debug(("Request body is too long"));
891                                 return (DATA_TOO_LONG);
892                         }
893
894                         req->body_size += (size_t)ntoread;
895                         req->ntoread = ntoread;
896                         if (req->ntoread == 0) {
897                                 /* Last chunk */
898                                 return (ALL_DATA_READ);
899                         }
900                         continue;
901                 }
902
903                 /* req->ntoread is signed int64, len is ssize_t, based on arch,
904                  * ssize_t could only be 32b, check for these conditions */
905                 if (req->ntoread > EV_SSIZE_MAX) {
906                         return DATA_CORRUPTED;
907                 }
908
909                 /* don't have enough to complete a chunk; wait for more */
910                 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
911                         return (MORE_DATA_EXPECTED);
912
913                 /* Completed chunk */
914                 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
915                 req->ntoread = -1;
916                 if (req->chunk_cb != NULL) {
917                         req->flags |= EVHTTP_REQ_DEFER_FREE;
918                         (*req->chunk_cb)(req, req->cb_arg);
919                         evbuffer_drain(req->input_buffer,
920                             evbuffer_get_length(req->input_buffer));
921                         req->flags &= ~EVHTTP_REQ_DEFER_FREE;
922                         if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
923                                 return (REQUEST_CANCELED);
924                         }
925                 }
926         }
927
928         return (MORE_DATA_EXPECTED);
929 }
930
931 static void
932 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
933 {
934         struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
935
936         switch (evhttp_parse_headers(req, buf)) {
937         case DATA_CORRUPTED:
938         case DATA_TOO_LONG:
939                 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
940                 break;
941         case ALL_DATA_READ:
942                 bufferevent_disable(evcon->bufev, EV_READ);
943                 evhttp_connection_done(evcon);
944                 break;
945         case MORE_DATA_EXPECTED:
946         case REQUEST_CANCELED: /* ??? */
947         default:
948                 bufferevent_enable(evcon->bufev, EV_READ);
949                 break;
950         }
951 }
952
953 static void
954 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
955 {
956         struct evbuffer *buf = bufferevent_get_input(evcon->bufev);
957
958         if (req->chunked) {
959                 switch (evhttp_handle_chunked_read(req, buf)) {
960                 case ALL_DATA_READ:
961                         /* finished last chunk */
962                         evcon->state = EVCON_READING_TRAILER;
963                         evhttp_read_trailer(evcon, req);
964                         return;
965                 case DATA_CORRUPTED:
966                 case DATA_TOO_LONG:/*separate error for this? XXX */
967                         /* corrupted data */
968                         evhttp_connection_fail(evcon,
969                             EVCON_HTTP_INVALID_HEADER);
970                         return;
971                 case REQUEST_CANCELED:
972                         /* request canceled */
973                         evhttp_request_free(req);
974                         return;
975                 case MORE_DATA_EXPECTED:
976                 default:
977                         break;
978                 }
979         } else if (req->ntoread < 0) {
980                 /* Read until connection close. */
981                 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
982                         evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
983                         return;
984                 }
985
986                 req->body_size += evbuffer_get_length(buf);
987                 evbuffer_add_buffer(req->input_buffer, buf);
988         } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
989                 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
990                 /* We've postponed moving the data until now, but we're
991                  * about to use it. */
992                 size_t n = evbuffer_get_length(buf);
993
994                 if (n > (size_t) req->ntoread)
995                         n = (size_t) req->ntoread;
996                 req->ntoread -= n;
997                 req->body_size += n;
998                 evbuffer_remove_buffer(buf, req->input_buffer, n);
999         }
1000
1001         if (req->body_size > req->evcon->max_body_size ||
1002             (!req->chunked && req->ntoread >= 0 &&
1003                 (size_t)req->ntoread > req->evcon->max_body_size)) {
1004                 /* XXX: The above casted comparison must checked for overflow */
1005                 /* failed body length test */
1006                 event_debug(("Request body is too long"));
1007                 evhttp_connection_fail(evcon,
1008                                        EVCON_HTTP_INVALID_HEADER);
1009                 return;
1010         }
1011
1012         if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) {
1013                 req->flags |= EVHTTP_REQ_DEFER_FREE;
1014                 (*req->chunk_cb)(req, req->cb_arg);
1015                 req->flags &= ~EVHTTP_REQ_DEFER_FREE;
1016                 evbuffer_drain(req->input_buffer,
1017                     evbuffer_get_length(req->input_buffer));
1018                 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) {
1019                         evhttp_request_free(req);
1020                         return;
1021                 }
1022         }
1023
1024         if (req->ntoread == 0) {
1025                 bufferevent_disable(evcon->bufev, EV_READ);
1026                 /* Completed content length */
1027                 evhttp_connection_done(evcon);
1028                 return;
1029         }
1030
1031         /* Read more! */
1032         bufferevent_enable(evcon->bufev, EV_READ);
1033 }
1034
1035 #define get_deferred_queue(evcon)               \
1036         (event_base_get_deferred_cb_queue((evcon)->base))
1037
1038 /*
1039  * Gets called when more data becomes available
1040  */
1041
1042 static void
1043 evhttp_read_cb(struct bufferevent *bufev, void *arg)
1044 {
1045         struct evhttp_connection *evcon = arg;
1046         struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1047
1048         /* Cancel if it's pending. */
1049         event_deferred_cb_cancel(get_deferred_queue(evcon),
1050             &evcon->read_more_deferred_cb);
1051
1052         switch (evcon->state) {
1053         case EVCON_READING_FIRSTLINE:
1054                 evhttp_read_firstline(evcon, req);
1055                 /* note the request may have been freed in
1056                  * evhttp_read_body */
1057                 break;
1058         case EVCON_READING_HEADERS:
1059                 evhttp_read_header(evcon, req);
1060                 /* note the request may have been freed in
1061                  * evhttp_read_body */
1062                 break;
1063         case EVCON_READING_BODY:
1064                 evhttp_read_body(evcon, req);
1065                 /* note the request may have been freed in
1066                  * evhttp_read_body */
1067                 break;
1068         case EVCON_READING_TRAILER:
1069                 evhttp_read_trailer(evcon, req);
1070                 break;
1071         case EVCON_IDLE:
1072                 {
1073 #ifdef USE_DEBUG
1074                         struct evbuffer *input;
1075                         size_t total_len;
1076
1077                         input = bufferevent_get_input(evcon->bufev);
1078                         total_len = evbuffer_get_length(input);
1079                         event_debug(("%s: read %d bytes in EVCON_IDLE state,"
1080                                     " resetting connection",
1081                                         __func__, (int)total_len));
1082 #endif
1083
1084                         evhttp_connection_reset(evcon);
1085                 }
1086                 break;
1087         case EVCON_DISCONNECTED:
1088         case EVCON_CONNECTING:
1089         case EVCON_WRITING:
1090         default:
1091                 event_errx(1, "%s: illegal connection state %d",
1092                            __func__, evcon->state);
1093         }
1094 }
1095
1096 static void
1097 evhttp_deferred_read_cb(struct deferred_cb *cb, void *data)
1098 {
1099         struct evhttp_connection *evcon = data;
1100         evhttp_read_cb(evcon->bufev, evcon);
1101 }
1102
1103 static void
1104 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
1105 {
1106         /* This is after writing the request to the server */
1107         struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1108         EVUTIL_ASSERT(req != NULL);
1109
1110         EVUTIL_ASSERT(evcon->state == EVCON_WRITING);
1111
1112         /* We are done writing our header and are now expecting the response */
1113         req->kind = EVHTTP_RESPONSE;
1114
1115         evhttp_start_read(evcon);
1116 }
1117
1118 /*
1119  * Clean up a connection object
1120  */
1121
1122 void
1123 evhttp_connection_free(struct evhttp_connection *evcon)
1124 {
1125         struct evhttp_request *req;
1126
1127         /* notify interested parties that this connection is going down */
1128         if (evcon->fd != -1) {
1129                 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1130                         (*evcon->closecb)(evcon, evcon->closecb_arg);
1131         }
1132
1133         /* remove all requests that might be queued on this
1134          * connection.  for server connections, this should be empty.
1135          * because it gets dequeued either in evhttp_connection_done or
1136          * evhttp_connection_fail.
1137          */
1138         while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1139                 TAILQ_REMOVE(&evcon->requests, req, next);
1140                 evhttp_request_free(req);
1141         }
1142
1143         if (evcon->http_server != NULL) {
1144                 struct evhttp *http = evcon->http_server;
1145                 TAILQ_REMOVE(&http->connections, evcon, next);
1146         }
1147
1148         if (event_initialized(&evcon->retry_ev)) {
1149                 event_del(&evcon->retry_ev);
1150                 event_debug_unassign(&evcon->retry_ev);
1151         }
1152
1153         if (evcon->bufev != NULL)
1154                 bufferevent_free(evcon->bufev);
1155
1156         event_deferred_cb_cancel(get_deferred_queue(evcon),
1157             &evcon->read_more_deferred_cb);
1158
1159         if (evcon->fd != -1) {
1160                 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1161                 evutil_closesocket(evcon->fd);
1162         }
1163
1164         if (evcon->bind_address != NULL)
1165                 mm_free(evcon->bind_address);
1166
1167         if (evcon->address != NULL)
1168                 mm_free(evcon->address);
1169
1170         mm_free(evcon);
1171 }
1172
1173 void
1174 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1175     const char *address)
1176 {
1177         EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1178         if (evcon->bind_address)
1179                 mm_free(evcon->bind_address);
1180         if ((evcon->bind_address = mm_strdup(address)) == NULL)
1181                 event_warn("%s: strdup", __func__);
1182 }
1183
1184 void
1185 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1186     ev_uint16_t port)
1187 {
1188         EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
1189         evcon->bind_port = port;
1190 }
1191
1192 static void
1193 evhttp_request_dispatch(struct evhttp_connection* evcon)
1194 {
1195         struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1196
1197         /* this should not usually happy but it's possible */
1198         if (req == NULL)
1199                 return;
1200
1201         /* delete possible close detection events */
1202         evhttp_connection_stop_detectclose(evcon);
1203
1204         /* we assume that the connection is connected already */
1205         EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1206
1207         evcon->state = EVCON_WRITING;
1208
1209         /* Create the header from the store arguments */
1210         evhttp_make_header(evcon, req);
1211
1212         evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1213 }
1214
1215 /* Reset our connection state: disables reading/writing, closes our fd (if
1216 * any), clears out buffers, and puts us in state DISCONNECTED. */
1217 void
1218 evhttp_connection_reset(struct evhttp_connection *evcon)
1219 {
1220         struct evbuffer *tmp;
1221
1222         /* XXXX This is not actually an optimal fix.  Instead we ought to have
1223            an API for "stop connecting", or use bufferevent_setfd to turn off
1224            connecting.  But for Libevent 2.0, this seems like a minimal change
1225            least likely to disrupt the rest of the bufferevent and http code.
1226
1227            Why is this here?  If the fd is set in the bufferevent, and the
1228            bufferevent is connecting, then you can't actually stop the
1229            bufferevent from trying to connect with bufferevent_disable().  The
1230            connect will never trigger, since we close the fd, but the timeout
1231            might.  That caused an assertion failure in evhttp_connection_fail.
1232         */
1233         bufferevent_disable_hard(evcon->bufev, EV_READ|EV_WRITE);
1234
1235         if (evcon->fd != -1) {
1236                 /* inform interested parties about connection close */
1237                 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1238                         (*evcon->closecb)(evcon, evcon->closecb_arg);
1239
1240                 shutdown(evcon->fd, EVUTIL_SHUT_WR);
1241                 evutil_closesocket(evcon->fd);
1242                 evcon->fd = -1;
1243         }
1244
1245         /* we need to clean up any buffered data */
1246         tmp = bufferevent_get_output(evcon->bufev);
1247         evbuffer_drain(tmp, evbuffer_get_length(tmp));
1248         tmp = bufferevent_get_input(evcon->bufev);
1249         evbuffer_drain(tmp, evbuffer_get_length(tmp));
1250
1251         evcon->state = EVCON_DISCONNECTED;
1252 }
1253
1254 static void
1255 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1256 {
1257         evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1258
1259         bufferevent_enable(evcon->bufev, EV_READ);
1260 }
1261
1262 static void
1263 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1264 {
1265         evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1266
1267         bufferevent_disable(evcon->bufev, EV_READ);
1268 }
1269
1270 static void
1271 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg)
1272 {
1273         struct evhttp_connection *evcon = arg;
1274
1275         evcon->state = EVCON_DISCONNECTED;
1276         evhttp_connection_connect(evcon);
1277 }
1278
1279 static void
1280 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
1281 {
1282         struct evcon_requestq requests;
1283
1284         if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1285                 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
1286                 /* XXXX handle failure from evhttp_add_event */
1287                 evhttp_add_event(&evcon->retry_ev,
1288                     MIN(3600, 2 << evcon->retry_cnt),
1289                     HTTP_CONNECT_TIMEOUT);
1290                 evcon->retry_cnt++;
1291                 return;
1292         }
1293         evhttp_connection_reset(evcon);
1294
1295         /*
1296          * User callback can do evhttp_make_request() on the same
1297          * evcon so new request will be added to evcon->requests.  To
1298          * avoid freeing it prematurely we iterate over the copy of
1299          * the queue.
1300          */
1301         TAILQ_INIT(&requests);
1302         while (TAILQ_FIRST(&evcon->requests) != NULL) {
1303                 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1304                 TAILQ_REMOVE(&evcon->requests, request, next);
1305                 TAILQ_INSERT_TAIL(&requests, request, next);
1306         }
1307
1308         /* for now, we just signal all requests by executing their callbacks */
1309         while (TAILQ_FIRST(&requests) != NULL) {
1310                 struct evhttp_request *request = TAILQ_FIRST(&requests);
1311                 TAILQ_REMOVE(&requests, request, next);
1312                 request->evcon = NULL;
1313
1314                 /* we might want to set an error here */
1315                 request->cb(request, request->cb_arg);
1316                 evhttp_request_free(request);
1317         }
1318 }
1319
1320 static void
1321 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
1322 {
1323         struct evhttp_connection *evcon = arg;
1324         struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1325
1326         switch (evcon->state) {
1327         case EVCON_CONNECTING:
1328                 if (what & BEV_EVENT_TIMEOUT) {
1329                         event_debug(("%s: connection timeout for \"%s:%d\" on %d",
1330                                 __func__, evcon->address, evcon->port,
1331                                 evcon->fd));
1332                         evhttp_connection_cb_cleanup(evcon);
1333                         return;
1334                 }
1335                 break;
1336
1337         case EVCON_READING_BODY:
1338                 if (!req->chunked && req->ntoread < 0
1339                     && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) {
1340                         /* EOF on read can be benign */
1341                         evhttp_connection_done(evcon);
1342                         return;
1343                 }
1344                 break;
1345
1346         case EVCON_DISCONNECTED:
1347         case EVCON_IDLE:
1348         case EVCON_READING_FIRSTLINE:
1349         case EVCON_READING_HEADERS:
1350         case EVCON_READING_TRAILER:
1351         case EVCON_WRITING:
1352         default:
1353                 break;
1354         }
1355
1356         /* when we are in close detect mode, a read error means that
1357          * the other side closed their connection.
1358          */
1359         if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
1360                 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1361                 EVUTIL_ASSERT(evcon->http_server == NULL);
1362                 /* For connections from the client, we just
1363                  * reset the connection so that it becomes
1364                  * disconnected.
1365                  */
1366                 EVUTIL_ASSERT(evcon->state == EVCON_IDLE);
1367                 evhttp_connection_reset(evcon);
1368                 return;
1369         }
1370
1371         if (what & BEV_EVENT_TIMEOUT) {
1372                 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
1373         } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
1374                 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
1375         } else {
1376                 evhttp_connection_fail(evcon, EVCON_HTTP_BUFFER_ERROR);
1377         }
1378 }
1379
1380 /*
1381  * Event callback for asynchronous connection attempt.
1382  */
1383 static void
1384 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg)
1385 {
1386         struct evhttp_connection *evcon = arg;
1387         int error;
1388         ev_socklen_t errsz = sizeof(error);
1389
1390         if (!(what & BEV_EVENT_CONNECTED)) {
1391                 /* some operating systems return ECONNREFUSED immediately
1392                  * when connecting to a local address.  the cleanup is going
1393                  * to reschedule this function call.
1394                  */
1395 #ifndef WIN32
1396                 if (errno == ECONNREFUSED)
1397                         goto cleanup;
1398 #endif
1399                 evhttp_error_cb(bufev, what, arg);
1400                 return;
1401         }
1402
1403         /* Check if the connection completed */
1404         if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1405                        &errsz) == -1) {
1406                 event_debug(("%s: getsockopt for \"%s:%d\" on %d",
1407                         __func__, evcon->address, evcon->port, evcon->fd));
1408                 goto cleanup;
1409         }
1410
1411         if (error) {
1412                 event_debug(("%s: connect failed for \"%s:%d\" on %d: %s",
1413                     __func__, evcon->address, evcon->port, evcon->fd,
1414                         evutil_socket_error_to_string(error)));
1415                 goto cleanup;
1416         }
1417
1418         /* We are connected to the server now */
1419         event_debug(("%s: connected to \"%s:%d\" on %d\n",
1420                         __func__, evcon->address, evcon->port, evcon->fd));
1421
1422         /* Reset the retry count as we were successful in connecting */
1423         evcon->retry_cnt = 0;
1424         evcon->state = EVCON_IDLE;
1425
1426         /* reset the bufferevent cbs */
1427         bufferevent_setcb(evcon->bufev,
1428             evhttp_read_cb,
1429             evhttp_write_cb,
1430             evhttp_error_cb,
1431             evcon);
1432
1433         if (evcon->timeout == -1)
1434                 bufferevent_settimeout(evcon->bufev,
1435                     HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
1436         else {
1437                 struct timeval tv;
1438                 tv.tv_sec = evcon->timeout;
1439                 tv.tv_usec = 0;
1440                 bufferevent_set_timeouts(evcon->bufev, &tv, &tv);
1441         }
1442
1443         /* try to start requests that have queued up on this connection */
1444         evhttp_request_dispatch(evcon);
1445         return;
1446
1447  cleanup:
1448         evhttp_connection_cb_cleanup(evcon);
1449 }
1450
1451 /*
1452  * Check if we got a valid response code.
1453  */
1454
1455 static int
1456 evhttp_valid_response_code(int code)
1457 {
1458         if (code == 0)
1459                 return (0);
1460
1461         return (1);
1462 }
1463
1464 static int
1465 evhttp_parse_http_version(const char *version, struct evhttp_request *req)
1466 {
1467         int major, minor;
1468         char ch;
1469         int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch);
1470         if (n > 2 || major > 1) {
1471                 event_debug(("%s: bad version %s on message %p from %s",
1472                         __func__, version, req, req->remote_host));
1473                 return (-1);
1474         }
1475         req->major = major;
1476         req->minor = minor;
1477         return (0);
1478 }
1479
1480 /* Parses the status line of a web server */
1481
1482 static int
1483 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1484 {
1485         char *protocol;
1486         char *number;
1487         const char *readable = "";
1488
1489         protocol = strsep(&line, " ");
1490         if (line == NULL)
1491                 return (-1);
1492         number = strsep(&line, " ");
1493         if (line != NULL)
1494                 readable = line;
1495
1496         if (evhttp_parse_http_version(protocol, req) < 0)
1497                 return (-1);
1498
1499         req->response_code = atoi(number);
1500         if (!evhttp_valid_response_code(req->response_code)) {
1501                 event_debug(("%s: bad response code \"%s\"",
1502                         __func__, number));
1503                 return (-1);
1504         }
1505
1506         if ((req->response_code_line = mm_strdup(readable)) == NULL) {
1507                 event_warn("%s: strdup", __func__);
1508                 return (-1);
1509         }
1510
1511         return (0);
1512 }
1513
1514 /* Parse the first line of a HTTP request */
1515
1516 static int
1517 evhttp_parse_request_line(struct evhttp_request *req, char *line)
1518 {
1519         char *method;
1520         char *uri;
1521         char *version;
1522         const char *hostname;
1523         const char *scheme;
1524
1525         /* Parse the request line */
1526         method = strsep(&line, " ");
1527         if (line == NULL)
1528                 return (-1);
1529         uri = strsep(&line, " ");
1530         if (line == NULL)
1531                 return (-1);
1532         version = strsep(&line, " ");
1533         if (line != NULL)
1534                 return (-1);
1535
1536         /* First line */
1537         if (strcmp(method, "GET") == 0) {
1538                 req->type = EVHTTP_REQ_GET;
1539         } else if (strcmp(method, "POST") == 0) {
1540                 req->type = EVHTTP_REQ_POST;
1541         } else if (strcmp(method, "HEAD") == 0) {
1542                 req->type = EVHTTP_REQ_HEAD;
1543         } else if (strcmp(method, "PUT") == 0) {
1544                 req->type = EVHTTP_REQ_PUT;
1545         } else if (strcmp(method, "DELETE") == 0) {
1546                 req->type = EVHTTP_REQ_DELETE;
1547         } else if (strcmp(method, "OPTIONS") == 0) {
1548                 req->type = EVHTTP_REQ_OPTIONS;
1549         } else if (strcmp(method, "TRACE") == 0) {
1550                 req->type = EVHTTP_REQ_TRACE;
1551         } else if (strcmp(method, "PATCH") == 0) {
1552                 req->type = EVHTTP_REQ_PATCH;
1553         } else {
1554                 req->type = _EVHTTP_REQ_UNKNOWN;
1555                 event_debug(("%s: bad method %s on request %p from %s",
1556                         __func__, method, req, req->remote_host));
1557                 /* No error yet; we'll give a better error later when
1558                  * we see that req->type is unsupported. */
1559         }
1560
1561         if (evhttp_parse_http_version(version, req) < 0)
1562                 return (-1);
1563
1564         if ((req->uri = mm_strdup(uri)) == NULL) {
1565                 event_debug(("%s: mm_strdup", __func__));
1566                 return (-1);
1567         }
1568
1569         if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri,
1570                     EVHTTP_URI_NONCONFORMANT)) == NULL) {
1571                 return -1;
1572         }
1573
1574         /* If we have an absolute-URI, check to see if it is an http request
1575            for a known vhost or server alias. If we don't know about this
1576            host, we consider it a proxy request. */
1577         scheme = evhttp_uri_get_scheme(req->uri_elems);
1578         hostname = evhttp_uri_get_host(req->uri_elems);
1579         if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") ||
1580                        !evutil_ascii_strcasecmp(scheme, "https")) &&
1581             hostname &&
1582             !evhttp_find_vhost(req->evcon->http_server, NULL, hostname))
1583                 req->flags |= EVHTTP_PROXY_REQUEST;
1584
1585         return (0);
1586 }
1587
1588 const char *
1589 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1590 {
1591         struct evkeyval *header;
1592
1593         TAILQ_FOREACH(header, headers, next) {
1594                 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1595                         return (header->value);
1596         }
1597
1598         return (NULL);
1599 }
1600
1601 void
1602 evhttp_clear_headers(struct evkeyvalq *headers)
1603 {
1604         struct evkeyval *header;
1605
1606         for (header = TAILQ_FIRST(headers);
1607             header != NULL;
1608             header = TAILQ_FIRST(headers)) {
1609                 TAILQ_REMOVE(headers, header, next);
1610                 mm_free(header->key);
1611                 mm_free(header->value);
1612                 mm_free(header);
1613         }
1614 }
1615
1616 /*
1617  * Returns 0,  if the header was successfully removed.
1618  * Returns -1, if the header could not be found.
1619  */
1620
1621 int
1622 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1623 {
1624         struct evkeyval *header;
1625
1626         TAILQ_FOREACH(header, headers, next) {
1627                 if (evutil_ascii_strcasecmp(header->key, key) == 0)
1628                         break;
1629         }
1630
1631         if (header == NULL)
1632                 return (-1);
1633
1634         /* Free and remove the header that we found */
1635         TAILQ_REMOVE(headers, header, next);
1636         mm_free(header->key);
1637         mm_free(header->value);
1638         mm_free(header);
1639
1640         return (0);
1641 }
1642
1643 static int
1644 evhttp_header_is_valid_value(const char *value)
1645 {
1646         const char *p = value;
1647
1648         while ((p = strpbrk(p, "\r\n")) != NULL) {
1649                 /* we really expect only one new line */
1650                 p += strspn(p, "\r\n");
1651                 /* we expect a space or tab for continuation */
1652                 if (*p != ' ' && *p != '\t')
1653                         return (0);
1654         }
1655         return (1);
1656 }
1657
1658 int
1659 evhttp_add_header(struct evkeyvalq *headers,
1660     const char *key, const char *value)
1661 {
1662         event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1663
1664         if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1665                 /* drop illegal headers */
1666                 event_debug(("%s: dropping illegal header key\n", __func__));
1667                 return (-1);
1668         }
1669
1670         if (!evhttp_header_is_valid_value(value)) {
1671                 event_debug(("%s: dropping illegal header value\n", __func__));
1672                 return (-1);
1673         }
1674
1675         return (evhttp_add_header_internal(headers, key, value));
1676 }
1677
1678 static int
1679 evhttp_add_header_internal(struct evkeyvalq *headers,
1680     const char *key, const char *value)
1681 {
1682         struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval));
1683         if (header == NULL) {
1684                 event_warn("%s: calloc", __func__);
1685                 return (-1);
1686         }
1687         if ((header->key = mm_strdup(key)) == NULL) {
1688                 mm_free(header);
1689                 event_warn("%s: strdup", __func__);
1690                 return (-1);
1691         }
1692         if ((header->value = mm_strdup(value)) == NULL) {
1693                 mm_free(header->key);
1694                 mm_free(header);
1695                 event_warn("%s: strdup", __func__);
1696                 return (-1);
1697         }
1698
1699         TAILQ_INSERT_TAIL(headers, header, next);
1700
1701         return (0);
1702 }
1703
1704 /*
1705  * Parses header lines from a request or a response into the specified
1706  * request object given an event buffer.
1707  *
1708  * Returns
1709  *   DATA_CORRUPTED      on error
1710  *   MORE_DATA_EXPECTED  when we need to read more headers
1711  *   ALL_DATA_READ       when all headers have been read.
1712  */
1713
1714 enum message_read_status
1715 evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
1716 {
1717         char *line;
1718         enum message_read_status status = ALL_DATA_READ;
1719
1720         size_t line_length;
1721         /* XXX try */
1722         line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF);
1723         if (line == NULL) {
1724                 if (req->evcon != NULL &&
1725                     evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1726                         return (DATA_TOO_LONG);
1727                 else
1728                         return (MORE_DATA_EXPECTED);
1729         }
1730
1731         if (req->evcon != NULL &&
1732             line_length > req->evcon->max_headers_size) {
1733                 mm_free(line);
1734                 return (DATA_TOO_LONG);
1735         }
1736
1737         req->headers_size = line_length;
1738
1739         switch (req->kind) {
1740         case EVHTTP_REQUEST:
1741                 if (evhttp_parse_request_line(req, line) == -1)
1742                         status = DATA_CORRUPTED;
1743                 break;
1744         case EVHTTP_RESPONSE:
1745                 if (evhttp_parse_response_line(req, line) == -1)
1746                         status = DATA_CORRUPTED;
1747                 break;
1748         default:
1749                 status = DATA_CORRUPTED;
1750         }
1751
1752         mm_free(line);
1753         return (status);
1754 }
1755
1756 static int
1757 evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
1758 {
1759         struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
1760         char *newval;
1761         size_t old_len, line_len;
1762
1763         if (header == NULL)
1764                 return (-1);
1765
1766         old_len = strlen(header->value);
1767         line_len = strlen(line);
1768
1769         newval = mm_realloc(header->value, old_len + line_len + 1);
1770         if (newval == NULL)
1771                 return (-1);
1772
1773         memcpy(newval + old_len, line, line_len + 1);
1774         header->value = newval;
1775
1776         return (0);
1777 }
1778
1779 enum message_read_status
1780 evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
1781 {
1782         enum message_read_status errcode = DATA_CORRUPTED;
1783         char *line;
1784         enum message_read_status status = MORE_DATA_EXPECTED;
1785
1786         struct evkeyvalq* headers = req->input_headers;
1787         size_t line_length;
1788         while ((line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF))
1789                != NULL) {
1790                 char *skey, *svalue;
1791
1792                 req->headers_size += line_length;
1793
1794                 if (req->evcon != NULL &&
1795                     req->headers_size > req->evcon->max_headers_size) {
1796                         errcode = DATA_TOO_LONG;
1797                         goto error;
1798                 }
1799
1800                 if (*line == '\0') { /* Last header - Done */
1801                         status = ALL_DATA_READ;
1802                         mm_free(line);
1803                         break;
1804                 }
1805
1806                 /* Check if this is a continuation line */
1807                 if (*line == ' ' || *line == '\t') {
1808                         if (evhttp_append_to_last_header(headers, line) == -1)
1809                                 goto error;
1810                         mm_free(line);
1811                         continue;
1812                 }
1813
1814                 /* Processing of header lines */
1815                 svalue = line;
1816                 skey = strsep(&svalue, ":");
1817                 if (svalue == NULL)
1818                         goto error;
1819
1820                 svalue += strspn(svalue, " ");
1821
1822                 if (evhttp_add_header(headers, skey, svalue) == -1)
1823                         goto error;
1824
1825                 mm_free(line);
1826         }
1827
1828         if (status == MORE_DATA_EXPECTED) {
1829                 if (req->evcon != NULL &&
1830                 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size)
1831                         return (DATA_TOO_LONG);
1832         }
1833
1834         return (status);
1835
1836  error:
1837         mm_free(line);
1838         return (errcode);
1839 }
1840
1841 static int
1842 evhttp_get_body_length(struct evhttp_request *req)
1843 {
1844         struct evkeyvalq *headers = req->input_headers;
1845         const char *content_length;
1846         const char *connection;
1847
1848         content_length = evhttp_find_header(headers, "Content-Length");
1849         connection = evhttp_find_header(headers, "Connection");
1850
1851         if (content_length == NULL && connection == NULL)
1852                 req->ntoread = -1;
1853         else if (content_length == NULL &&
1854             evutil_ascii_strcasecmp(connection, "Close") != 0) {
1855                 /* Bad combination, we don't know when it will end */
1856                 event_warnx("%s: we got no content length, but the "
1857                     "server wants to keep the connection open: %s.",
1858                     __func__, connection);
1859                 return (-1);
1860         } else if (content_length == NULL) {
1861                 req->ntoread = -1;
1862         } else {
1863                 char *endp;
1864                 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
1865                 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
1866                         event_debug(("%s: illegal content length: %s",
1867                                 __func__, content_length));
1868                         return (-1);
1869                 }
1870                 req->ntoread = ntoread;
1871         }
1872
1873         event_debug(("%s: bytes to read: %ld (in buffer %ld)\n",
1874                 __func__, (long)req->ntoread,
1875                 evbuffer_get_length(bufferevent_get_input(req->evcon->bufev))));
1876
1877         return (0);
1878 }
1879
1880 static int
1881 evhttp_method_may_have_body(enum evhttp_cmd_type type)
1882 {
1883         switch (type) {
1884         case EVHTTP_REQ_POST:
1885         case EVHTTP_REQ_PUT:
1886         case EVHTTP_REQ_PATCH:
1887                 return 1;
1888         case EVHTTP_REQ_TRACE:
1889                 return 0;
1890         /* XXX May any of the below methods have a body? */
1891         case EVHTTP_REQ_GET:
1892         case EVHTTP_REQ_HEAD:
1893         case EVHTTP_REQ_DELETE:
1894         case EVHTTP_REQ_OPTIONS:
1895         case EVHTTP_REQ_CONNECT:
1896                 return 0;
1897         default:
1898                 return 0;
1899         }
1900 }
1901
1902 static void
1903 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1904 {
1905         const char *xfer_enc;
1906
1907         /* If this is a request without a body, then we are done */
1908         if (req->kind == EVHTTP_REQUEST &&
1909             !evhttp_method_may_have_body(req->type)) {
1910                 evhttp_connection_done(evcon);
1911                 return;
1912         }
1913         evcon->state = EVCON_READING_BODY;
1914         xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
1915         if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) {
1916                 req->chunked = 1;
1917                 req->ntoread = -1;
1918         } else {
1919                 if (evhttp_get_body_length(req) == -1) {
1920                         evhttp_connection_fail(evcon,
1921                             EVCON_HTTP_INVALID_HEADER);
1922                         return;
1923                 }
1924                 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) {
1925                         /* An incoming request with no content-length and no
1926                          * transfer-encoding has no body. */
1927                         evhttp_connection_done(evcon);
1928                         return;
1929                 }
1930         }
1931
1932         /* Should we send a 100 Continue status line? */
1933         if (req->kind == EVHTTP_REQUEST && REQ_VERSION_ATLEAST(req, 1, 1)) {
1934                 const char *expect;
1935
1936                 expect = evhttp_find_header(req->input_headers, "Expect");
1937                 if (expect) {
1938                         if (!evutil_ascii_strcasecmp(expect, "100-continue")) {
1939                                 /* XXX It would be nice to do some sanity
1940                                    checking here. Does the resource exist?
1941                                    Should the resource accept post requests? If
1942                                    no, we should respond with an error. For
1943                                    now, just optimistically tell the client to
1944                                    send their message body. */
1945                                 if (req->ntoread > 0) {
1946                                         /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */ 
1947                                         if ((req->evcon->max_body_size <= EV_INT64_MAX) && (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
1948                                                 evhttp_send_error(req, HTTP_ENTITYTOOLARGE, NULL);
1949                                                 return;
1950                                         }
1951                                 }
1952                                 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
1953                                         evhttp_send_continue(evcon, req);
1954                         } else {
1955                                 evhttp_send_error(req, HTTP_EXPECTATIONFAILED,
1956                                         NULL);
1957                                 return;
1958                         }
1959                 }
1960         }
1961
1962         evhttp_read_body(evcon, req);
1963         /* note the request may have been freed in evhttp_read_body */
1964 }
1965
1966 static void
1967 evhttp_read_firstline(struct evhttp_connection *evcon,
1968                       struct evhttp_request *req)
1969 {
1970         enum message_read_status res;
1971
1972         res = evhttp_parse_firstline(req, bufferevent_get_input(evcon->bufev));
1973         if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
1974                 /* Error while reading, terminate */
1975                 event_debug(("%s: bad header lines on %d\n",
1976                         __func__, evcon->fd));
1977                 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1978                 return;
1979         } else if (res == MORE_DATA_EXPECTED) {
1980                 /* Need more header lines */
1981                 return;
1982         }
1983
1984         evcon->state = EVCON_READING_HEADERS;
1985         evhttp_read_header(evcon, req);
1986 }
1987
1988 static void
1989 evhttp_read_header(struct evhttp_connection *evcon,
1990                    struct evhttp_request *req)
1991 {
1992         enum message_read_status res;
1993         evutil_socket_t fd = evcon->fd;
1994
1995         res = evhttp_parse_headers(req, bufferevent_get_input(evcon->bufev));
1996         if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) {
1997                 /* Error while reading, terminate */
1998                 event_debug(("%s: bad header lines on %d\n", __func__, fd));
1999                 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
2000                 return;
2001         } else if (res == MORE_DATA_EXPECTED) {
2002                 /* Need more header lines */
2003                 return;
2004         }
2005
2006         /* Disable reading for now */
2007         bufferevent_disable(evcon->bufev, EV_READ);
2008
2009         /* Done reading headers, do the real work */
2010         switch (req->kind) {
2011         case EVHTTP_REQUEST:
2012                 event_debug(("%s: checking for post data on %d\n",
2013                                 __func__, fd));
2014                 evhttp_get_body(evcon, req);
2015                 /* note the request may have been freed in evhttp_get_body */
2016                 break;
2017
2018         case EVHTTP_RESPONSE:
2019                 /* Start over if we got a 100 Continue response. */
2020                 if (req->response_code == 100) {
2021                         evhttp_start_read(evcon);
2022                         return;
2023                 }
2024                 if (!evhttp_response_needs_body(req)) {
2025                         event_debug(("%s: skipping body for code %d\n",
2026                                         __func__, req->response_code));
2027                         evhttp_connection_done(evcon);
2028                 } else {
2029                         event_debug(("%s: start of read body for %s on %d\n",
2030                                 __func__, req->remote_host, fd));
2031                         evhttp_get_body(evcon, req);
2032                         /* note the request may have been freed in
2033                          * evhttp_get_body */
2034                 }
2035                 break;
2036
2037         default:
2038                 event_warnx("%s: bad header on %d", __func__, fd);
2039                 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
2040                 break;
2041         }
2042         /* request may have been freed above */
2043 }
2044
2045 /*
2046  * Creates a TCP connection to the specified port and executes a callback
2047  * when finished.  Failure or success is indicate by the passed connection
2048  * object.
2049  *
2050  * Although this interface accepts a hostname, it is intended to take
2051  * only numeric hostnames so that non-blocking DNS resolution can
2052  * happen elsewhere.
2053  */
2054
2055 struct evhttp_connection *
2056 evhttp_connection_new(const char *address, unsigned short port)
2057 {
2058         return (evhttp_connection_base_new(NULL, NULL, address, port));
2059 }
2060
2061 struct evhttp_connection *
2062 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase,
2063     const char *address, unsigned short port)
2064 {
2065         struct evhttp_connection *evcon = NULL;
2066
2067         event_debug(("Attempting connection to %s:%d\n", address, port));
2068
2069         if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) {
2070                 event_warn("%s: calloc failed", __func__);
2071                 goto error;
2072         }
2073
2074         evcon->fd = -1;
2075         evcon->port = port;
2076
2077         evcon->max_headers_size = EV_SIZE_MAX;
2078         evcon->max_body_size = EV_SIZE_MAX;
2079
2080         evcon->timeout = -1;
2081         evcon->retry_cnt = evcon->retry_max = 0;
2082
2083         if ((evcon->address = mm_strdup(address)) == NULL) {
2084                 event_warn("%s: strdup failed", __func__);
2085                 goto error;
2086         }
2087
2088         if ((evcon->bufev = bufferevent_new(-1,
2089                     evhttp_read_cb,
2090                     evhttp_write_cb,
2091                     evhttp_error_cb, evcon)) == NULL) {
2092                 event_warn("%s: bufferevent_new failed", __func__);
2093                 goto error;
2094         }
2095
2096         evcon->state = EVCON_DISCONNECTED;
2097         TAILQ_INIT(&evcon->requests);
2098
2099         if (base != NULL) {
2100                 evcon->base = base;
2101                 bufferevent_base_set(base, evcon->bufev);
2102         }
2103
2104
2105         event_deferred_cb_init(&evcon->read_more_deferred_cb,
2106             evhttp_deferred_read_cb, evcon);
2107
2108         evcon->dns_base = dnsbase;
2109
2110         return (evcon);
2111
2112  error:
2113         if (evcon != NULL)
2114                 evhttp_connection_free(evcon);
2115         return (NULL);
2116 }
2117
2118 void
2119 evhttp_connection_set_base(struct evhttp_connection *evcon,
2120     struct event_base *base)
2121 {
2122         EVUTIL_ASSERT(evcon->base == NULL);
2123         EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED);
2124         evcon->base = base;
2125         bufferevent_base_set(base, evcon->bufev);
2126 }
2127
2128 void
2129 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
2130     int timeout_in_secs)
2131 {
2132         evcon->timeout = timeout_in_secs;
2133
2134         if (evcon->timeout == -1)
2135                 bufferevent_settimeout(evcon->bufev,
2136                     HTTP_READ_TIMEOUT, HTTP_WRITE_TIMEOUT);
2137         else
2138                 bufferevent_settimeout(evcon->bufev,
2139                     evcon->timeout, evcon->timeout);
2140 }
2141
2142 void
2143 evhttp_connection_set_retries(struct evhttp_connection *evcon,
2144     int retry_max)
2145 {
2146         evcon->retry_max = retry_max;
2147 }
2148
2149 void
2150 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
2151     void (*cb)(struct evhttp_connection *, void *), void *cbarg)
2152 {
2153         evcon->closecb = cb;
2154         evcon->closecb_arg = cbarg;
2155 }
2156
2157 void
2158 evhttp_connection_get_peer(struct evhttp_connection *evcon,
2159     char **address, ev_uint16_t *port)
2160 {
2161         *address = evcon->address;
2162         *port = evcon->port;
2163 }
2164
2165 int
2166 evhttp_connection_connect(struct evhttp_connection *evcon)
2167 {
2168         if (evcon->state == EVCON_CONNECTING)
2169                 return (0);
2170
2171         evhttp_connection_reset(evcon);
2172
2173         EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING));
2174         evcon->flags |= EVHTTP_CON_OUTGOING;
2175
2176         evcon->fd = bind_socket(
2177                 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
2178         if (evcon->fd == -1) {
2179                 event_debug(("%s: failed to bind to \"%s\"",
2180                         __func__, evcon->bind_address));
2181                 return (-1);
2182         }
2183
2184         /* Set up a callback for successful connection setup */
2185         bufferevent_setfd(evcon->bufev, evcon->fd);
2186         bufferevent_setcb(evcon->bufev,
2187             NULL /* evhttp_read_cb */,
2188             NULL /* evhttp_write_cb */,
2189             evhttp_connection_cb,
2190             evcon);
2191         bufferevent_settimeout(evcon->bufev, 0,
2192             evcon->timeout != -1 ? evcon->timeout : HTTP_CONNECT_TIMEOUT);
2193         /* make sure that we get a write callback */
2194         bufferevent_enable(evcon->bufev, EV_WRITE);
2195
2196         if (bufferevent_socket_connect_hostname(evcon->bufev, evcon->dns_base,
2197                 AF_UNSPEC, evcon->address, evcon->port) < 0) {
2198                 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
2199                     __func__, evcon->address);
2200                 /* some operating systems return ECONNREFUSED immediately
2201                  * when connecting to a local address.  the cleanup is going
2202                  * to reschedule this function call.
2203                  */
2204                 evhttp_connection_cb_cleanup(evcon);
2205                 return (0);
2206         }
2207
2208         evcon->state = EVCON_CONNECTING;
2209
2210         return (0);
2211 }
2212
2213 /*
2214  * Starts an HTTP request on the provided evhttp_connection object.
2215  * If the connection object is not connected to the web server already,
2216  * this will start the connection.
2217  */
2218
2219 int
2220 evhttp_make_request(struct evhttp_connection *evcon,
2221     struct evhttp_request *req,
2222     enum evhttp_cmd_type type, const char *uri)
2223 {
2224         /* We are making a request */
2225         req->kind = EVHTTP_REQUEST;
2226         req->type = type;
2227         if (req->uri != NULL)
2228                 mm_free(req->uri);
2229         if ((req->uri = mm_strdup(uri)) == NULL) {
2230                 event_warn("%s: strdup", __func__);
2231                 evhttp_request_free(req);
2232                 return (-1);
2233         }
2234
2235         /* Set the protocol version if it is not supplied */
2236         if (!req->major && !req->minor) {
2237                 req->major = 1;
2238                 req->minor = 1;
2239         }
2240
2241         EVUTIL_ASSERT(req->evcon == NULL);
2242         req->evcon = evcon;
2243         EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
2244
2245        TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2246
2247         /* If the connection object is not connected; make it so */
2248         if (!evhttp_connected(evcon)) {
2249                 int res = evhttp_connection_connect(evcon);
2250                /* evhttp_connection_fail(), which is called through
2251                 * evhttp_connection_connect(), assumes that req lies in
2252                 * evcon->requests.  Thus, enqueue the request in advance and r
2253                 * it in the error case. */
2254                if (res != 0)
2255                        TAILQ_REMOVE(&evcon->requests, req, next);
2256
2257                 return res;
2258         }
2259
2260         /*
2261          * If it's connected already and we are the first in the queue,
2262          * then we can dispatch this request immediately.  Otherwise, it
2263          * will be dispatched once the pending requests are completed.
2264          */
2265         if (TAILQ_FIRST(&evcon->requests) == req)
2266                 evhttp_request_dispatch(evcon);
2267
2268         return (0);
2269 }
2270
2271 void
2272 evhttp_cancel_request(struct evhttp_request *req)
2273 {
2274         struct evhttp_connection *evcon = req->evcon;
2275         if (evcon != NULL) {
2276                 /* We need to remove it from the connection */
2277                 if (TAILQ_FIRST(&evcon->requests) == req) {
2278                         /* it's currently being worked on, so reset
2279                          * the connection.
2280                          */
2281                         evhttp_connection_fail(evcon,
2282                             EVCON_HTTP_REQUEST_CANCEL);
2283
2284                         /* connection fail freed the request */
2285                         return;
2286                 } else {
2287                         /* otherwise, we can just remove it from the
2288                          * queue
2289                          */
2290                         TAILQ_REMOVE(&evcon->requests, req, next);
2291                 }
2292         }
2293
2294         evhttp_request_free(req);
2295 }
2296
2297 /*
2298  * Reads data from file descriptor into request structure
2299  * Request structure needs to be set up correctly.
2300  */
2301
2302 void
2303 evhttp_start_read(struct evhttp_connection *evcon)
2304 {
2305         /* Set up an event to read the headers */
2306         bufferevent_disable(evcon->bufev, EV_WRITE);
2307         bufferevent_enable(evcon->bufev, EV_READ);
2308         evcon->state = EVCON_READING_FIRSTLINE;
2309         /* Reset the bufferevent callbacks */
2310         bufferevent_setcb(evcon->bufev,
2311             evhttp_read_cb,
2312             evhttp_write_cb,
2313             evhttp_error_cb,
2314             evcon);
2315
2316         /* If there's still data pending, process it next time through the
2317          * loop.  Don't do it now; that could get recusive. */
2318         if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) {
2319                 event_deferred_cb_schedule(get_deferred_queue(evcon),
2320                     &evcon->read_more_deferred_cb);
2321         }
2322 }
2323
2324 static void
2325 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
2326 {
2327         int need_close;
2328         struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
2329         TAILQ_REMOVE(&evcon->requests, req, next);
2330
2331         need_close =
2332             (REQ_VERSION_BEFORE(req, 1, 1) &&
2333                 !evhttp_is_connection_keepalive(req->input_headers))||
2334             evhttp_is_connection_close(req->flags, req->input_headers) ||
2335             evhttp_is_connection_close(req->flags, req->output_headers);
2336
2337         EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION);
2338         evhttp_request_free(req);
2339
2340         if (need_close) {
2341                 evhttp_connection_free(evcon);
2342                 return;
2343         }
2344
2345         /* we have a persistent connection; try to accept another request. */
2346         if (evhttp_associate_new_request_with_connection(evcon) == -1) {
2347                 evhttp_connection_free(evcon);
2348         }
2349 }
2350
2351 /*
2352  * Returns an error page.
2353  */
2354
2355 void
2356 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
2357 {
2358
2359 #define ERR_FORMAT "<HTML><HEAD>\n" \
2360             "<TITLE>%d %s</TITLE>\n" \
2361             "</HEAD><BODY>\n" \
2362             "<H1>%s</H1>\n" \
2363             "</BODY></HTML>\n"
2364
2365         struct evbuffer *buf = evbuffer_new();
2366         if (buf == NULL) {
2367                 /* if we cannot allocate memory; we just drop the connection */
2368                 evhttp_connection_free(req->evcon);
2369                 return;
2370         }
2371         if (reason == NULL) {
2372                 reason = evhttp_response_phrase_internal(error);
2373         }
2374
2375         evhttp_response_code(req, error, reason);
2376
2377         evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason);
2378
2379         evhttp_send_page(req, buf);
2380
2381         evbuffer_free(buf);
2382 #undef ERR_FORMAT
2383 }
2384
2385 /* Requires that headers and response code are already set up */
2386
2387 static inline void
2388 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
2389 {
2390         struct evhttp_connection *evcon = req->evcon;
2391
2392         if (evcon == NULL) {
2393                 evhttp_request_free(req);
2394                 return;
2395         }
2396
2397         EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req);
2398
2399         /* we expect no more calls form the user on this request */
2400         req->userdone = 1;
2401
2402         /* xxx: not sure if we really should expose the data buffer this way */
2403         if (databuf != NULL)
2404                 evbuffer_add_buffer(req->output_buffer, databuf);
2405
2406         /* Adds headers to the response */
2407         evhttp_make_header(evcon, req);
2408
2409         evhttp_write_buffer(evcon, evhttp_send_done, NULL);
2410 }
2411
2412 void
2413 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
2414     struct evbuffer *databuf)
2415 {
2416         evhttp_response_code(req, code, reason);
2417
2418         evhttp_send(req, databuf);
2419 }
2420
2421 void
2422 evhttp_send_reply_start(struct evhttp_request *req, int code,
2423     const char *reason)
2424 {
2425         evhttp_response_code(req, code, reason);
2426         if (evhttp_find_header(req->output_headers, "Content-Length") == NULL &&
2427             REQ_VERSION_ATLEAST(req, 1, 1) &&
2428             evhttp_response_needs_body(req)) {
2429                 /*
2430                  * prefer HTTP/1.1 chunked encoding to closing the connection;
2431                  * note RFC 2616 section 4.4 forbids it with Content-Length:
2432                  * and it's not necessary then anyway.
2433                  */
2434                 evhttp_add_header(req->output_headers, "Transfer-Encoding",
2435                     "chunked");
2436                 req->chunked = 1;
2437         } else {
2438                 req->chunked = 0;
2439         }
2440         evhttp_make_header(req->evcon, req);
2441         evhttp_write_buffer(req->evcon, NULL, NULL);
2442 }
2443
2444 void
2445 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
2446 {
2447         struct evhttp_connection *evcon = req->evcon;
2448         struct evbuffer *output;
2449
2450         if (evcon == NULL)
2451                 return;
2452
2453         output = bufferevent_get_output(evcon->bufev);
2454
2455         if (evbuffer_get_length(databuf) == 0)
2456                 return;
2457         if (!evhttp_response_needs_body(req))
2458                 return;
2459         if (req->chunked) {
2460                 evbuffer_add_printf(output, "%x\r\n",
2461                                     (unsigned)evbuffer_get_length(databuf));
2462         }
2463         evbuffer_add_buffer(output, databuf);
2464         if (req->chunked) {
2465                 evbuffer_add(output, "\r\n", 2);
2466         }
2467         evhttp_write_buffer(evcon, NULL, NULL);
2468 }
2469
2470 void
2471 evhttp_send_reply_end(struct evhttp_request *req)
2472 {
2473         struct evhttp_connection *evcon = req->evcon;
2474         struct evbuffer *output;
2475
2476         if (evcon == NULL) {
2477                 evhttp_request_free(req);
2478                 return;
2479         }
2480
2481         output = bufferevent_get_output(evcon->bufev);
2482
2483         /* we expect no more calls form the user on this request */
2484         req->userdone = 1;
2485
2486         if (req->chunked) {
2487                 evbuffer_add(output, "0\r\n\r\n", 5);
2488                 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2489                 req->chunked = 0;
2490         } else if (evbuffer_get_length(output) == 0) {
2491                 /* let the connection know that we are done with the request */
2492                 evhttp_send_done(evcon, NULL);
2493         } else {
2494                 /* make the callback execute after all data has been written */
2495                 evcon->cb = evhttp_send_done;
2496                 evcon->cb_arg = NULL;
2497         }
2498 }
2499
2500 static const char *informational_phrases[] = {
2501         /* 100 */ "Continue",
2502         /* 101 */ "Switching Protocols"
2503 };
2504
2505 static const char *success_phrases[] = {
2506         /* 200 */ "OK",
2507         /* 201 */ "Created",
2508         /* 202 */ "Accepted",
2509         /* 203 */ "Non-Authoritative Information",
2510         /* 204 */ "No Content",
2511         /* 205 */ "Reset Content",
2512         /* 206 */ "Partial Content"
2513 };
2514
2515 static const char *redirection_phrases[] = {
2516         /* 300 */ "Multiple Choices",
2517         /* 301 */ "Moved Permanently",
2518         /* 302 */ "Found",
2519         /* 303 */ "See Other",
2520         /* 304 */ "Not Modified",
2521         /* 305 */ "Use Proxy",
2522         /* 307 */ "Temporary Redirect"
2523 };
2524
2525 static const char *client_error_phrases[] = {
2526         /* 400 */ "Bad Request",
2527         /* 401 */ "Unauthorized",
2528         /* 402 */ "Payment Required",
2529         /* 403 */ "Forbidden",
2530         /* 404 */ "Not Found",
2531         /* 405 */ "Method Not Allowed",
2532         /* 406 */ "Not Acceptable",
2533         /* 407 */ "Proxy Authentication Required",
2534         /* 408 */ "Request Time-out",
2535         /* 409 */ "Conflict",
2536         /* 410 */ "Gone",
2537         /* 411 */ "Length Required",
2538         /* 412 */ "Precondition Failed",
2539         /* 413 */ "Request Entity Too Large",
2540         /* 414 */ "Request-URI Too Large",
2541         /* 415 */ "Unsupported Media Type",
2542         /* 416 */ "Requested range not satisfiable",
2543         /* 417 */ "Expectation Failed"
2544 };
2545
2546 static const char *server_error_phrases[] = {
2547         /* 500 */ "Internal Server Error",
2548         /* 501 */ "Not Implemented",
2549         /* 502 */ "Bad Gateway",
2550         /* 503 */ "Service Unavailable",
2551         /* 504 */ "Gateway Time-out",
2552         /* 505 */ "HTTP Version not supported"
2553 };
2554
2555 struct response_class {
2556         const char *name;
2557         size_t num_responses;
2558         const char **responses;
2559 };
2560
2561 #ifndef MEMBERSOF
2562 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0]))
2563 #endif
2564
2565 static const struct response_class response_classes[] = {
2566         /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases },
2567         /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases },
2568         /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases },
2569         /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases },
2570         /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases }
2571 };
2572
2573 static const char *
2574 evhttp_response_phrase_internal(int code)
2575 {
2576         int klass = code / 100 - 1;
2577         int subcode = code % 100;
2578
2579         /* Unknown class - can't do any better here */
2580         if (klass < 0 || klass >= (int) MEMBERSOF(response_classes))
2581                 return "Unknown Status Class";
2582
2583         /* Unknown sub-code, return class name at least */
2584         if (subcode >= (int) response_classes[klass].num_responses)
2585                 return response_classes[klass].name;
2586
2587         return response_classes[klass].responses[subcode];
2588 }
2589
2590 void
2591 evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
2592 {
2593         req->kind = EVHTTP_RESPONSE;
2594         req->response_code = code;
2595         if (req->response_code_line != NULL)
2596                 mm_free(req->response_code_line);
2597         if (reason == NULL)
2598                 reason = evhttp_response_phrase_internal(code);
2599         req->response_code_line = mm_strdup(reason);
2600         if (req->response_code_line == NULL) {
2601                 event_warn("%s: strdup", __func__);
2602                 /* XXX what else can we do? */
2603         }
2604 }
2605
2606 void
2607 evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
2608 {
2609         if (!req->major || !req->minor) {
2610                 req->major = 1;
2611                 req->minor = 1;
2612         }
2613
2614         if (req->kind != EVHTTP_RESPONSE)
2615                 evhttp_response_code(req, 200, "OK");
2616
2617         evhttp_clear_headers(req->output_headers);
2618         evhttp_add_header(req->output_headers, "Content-Type", "text/html");
2619         evhttp_add_header(req->output_headers, "Connection", "close");
2620
2621         evhttp_send(req, databuf);
2622 }
2623
2624 static const char uri_chars[256] = {
2625         /* 0 */
2626         0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
2627         0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
2628         0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 1, 1, 0,
2629         1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 0, 0, 0, 0, 0, 0,
2630         /* 64 */
2631         0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
2632         1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 0, 1,
2633         0, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,
2634         1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 0, 0, 0, 1, 0,
2635         /* 128 */
2636         0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
2637         0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
2638         0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
2639         0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,
2640         /* 192 */
2641         0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0,
2645 };
2646
2647 #define CHAR_IS_UNRESERVED(c)                   \
2648         (uri_chars[(unsigned char)(c)])
2649
2650 /*
2651  * Helper functions to encode/decode a string for inclusion in a URI.
2652  * The returned string must be freed by the caller.
2653  */
2654 char *
2655 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus)
2656 {
2657         struct evbuffer *buf = evbuffer_new();
2658         const char *p, *end;
2659         char *result;
2660
2661         if (buf == NULL)
2662                 return (NULL);
2663
2664         if (len >= 0)
2665                 end = uri+len;
2666         else
2667                 end = uri+strlen(uri);
2668
2669         for (p = uri; p < end; p++) {
2670                 if (CHAR_IS_UNRESERVED(*p)) {
2671                         evbuffer_add(buf, p, 1);
2672                 } else if (*p == ' ' && space_as_plus) {
2673                         evbuffer_add(buf, "+", 1);
2674                 } else {
2675                         evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p));
2676                 }
2677         }
2678         evbuffer_add(buf, "", 1); /* NUL-terminator. */
2679         result = mm_malloc(evbuffer_get_length(buf));
2680         if (!result)
2681                 return NULL;
2682         evbuffer_remove(buf, result, evbuffer_get_length(buf));
2683         evbuffer_free(buf);
2684
2685         return (result);
2686 }
2687
2688 char *
2689 evhttp_encode_uri(const char *str)
2690 {
2691         return evhttp_uriencode(str, -1, 0);
2692 }
2693
2694 /*
2695  * @param decode_plus_ctl: if 1, we decode plus into space.  If 0, we don't.
2696  *     If -1, when true we transform plus to space only after we've seen
2697  *     a ?.  -1 is deprecated.
2698  * @return the number of bytes written to 'ret'.
2699  */
2700 static int
2701 evhttp_decode_uri_internal(
2702         const char *uri, size_t length, char *ret, int decode_plus_ctl)
2703 {
2704         char c;
2705         int j;
2706         int decode_plus = (decode_plus_ctl == 1) ? 1: 0;
2707         unsigned i;
2708
2709         for (i = j = 0; i < length; i++) {
2710                 c = uri[i];
2711                 if (c == '?') {
2712                         if (decode_plus_ctl < 0)
2713                                 decode_plus = 1;
2714                 } else if (c == '+' && decode_plus) {
2715                         c = ' ';
2716                 } else if (c == '%' && EVUTIL_ISXDIGIT(uri[i+1]) &&
2717                     EVUTIL_ISXDIGIT(uri[i+2])) {
2718                         char tmp[3];
2719                         tmp[0] = uri[i+1];
2720                         tmp[1] = uri[i+2];
2721                         tmp[2] = '\0';
2722                         c = (char)strtol(tmp, NULL, 16);
2723                         i += 2;
2724                 }
2725                 ret[j++] = c;
2726         }
2727         ret[j] = '\0';
2728
2729         return (j);
2730 }
2731
2732 /* deprecated */
2733 char *
2734 evhttp_decode_uri(const char *uri)
2735 {
2736         char *ret;
2737
2738         if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2739                 event_warn("%s: malloc(%lu)", __func__,
2740                           (unsigned long)(strlen(uri) + 1));
2741                 return (NULL);
2742         }
2743
2744         evhttp_decode_uri_internal(uri, strlen(uri),
2745             ret, -1 /*always_decode_plus*/);
2746
2747         return (ret);
2748 }
2749
2750 char *
2751 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out)
2752 {
2753         char *ret;
2754         int n;
2755
2756         if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) {
2757                 event_warn("%s: malloc(%lu)", __func__,
2758                           (unsigned long)(strlen(uri) + 1));
2759                 return (NULL);
2760         }
2761
2762         n = evhttp_decode_uri_internal(uri, strlen(uri),
2763             ret, !!decode_plus/*always_decode_plus*/);
2764
2765         if (size_out) {
2766                 EVUTIL_ASSERT(n >= 0);
2767                 *size_out = (size_t)n;
2768         }
2769
2770         return (ret);
2771 }
2772
2773 /*
2774  * Helper function to parse out arguments in a query.
2775  * The arguments are separated by key and value.
2776  */
2777
2778 static int
2779 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers,
2780     int is_whole_uri)
2781 {
2782         char *line=NULL;
2783         char *argument;
2784         char *p;
2785         const char *query_part;
2786         int result = -1;
2787         struct evhttp_uri *uri=NULL;
2788
2789         TAILQ_INIT(headers);
2790
2791         if (is_whole_uri) {
2792                 uri = evhttp_uri_parse(str);
2793                 if (!uri)
2794                         goto error;
2795                 query_part = evhttp_uri_get_query(uri);
2796         } else {
2797                 query_part = str;
2798         }
2799
2800         /* No arguments - we are done */
2801         if (!query_part || !strlen(query_part)) {
2802                 result = 0;
2803                 goto done;
2804         }
2805
2806         if ((line = mm_strdup(query_part)) == NULL) {
2807                 event_warn("%s: strdup", __func__);
2808                 goto error;
2809         }
2810
2811         p = argument = line;
2812         while (p != NULL && *p != '\0') {
2813                 char *key, *value, *decoded_value;
2814                 argument = strsep(&p, "&");
2815
2816                 value = argument;
2817                 key = strsep(&value, "=");
2818                 if (value == NULL || *key == '\0') {
2819                         goto error;
2820                 }
2821
2822                 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) {
2823                         event_warn("%s: mm_malloc", __func__);
2824                         goto error;
2825                 }
2826                 evhttp_decode_uri_internal(value, strlen(value),
2827                     decoded_value, 1 /*always_decode_plus*/);
2828                 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
2829                 evhttp_add_header_internal(headers, key, decoded_value);
2830                 mm_free(decoded_value);
2831         }
2832
2833         result = 0;
2834         goto done;
2835 error:
2836         evhttp_clear_headers(headers);
2837 done:
2838         if (line)
2839                 mm_free(line);
2840         if (uri)
2841                 evhttp_uri_free(uri);
2842         return result;
2843 }
2844
2845 int
2846 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
2847 {
2848         return evhttp_parse_query_impl(uri, headers, 1);
2849 }
2850 int
2851 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers)
2852 {
2853         return evhttp_parse_query_impl(uri, headers, 0);
2854 }
2855
2856 static struct evhttp_cb *
2857 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
2858 {
2859         struct evhttp_cb *cb;
2860         size_t offset = 0;
2861         char *translated;
2862         const char *path;
2863
2864         /* Test for different URLs */
2865         path = evhttp_uri_get_path(req->uri_elems);
2866         offset = strlen(path);
2867         if ((translated = mm_malloc(offset + 1)) == NULL)
2868                 return (NULL);
2869         evhttp_decode_uri_internal(path, offset, translated,
2870             0 /* decode_plus */);
2871
2872         TAILQ_FOREACH(cb, callbacks, next) {
2873                 if (!strcmp(cb->what, translated)) {
2874                         mm_free(translated);
2875                         return (cb);
2876                 }
2877         }
2878
2879         mm_free(translated);
2880         return (NULL);
2881 }
2882
2883
2884 static int
2885 prefix_suffix_match(const char *pattern, const char *name, int ignorecase)
2886 {
2887         char c;
2888
2889         while (1) {
2890                 switch (c = *pattern++) {
2891                 case '\0':
2892                         return *name == '\0';
2893
2894                 case '*':
2895                         while (*name != '\0') {
2896                                 if (prefix_suffix_match(pattern, name,
2897                                         ignorecase))
2898                                         return (1);
2899                                 ++name;
2900                         }
2901                         return (0);
2902                 default:
2903                         if (c != *name) {
2904                                 if (!ignorecase ||
2905                                     EVUTIL_TOLOWER(c) != EVUTIL_TOLOWER(*name))
2906                                         return (0);
2907                         }
2908                         ++name;
2909                 }
2910         }
2911         /* NOTREACHED */
2912 }
2913
2914 /*
2915    Search the vhost hierarchy beginning with http for a server alias
2916    matching hostname.  If a match is found, and outhttp is non-null,
2917    outhttp is set to the matching http object and 1 is returned.
2918 */
2919
2920 static int
2921 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp,
2922                   const char *hostname)
2923 {
2924         struct evhttp_server_alias *alias;
2925         struct evhttp *vhost;
2926
2927         TAILQ_FOREACH(alias, &http->aliases, next) {
2928                 /* XXX Do we need to handle IP addresses? */
2929                 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) {
2930                         if (outhttp)
2931                                 *outhttp = http;
2932                         return 1;
2933                 }
2934         }
2935
2936         /* XXX It might be good to avoid recursion here, but I don't
2937            see a way to do that w/o a list. */
2938         TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
2939                 if (evhttp_find_alias(vhost, outhttp, hostname))
2940                         return 1;
2941         }
2942
2943         return 0;
2944 }
2945
2946 /*
2947    Attempts to find the best http object to handle a request for a hostname.
2948    All aliases for the root http object and vhosts are searched for an exact
2949    match. Then, the vhost hierarchy is traversed again for a matching
2950    pattern.
2951
2952    If an alias or vhost is matched, 1 is returned, and outhttp, if non-null,
2953    is set with the best matching http object. If there are no matches, the
2954    root http object is stored in outhttp and 0 is returned.
2955 */
2956
2957 static int
2958 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp,
2959                   const char *hostname)
2960 {
2961         struct evhttp *vhost;
2962         struct evhttp *oldhttp;
2963         int match_found = 0;
2964
2965         if (evhttp_find_alias(http, outhttp, hostname))
2966                 return 1;
2967
2968         do {
2969                 oldhttp = http;
2970                 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) {
2971                         if (prefix_suffix_match(vhost->vhost_pattern,
2972                                 hostname, 1 /* ignorecase */)) {
2973                                 http = vhost;
2974                                 match_found = 1;
2975                                 break;
2976                         }
2977                 }
2978         } while (oldhttp != http);
2979
2980         if (outhttp)
2981                 *outhttp = http;
2982
2983         return match_found;
2984 }
2985
2986 static void
2987 evhttp_handle_request(struct evhttp_request *req, void *arg)
2988 {
2989         struct evhttp *http = arg;
2990         struct evhttp_cb *cb = NULL;
2991         const char *hostname;
2992
2993         /* we have a new request on which the user needs to take action */
2994         req->userdone = 0;
2995
2996         if (req->type == 0 || req->uri == NULL) {
2997                 evhttp_send_error(req, HTTP_BADREQUEST, NULL);
2998                 return;
2999         }
3000
3001         if ((http->allowed_methods & req->type) == 0) {
3002                 event_debug(("Rejecting disallowed method %x (allowed: %x)\n",
3003                         (unsigned)req->type, (unsigned)http->allowed_methods));
3004                 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL);
3005                 return;
3006         }
3007
3008         /* handle potential virtual hosts */
3009         hostname = evhttp_request_get_host(req);
3010         if (hostname != NULL) {
3011                 evhttp_find_vhost(http, &http, hostname);
3012         }
3013
3014         if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
3015                 (*cb->cb)(req, cb->cbarg);
3016                 return;
3017         }
3018
3019         /* Generic call back */
3020         if (http->gencb) {
3021                 (*http->gencb)(req, http->gencbarg);
3022                 return;
3023         } else {
3024                 /* We need to send a 404 here */
3025 #define ERR_FORMAT "<html><head>" \
3026                     "<title>404 Not Found</title>" \
3027                     "</head><body>" \
3028                     "<h1>Not Found</h1>" \
3029                     "<p>The requested URL %s was not found on this server.</p>"\
3030                     "</body></html>\n"
3031
3032                 char *escaped_html;
3033                 struct evbuffer *buf;
3034
3035                 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) {
3036                         evhttp_connection_free(req->evcon);
3037                         return;
3038                 }
3039
3040                 if ((buf = evbuffer_new()) == NULL) {
3041                         mm_free(escaped_html);
3042                         evhttp_connection_free(req->evcon);
3043                         return;
3044                 }
3045
3046                 evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
3047
3048                 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
3049
3050                 mm_free(escaped_html);
3051
3052                 evhttp_send_page(req, buf);
3053
3054                 evbuffer_free(buf);
3055 #undef ERR_FORMAT
3056         }
3057 }
3058
3059 /* Listener callback when a connection arrives at a server. */
3060 static void
3061 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg)
3062 {
3063         struct evhttp *http = arg;
3064
3065         evhttp_get_request(http, nfd, peer_sa, peer_socklen);
3066 }
3067
3068 int
3069 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
3070 {
3071         struct evhttp_bound_socket *bound =
3072                 evhttp_bind_socket_with_handle(http, address, port);
3073         if (bound == NULL)
3074                 return (-1);
3075         return (0);
3076 }
3077
3078 struct evhttp_bound_socket *
3079 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port)
3080 {
3081         evutil_socket_t fd;
3082         struct evhttp_bound_socket *bound;
3083
3084         if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
3085                 return (NULL);
3086
3087         if (listen(fd, 128) == -1) {
3088                 event_sock_warn(fd, "%s: listen", __func__);
3089                 evutil_closesocket(fd);
3090                 return (NULL);
3091         }
3092
3093         bound = evhttp_accept_socket_with_handle(http, fd);
3094
3095         if (bound != NULL) {
3096                 event_debug(("Bound to port %d - Awaiting connections ... ",
3097                         port));
3098                 return (bound);
3099         }
3100
3101         return (NULL);
3102 }
3103
3104 int
3105 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
3106 {
3107         struct evhttp_bound_socket *bound =
3108                 evhttp_accept_socket_with_handle(http, fd);
3109         if (bound == NULL)
3110                 return (-1);
3111         return (0);
3112 }
3113
3114
3115 struct evhttp_bound_socket *
3116 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd)
3117 {
3118         struct evhttp_bound_socket *bound;
3119         struct evconnlistener *listener;
3120         const int flags =
3121             LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE;
3122
3123         listener = evconnlistener_new(http->base, NULL, NULL,
3124             flags,
3125             0, /* Backlog is '0' because we already said 'listen' */
3126             fd);
3127         if (!listener)
3128                 return (NULL);
3129
3130         bound = evhttp_bind_listener(http, listener);
3131         if (!bound) {
3132                 evconnlistener_free(listener);
3133                 return (NULL);
3134         }
3135         return (bound);
3136 }
3137
3138 struct evhttp_bound_socket *
3139 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener)
3140 {
3141         struct evhttp_bound_socket *bound;
3142
3143         bound = mm_malloc(sizeof(struct evhttp_bound_socket));
3144         if (bound == NULL)
3145                 return (NULL);
3146
3147         bound->listener = listener;
3148         TAILQ_INSERT_TAIL(&http->sockets, bound, next);
3149
3150         evconnlistener_set_cb(listener, accept_socket_cb, http);
3151         return bound;
3152 }
3153
3154 evutil_socket_t
3155 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound)
3156 {
3157         return evconnlistener_get_fd(bound->listener);
3158 }
3159
3160 struct evconnlistener *
3161 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound)
3162 {
3163         return bound->listener;
3164 }
3165
3166 void
3167 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound)
3168 {
3169         TAILQ_REMOVE(&http->sockets, bound, next);
3170         evconnlistener_free(bound->listener);
3171         mm_free(bound);
3172 }
3173
3174 static struct evhttp*
3175 evhttp_new_object(void)
3176 {
3177         struct evhttp *http = NULL;
3178
3179         if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) {
3180                 event_warn("%s: calloc", __func__);
3181                 return (NULL);
3182         }
3183
3184         http->timeout = -1;
3185         evhttp_set_max_headers_size(http, EV_SIZE_MAX);
3186         evhttp_set_max_body_size(http, EV_SIZE_MAX);
3187         evhttp_set_allowed_methods(http,
3188             EVHTTP_REQ_GET |
3189             EVHTTP_REQ_POST |
3190             EVHTTP_REQ_HEAD |
3191             EVHTTP_REQ_PUT |
3192             EVHTTP_REQ_DELETE);
3193
3194         TAILQ_INIT(&http->sockets);
3195         TAILQ_INIT(&http->callbacks);
3196         TAILQ_INIT(&http->connections);
3197         TAILQ_INIT(&http->virtualhosts);
3198         TAILQ_INIT(&http->aliases);
3199
3200         return (http);
3201 }
3202
3203 struct evhttp *
3204 evhttp_new(struct event_base *base)
3205 {
3206         struct evhttp *http = evhttp_new_object();
3207
3208         http->base = base;
3209
3210         return (http);
3211 }
3212
3213 /*
3214  * Start a web server on the specified address and port.
3215  */
3216
3217 struct evhttp *
3218 evhttp_start(const char *address, unsigned short port)
3219 {
3220         struct evhttp *http = evhttp_new_object();
3221
3222         if (evhttp_bind_socket(http, address, port) == -1) {
3223                 mm_free(http);
3224                 return (NULL);
3225         }
3226
3227         return (http);
3228 }
3229
3230 void
3231 evhttp_free(struct evhttp* http)
3232 {
3233         struct evhttp_cb *http_cb;
3234         struct evhttp_connection *evcon;
3235         struct evhttp_bound_socket *bound;
3236         struct evhttp* vhost;
3237         struct evhttp_server_alias *alias;
3238
3239         /* Remove the accepting part */
3240         while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
3241                 TAILQ_REMOVE(&http->sockets, bound, next);
3242
3243                 evconnlistener_free(bound->listener);
3244
3245                 mm_free(bound);
3246         }
3247
3248         while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
3249                 /* evhttp_connection_free removes the connection */
3250                 evhttp_connection_free(evcon);
3251         }
3252
3253         while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
3254                 TAILQ_REMOVE(&http->callbacks, http_cb, next);
3255                 mm_free(http_cb->what);
3256                 mm_free(http_cb);
3257         }
3258
3259         while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) {
3260                 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3261
3262                 evhttp_free(vhost);
3263         }
3264
3265         if (http->vhost_pattern != NULL)
3266                 mm_free(http->vhost_pattern);
3267
3268         while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) {
3269                 TAILQ_REMOVE(&http->aliases, alias, next);
3270                 mm_free(alias->alias);
3271                 mm_free(alias);
3272         }
3273
3274         mm_free(http);
3275 }
3276
3277 int
3278 evhttp_add_virtual_host(struct evhttp* http, const char *pattern,
3279     struct evhttp* vhost)
3280 {
3281         /* a vhost can only be a vhost once and should not have bound sockets */
3282         if (vhost->vhost_pattern != NULL ||
3283             TAILQ_FIRST(&vhost->sockets) != NULL)
3284                 return (-1);
3285
3286         vhost->vhost_pattern = mm_strdup(pattern);
3287         if (vhost->vhost_pattern == NULL)
3288                 return (-1);
3289
3290         TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost);
3291
3292         return (0);
3293 }
3294
3295 int
3296 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost)
3297 {
3298         if (vhost->vhost_pattern == NULL)
3299                 return (-1);
3300
3301         TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost);
3302
3303         mm_free(vhost->vhost_pattern);
3304         vhost->vhost_pattern = NULL;
3305
3306         return (0);
3307 }
3308
3309 int
3310 evhttp_add_server_alias(struct evhttp *http, const char *alias)
3311 {
3312         struct evhttp_server_alias *evalias;
3313
3314         evalias = mm_calloc(1, sizeof(*evalias));
3315         if (!evalias)
3316                 return -1;
3317
3318         evalias->alias = mm_strdup(alias);
3319         if (!evalias->alias) {
3320                 mm_free(evalias);
3321                 return -1;
3322         }
3323
3324         TAILQ_INSERT_TAIL(&http->aliases, evalias, next);
3325
3326         return 0;
3327 }
3328
3329 int
3330 evhttp_remove_server_alias(struct evhttp *http, const char *alias)
3331 {
3332         struct evhttp_server_alias *evalias;
3333
3334         TAILQ_FOREACH(evalias, &http->aliases, next) {
3335                 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) {
3336                         TAILQ_REMOVE(&http->aliases, evalias, next);
3337                         mm_free(evalias->alias);
3338                         mm_free(evalias);
3339                         return 0;
3340                 }
3341         }
3342
3343         return -1;
3344 }
3345
3346 void
3347 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
3348 {
3349         http->timeout = timeout_in_secs;
3350 }
3351
3352 void
3353 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size)
3354 {
3355         if (max_headers_size < 0)
3356                 http->default_max_headers_size = EV_SIZE_MAX;
3357         else
3358                 http->default_max_headers_size = max_headers_size;
3359 }
3360
3361 void
3362 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size)
3363 {
3364         if (max_body_size < 0)
3365                 http->default_max_body_size = EV_UINT64_MAX;
3366         else
3367                 http->default_max_body_size = max_body_size;
3368 }
3369
3370 void
3371 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods)
3372 {
3373         http->allowed_methods = methods;
3374 }
3375
3376 int
3377 evhttp_set_cb(struct evhttp *http, const char *uri,
3378     void (*cb)(struct evhttp_request *, void *), void *cbarg)
3379 {
3380         struct evhttp_cb *http_cb;
3381
3382         TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3383                 if (strcmp(http_cb->what, uri) == 0)
3384                         return (-1);
3385         }
3386
3387         if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) {
3388                 event_warn("%s: calloc", __func__);
3389                 return (-2);
3390         }
3391
3392         http_cb->what = mm_strdup(uri);
3393         if (http_cb->what == NULL) {
3394                 event_warn("%s: strdup", __func__);
3395                 mm_free(http_cb);
3396                 return (-3);
3397         }
3398         http_cb->cb = cb;
3399         http_cb->cbarg = cbarg;
3400
3401         TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
3402
3403         return (0);
3404 }
3405
3406 int
3407 evhttp_del_cb(struct evhttp *http, const char *uri)
3408 {
3409         struct evhttp_cb *http_cb;
3410
3411         TAILQ_FOREACH(http_cb, &http->callbacks, next) {
3412                 if (strcmp(http_cb->what, uri) == 0)
3413                         break;
3414         }
3415         if (http_cb == NULL)
3416                 return (-1);
3417
3418         TAILQ_REMOVE(&http->callbacks, http_cb, next);
3419         mm_free(http_cb->what);
3420         mm_free(http_cb);
3421
3422         return (0);
3423 }
3424
3425 void
3426 evhttp_set_gencb(struct evhttp *http,
3427     void (*cb)(struct evhttp_request *, void *), void *cbarg)
3428 {
3429         http->gencb = cb;
3430         http->gencbarg = cbarg;
3431 }
3432
3433 /*
3434  * Request related functions
3435  */
3436
3437 struct evhttp_request *
3438 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
3439 {
3440         struct evhttp_request *req = NULL;
3441
3442         /* Allocate request structure */
3443         if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) {
3444                 event_warn("%s: calloc", __func__);
3445                 goto error;
3446         }
3447
3448         req->headers_size = 0;
3449         req->body_size = 0;
3450
3451         req->kind = EVHTTP_RESPONSE;
3452         req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3453         if (req->input_headers == NULL) {
3454                 event_warn("%s: calloc", __func__);
3455                 goto error;
3456         }
3457         TAILQ_INIT(req->input_headers);
3458
3459         req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq));
3460         if (req->output_headers == NULL) {
3461                 event_warn("%s: calloc", __func__);
3462                 goto error;
3463         }
3464         TAILQ_INIT(req->output_headers);
3465
3466         if ((req->input_buffer = evbuffer_new()) == NULL) {
3467                 event_warn("%s: evbuffer_new", __func__);
3468                 goto error;
3469         }
3470
3471         if ((req->output_buffer = evbuffer_new()) == NULL) {
3472                 event_warn("%s: evbuffer_new", __func__);
3473                 goto error;
3474         }
3475
3476         req->cb = cb;
3477         req->cb_arg = arg;
3478
3479         return (req);
3480
3481  error:
3482         if (req != NULL)
3483                 evhttp_request_free(req);
3484         return (NULL);
3485 }
3486
3487 void
3488 evhttp_request_free(struct evhttp_request *req)
3489 {
3490         if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) {
3491                 req->flags |= EVHTTP_REQ_NEEDS_FREE;
3492                 return;
3493         }
3494
3495         if (req->remote_host != NULL)
3496                 mm_free(req->remote_host);
3497         if (req->uri != NULL)
3498                 mm_free(req->uri);
3499         if (req->uri_elems != NULL)
3500                 evhttp_uri_free(req->uri_elems);
3501         if (req->response_code_line != NULL)
3502                 mm_free(req->response_code_line);
3503         if (req->host_cache != NULL)
3504                 mm_free(req->host_cache);
3505
3506         evhttp_clear_headers(req->input_headers);
3507         mm_free(req->input_headers);
3508
3509         evhttp_clear_headers(req->output_headers);
3510         mm_free(req->output_headers);
3511
3512         if (req->input_buffer != NULL)
3513                 evbuffer_free(req->input_buffer);
3514
3515         if (req->output_buffer != NULL)
3516                 evbuffer_free(req->output_buffer);
3517
3518         mm_free(req);
3519 }
3520
3521 void
3522 evhttp_request_own(struct evhttp_request *req)
3523 {
3524         req->flags |= EVHTTP_USER_OWNED;
3525 }
3526
3527 int
3528 evhttp_request_is_owned(struct evhttp_request *req)
3529 {
3530         return (req->flags & EVHTTP_USER_OWNED) != 0;
3531 }
3532
3533 struct evhttp_connection *
3534 evhttp_request_get_connection(struct evhttp_request *req)
3535 {
3536         return req->evcon;
3537 }
3538
3539 struct event_base *
3540 evhttp_connection_get_base(struct evhttp_connection *conn)
3541 {
3542         return conn->base;
3543 }
3544
3545 void
3546 evhttp_request_set_chunked_cb(struct evhttp_request *req,
3547     void (*cb)(struct evhttp_request *, void *))
3548 {
3549         req->chunk_cb = cb;
3550 }
3551
3552 /*
3553  * Allows for inspection of the request URI
3554  */
3555
3556 const char *
3557 evhttp_request_get_uri(const struct evhttp_request *req) {
3558         if (req->uri == NULL)
3559                 event_debug(("%s: request %p has no uri\n", __func__, req));
3560         return (req->uri);
3561 }
3562
3563 const struct evhttp_uri *
3564 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) {
3565         if (req->uri_elems == NULL)
3566                 event_debug(("%s: request %p has no uri elems\n",
3567                             __func__, req));
3568         return (req->uri_elems);
3569 }
3570
3571 const char *
3572 evhttp_request_get_host(struct evhttp_request *req)
3573 {
3574         const char *host = NULL;
3575
3576         if (req->host_cache)
3577                 return req->host_cache;
3578
3579         if (req->uri_elems)
3580                 host = evhttp_uri_get_host(req->uri_elems);
3581         if (!host && req->input_headers) {
3582                 const char *p;
3583                 size_t len;
3584
3585                 host = evhttp_find_header(req->input_headers, "Host");
3586                 /* The Host: header may include a port. Remove it here
3587                    to be consistent with uri_elems case above. */
3588                 if (host) {
3589                         p = host + strlen(host) - 1;
3590                         while (p > host && EVUTIL_ISDIGIT(*p))
3591                                 --p;
3592                         if (p > host && *p == ':') {
3593                                 len = p - host;
3594                                 req->host_cache = mm_malloc(len + 1);
3595                                 if (!req->host_cache) {
3596                                         event_warn("%s: malloc", __func__);
3597                                         return NULL;
3598                                 }
3599                                 memcpy(req->host_cache, host, len);
3600                                 req->host_cache[len] = '\0';
3601                                 host = req->host_cache;
3602                         }
3603                 }
3604         }
3605
3606         return host;
3607 }
3608
3609 enum evhttp_cmd_type
3610 evhttp_request_get_command(const struct evhttp_request *req) {
3611         return (req->type);
3612 }
3613
3614 int
3615 evhttp_request_get_response_code(const struct evhttp_request *req)
3616 {
3617         return req->response_code;
3618 }
3619
3620 /** Returns the input headers */
3621 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req)
3622 {
3623         return (req->input_headers);
3624 }
3625
3626 /** Returns the output headers */
3627 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req)
3628 {
3629         return (req->output_headers);
3630 }
3631
3632 /** Returns the input buffer */
3633 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req)
3634 {
3635         return (req->input_buffer);
3636 }
3637
3638 /** Returns the output buffer */
3639 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req)
3640 {
3641         return (req->output_buffer);
3642 }
3643
3644
3645 /*
3646  * Takes a file descriptor to read a request from.
3647  * The callback is executed once the whole request has been read.
3648  */
3649
3650 static struct evhttp_connection*
3651 evhttp_get_request_connection(
3652         struct evhttp* http,
3653         evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen)
3654 {
3655         struct evhttp_connection *evcon;
3656         char *hostname = NULL, *portname = NULL;
3657
3658         name_from_addr(sa, salen, &hostname, &portname);
3659         if (hostname == NULL || portname == NULL) {
3660                 if (hostname) mm_free(hostname);
3661                 if (portname) mm_free(portname);
3662                 return (NULL);
3663         }
3664
3665         event_debug(("%s: new request from %s:%s on %d\n",
3666                         __func__, hostname, portname, fd));
3667
3668         /* we need a connection object to put the http request on */
3669         evcon = evhttp_connection_base_new(
3670                 http->base, NULL, hostname, atoi(portname));
3671         mm_free(hostname);
3672         mm_free(portname);
3673         if (evcon == NULL)
3674                 return (NULL);
3675
3676         evcon->max_headers_size = http->default_max_headers_size;
3677         evcon->max_body_size = http->default_max_body_size;
3678
3679         evcon->flags |= EVHTTP_CON_INCOMING;
3680         evcon->state = EVCON_READING_FIRSTLINE;
3681
3682         evcon->fd = fd;
3683
3684         bufferevent_setfd(evcon->bufev, fd);
3685
3686         return (evcon);
3687 }
3688
3689 static int
3690 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
3691 {
3692         struct evhttp *http = evcon->http_server;
3693         struct evhttp_request *req;
3694         if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
3695                 return (-1);
3696
3697         if ((req->remote_host = mm_strdup(evcon->address)) == NULL) {
3698                 event_warn("%s: strdup", __func__);
3699                 evhttp_request_free(req);
3700                 return (-1);
3701         }
3702         req->remote_port = evcon->port;
3703
3704         req->evcon = evcon;     /* the request ends up owning the connection */
3705         req->flags |= EVHTTP_REQ_OWN_CONNECTION;
3706
3707         /* We did not present the request to the user user yet, so treat it as
3708          * if the user was done with the request.  This allows us to free the
3709          * request on a persistent connection if the client drops it without
3710          * sending a request.
3711          */
3712         req->userdone = 1;
3713
3714         TAILQ_INSERT_TAIL(&evcon->requests, req, next);
3715
3716         req->kind = EVHTTP_REQUEST;
3717
3718
3719         evhttp_start_read(evcon);
3720
3721         return (0);
3722 }
3723
3724 static void
3725 evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
3726     struct sockaddr *sa, ev_socklen_t salen)
3727 {
3728         struct evhttp_connection *evcon;
3729
3730         evcon = evhttp_get_request_connection(http, fd, sa, salen);
3731         if (evcon == NULL) {
3732                 event_sock_warn(fd, "%s: cannot get connection on %d", __func__, fd);
3733                 evutil_closesocket(fd);
3734                 return;
3735         }
3736
3737         /* the timeout can be used by the server to close idle connections */
3738         if (http->timeout != -1)
3739                 evhttp_connection_set_timeout(evcon, http->timeout);
3740
3741         /*
3742          * if we want to accept more than one request on a connection,
3743          * we need to know which http server it belongs to.
3744          */
3745         evcon->http_server = http;
3746         TAILQ_INSERT_TAIL(&http->connections, evcon, next);
3747
3748         if (evhttp_associate_new_request_with_connection(evcon) == -1)
3749                 evhttp_connection_free(evcon);
3750 }
3751
3752
3753 /*
3754  * Network helper functions that we do not want to export to the rest of
3755  * the world.
3756  */
3757
3758 static void
3759 name_from_addr(struct sockaddr *sa, ev_socklen_t salen,
3760     char **phost, char **pport)
3761 {
3762         char ntop[NI_MAXHOST];
3763         char strport[NI_MAXSERV];
3764         int ni_result;
3765
3766 #ifdef _EVENT_HAVE_GETNAMEINFO
3767         ni_result = getnameinfo(sa, salen,
3768                 ntop, sizeof(ntop), strport, sizeof(strport),
3769                 NI_NUMERICHOST|NI_NUMERICSERV);
3770
3771         if (ni_result != 0) {
3772 #ifdef EAI_SYSTEM
3773                 /* Windows doesn't have an EAI_SYSTEM. */
3774                 if (ni_result == EAI_SYSTEM)
3775                         event_err(1, "getnameinfo failed");
3776                 else
3777 #endif
3778                         event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
3779                 return;
3780         }
3781 #else
3782         ni_result = fake_getnameinfo(sa, salen,
3783                 ntop, sizeof(ntop), strport, sizeof(strport),
3784                 NI_NUMERICHOST|NI_NUMERICSERV);
3785         if (ni_result != 0)
3786                         return;
3787 #endif
3788
3789         *phost = mm_strdup(ntop);
3790         *pport = mm_strdup(strport);
3791 }
3792
3793 /* Create a non-blocking socket and bind it */
3794 /* todo: rename this function */
3795 static evutil_socket_t
3796 bind_socket_ai(struct evutil_addrinfo *ai, int reuse)
3797 {
3798         evutil_socket_t fd;
3799
3800         int on = 1, r;
3801         int serrno;
3802
3803         /* Create listen socket */
3804         fd = socket(ai ? ai->ai_family : AF_INET, SOCK_STREAM, 0);
3805         if (fd == -1) {
3806                         event_sock_warn(-1, "socket");
3807                         return (-1);
3808         }
3809
3810         if (evutil_make_socket_nonblocking(fd) < 0)
3811                 goto out;
3812         if (evutil_make_socket_closeonexec(fd) < 0)
3813                 goto out;
3814
3815         setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
3816         if (reuse)
3817                 evutil_make_listen_socket_reuseable(fd);
3818
3819         if (ai != NULL) {
3820                 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen);
3821                 if (r == -1)
3822                         goto out;
3823         }
3824
3825         return (fd);
3826
3827  out:
3828         serrno = EVUTIL_SOCKET_ERROR();
3829         evutil_closesocket(fd);
3830         EVUTIL_SET_SOCKET_ERROR(serrno);
3831         return (-1);
3832 }
3833
3834 static struct evutil_addrinfo *
3835 make_addrinfo(const char *address, ev_uint16_t port)
3836 {
3837         struct evutil_addrinfo *ai = NULL;
3838
3839         struct evutil_addrinfo hints;
3840         char strport[NI_MAXSERV];
3841         int ai_result;
3842
3843         memset(&hints, 0, sizeof(hints));
3844         hints.ai_family = AF_UNSPEC;
3845         hints.ai_socktype = SOCK_STREAM;
3846         /* turn NULL hostname into INADDR_ANY, and skip looking up any address
3847          * types we don't have an interface to connect to. */
3848         hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
3849         evutil_snprintf(strport, sizeof(strport), "%d", port);
3850         if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai))
3851             != 0) {
3852                 if (ai_result == EVUTIL_EAI_SYSTEM)
3853                         event_warn("getaddrinfo");
3854                 else
3855                         event_warnx("getaddrinfo: %s",
3856                             evutil_gai_strerror(ai_result));
3857                 return (NULL);
3858         }
3859
3860         return (ai);
3861 }
3862
3863 static evutil_socket_t
3864 bind_socket(const char *address, ev_uint16_t port, int reuse)
3865 {
3866         evutil_socket_t fd;
3867         struct evutil_addrinfo *aitop = NULL;
3868
3869         /* just create an unbound socket */
3870         if (address == NULL && port == 0)
3871                 return bind_socket_ai(NULL, 0);
3872
3873         aitop = make_addrinfo(address, port);
3874
3875         if (aitop == NULL)
3876                 return (-1);
3877
3878         fd = bind_socket_ai(aitop, reuse);
3879
3880         evutil_freeaddrinfo(aitop);
3881
3882         return (fd);
3883 }
3884
3885 struct evhttp_uri {
3886         unsigned flags;
3887         char *scheme; /* scheme; e.g http, ftp etc */
3888         char *userinfo; /* userinfo (typically username:pass), or NULL */
3889         char *host; /* hostname, IP address, or NULL */
3890         int port; /* port, or zero */
3891         char *path; /* path, or "". */
3892         char *query; /* query, or NULL */
3893         char *fragment; /* fragment or NULL */
3894 };
3895
3896 struct evhttp_uri *
3897 evhttp_uri_new(void)
3898 {
3899         struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1);
3900         if (uri)
3901                 uri->port = -1;
3902         return uri;
3903 }
3904
3905 void
3906 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags)
3907 {
3908         uri->flags = flags;
3909 }
3910
3911 /* Return true if the string starting at s and ending immediately before eos
3912  * is a valid URI scheme according to RFC3986
3913  */
3914 static int
3915 scheme_ok(const char *s, const char *eos)
3916 {
3917         /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */
3918         EVUTIL_ASSERT(eos >= s);
3919         if (s == eos)
3920                 return 0;
3921         if (!EVUTIL_ISALPHA(*s))
3922                 return 0;
3923         while (++s < eos) {
3924                 if (! EVUTIL_ISALNUM(*s) &&
3925                     *s != '+' && *s != '-' && *s != '.')
3926                         return 0;
3927         }
3928         return 1;
3929 }
3930
3931 #define SUBDELIMS "!$&'()*+,;="
3932
3933 /* Return true iff [s..eos) is a valid userinfo */
3934 static int
3935 userinfo_ok(const char *s, const char *eos)
3936 {
3937         while (s < eos) {
3938                 if (CHAR_IS_UNRESERVED(*s) ||
3939                     strchr(SUBDELIMS, *s) ||
3940                     *s == ':')
3941                         ++s;
3942                 else if (*s == '%' && s+2 < eos &&
3943                     EVUTIL_ISXDIGIT(s[1]) &&
3944                     EVUTIL_ISXDIGIT(s[2]))
3945                         s += 3;
3946                 else
3947                         return 0;
3948         }
3949         return 1;
3950 }
3951
3952 static int
3953 regname_ok(const char *s, const char *eos)
3954 {
3955         while (s && s<eos) {
3956                 if (CHAR_IS_UNRESERVED(*s) ||
3957                     strchr(SUBDELIMS, *s))
3958                         ++s;
3959                 else if (*s == '%' &&
3960                     EVUTIL_ISXDIGIT(s[1]) &&
3961                     EVUTIL_ISXDIGIT(s[2]))
3962                         s += 3;
3963                 else
3964                         return 0;
3965         }
3966         return 1;
3967 }
3968
3969 static int
3970 parse_port(const char *s, const char *eos)
3971 {
3972         int portnum = 0;
3973         while (s < eos) {
3974                 if (! EVUTIL_ISDIGIT(*s))
3975                         return -1;
3976                 portnum = (portnum * 10) + (*s - '0');
3977                 if (portnum < 0)
3978                         return -1;
3979                 ++s;
3980         }
3981         return portnum;
3982 }
3983
3984 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */
3985 static int
3986 bracket_addr_ok(const char *s, const char *eos)
3987 {
3988         if (s + 3 > eos || *s != '[' || *(eos-1) != ']')
3989                 return 0;
3990         if (s[1] == 'v') {
3991                 /* IPvFuture, or junk.
3992                    "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
3993                  */
3994                 s += 2; /* skip [v */
3995                 --eos;
3996                 if (!EVUTIL_ISXDIGIT(*s)) /*require at least one*/
3997                         return 0;
3998                 while (s < eos && *s != '.') {
3999                         if (EVUTIL_ISXDIGIT(*s))
4000                                 ++s;
4001                         else
4002                                 return 0;
4003                 }
4004                 if (*s != '.')
4005                         return 0;
4006                 ++s;
4007                 while (s < eos) {
4008                         if (CHAR_IS_UNRESERVED(*s) ||
4009                             strchr(SUBDELIMS, *s) ||
4010                             *s == ':')
4011                                 ++s;
4012                         else
4013                                 return 0;
4014                 }
4015                 return 2;
4016         } else {
4017                 /* IPv6, or junk */
4018                 char buf[64];
4019                 ev_ssize_t n_chars = eos-s-2;
4020                 struct in6_addr in6;
4021                 if (n_chars >= 64) /* way too long */
4022                         return 0;
4023                 memcpy(buf, s+1, n_chars);
4024                 buf[n_chars]='\0';
4025                 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0;
4026         }
4027 }
4028
4029 static int
4030 parse_authority(struct evhttp_uri *uri, char *s, char *eos)
4031 {
4032         char *cp, *port;
4033         EVUTIL_ASSERT(eos);
4034         if (eos == s) {
4035                 uri->host = mm_strdup("");
4036                 if (uri->host == NULL) {
4037                         event_warn("%s: strdup", __func__);
4038                         return -1;
4039                 }
4040                 return 0;
4041         }
4042
4043         /* Optionally, we start with "userinfo@" */
4044
4045         cp = strchr(s, '@');
4046         if (cp && cp < eos) {
4047                 if (! userinfo_ok(s,cp))
4048                         return -1;
4049                 *cp++ = '\0';
4050                 uri->userinfo = mm_strdup(s);
4051                 if (uri->userinfo == NULL) {
4052                         event_warn("%s: strdup", __func__);
4053                         return -1;
4054                 }
4055         } else {
4056                 cp = s;
4057         }
4058         /* Optionally, we end with ":port" */
4059         for (port=eos-1; port >= cp && EVUTIL_ISDIGIT(*port); --port)
4060                 ;
4061         if (port >= cp && *port == ':') {
4062                 if (port+1 == eos) /* Leave port unspecified; the RFC allows a
4063                                     * nil port */
4064                         uri->port = -1;
4065                 else if ((uri->port = parse_port(port+1, eos))<0)
4066                         return -1;
4067                 eos = port;
4068         }
4069         /* Now, cp..eos holds the "host" port, which can be an IPv4Address,
4070          * an IP-Literal, or a reg-name */
4071         EVUTIL_ASSERT(eos >= cp);
4072         if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') {
4073                 /* IPv6address, IP-Literal, or junk. */
4074                 if (! bracket_addr_ok(cp, eos))
4075                         return -1;
4076         } else {
4077                 /* Make sure the host part is ok. */
4078                 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */
4079                         return -1;
4080         }
4081         uri->host = mm_malloc(eos-cp+1);
4082         if (uri->host == NULL) {
4083                 event_warn("%s: malloc", __func__);
4084                 return -1;
4085         }
4086         memcpy(uri->host, cp, eos-cp);
4087         uri->host[eos-cp] = '\0';
4088         return 0;
4089
4090 }
4091
4092 static char *
4093 end_of_authority(char *cp)
4094 {
4095         while (*cp) {
4096                 if (*cp == '?' || *cp == '#' || *cp == '/')
4097                         return cp;
4098                 ++cp;
4099         }
4100         return cp;
4101 }
4102
4103 enum uri_part {
4104         PART_PATH,
4105         PART_QUERY,
4106         PART_FRAGMENT
4107 };
4108
4109 /* Return the character after the longest prefix of 'cp' that matches...
4110  *   *pchar / "/" if allow_qchars is false, or
4111  *   *(pchar / "/" / "?") if allow_qchars is true.
4112  */
4113 static char *
4114 end_of_path(char *cp, enum uri_part part, unsigned flags)
4115 {
4116         if (flags & EVHTTP_URI_NONCONFORMANT) {
4117                 /* If NONCONFORMANT:
4118                  *   Path is everything up to a # or ? or nul.
4119                  *   Query is everything up a # or nul
4120                  *   Fragment is everything up to a nul.
4121                  */
4122                 switch (part) {
4123                 case PART_PATH:
4124                         while (*cp && *cp != '#' && *cp != '?')
4125                                 ++cp;
4126                         break;
4127                 case PART_QUERY:
4128                         while (*cp && *cp != '#')
4129                                 ++cp;
4130                         break;
4131                 case PART_FRAGMENT:
4132                         cp += strlen(cp);
4133                         break;
4134                 };
4135                 return cp;
4136         }
4137
4138         while (*cp) {
4139                 if (CHAR_IS_UNRESERVED(*cp) ||
4140                     strchr(SUBDELIMS, *cp) ||
4141                     *cp == ':' || *cp == '@' || *cp == '/')
4142                         ++cp;
4143                 else if (*cp == '%' && EVUTIL_ISXDIGIT(cp[1]) &&
4144                     EVUTIL_ISXDIGIT(cp[2]))
4145                         cp += 3;
4146                 else if (*cp == '?' && part != PART_PATH)
4147                         ++cp;
4148                 else
4149                         return cp;
4150         }
4151         return cp;
4152 }
4153
4154 static int
4155 path_matches_noscheme(const char *cp)
4156 {
4157         while (*cp) {
4158                 if (*cp == ':')
4159                         return 0;
4160                 else if (*cp == '/')
4161                         return 1;
4162                 ++cp;
4163         }
4164         return 1;
4165 }
4166
4167 struct evhttp_uri *
4168 evhttp_uri_parse(const char *source_uri)
4169 {
4170         return evhttp_uri_parse_with_flags(source_uri, 0);
4171 }
4172
4173 struct evhttp_uri *
4174 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags)
4175 {
4176         char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL;
4177         char *path = NULL, *fragment = NULL;
4178         int got_authority = 0;
4179
4180         struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri));
4181         if (uri == NULL) {
4182                 event_warn("%s: calloc", __func__);
4183                 goto err;
4184         }
4185         uri->port = -1;
4186         uri->flags = flags;
4187
4188         readbuf = mm_strdup(source_uri);
4189         if (readbuf == NULL) {
4190                 event_warn("%s: strdup", __func__);
4191                 goto err;
4192         }
4193
4194         readp = readbuf;
4195         token = NULL;
4196
4197         /* We try to follow RFC3986 here as much as we can, and match
4198            the productions
4199
4200               URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
4201
4202               relative-ref  = relative-part [ "?" query ] [ "#" fragment ]
4203          */
4204
4205         /* 1. scheme: */
4206         token = strchr(readp, ':');
4207         if (token && scheme_ok(readp,token)) {
4208                 *token = '\0';
4209                 uri->scheme = mm_strdup(readp);
4210                 if (uri->scheme == NULL) {
4211                         event_warn("%s: strdup", __func__);
4212                         goto err;
4213                 }
4214                 readp = token+1; /* eat : */
4215         }
4216
4217         /* 2. Optionally, "//" then an 'authority' part. */
4218         if (readp[0]=='/' && readp[1] == '/') {
4219                 char *authority;
4220                 readp += 2;
4221                 authority = readp;
4222                 path = end_of_authority(readp);
4223                 if (parse_authority(uri, authority, path) < 0)
4224                         goto err;
4225                 readp = path;
4226                 got_authority = 1;
4227         }
4228
4229         /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty
4230          */
4231         path = readp;
4232         readp = end_of_path(path, PART_PATH, flags);
4233
4234         /* Query */
4235         if (*readp == '?') {
4236                 *readp = '\0';
4237                 ++readp;
4238                 query = readp;
4239                 readp = end_of_path(readp, PART_QUERY, flags);
4240         }
4241         /* fragment */
4242         if (*readp == '#') {
4243                 *readp = '\0';
4244                 ++readp;
4245                 fragment = readp;
4246                 readp = end_of_path(readp, PART_FRAGMENT, flags);
4247         }
4248         if (*readp != '\0') {
4249                 goto err;
4250         }
4251
4252         /* These next two cases may be unreachable; I'm leaving them
4253          * in to be defensive. */
4254         /* If you didn't get an authority, the path can't begin with "//" */
4255         if (!got_authority && path[0]=='/' && path[1]=='/')
4256                 goto err;
4257         /* If you did get an authority, the path must begin with "/" or be
4258          * empty. */
4259         if (got_authority && path[0] != '/' && path[0] != '\0')
4260                 goto err;
4261         /* (End of maybe-unreachable cases) */
4262
4263         /* If there was no scheme, the first part of the path (if any) must
4264          * have no colon in it. */
4265         if (! uri->scheme && !path_matches_noscheme(path))
4266                 goto err;
4267
4268         EVUTIL_ASSERT(path);
4269         uri->path = mm_strdup(path);
4270         if (uri->path == NULL) {
4271                 event_warn("%s: strdup", __func__);
4272                 goto err;
4273         }
4274
4275         if (query) {
4276                 uri->query = mm_strdup(query);
4277                 if (uri->query == NULL) {
4278                         event_warn("%s: strdup", __func__);
4279                         goto err;
4280                 }
4281         }
4282         if (fragment) {
4283                 uri->fragment = mm_strdup(fragment);
4284                 if (uri->fragment == NULL) {
4285                         event_warn("%s: strdup", __func__);
4286                         goto err;
4287                 }
4288         }
4289
4290         mm_free(readbuf);
4291
4292         return uri;
4293 err:
4294         if (uri)
4295                 evhttp_uri_free(uri);
4296         if (readbuf)
4297                 mm_free(readbuf);
4298         return NULL;
4299 }
4300
4301 void
4302 evhttp_uri_free(struct evhttp_uri *uri)
4303 {
4304 #define _URI_FREE_STR(f)                \
4305         if (uri->f) {                   \
4306                 mm_free(uri->f);                \
4307         }
4308
4309         _URI_FREE_STR(scheme);
4310         _URI_FREE_STR(userinfo);
4311         _URI_FREE_STR(host);
4312         _URI_FREE_STR(path);
4313         _URI_FREE_STR(query);
4314         _URI_FREE_STR(fragment);
4315
4316         mm_free(uri);
4317 #undef _URI_FREE_STR
4318 }
4319
4320 char *
4321 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit)
4322 {
4323         struct evbuffer *tmp = 0;
4324         size_t joined_size = 0;
4325         char *output = NULL;
4326
4327 #define _URI_ADD(f)     evbuffer_add(tmp, uri->f, strlen(uri->f))
4328
4329         if (!uri || !buf || !limit)
4330                 return NULL;
4331
4332         tmp = evbuffer_new();
4333         if (!tmp)
4334                 return NULL;
4335
4336         if (uri->scheme) {
4337                 _URI_ADD(scheme);
4338                 evbuffer_add(tmp, ":", 1);
4339         }
4340         if (uri->host) {
4341                 evbuffer_add(tmp, "//", 2);
4342                 if (uri->userinfo)
4343                         evbuffer_add_printf(tmp,"%s@", uri->userinfo);
4344                 _URI_ADD(host);
4345                 if (uri->port >= 0)
4346                         evbuffer_add_printf(tmp,":%d", uri->port);
4347
4348                 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0')
4349                         goto err;
4350         }
4351
4352         if (uri->path)
4353                 _URI_ADD(path);
4354
4355         if (uri->query) {
4356                 evbuffer_add(tmp, "?", 1);
4357                 _URI_ADD(query);
4358         }
4359
4360         if (uri->fragment) {
4361                 evbuffer_add(tmp, "#", 1);
4362                 _URI_ADD(fragment);
4363         }
4364
4365         evbuffer_add(tmp, "\0", 1); /* NUL */
4366
4367         joined_size = evbuffer_get_length(tmp);
4368
4369         if (joined_size > limit) {
4370                 /* It doesn't fit. */
4371                 evbuffer_free(tmp);
4372                 return NULL;
4373         }
4374         evbuffer_remove(tmp, buf, joined_size);
4375
4376         output = buf;
4377 err:
4378         evbuffer_free(tmp);
4379
4380         return output;
4381 #undef _URI_ADD
4382 }
4383
4384 const char *
4385 evhttp_uri_get_scheme(const struct evhttp_uri *uri)
4386 {
4387         return uri->scheme;
4388 }
4389 const char *
4390 evhttp_uri_get_userinfo(const struct evhttp_uri *uri)
4391 {
4392         return uri->userinfo;
4393 }
4394 const char *
4395 evhttp_uri_get_host(const struct evhttp_uri *uri)
4396 {
4397         return uri->host;
4398 }
4399 int
4400 evhttp_uri_get_port(const struct evhttp_uri *uri)
4401 {
4402         return uri->port;
4403 }
4404 const char *
4405 evhttp_uri_get_path(const struct evhttp_uri *uri)
4406 {
4407         return uri->path;
4408 }
4409 const char *
4410 evhttp_uri_get_query(const struct evhttp_uri *uri)
4411 {
4412         return uri->query;
4413 }
4414 const char *
4415 evhttp_uri_get_fragment(const struct evhttp_uri *uri)
4416 {
4417         return uri->fragment;
4418 }
4419
4420 #define _URI_SET_STR(f) do {                                    \
4421         if (uri->f)                                             \
4422                 mm_free(uri->f);                                \
4423         if (f) {                                                \
4424                 if ((uri->f = mm_strdup(f)) == NULL) {          \
4425                         event_warn("%s: strdup()", __func__);   \
4426                         return -1;                              \
4427                 }                                               \
4428         } else {                                                \
4429                 uri->f = NULL;                                  \
4430         }                                                       \
4431         } while(0)
4432
4433 int
4434 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme)
4435 {
4436         if (scheme && !scheme_ok(scheme, scheme+strlen(scheme)))
4437                 return -1;
4438
4439         _URI_SET_STR(scheme);
4440         return 0;
4441 }
4442 int
4443 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo)
4444 {
4445         if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo)))
4446                 return -1;
4447         _URI_SET_STR(userinfo);
4448         return 0;
4449 }
4450 int
4451 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host)
4452 {
4453         if (host) {
4454                 if (host[0] == '[') {
4455                         if (! bracket_addr_ok(host, host+strlen(host)))
4456                                 return -1;
4457                 } else {
4458                         if (! regname_ok(host, host+strlen(host)))
4459                                 return -1;
4460                 }
4461         }
4462
4463         _URI_SET_STR(host);
4464         return 0;
4465 }
4466 int
4467 evhttp_uri_set_port(struct evhttp_uri *uri, int port)
4468 {
4469         if (port < -1)
4470                 return -1;
4471         uri->port = port;
4472         return 0;
4473 }
4474 #define end_of_cpath(cp,p,f) \
4475         ((const char*)(end_of_path(((char*)(cp)), (p), (f))))
4476
4477 int
4478 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path)
4479 {
4480         if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path))
4481                 return -1;
4482
4483         _URI_SET_STR(path);
4484         return 0;
4485 }
4486 int
4487 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query)
4488 {
4489         if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query))
4490                 return -1;
4491         _URI_SET_STR(query);
4492         return 0;
4493 }
4494 int
4495 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment)
4496 {
4497         if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment))
4498                 return -1;
4499         _URI_SET_STR(fragment);
4500         return 0;
4501 }