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