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