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