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