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