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