Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Side by Side Diff: third_party/libevent/http.c

Issue 1531573008: move libevent into base (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix shim path Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/libevent/freebsd/event-config.h ('k') | third_party/libevent/http-internal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2002-2006 Niels Provos <provos@citi.umich.edu>
3 * All rights reserved.
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 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #ifdef HAVE_SYS_PARAM_H
33 #include <sys/param.h>
34 #endif
35 #ifdef HAVE_SYS_TYPES_H
36 #include <sys/types.h>
37 #endif
38
39 #ifdef HAVE_SYS_TIME_H
40 #include <sys/time.h>
41 #endif
42 #ifdef HAVE_SYS_IOCCOM_H
43 #include <sys/ioccom.h>
44 #endif
45
46 #ifndef WIN32
47 #include <sys/resource.h>
48 #include <sys/socket.h>
49 #include <sys/stat.h>
50 #include <sys/wait.h>
51 #endif
52
53 #include <sys/queue.h>
54
55 #ifndef WIN32
56 #include <netinet/in.h>
57 #include <netdb.h>
58 #endif
59
60 #ifdef WIN32
61 #include <winsock2.h>
62 #endif
63
64 #include <assert.h>
65 #include <ctype.h>
66 #include <errno.h>
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #ifndef WIN32
71 #include <syslog.h>
72 #endif
73 #include <signal.h>
74 #include <time.h>
75 #ifdef HAVE_UNISTD_H
76 #include <unistd.h>
77 #endif
78 #ifdef HAVE_FCNTL_H
79 #include <fcntl.h>
80 #endif
81
82 #undef timeout_pending
83 #undef timeout_initialized
84
85 #include "strlcpy-internal.h"
86 #include "event.h"
87 #include "evhttp.h"
88 #include "evutil.h"
89 #include "log.h"
90 #include "http-internal.h"
91
92 #ifdef WIN32
93 #define strcasecmp _stricmp
94 #define strncasecmp _strnicmp
95 #define strdup _strdup
96 #endif
97
98 #ifndef HAVE_GETNAMEINFO
99 #define NI_MAXSERV 32
100 #define NI_MAXHOST 1025
101
102 #ifndef NI_NUMERICHOST
103 #define NI_NUMERICHOST 1
104 #endif
105
106 #ifndef NI_NUMERICSERV
107 #define NI_NUMERICSERV 2
108 #endif
109
110 static int
111 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
112 size_t hostlen, char *serv, size_t servlen, int flags)
113 {
114 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
115
116 if (serv != NULL) {
117 char tmpserv[16];
118 evutil_snprintf(tmpserv, sizeof(tmpserv),
119 "%d", ntohs(sin->sin_port));
120 if (strlcpy(serv, tmpserv, servlen) >= servlen)
121 return (-1);
122 }
123
124 if (host != NULL) {
125 if (flags & NI_NUMERICHOST) {
126 if (strlcpy(host, inet_ntoa(sin->sin_addr),
127 hostlen) >= hostlen)
128 return (-1);
129 else
130 return (0);
131 } else {
132 struct hostent *hp;
133 hp = gethostbyaddr((char *)&sin->sin_addr,
134 sizeof(struct in_addr), AF_INET);
135 if (hp == NULL)
136 return (-2);
137
138 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
139 return (-1);
140 else
141 return (0);
142 }
143 }
144 return (0);
145 }
146
147 #endif
148
149 #ifndef HAVE_GETADDRINFO
150 /* Apparently msvc2010 does have an addrinfo definition visible here */
151 #if !defined(WIN32) || !defined(_MSC_VER) || (_MSC_VER < 1600)
152 struct addrinfo {
153 int ai_family;
154 int ai_socktype;
155 int ai_protocol;
156 size_t ai_addrlen;
157 struct sockaddr *ai_addr;
158 struct addrinfo *ai_next;
159 };
160 #endif
161 static int
162 fake_getaddrinfo(const char *hostname, struct addrinfo *ai)
163 {
164 struct hostent *he = NULL;
165 struct sockaddr_in *sa;
166 if (hostname) {
167 he = gethostbyname(hostname);
168 if (!he)
169 return (-1);
170 }
171 ai->ai_family = he ? he->h_addrtype : AF_INET;
172 ai->ai_socktype = SOCK_STREAM;
173 ai->ai_protocol = 0;
174 ai->ai_addrlen = sizeof(struct sockaddr_in);
175 if (NULL == (ai->ai_addr = malloc(ai->ai_addrlen)))
176 return (-1);
177 sa = (struct sockaddr_in*)ai->ai_addr;
178 memset(sa, 0, ai->ai_addrlen);
179 if (he) {
180 sa->sin_family = he->h_addrtype;
181 memcpy(&sa->sin_addr, he->h_addr_list[0], he->h_length);
182 } else {
183 sa->sin_family = AF_INET;
184 sa->sin_addr.s_addr = INADDR_ANY;
185 }
186 ai->ai_next = NULL;
187 return (0);
188 }
189 static void
190 fake_freeaddrinfo(struct addrinfo *ai)
191 {
192 free(ai->ai_addr);
193 }
194 #endif
195
196 #ifndef MIN
197 #define MIN(a,b) (((a)<(b))?(a):(b))
198 #endif
199
200 /* wrapper for setting the base from the http server */
201 #define EVHTTP_BASE_SET(x, y) do { \
202 if ((x)->base != NULL) event_base_set((x)->base, y); \
203 } while (0)
204
205 extern int debug;
206
207 static int socket_connect(int fd, const char *address, unsigned short port);
208 static int bind_socket_ai(struct addrinfo *, int reuse);
209 static int bind_socket(const char *, u_short, int reuse);
210 static void name_from_addr(struct sockaddr *, socklen_t, char **, char **);
211 static int evhttp_associate_new_request_with_connection(
212 struct evhttp_connection *evcon);
213 static void evhttp_connection_start_detectclose(
214 struct evhttp_connection *evcon);
215 static void evhttp_connection_stop_detectclose(
216 struct evhttp_connection *evcon);
217 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
218 static void evhttp_read_firstline(struct evhttp_connection *evcon,
219 struct evhttp_request *req);
220 static void evhttp_read_header(struct evhttp_connection *evcon,
221 struct evhttp_request *req);
222 static int evhttp_add_header_internal(struct evkeyvalq *headers,
223 const char *key, const char *value);
224 static int evhttp_decode_uri_internal(const char *uri, size_t length,
225 char *ret, int always_decode_plus);
226
227 void evhttp_read(int, short, void *);
228 void evhttp_write(int, short, void *);
229
230 #ifndef HAVE_STRSEP
231 /* strsep replacement for platforms that lack it. Only works if
232 * del is one character long. */
233 static char *
234 strsep(char **s, const char *del)
235 {
236 char *d, *tok;
237 assert(strlen(del) == 1);
238 if (!s || !*s)
239 return NULL;
240 tok = *s;
241 d = strstr(tok, del);
242 if (d) {
243 *d = '\0';
244 *s = d + 1;
245 } else
246 *s = NULL;
247 return tok;
248 }
249 #endif
250
251 static const char *
252 html_replace(char ch, char *buf)
253 {
254 switch (ch) {
255 case '<':
256 return "&lt;";
257 case '>':
258 return "&gt;";
259 case '"':
260 return "&quot;";
261 case '\'':
262 return "&#039;";
263 case '&':
264 return "&amp;";
265 default:
266 break;
267 }
268
269 /* Echo the character back */
270 buf[0] = ch;
271 buf[1] = '\0';
272
273 return buf;
274 }
275
276 /*
277 * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
278 * &#039; and &amp; correspondingly.
279 *
280 * The returned string needs to be freed by the caller.
281 */
282
283 char *
284 evhttp_htmlescape(const char *html)
285 {
286 int i, new_size = 0, old_size = strlen(html);
287 char *escaped_html, *p;
288 char scratch_space[2];
289
290 for (i = 0; i < old_size; ++i)
291 new_size += strlen(html_replace(html[i], scratch_space));
292
293 p = escaped_html = malloc(new_size + 1);
294 if (escaped_html == NULL)
295 event_err(1, "%s: malloc(%d)", __func__, new_size + 1);
296 for (i = 0; i < old_size; ++i) {
297 const char *replaced = html_replace(html[i], scratch_space);
298 /* this is length checked */
299 strcpy(p, replaced);
300 p += strlen(replaced);
301 }
302
303 *p = '\0';
304
305 return (escaped_html);
306 }
307
308 static const char *
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 default:
324 method = NULL;
325 break;
326 }
327
328 return (method);
329 }
330
331 static void
332 evhttp_add_event(struct event *ev, int timeout, int default_timeout)
333 {
334 if (timeout != 0) {
335 struct timeval tv;
336
337 evutil_timerclear(&tv);
338 tv.tv_sec = timeout != -1 ? timeout : default_timeout;
339 event_add(ev, &tv);
340 } else {
341 event_add(ev, NULL);
342 }
343 }
344
345 void
346 evhttp_write_buffer(struct evhttp_connection *evcon,
347 void (*cb)(struct evhttp_connection *, void *), void *arg)
348 {
349 event_debug(("%s: preparing to write buffer\n", __func__));
350
351 /* Set call back */
352 evcon->cb = cb;
353 evcon->cb_arg = arg;
354
355 /* check if the event is already pending */
356 if (event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL))
357 event_del(&evcon->ev);
358
359 event_set(&evcon->ev, evcon->fd, EV_WRITE, evhttp_write, evcon);
360 EVHTTP_BASE_SET(evcon, &evcon->ev);
361 evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_WRITE_TIMEOUT);
362 }
363
364 static int
365 evhttp_connected(struct evhttp_connection *evcon)
366 {
367 switch (evcon->state) {
368 case EVCON_DISCONNECTED:
369 case EVCON_CONNECTING:
370 return (0);
371 case EVCON_IDLE:
372 case EVCON_READING_FIRSTLINE:
373 case EVCON_READING_HEADERS:
374 case EVCON_READING_BODY:
375 case EVCON_READING_TRAILER:
376 case EVCON_WRITING:
377 default:
378 return (1);
379 }
380 }
381
382 /*
383 * Create the headers needed for an HTTP request
384 */
385 static void
386 evhttp_make_header_request(struct evhttp_connection *evcon,
387 struct evhttp_request *req)
388 {
389 const char *method;
390
391 evhttp_remove_header(req->output_headers, "Proxy-Connection");
392
393 /* Generate request line */
394 method = evhttp_method(req->type);
395 evbuffer_add_printf(evcon->output_buffer, "%s %s HTTP/%d.%d\r\n",
396 method, req->uri, req->major, req->minor);
397
398 /* Add the content length on a post request if missing */
399 if (req->type == EVHTTP_REQ_POST &&
400 evhttp_find_header(req->output_headers, "Content-Length") == NULL){
401 char size[22];
402 evutil_snprintf(size, sizeof(size), "%ld",
403 (long)EVBUFFER_LENGTH(req->output_buffer));
404 evhttp_add_header(req->output_headers, "Content-Length", size);
405 }
406 }
407
408 static int
409 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
410 {
411 if (flags & EVHTTP_PROXY_REQUEST) {
412 /* proxy connection */
413 const char *connection = evhttp_find_header(headers, "Proxy-Conn ection");
414 return (connection == NULL || strcasecmp(connection, "keep-alive ") != 0);
415 } else {
416 const char *connection = evhttp_find_header(headers, "Connection ");
417 return (connection != NULL && strcasecmp(connection, "close") == 0);
418 }
419 }
420
421 static int
422 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
423 {
424 const char *connection = evhttp_find_header(headers, "Connection");
425 return (connection != NULL
426 && strncasecmp(connection, "keep-alive", 10) == 0);
427 }
428
429 static void
430 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
431 {
432 if (evhttp_find_header(headers, "Date") == NULL) {
433 char date[50];
434 #ifndef WIN32
435 struct tm cur;
436 #endif
437 struct tm *cur_p;
438 time_t t = time(NULL);
439 #ifdef WIN32
440 cur_p = gmtime(&t);
441 #else
442 gmtime_r(&t, &cur);
443 cur_p = &cur;
444 #endif
445 if (strftime(date, sizeof(date),
446 "%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) {
447 evhttp_add_header(headers, "Date", date);
448 }
449 }
450 }
451
452 static void
453 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
454 long content_length)
455 {
456 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
457 evhttp_find_header(headers, "Content-Length") == NULL) {
458 char len[22];
459 evutil_snprintf(len, sizeof(len), "%ld", content_length);
460 evhttp_add_header(headers, "Content-Length", len);
461 }
462 }
463
464 /*
465 * Create the headers needed for an HTTP reply
466 */
467
468 static void
469 evhttp_make_header_response(struct evhttp_connection *evcon,
470 struct evhttp_request *req)
471 {
472 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
473 evbuffer_add_printf(evcon->output_buffer, "HTTP/%d.%d %d %s\r\n",
474 req->major, req->minor, req->response_code,
475 req->response_code_line);
476
477 if (req->major == 1) {
478 if (req->minor == 1)
479 evhttp_maybe_add_date_header(req->output_headers);
480
481 /*
482 * if the protocol is 1.0; and the connection was keep-alive
483 * we need to add a keep-alive header, too.
484 */
485 if (req->minor == 0 && is_keepalive)
486 evhttp_add_header(req->output_headers,
487 "Connection", "keep-alive");
488
489 if (req->minor == 1 || is_keepalive) {
490 /*
491 * we need to add the content length if the
492 * user did not give it, this is required for
493 * persistent connections to work.
494 */
495 evhttp_maybe_add_content_length_header(
496 req->output_headers,
497 (long)EVBUFFER_LENGTH(req->output_buffer));
498 }
499 }
500
501 /* Potentially add headers for unidentified content. */
502 if (EVBUFFER_LENGTH(req->output_buffer)) {
503 if (evhttp_find_header(req->output_headers,
504 "Content-Type") == NULL) {
505 evhttp_add_header(req->output_headers,
506 "Content-Type", "text/html; charset=ISO-8859-1");
507 }
508 }
509
510 /* if the request asked for a close, we send a close, too */
511 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
512 evhttp_remove_header(req->output_headers, "Connection");
513 if (!(req->flags & EVHTTP_PROXY_REQUEST))
514 evhttp_add_header(req->output_headers, "Connection", "close" );
515 evhttp_remove_header(req->output_headers, "Proxy-Connection");
516 }
517 }
518
519 void
520 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
521 {
522 struct evkeyval *header;
523
524 /*
525 * Depending if this is a HTTP request or response, we might need to
526 * add some new headers or remove existing headers.
527 */
528 if (req->kind == EVHTTP_REQUEST) {
529 evhttp_make_header_request(evcon, req);
530 } else {
531 evhttp_make_header_response(evcon, req);
532 }
533
534 TAILQ_FOREACH(header, req->output_headers, next) {
535 evbuffer_add_printf(evcon->output_buffer, "%s: %s\r\n",
536 header->key, header->value);
537 }
538 evbuffer_add(evcon->output_buffer, "\r\n", 2);
539
540 if (EVBUFFER_LENGTH(req->output_buffer) > 0) {
541 /*
542 * For a request, we add the POST data, for a reply, this
543 * is the regular data.
544 */
545 evbuffer_add_buffer(evcon->output_buffer, req->output_buffer);
546 }
547 }
548
549 /* Separated host, port and file from URI */
550
551 int
552 evhttp_hostportfile(char *url, char **phost, u_short *pport, char **pfile)
553 {
554 /* XXX not threadsafe. */
555 static char host[1024];
556 static char file[1024];
557 char *p;
558 const char *p2;
559 int len;
560 u_short port;
561
562 len = strlen(HTTP_PREFIX);
563 if (strncasecmp(url, HTTP_PREFIX, len))
564 return (-1);
565
566 url += len;
567
568 /* We might overrun */
569 if (strlcpy(host, url, sizeof (host)) >= sizeof(host))
570 return (-1);
571
572 p = strchr(host, '/');
573 if (p != NULL) {
574 *p = '\0';
575 p2 = p + 1;
576 } else
577 p2 = NULL;
578
579 if (pfile != NULL) {
580 /* Generate request file */
581 if (p2 == NULL)
582 p2 = "";
583 evutil_snprintf(file, sizeof(file), "/%s", p2);
584 }
585
586 p = strchr(host, ':');
587 if (p != NULL) {
588 *p = '\0';
589 port = atoi(p + 1);
590
591 if (port == 0)
592 return (-1);
593 } else
594 port = HTTP_DEFAULTPORT;
595
596 if (phost != NULL)
597 *phost = host;
598 if (pport != NULL)
599 *pport = port;
600 if (pfile != NULL)
601 *pfile = file;
602
603 return (0);
604 }
605
606 static int
607 evhttp_connection_incoming_fail(struct evhttp_request *req,
608 enum evhttp_connection_error error)
609 {
610 switch (error) {
611 case EVCON_HTTP_TIMEOUT:
612 case EVCON_HTTP_EOF:
613 /*
614 * these are cases in which we probably should just
615 * close the connection and not send a reply. this
616 * case may happen when a browser keeps a persistent
617 * connection open and we timeout on the read. when
618 * the request is still being used for sending, we
619 * need to disassociated it from the connection here.
620 */
621 if (!req->userdone) {
622 /* remove it so that it will not be freed */
623 TAILQ_REMOVE(&req->evcon->requests, req, next);
624 /* indicate that this request no longer has a
625 * connection object
626 */
627 req->evcon = NULL;
628 }
629 return (-1);
630 case EVCON_HTTP_INVALID_HEADER:
631 default: /* xxx: probably should just error on default */
632 /* the callback looks at the uri to determine errors */
633 if (req->uri) {
634 free(req->uri);
635 req->uri = NULL;
636 }
637
638 /*
639 * the callback needs to send a reply, once the reply has
640 * been send, the connection should get freed.
641 */
642 (*req->cb)(req, req->cb_arg);
643 }
644
645 return (0);
646 }
647
648 void
649 evhttp_connection_fail(struct evhttp_connection *evcon,
650 enum evhttp_connection_error error)
651 {
652 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
653 void (*cb)(struct evhttp_request *, void *);
654 void *cb_arg;
655 assert(req != NULL);
656
657 if (evcon->flags & EVHTTP_CON_INCOMING) {
658 /*
659 * for incoming requests, there are two different
660 * failure cases. it's either a network level error
661 * or an http layer error. for problems on the network
662 * layer like timeouts we just drop the connections.
663 * For HTTP problems, we might have to send back a
664 * reply before the connection can be freed.
665 */
666 if (evhttp_connection_incoming_fail(req, error) == -1)
667 evhttp_connection_free(evcon);
668 return;
669 }
670
671 /* save the callback for later; the cb might free our object */
672 cb = req->cb;
673 cb_arg = req->cb_arg;
674
675 /* do not fail all requests; the next request is going to get
676 * send over a new connection. when a user cancels a request,
677 * all other pending requests should be processed as normal
678 */
679 TAILQ_REMOVE(&evcon->requests, req, next);
680 evhttp_request_free(req);
681
682 /* reset the connection */
683 evhttp_connection_reset(evcon);
684
685 /* We are trying the next request that was queued on us */
686 if (TAILQ_FIRST(&evcon->requests) != NULL)
687 evhttp_connection_connect(evcon);
688
689 /* inform the user */
690 if (cb != NULL)
691 (*cb)(NULL, cb_arg);
692 }
693
694 void
695 evhttp_write(int fd, short what, void *arg)
696 {
697 struct evhttp_connection *evcon = arg;
698 int n;
699
700 if (what == EV_TIMEOUT) {
701 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
702 return;
703 }
704
705 n = evbuffer_write(evcon->output_buffer, fd);
706 if (n == -1) {
707 event_debug(("%s: evbuffer_write", __func__));
708 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
709 return;
710 }
711
712 if (n == 0) {
713 event_debug(("%s: write nothing", __func__));
714 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
715 return;
716 }
717
718 if (EVBUFFER_LENGTH(evcon->output_buffer) != 0) {
719 evhttp_add_event(&evcon->ev,
720 evcon->timeout, HTTP_WRITE_TIMEOUT);
721 return;
722 }
723
724 /* Activate our call back */
725 if (evcon->cb != NULL)
726 (*evcon->cb)(evcon, evcon->cb_arg);
727 }
728
729 /**
730 * Advance the connection state.
731 * - If this is an outgoing connection, we've just processed the response;
732 * idle or close the connection.
733 * - If this is an incoming connection, we've just processed the request;
734 * respond.
735 */
736 static void
737 evhttp_connection_done(struct evhttp_connection *evcon)
738 {
739 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
740 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
741
742 if (con_outgoing) {
743 /* idle or close the connection */
744 int need_close;
745 TAILQ_REMOVE(&evcon->requests, req, next);
746 req->evcon = NULL;
747
748 evcon->state = EVCON_IDLE;
749
750 need_close =
751 evhttp_is_connection_close(req->flags, req->input_headers)||
752 evhttp_is_connection_close(req->flags, req->output_headers);
753
754 /* check if we got asked to close the connection */
755 if (need_close)
756 evhttp_connection_reset(evcon);
757
758 if (TAILQ_FIRST(&evcon->requests) != NULL) {
759 /*
760 * We have more requests; reset the connection
761 * and deal with the next request.
762 */
763 if (!evhttp_connected(evcon))
764 evhttp_connection_connect(evcon);
765 else
766 evhttp_request_dispatch(evcon);
767 } else if (!need_close) {
768 /*
769 * The connection is going to be persistent, but we
770 * need to detect if the other side closes it.
771 */
772 evhttp_connection_start_detectclose(evcon);
773 }
774 } else if (evcon->state != EVCON_DISCONNECTED) {
775 /*
776 * incoming connection - we need to leave the request on the
777 * connection so that we can reply to it.
778 */
779 evcon->state = EVCON_WRITING;
780 }
781
782 /* notify the user of the request */
783 (*req->cb)(req, req->cb_arg);
784
785 /* if this was an outgoing request, we own and it's done. so free it */
786 if (con_outgoing) {
787 evhttp_request_free(req);
788 }
789 }
790
791 /*
792 * Handles reading from a chunked request.
793 * return ALL_DATA_READ:
794 * all data has been read
795 * return MORE_DATA_EXPECTED:
796 * more data is expected
797 * return DATA_CORRUPTED:
798 * data is corrupted
799 * return REQUEST_CANCLED:
800 * request was canceled by the user calling evhttp_cancel_request
801 */
802
803 static enum message_read_status
804 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
805 {
806 int len;
807
808 while ((len = EVBUFFER_LENGTH(buf)) > 0) {
809 if (req->ntoread < 0) {
810 /* Read chunk size */
811 ev_int64_t ntoread;
812 char *p = evbuffer_readline(buf);
813 char *endp;
814 int error;
815 if (p == NULL)
816 break;
817 /* the last chunk is on a new line? */
818 if (strlen(p) == 0) {
819 free(p);
820 continue;
821 }
822 ntoread = evutil_strtoll(p, &endp, 16);
823 error = (*p == '\0' ||
824 (*endp != '\0' && *endp != ' ') ||
825 ntoread < 0);
826 free(p);
827 if (error) {
828 /* could not get chunk size */
829 return (DATA_CORRUPTED);
830 }
831 req->ntoread = ntoread;
832 if (req->ntoread == 0) {
833 /* Last chunk */
834 return (ALL_DATA_READ);
835 }
836 continue;
837 }
838
839 /* don't have enough to complete a chunk; wait for more */
840 if (len < req->ntoread)
841 return (MORE_DATA_EXPECTED);
842
843 /* Completed chunk */
844 evbuffer_add(req->input_buffer,
845 EVBUFFER_DATA(buf), (size_t)req->ntoread);
846 evbuffer_drain(buf, (size_t)req->ntoread);
847 req->ntoread = -1;
848 if (req->chunk_cb != NULL) {
849 (*req->chunk_cb)(req, req->cb_arg);
850 evbuffer_drain(req->input_buffer,
851 EVBUFFER_LENGTH(req->input_buffer));
852 }
853 }
854
855 return (MORE_DATA_EXPECTED);
856 }
857
858 static void
859 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
860 {
861 struct evbuffer *buf = evcon->input_buffer;
862
863 switch (evhttp_parse_headers(req, buf)) {
864 case DATA_CORRUPTED:
865 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
866 break;
867 case ALL_DATA_READ:
868 event_del(&evcon->ev);
869 evhttp_connection_done(evcon);
870 break;
871 case MORE_DATA_EXPECTED:
872 default:
873 evhttp_add_event(&evcon->ev, evcon->timeout,
874 HTTP_READ_TIMEOUT);
875 break;
876 }
877 }
878
879 static void
880 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
881 {
882 struct evbuffer *buf = evcon->input_buffer;
883
884 if (req->chunked) {
885 switch (evhttp_handle_chunked_read(req, buf)) {
886 case ALL_DATA_READ:
887 /* finished last chunk */
888 evcon->state = EVCON_READING_TRAILER;
889 evhttp_read_trailer(evcon, req);
890 return;
891 case DATA_CORRUPTED:
892 /* corrupted data */
893 evhttp_connection_fail(evcon,
894 EVCON_HTTP_INVALID_HEADER);
895 return;
896 case REQUEST_CANCELED:
897 /* request canceled */
898 evhttp_request_free(req);
899 return;
900 case MORE_DATA_EXPECTED:
901 default:
902 break;
903 }
904 } else if (req->ntoread < 0) {
905 /* Read until connection close. */
906 evbuffer_add_buffer(req->input_buffer, buf);
907 } else if (EVBUFFER_LENGTH(buf) >= req->ntoread) {
908 /* Completed content length */
909 evbuffer_add(req->input_buffer, EVBUFFER_DATA(buf),
910 (size_t)req->ntoread);
911 evbuffer_drain(buf, (size_t)req->ntoread);
912 req->ntoread = 0;
913 evhttp_connection_done(evcon);
914 return;
915 }
916 /* Read more! */
917 event_set(&evcon->ev, evcon->fd, EV_READ, evhttp_read, evcon);
918 EVHTTP_BASE_SET(evcon, &evcon->ev);
919 evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
920 }
921
922 /*
923 * Reads data into a buffer structure until no more data
924 * can be read on the file descriptor or we have read all
925 * the data that we wanted to read.
926 * Execute callback when done.
927 */
928
929 void
930 evhttp_read(int fd, short what, void *arg)
931 {
932 struct evhttp_connection *evcon = arg;
933 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
934 struct evbuffer *buf = evcon->input_buffer;
935 int n, len;
936
937 if (what == EV_TIMEOUT) {
938 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
939 return;
940 }
941 n = evbuffer_read(buf, fd, -1);
942 len = EVBUFFER_LENGTH(buf);
943 event_debug(("%s: got %d on %d\n", __func__, n, fd));
944
945 if (n == -1) {
946 if (errno != EINTR && errno != EAGAIN) {
947 event_debug(("%s: evbuffer_read", __func__));
948 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
949 } else {
950 evhttp_add_event(&evcon->ev, evcon->timeout,
951 HTTP_READ_TIMEOUT);
952 }
953 return;
954 } else if (n == 0) {
955 /* Connection closed */
956 evcon->state = EVCON_DISCONNECTED;
957 evhttp_connection_done(evcon);
958 return;
959 }
960
961 switch (evcon->state) {
962 case EVCON_READING_FIRSTLINE:
963 evhttp_read_firstline(evcon, req);
964 break;
965 case EVCON_READING_HEADERS:
966 evhttp_read_header(evcon, req);
967 break;
968 case EVCON_READING_BODY:
969 evhttp_read_body(evcon, req);
970 break;
971 case EVCON_READING_TRAILER:
972 evhttp_read_trailer(evcon, req);
973 break;
974 case EVCON_DISCONNECTED:
975 case EVCON_CONNECTING:
976 case EVCON_IDLE:
977 case EVCON_WRITING:
978 default:
979 event_errx(1, "%s: illegal connection state %d",
980 __func__, evcon->state);
981 }
982 }
983
984 static void
985 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
986 {
987 /* This is after writing the request to the server */
988 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
989 assert(req != NULL);
990
991 assert(evcon->state == EVCON_WRITING);
992
993 /* We are done writing our header and are now expecting the response */
994 req->kind = EVHTTP_RESPONSE;
995
996 evhttp_start_read(evcon);
997 }
998
999 /*
1000 * Clean up a connection object
1001 */
1002
1003 void
1004 evhttp_connection_free(struct evhttp_connection *evcon)
1005 {
1006 struct evhttp_request *req;
1007
1008 /* notify interested parties that this connection is going down */
1009 if (evcon->fd != -1) {
1010 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1011 (*evcon->closecb)(evcon, evcon->closecb_arg);
1012 }
1013
1014 /* remove all requests that might be queued on this
1015 * connection. for server connections, this should be empty.
1016 * because it gets dequeued either in evhttp_connection_done or
1017 * evhttp_connection_fail.
1018 */
1019 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
1020 TAILQ_REMOVE(&evcon->requests, req, next);
1021 evhttp_request_free(req);
1022 }
1023
1024 if (evcon->http_server != NULL) {
1025 struct evhttp *http = evcon->http_server;
1026 TAILQ_REMOVE(&http->connections, evcon, next);
1027 }
1028
1029 if (event_initialized(&evcon->close_ev))
1030 event_del(&evcon->close_ev);
1031
1032 if (event_initialized(&evcon->ev))
1033 event_del(&evcon->ev);
1034
1035 if (evcon->fd != -1)
1036 EVUTIL_CLOSESOCKET(evcon->fd);
1037
1038 if (evcon->bind_address != NULL)
1039 free(evcon->bind_address);
1040
1041 if (evcon->address != NULL)
1042 free(evcon->address);
1043
1044 if (evcon->input_buffer != NULL)
1045 evbuffer_free(evcon->input_buffer);
1046
1047 if (evcon->output_buffer != NULL)
1048 evbuffer_free(evcon->output_buffer);
1049
1050 free(evcon);
1051 }
1052
1053 void
1054 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1055 const char *address)
1056 {
1057 assert(evcon->state == EVCON_DISCONNECTED);
1058 if (evcon->bind_address)
1059 free(evcon->bind_address);
1060 if ((evcon->bind_address = strdup(address)) == NULL)
1061 event_err(1, "%s: strdup", __func__);
1062 }
1063
1064 void
1065 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1066 unsigned short port)
1067 {
1068 assert(evcon->state == EVCON_DISCONNECTED);
1069 evcon->bind_port = port;
1070 }
1071
1072 static void
1073 evhttp_request_dispatch(struct evhttp_connection* evcon)
1074 {
1075 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1076
1077 /* this should not usually happy but it's possible */
1078 if (req == NULL)
1079 return;
1080
1081 /* delete possible close detection events */
1082 evhttp_connection_stop_detectclose(evcon);
1083
1084 /* we assume that the connection is connected already */
1085 assert(evcon->state == EVCON_IDLE);
1086
1087 evcon->state = EVCON_WRITING;
1088
1089 /* Create the header from the store arguments */
1090 evhttp_make_header(evcon, req);
1091
1092 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1093 }
1094
1095 /* Reset our connection state */
1096 void
1097 evhttp_connection_reset(struct evhttp_connection *evcon)
1098 {
1099 if (event_initialized(&evcon->ev))
1100 event_del(&evcon->ev);
1101
1102 if (evcon->fd != -1) {
1103 /* inform interested parties about connection close */
1104 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1105 (*evcon->closecb)(evcon, evcon->closecb_arg);
1106
1107 EVUTIL_CLOSESOCKET(evcon->fd);
1108 evcon->fd = -1;
1109 }
1110 evcon->state = EVCON_DISCONNECTED;
1111
1112 evbuffer_drain(evcon->input_buffer,
1113 EVBUFFER_LENGTH(evcon->input_buffer));
1114 evbuffer_drain(evcon->output_buffer,
1115 EVBUFFER_LENGTH(evcon->output_buffer));
1116 }
1117
1118 static void
1119 evhttp_detect_close_cb(int fd, short what, void *arg)
1120 {
1121 struct evhttp_connection *evcon = arg;
1122 evhttp_connection_reset(evcon);
1123 }
1124
1125 static void
1126 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1127 {
1128 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1129
1130 if (event_initialized(&evcon->close_ev))
1131 event_del(&evcon->close_ev);
1132 event_set(&evcon->close_ev, evcon->fd, EV_READ,
1133 evhttp_detect_close_cb, evcon);
1134 EVHTTP_BASE_SET(evcon, &evcon->close_ev);
1135 event_add(&evcon->close_ev, NULL);
1136 }
1137
1138 static void
1139 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1140 {
1141 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1142 event_del(&evcon->close_ev);
1143 }
1144
1145 static void
1146 evhttp_connection_retry(int fd, short what, void *arg)
1147 {
1148 struct evhttp_connection *evcon = arg;
1149
1150 evcon->state = EVCON_DISCONNECTED;
1151 evhttp_connection_connect(evcon);
1152 }
1153
1154 /*
1155 * Call back for asynchronous connection attempt.
1156 */
1157
1158 static void
1159 evhttp_connectioncb(int fd, short what, void *arg)
1160 {
1161 struct evhttp_connection *evcon = arg;
1162 int error;
1163 socklen_t errsz = sizeof(error);
1164
1165 if (what == EV_TIMEOUT) {
1166 event_debug(("%s: connection timeout for \"%s:%d\" on %d",
1167 __func__, evcon->address, evcon->port, evcon->fd));
1168 goto cleanup;
1169 }
1170
1171 /* Check if the connection completed */
1172 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1173 &errsz) == -1) {
1174 event_debug(("%s: getsockopt for \"%s:%d\" on %d",
1175 __func__, evcon->address, evcon->port, evcon->fd));
1176 goto cleanup;
1177 }
1178
1179 if (error) {
1180 event_debug(("%s: connect failed for \"%s:%d\" on %d: %s",
1181 __func__, evcon->address, evcon->port, evcon->fd,
1182 strerror(error)));
1183 goto cleanup;
1184 }
1185
1186 /* We are connected to the server now */
1187 event_debug(("%s: connected to \"%s:%d\" on %d\n",
1188 __func__, evcon->address, evcon->port, evcon->fd));
1189
1190 /* Reset the retry count as we were successful in connecting */
1191 evcon->retry_cnt = 0;
1192 evcon->state = EVCON_IDLE;
1193
1194 /* try to start requests that have queued up on this connection */
1195 evhttp_request_dispatch(evcon);
1196 return;
1197
1198 cleanup:
1199 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1200 evtimer_set(&evcon->ev, evhttp_connection_retry, evcon);
1201 EVHTTP_BASE_SET(evcon, &evcon->ev);
1202 evhttp_add_event(&evcon->ev, MIN(3600, 2 << evcon->retry_cnt),
1203 HTTP_CONNECT_TIMEOUT);
1204 evcon->retry_cnt++;
1205 return;
1206 }
1207 evhttp_connection_reset(evcon);
1208
1209 /* for now, we just signal all requests by executing their callbacks */
1210 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1211 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1212 TAILQ_REMOVE(&evcon->requests, request, next);
1213 request->evcon = NULL;
1214
1215 /* we might want to set an error here */
1216 request->cb(request, request->cb_arg);
1217 evhttp_request_free(request);
1218 }
1219 }
1220
1221 /*
1222 * Check if we got a valid response code.
1223 */
1224
1225 static int
1226 evhttp_valid_response_code(int code)
1227 {
1228 if (code == 0)
1229 return (0);
1230
1231 return (1);
1232 }
1233
1234 /* Parses the status line of a web server */
1235
1236 static int
1237 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1238 {
1239 char *protocol;
1240 char *number;
1241 const char *readable = "";
1242
1243 protocol = strsep(&line, " ");
1244 if (line == NULL)
1245 return (-1);
1246 number = strsep(&line, " ");
1247 if (line != NULL)
1248 readable = line;
1249
1250 if (strcmp(protocol, "HTTP/1.0") == 0) {
1251 req->major = 1;
1252 req->minor = 0;
1253 } else if (strcmp(protocol, "HTTP/1.1") == 0) {
1254 req->major = 1;
1255 req->minor = 1;
1256 } else {
1257 event_debug(("%s: bad protocol \"%s\"",
1258 __func__, protocol));
1259 return (-1);
1260 }
1261
1262 req->response_code = atoi(number);
1263 if (!evhttp_valid_response_code(req->response_code)) {
1264 event_debug(("%s: bad response code \"%s\"",
1265 __func__, number));
1266 return (-1);
1267 }
1268
1269 if ((req->response_code_line = strdup(readable)) == NULL)
1270 event_err(1, "%s: strdup", __func__);
1271
1272 return (0);
1273 }
1274
1275 /* Parse the first line of a HTTP request */
1276
1277 static int
1278 evhttp_parse_request_line(struct evhttp_request *req, char *line)
1279 {
1280 char *method;
1281 char *uri;
1282 char *version;
1283
1284 /* Parse the request line */
1285 method = strsep(&line, " ");
1286 if (line == NULL)
1287 return (-1);
1288 uri = strsep(&line, " ");
1289 if (line == NULL)
1290 return (-1);
1291 version = strsep(&line, " ");
1292 if (line != NULL)
1293 return (-1);
1294
1295 /* First line */
1296 if (strcmp(method, "GET") == 0) {
1297 req->type = EVHTTP_REQ_GET;
1298 } else if (strcmp(method, "POST") == 0) {
1299 req->type = EVHTTP_REQ_POST;
1300 } else if (strcmp(method, "HEAD") == 0) {
1301 req->type = EVHTTP_REQ_HEAD;
1302 } else {
1303 event_debug(("%s: bad method %s on request %p from %s",
1304 __func__, method, req, req->remote_host));
1305 return (-1);
1306 }
1307
1308 if (strcmp(version, "HTTP/1.0") == 0) {
1309 req->major = 1;
1310 req->minor = 0;
1311 } else if (strcmp(version, "HTTP/1.1") == 0) {
1312 req->major = 1;
1313 req->minor = 1;
1314 } else {
1315 event_debug(("%s: bad version %s on request %p from %s",
1316 __func__, version, req, req->remote_host));
1317 return (-1);
1318 }
1319
1320 if ((req->uri = strdup(uri)) == NULL) {
1321 event_debug(("%s: strdup", __func__));
1322 return (-1);
1323 }
1324
1325 /* determine if it's a proxy request */
1326 if (strlen(req->uri) > 0 && req->uri[0] != '/')
1327 req->flags |= EVHTTP_PROXY_REQUEST;
1328
1329 return (0);
1330 }
1331
1332 const char *
1333 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1334 {
1335 struct evkeyval *header;
1336
1337 TAILQ_FOREACH(header, headers, next) {
1338 if (strcasecmp(header->key, key) == 0)
1339 return (header->value);
1340 }
1341
1342 return (NULL);
1343 }
1344
1345 void
1346 evhttp_clear_headers(struct evkeyvalq *headers)
1347 {
1348 struct evkeyval *header;
1349
1350 for (header = TAILQ_FIRST(headers);
1351 header != NULL;
1352 header = TAILQ_FIRST(headers)) {
1353 TAILQ_REMOVE(headers, header, next);
1354 free(header->key);
1355 free(header->value);
1356 free(header);
1357 }
1358 }
1359
1360 /*
1361 * Returns 0, if the header was successfully removed.
1362 * Returns -1, if the header could not be found.
1363 */
1364
1365 int
1366 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1367 {
1368 struct evkeyval *header;
1369
1370 TAILQ_FOREACH(header, headers, next) {
1371 if (strcasecmp(header->key, key) == 0)
1372 break;
1373 }
1374
1375 if (header == NULL)
1376 return (-1);
1377
1378 /* Free and remove the header that we found */
1379 TAILQ_REMOVE(headers, header, next);
1380 free(header->key);
1381 free(header->value);
1382 free(header);
1383
1384 return (0);
1385 }
1386
1387 static int
1388 evhttp_header_is_valid_value(const char *value)
1389 {
1390 const char *p = value;
1391
1392 while ((p = strpbrk(p, "\r\n")) != NULL) {
1393 /* we really expect only one new line */
1394 p += strspn(p, "\r\n");
1395 /* we expect a space or tab for continuation */
1396 if (*p != ' ' && *p != '\t')
1397 return (0);
1398 }
1399 return (1);
1400 }
1401
1402 int
1403 evhttp_add_header(struct evkeyvalq *headers,
1404 const char *key, const char *value)
1405 {
1406 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1407
1408 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1409 /* drop illegal headers */
1410 event_debug(("%s: dropping illegal header key\n", __func__));
1411 return (-1);
1412 }
1413
1414 if (!evhttp_header_is_valid_value(value)) {
1415 event_debug(("%s: dropping illegal header value\n", __func__));
1416 return (-1);
1417 }
1418
1419 return (evhttp_add_header_internal(headers, key, value));
1420 }
1421
1422 static int
1423 evhttp_add_header_internal(struct evkeyvalq *headers,
1424 const char *key, const char *value)
1425 {
1426 struct evkeyval *header = calloc(1, sizeof(struct evkeyval));
1427 if (header == NULL) {
1428 event_warn("%s: calloc", __func__);
1429 return (-1);
1430 }
1431 if ((header->key = strdup(key)) == NULL) {
1432 free(header);
1433 event_warn("%s: strdup", __func__);
1434 return (-1);
1435 }
1436 if ((header->value = strdup(value)) == NULL) {
1437 free(header->key);
1438 free(header);
1439 event_warn("%s: strdup", __func__);
1440 return (-1);
1441 }
1442
1443 TAILQ_INSERT_TAIL(headers, header, next);
1444
1445 return (0);
1446 }
1447
1448 /*
1449 * Parses header lines from a request or a response into the specified
1450 * request object given an event buffer.
1451 *
1452 * Returns
1453 * DATA_CORRUPTED on error
1454 * MORE_DATA_EXPECTED when we need to read more headers
1455 * ALL_DATA_READ when all headers have been read.
1456 */
1457
1458 enum message_read_status
1459 evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
1460 {
1461 char *line;
1462 enum message_read_status status = ALL_DATA_READ;
1463
1464 line = evbuffer_readline(buffer);
1465 if (line == NULL)
1466 return (MORE_DATA_EXPECTED);
1467
1468 switch (req->kind) {
1469 case EVHTTP_REQUEST:
1470 if (evhttp_parse_request_line(req, line) == -1)
1471 status = DATA_CORRUPTED;
1472 break;
1473 case EVHTTP_RESPONSE:
1474 if (evhttp_parse_response_line(req, line) == -1)
1475 status = DATA_CORRUPTED;
1476 break;
1477 default:
1478 status = DATA_CORRUPTED;
1479 }
1480
1481 free(line);
1482 return (status);
1483 }
1484
1485 static int
1486 evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
1487 {
1488 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
1489 char *newval;
1490 size_t old_len, line_len;
1491
1492 if (header == NULL)
1493 return (-1);
1494
1495 old_len = strlen(header->value);
1496 line_len = strlen(line);
1497
1498 newval = realloc(header->value, old_len + line_len + 1);
1499 if (newval == NULL)
1500 return (-1);
1501
1502 memcpy(newval + old_len, line, line_len + 1);
1503 header->value = newval;
1504
1505 return (0);
1506 }
1507
1508 enum message_read_status
1509 evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
1510 {
1511 char *line;
1512 enum message_read_status status = MORE_DATA_EXPECTED;
1513
1514 struct evkeyvalq* headers = req->input_headers;
1515 while ((line = evbuffer_readline(buffer))
1516 != NULL) {
1517 char *skey, *svalue;
1518
1519 if (*line == '\0') { /* Last header - Done */
1520 status = ALL_DATA_READ;
1521 free(line);
1522 break;
1523 }
1524
1525 /* Check if this is a continuation line */
1526 if (*line == ' ' || *line == '\t') {
1527 if (evhttp_append_to_last_header(headers, line) == -1)
1528 goto error;
1529 free(line);
1530 continue;
1531 }
1532
1533 /* Processing of header lines */
1534 svalue = line;
1535 skey = strsep(&svalue, ":");
1536 if (svalue == NULL)
1537 goto error;
1538
1539 svalue += strspn(svalue, " ");
1540
1541 if (evhttp_add_header(headers, skey, svalue) == -1)
1542 goto error;
1543
1544 free(line);
1545 }
1546
1547 return (status);
1548
1549 error:
1550 free(line);
1551 return (DATA_CORRUPTED);
1552 }
1553
1554 static int
1555 evhttp_get_body_length(struct evhttp_request *req)
1556 {
1557 struct evkeyvalq *headers = req->input_headers;
1558 const char *content_length;
1559 const char *connection;
1560
1561 content_length = evhttp_find_header(headers, "Content-Length");
1562 connection = evhttp_find_header(headers, "Connection");
1563
1564 if (content_length == NULL && connection == NULL)
1565 req->ntoread = -1;
1566 else if (content_length == NULL &&
1567 strcasecmp(connection, "Close") != 0) {
1568 /* Bad combination, we don't know when it will end */
1569 event_warnx("%s: we got no content length, but the "
1570 "server wants to keep the connection open: %s.",
1571 __func__, connection);
1572 return (-1);
1573 } else if (content_length == NULL) {
1574 req->ntoread = -1;
1575 } else {
1576 char *endp;
1577 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
1578 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
1579 event_debug(("%s: illegal content length: %s",
1580 __func__, content_length));
1581 return (-1);
1582 }
1583 req->ntoread = ntoread;
1584 }
1585
1586 event_debug(("%s: bytes to read: %lld (in buffer %ld)\n",
1587 __func__, req->ntoread,
1588 EVBUFFER_LENGTH(req->evcon->input_buffer)));
1589
1590 return (0);
1591 }
1592
1593 static void
1594 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1595 {
1596 const char *xfer_enc;
1597
1598 /* If this is a request without a body, then we are done */
1599 if (req->kind == EVHTTP_REQUEST && req->type != EVHTTP_REQ_POST) {
1600 evhttp_connection_done(evcon);
1601 return;
1602 }
1603 evcon->state = EVCON_READING_BODY;
1604 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
1605 if (xfer_enc != NULL && strcasecmp(xfer_enc, "chunked") == 0) {
1606 req->chunked = 1;
1607 req->ntoread = -1;
1608 } else {
1609 if (evhttp_get_body_length(req) == -1) {
1610 evhttp_connection_fail(evcon,
1611 EVCON_HTTP_INVALID_HEADER);
1612 return;
1613 }
1614 }
1615 evhttp_read_body(evcon, req);
1616 }
1617
1618 static void
1619 evhttp_read_firstline(struct evhttp_connection *evcon,
1620 struct evhttp_request *req)
1621 {
1622 enum message_read_status res;
1623
1624 res = evhttp_parse_firstline(req, evcon->input_buffer);
1625 if (res == DATA_CORRUPTED) {
1626 /* Error while reading, terminate */
1627 event_debug(("%s: bad header lines on %d\n",
1628 __func__, evcon->fd));
1629 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1630 return;
1631 } else if (res == MORE_DATA_EXPECTED) {
1632 /* Need more header lines */
1633 evhttp_add_event(&evcon->ev,
1634 evcon->timeout, HTTP_READ_TIMEOUT);
1635 return;
1636 }
1637
1638 evcon->state = EVCON_READING_HEADERS;
1639 evhttp_read_header(evcon, req);
1640 }
1641
1642 static void
1643 evhttp_read_header(struct evhttp_connection *evcon, struct evhttp_request *req)
1644 {
1645 enum message_read_status res;
1646 int fd = evcon->fd;
1647
1648 res = evhttp_parse_headers(req, evcon->input_buffer);
1649 if (res == DATA_CORRUPTED) {
1650 /* Error while reading, terminate */
1651 event_debug(("%s: bad header lines on %d\n", __func__, fd));
1652 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1653 return;
1654 } else if (res == MORE_DATA_EXPECTED) {
1655 /* Need more header lines */
1656 evhttp_add_event(&evcon->ev,
1657 evcon->timeout, HTTP_READ_TIMEOUT);
1658 return;
1659 }
1660
1661 /* Done reading headers, do the real work */
1662 switch (req->kind) {
1663 case EVHTTP_REQUEST:
1664 event_debug(("%s: checking for post data on %d\n",
1665 __func__, fd));
1666 evhttp_get_body(evcon, req);
1667 break;
1668
1669 case EVHTTP_RESPONSE:
1670 if (req->response_code == HTTP_NOCONTENT ||
1671 req->response_code == HTTP_NOTMODIFIED ||
1672 (req->response_code >= 100 && req->response_code < 200)) {
1673 event_debug(("%s: skipping body for code %d\n",
1674 __func__, req->response_code));
1675 evhttp_connection_done(evcon);
1676 } else {
1677 event_debug(("%s: start of read body for %s on %d\n",
1678 __func__, req->remote_host, fd));
1679 evhttp_get_body(evcon, req);
1680 }
1681 break;
1682
1683 default:
1684 event_warnx("%s: bad header on %d", __func__, fd);
1685 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1686 break;
1687 }
1688 }
1689
1690 /*
1691 * Creates a TCP connection to the specified port and executes a callback
1692 * when finished. Failure or sucess is indicate by the passed connection
1693 * object.
1694 *
1695 * Although this interface accepts a hostname, it is intended to take
1696 * only numeric hostnames so that non-blocking DNS resolution can
1697 * happen elsewhere.
1698 */
1699
1700 struct evhttp_connection *
1701 evhttp_connection_new(const char *address, unsigned short port)
1702 {
1703 struct evhttp_connection *evcon = NULL;
1704
1705 event_debug(("Attempting connection to %s:%d\n", address, port));
1706
1707 if ((evcon = calloc(1, sizeof(struct evhttp_connection))) == NULL) {
1708 event_warn("%s: calloc failed", __func__);
1709 goto error;
1710 }
1711
1712 evcon->fd = -1;
1713 evcon->port = port;
1714
1715 evcon->timeout = -1;
1716 evcon->retry_cnt = evcon->retry_max = 0;
1717
1718 if ((evcon->address = strdup(address)) == NULL) {
1719 event_warn("%s: strdup failed", __func__);
1720 goto error;
1721 }
1722
1723 if ((evcon->input_buffer = evbuffer_new()) == NULL) {
1724 event_warn("%s: evbuffer_new failed", __func__);
1725 goto error;
1726 }
1727
1728 if ((evcon->output_buffer = evbuffer_new()) == NULL) {
1729 event_warn("%s: evbuffer_new failed", __func__);
1730 goto error;
1731 }
1732
1733 evcon->state = EVCON_DISCONNECTED;
1734 TAILQ_INIT(&evcon->requests);
1735
1736 return (evcon);
1737
1738 error:
1739 if (evcon != NULL)
1740 evhttp_connection_free(evcon);
1741 return (NULL);
1742 }
1743
1744 void evhttp_connection_set_base(struct evhttp_connection *evcon,
1745 struct event_base *base)
1746 {
1747 assert(evcon->base == NULL);
1748 assert(evcon->state == EVCON_DISCONNECTED);
1749 evcon->base = base;
1750 }
1751
1752 void
1753 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
1754 int timeout_in_secs)
1755 {
1756 evcon->timeout = timeout_in_secs;
1757 }
1758
1759 void
1760 evhttp_connection_set_retries(struct evhttp_connection *evcon,
1761 int retry_max)
1762 {
1763 evcon->retry_max = retry_max;
1764 }
1765
1766 void
1767 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
1768 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
1769 {
1770 evcon->closecb = cb;
1771 evcon->closecb_arg = cbarg;
1772 }
1773
1774 void
1775 evhttp_connection_get_peer(struct evhttp_connection *evcon,
1776 char **address, u_short *port)
1777 {
1778 *address = evcon->address;
1779 *port = evcon->port;
1780 }
1781
1782 int
1783 evhttp_connection_connect(struct evhttp_connection *evcon)
1784 {
1785 if (evcon->state == EVCON_CONNECTING)
1786 return (0);
1787
1788 evhttp_connection_reset(evcon);
1789
1790 assert(!(evcon->flags & EVHTTP_CON_INCOMING));
1791 evcon->flags |= EVHTTP_CON_OUTGOING;
1792
1793 evcon->fd = bind_socket(
1794 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
1795 if (evcon->fd == -1) {
1796 event_debug(("%s: failed to bind to \"%s\"",
1797 __func__, evcon->bind_address));
1798 return (-1);
1799 }
1800
1801 if (socket_connect(evcon->fd, evcon->address, evcon->port) == -1) {
1802 EVUTIL_CLOSESOCKET(evcon->fd); evcon->fd = -1;
1803 return (-1);
1804 }
1805
1806 /* Set up a callback for successful connection setup */
1807 event_set(&evcon->ev, evcon->fd, EV_WRITE, evhttp_connectioncb, evcon);
1808 EVHTTP_BASE_SET(evcon, &evcon->ev);
1809 evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_CONNECT_TIMEOUT);
1810
1811 evcon->state = EVCON_CONNECTING;
1812
1813 return (0);
1814 }
1815
1816 /*
1817 * Starts an HTTP request on the provided evhttp_connection object.
1818 * If the connection object is not connected to the web server already,
1819 * this will start the connection.
1820 */
1821
1822 int
1823 evhttp_make_request(struct evhttp_connection *evcon,
1824 struct evhttp_request *req,
1825 enum evhttp_cmd_type type, const char *uri)
1826 {
1827 /* We are making a request */
1828 req->kind = EVHTTP_REQUEST;
1829 req->type = type;
1830 if (req->uri != NULL)
1831 free(req->uri);
1832 if ((req->uri = strdup(uri)) == NULL)
1833 event_err(1, "%s: strdup", __func__);
1834
1835 /* Set the protocol version if it is not supplied */
1836 if (!req->major && !req->minor) {
1837 req->major = 1;
1838 req->minor = 1;
1839 }
1840
1841 assert(req->evcon == NULL);
1842 req->evcon = evcon;
1843 assert(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
1844
1845 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
1846
1847 /* If the connection object is not connected; make it so */
1848 if (!evhttp_connected(evcon))
1849 return (evhttp_connection_connect(evcon));
1850
1851 /*
1852 * If it's connected already and we are the first in the queue,
1853 * then we can dispatch this request immediately. Otherwise, it
1854 * will be dispatched once the pending requests are completed.
1855 */
1856 if (TAILQ_FIRST(&evcon->requests) == req)
1857 evhttp_request_dispatch(evcon);
1858
1859 return (0);
1860 }
1861
1862 /*
1863 * Reads data from file descriptor into request structure
1864 * Request structure needs to be set up correctly.
1865 */
1866
1867 void
1868 evhttp_start_read(struct evhttp_connection *evcon)
1869 {
1870 /* Set up an event to read the headers */
1871 if (event_initialized(&evcon->ev))
1872 event_del(&evcon->ev);
1873 event_set(&evcon->ev, evcon->fd, EV_READ, evhttp_read, evcon);
1874 EVHTTP_BASE_SET(evcon, &evcon->ev);
1875
1876 evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
1877 evcon->state = EVCON_READING_FIRSTLINE;
1878 }
1879
1880 static void
1881 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
1882 {
1883 int need_close;
1884 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1885 TAILQ_REMOVE(&evcon->requests, req, next);
1886
1887 /* delete possible close detection events */
1888 evhttp_connection_stop_detectclose(evcon);
1889
1890 need_close =
1891 (req->minor == 0 &&
1892 !evhttp_is_connection_keepalive(req->input_headers))||
1893 evhttp_is_connection_close(req->flags, req->input_headers) ||
1894 evhttp_is_connection_close(req->flags, req->output_headers);
1895
1896 assert(req->flags & EVHTTP_REQ_OWN_CONNECTION);
1897 evhttp_request_free(req);
1898
1899 if (need_close) {
1900 evhttp_connection_free(evcon);
1901 return;
1902 }
1903
1904 /* we have a persistent connection; try to accept another request. */
1905 if (evhttp_associate_new_request_with_connection(evcon) == -1)
1906 evhttp_connection_free(evcon);
1907 }
1908
1909 /*
1910 * Returns an error page.
1911 */
1912
1913 void
1914 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
1915 {
1916 #define ERR_FORMAT "<HTML><HEAD>\n" \
1917 "<TITLE>%d %s</TITLE>\n" \
1918 "</HEAD><BODY>\n" \
1919 "<H1>Method Not Implemented</H1>\n" \
1920 "Invalid method in request<P>\n" \
1921 "</BODY></HTML>\n"
1922
1923 struct evbuffer *buf = evbuffer_new();
1924
1925 /* close the connection on error */
1926 evhttp_add_header(req->output_headers, "Connection", "close");
1927
1928 evhttp_response_code(req, error, reason);
1929
1930 evbuffer_add_printf(buf, ERR_FORMAT, error, reason);
1931
1932 evhttp_send_page(req, buf);
1933
1934 evbuffer_free(buf);
1935 #undef ERR_FORMAT
1936 }
1937
1938 /* Requires that headers and response code are already set up */
1939
1940 static inline void
1941 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
1942 {
1943 struct evhttp_connection *evcon = req->evcon;
1944
1945 if (evcon == NULL) {
1946 evhttp_request_free(req);
1947 return;
1948 }
1949
1950 assert(TAILQ_FIRST(&evcon->requests) == req);
1951
1952 /* we expect no more calls form the user on this request */
1953 req->userdone = 1;
1954
1955 /* xxx: not sure if we really should expose the data buffer this way */
1956 if (databuf != NULL)
1957 evbuffer_add_buffer(req->output_buffer, databuf);
1958
1959 /* Adds headers to the response */
1960 evhttp_make_header(evcon, req);
1961
1962 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
1963 }
1964
1965 void
1966 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
1967 struct evbuffer *databuf)
1968 {
1969 evhttp_response_code(req, code, reason);
1970
1971 evhttp_send(req, databuf);
1972 }
1973
1974 void
1975 evhttp_send_reply_start(struct evhttp_request *req, int code,
1976 const char *reason)
1977 {
1978 evhttp_response_code(req, code, reason);
1979 if (req->major == 1 && req->minor == 1) {
1980 /* use chunked encoding for HTTP/1.1 */
1981 evhttp_add_header(req->output_headers, "Transfer-Encoding",
1982 "chunked");
1983 req->chunked = 1;
1984 }
1985 evhttp_make_header(req->evcon, req);
1986 evhttp_write_buffer(req->evcon, NULL, NULL);
1987 }
1988
1989 void
1990 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
1991 {
1992 struct evhttp_connection *evcon = req->evcon;
1993
1994 if (evcon == NULL)
1995 return;
1996
1997 if (req->chunked) {
1998 evbuffer_add_printf(evcon->output_buffer, "%x\r\n",
1999 (unsigned)EVBUFFER_LENGTH(databuf));
2000 }
2001 evbuffer_add_buffer(evcon->output_buffer, databuf);
2002 if (req->chunked) {
2003 evbuffer_add(evcon->output_buffer, "\r\n", 2);
2004 }
2005 evhttp_write_buffer(evcon, NULL, NULL);
2006 }
2007
2008 void
2009 evhttp_send_reply_end(struct evhttp_request *req)
2010 {
2011 struct evhttp_connection *evcon = req->evcon;
2012
2013 if (evcon == NULL) {
2014 evhttp_request_free(req);
2015 return;
2016 }
2017
2018 /* we expect no more calls form the user on this request */
2019 req->userdone = 1;
2020
2021 if (req->chunked) {
2022 evbuffer_add(req->evcon->output_buffer, "0\r\n\r\n", 5);
2023 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
2024 req->chunked = 0;
2025 } else if (!event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL)) {
2026 /* let the connection know that we are done with the request */
2027 evhttp_send_done(evcon, NULL);
2028 } else {
2029 /* make the callback execute after all data has been written */
2030 evcon->cb = evhttp_send_done;
2031 evcon->cb_arg = NULL;
2032 }
2033 }
2034
2035 void
2036 evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
2037 {
2038 req->kind = EVHTTP_RESPONSE;
2039 req->response_code = code;
2040 if (req->response_code_line != NULL)
2041 free(req->response_code_line);
2042 req->response_code_line = strdup(reason);
2043 }
2044
2045 void
2046 evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
2047 {
2048 if (!req->major || !req->minor) {
2049 req->major = 1;
2050 req->minor = 1;
2051 }
2052
2053 if (req->kind != EVHTTP_RESPONSE)
2054 evhttp_response_code(req, 200, "OK");
2055
2056 evhttp_clear_headers(req->output_headers);
2057 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
2058 evhttp_add_header(req->output_headers, "Connection", "close");
2059
2060 evhttp_send(req, databuf);
2061 }
2062
2063 static const char uri_chars[256] = {
2064 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2065 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2066 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2067 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0,
2068 /* 64 */
2069 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2070 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
2071 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2072 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
2073 /* 128 */
2074 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2075 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2076 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2077 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2078 /* 192 */
2079 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2080 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2081 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2082 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2083 };
2084
2085 /*
2086 * Helper functions to encode/decode a URI.
2087 * The returned string must be freed by the caller.
2088 */
2089 char *
2090 evhttp_encode_uri(const char *uri)
2091 {
2092 struct evbuffer *buf = evbuffer_new();
2093 char *p;
2094
2095 for (p = (char *)uri; *p != '\0'; p++) {
2096 if (uri_chars[(u_char)(*p)]) {
2097 evbuffer_add(buf, p, 1);
2098 } else {
2099 evbuffer_add_printf(buf, "%%%02X", (u_char)(*p));
2100 }
2101 }
2102 evbuffer_add(buf, "", 1);
2103 p = strdup((char *)EVBUFFER_DATA(buf));
2104 evbuffer_free(buf);
2105
2106 return (p);
2107 }
2108
2109 /*
2110 * @param always_decode_plus: when true we transform plus to space even
2111 * if we have not seen a ?.
2112 */
2113 static int
2114 evhttp_decode_uri_internal(
2115 const char *uri, size_t length, char *ret, int always_decode_plus)
2116 {
2117 char c;
2118 int i, j, in_query = always_decode_plus;
2119
2120 for (i = j = 0; uri[i] != '\0'; i++) {
2121 c = uri[i];
2122 if (c == '?') {
2123 in_query = 1;
2124 } else if (c == '+' && in_query) {
2125 c = ' ';
2126 } else if (c == '%' && isxdigit((unsigned char)uri[i+1]) &&
2127 isxdigit((unsigned char)uri[i+2])) {
2128 char tmp[] = { uri[i+1], uri[i+2], '\0' };
2129 c = (char)strtol(tmp, NULL, 16);
2130 i += 2;
2131 }
2132 ret[j++] = c;
2133 }
2134 ret[j] = '\0';
2135
2136 return (j);
2137 }
2138
2139 char *
2140 evhttp_decode_uri(const char *uri)
2141 {
2142 char *ret;
2143
2144 if ((ret = malloc(strlen(uri) + 1)) == NULL)
2145 event_err(1, "%s: malloc(%lu)", __func__,
2146 (unsigned long)(strlen(uri) + 1));
2147
2148 evhttp_decode_uri_internal(uri, strlen(uri),
2149 ret, 0 /*always_decode_plus*/);
2150
2151 return (ret);
2152 }
2153
2154 /*
2155 * Helper function to parse out arguments in a query.
2156 * The arguments are separated by key and value.
2157 */
2158
2159 void
2160 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
2161 {
2162 char *line;
2163 char *argument;
2164 char *p;
2165
2166 TAILQ_INIT(headers);
2167
2168 /* No arguments - we are done */
2169 if (strchr(uri, '?') == NULL)
2170 return;
2171
2172 if ((line = strdup(uri)) == NULL)
2173 event_err(1, "%s: strdup", __func__);
2174
2175
2176 argument = line;
2177
2178 /* We already know that there has to be a ? */
2179 strsep(&argument, "?");
2180
2181 p = argument;
2182 while (p != NULL && *p != '\0') {
2183 char *key, *value, *decoded_value;
2184 argument = strsep(&p, "&");
2185
2186 value = argument;
2187 key = strsep(&value, "=");
2188 if (value == NULL)
2189 goto error;
2190
2191 if ((decoded_value = malloc(strlen(value) + 1)) == NULL)
2192 event_err(1, "%s: malloc", __func__);
2193
2194 evhttp_decode_uri_internal(value, strlen(value),
2195 decoded_value, 1 /*always_decode_plus*/);
2196 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
2197 evhttp_add_header_internal(headers, key, decoded_value);
2198 free(decoded_value);
2199 }
2200
2201 error:
2202 free(line);
2203 }
2204
2205 static struct evhttp_cb *
2206 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
2207 {
2208 struct evhttp_cb *cb;
2209 size_t offset = 0;
2210
2211 /* Test for different URLs */
2212 char *p = strchr(req->uri, '?');
2213 if (p != NULL)
2214 offset = (size_t)(p - req->uri);
2215
2216 TAILQ_FOREACH(cb, callbacks, next) {
2217 int res = 0;
2218 if (p == NULL) {
2219 res = strcmp(cb->what, req->uri) == 0;
2220 } else {
2221 res = ((strncmp(cb->what, req->uri, offset) == 0) &&
2222 (cb->what[offset] == '\0'));
2223 }
2224
2225 if (res)
2226 return (cb);
2227 }
2228
2229 return (NULL);
2230 }
2231
2232 static void
2233 evhttp_handle_request(struct evhttp_request *req, void *arg)
2234 {
2235 struct evhttp *http = arg;
2236 struct evhttp_cb *cb = NULL;
2237
2238 event_debug(("%s: req->uri=%s", __func__, req->uri));
2239 if (req->uri == NULL) {
2240 event_debug(("%s: bad request", __func__));
2241 if (req->evcon->state == EVCON_DISCONNECTED) {
2242 evhttp_connection_fail(req->evcon, EVCON_HTTP_EOF);
2243 } else {
2244 event_debug(("%s: sending error", __func__));
2245 evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
2246 }
2247 return;
2248 }
2249
2250 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
2251 (*cb->cb)(req, cb->cbarg);
2252 return;
2253 }
2254
2255 /* Generic call back */
2256 if (http->gencb) {
2257 (*http->gencb)(req, http->gencbarg);
2258 return;
2259 } else {
2260 /* We need to send a 404 here */
2261 #define ERR_FORMAT "<html><head>" \
2262 "<title>404 Not Found</title>" \
2263 "</head><body>" \
2264 "<h1>Not Found</h1>" \
2265 "<p>The requested URL %s was not found on this server.</p>"\
2266 "</body></html>\n"
2267
2268 char *escaped_html = evhttp_htmlescape(req->uri);
2269 struct evbuffer *buf = evbuffer_new();
2270
2271 evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
2272
2273 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
2274
2275 free(escaped_html);
2276
2277 evhttp_send_page(req, buf);
2278
2279 evbuffer_free(buf);
2280 #undef ERR_FORMAT
2281 }
2282 }
2283
2284 static void
2285 accept_socket(int fd, short what, void *arg)
2286 {
2287 struct evhttp *http = arg;
2288 struct sockaddr_storage ss;
2289 socklen_t addrlen = sizeof(ss);
2290 int nfd;
2291
2292 if ((nfd = accept(fd, (struct sockaddr *)&ss, &addrlen)) == -1) {
2293 if (errno != EAGAIN && errno != EINTR)
2294 event_warn("%s: bad accept", __func__);
2295 return;
2296 }
2297 if (evutil_make_socket_nonblocking(nfd) < 0)
2298 return;
2299
2300 evhttp_get_request(http, nfd, (struct sockaddr *)&ss, addrlen);
2301 }
2302
2303 int
2304 evhttp_bind_socket(struct evhttp *http, const char *address, u_short port)
2305 {
2306 int fd;
2307 int res;
2308
2309 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
2310 return (-1);
2311
2312 if (listen(fd, 128) == -1) {
2313 event_warn("%s: listen", __func__);
2314 EVUTIL_CLOSESOCKET(fd);
2315 return (-1);
2316 }
2317
2318 res = evhttp_accept_socket(http, fd);
2319
2320 if (res != -1)
2321 event_debug(("Bound to port %d - Awaiting connections ... ",
2322 port));
2323
2324 return (res);
2325 }
2326
2327 int
2328 evhttp_accept_socket(struct evhttp *http, int fd)
2329 {
2330 struct evhttp_bound_socket *bound;
2331 struct event *ev;
2332 int res;
2333
2334 bound = malloc(sizeof(struct evhttp_bound_socket));
2335 if (bound == NULL)
2336 return (-1);
2337
2338 ev = &bound->bind_ev;
2339
2340 /* Schedule the socket for accepting */
2341 event_set(ev, fd, EV_READ | EV_PERSIST, accept_socket, http);
2342 EVHTTP_BASE_SET(http, ev);
2343
2344 res = event_add(ev, NULL);
2345
2346 if (res == -1) {
2347 free(bound);
2348 return (-1);
2349 }
2350
2351 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
2352
2353 return (0);
2354 }
2355
2356 static struct evhttp*
2357 evhttp_new_object(void)
2358 {
2359 struct evhttp *http = NULL;
2360
2361 if ((http = calloc(1, sizeof(struct evhttp))) == NULL) {
2362 event_warn("%s: calloc", __func__);
2363 return (NULL);
2364 }
2365
2366 http->timeout = -1;
2367
2368 TAILQ_INIT(&http->sockets);
2369 TAILQ_INIT(&http->callbacks);
2370 TAILQ_INIT(&http->connections);
2371
2372 return (http);
2373 }
2374
2375 struct evhttp *
2376 evhttp_new(struct event_base *base)
2377 {
2378 struct evhttp *http = evhttp_new_object();
2379
2380 http->base = base;
2381
2382 return (http);
2383 }
2384
2385 /*
2386 * Start a web server on the specified address and port.
2387 */
2388
2389 struct evhttp *
2390 evhttp_start(const char *address, u_short port)
2391 {
2392 struct evhttp *http = evhttp_new_object();
2393
2394 if (evhttp_bind_socket(http, address, port) == -1) {
2395 free(http);
2396 return (NULL);
2397 }
2398
2399 return (http);
2400 }
2401
2402 void
2403 evhttp_free(struct evhttp* http)
2404 {
2405 struct evhttp_cb *http_cb;
2406 struct evhttp_connection *evcon;
2407 struct evhttp_bound_socket *bound;
2408 int fd;
2409
2410 /* Remove the accepting part */
2411 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
2412 TAILQ_REMOVE(&http->sockets, bound, next);
2413
2414 fd = bound->bind_ev.ev_fd;
2415 event_del(&bound->bind_ev);
2416 EVUTIL_CLOSESOCKET(fd);
2417
2418 free(bound);
2419 }
2420
2421 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
2422 /* evhttp_connection_free removes the connection */
2423 evhttp_connection_free(evcon);
2424 }
2425
2426 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
2427 TAILQ_REMOVE(&http->callbacks, http_cb, next);
2428 free(http_cb->what);
2429 free(http_cb);
2430 }
2431
2432 free(http);
2433 }
2434
2435 void
2436 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
2437 {
2438 http->timeout = timeout_in_secs;
2439 }
2440
2441 void
2442 evhttp_set_cb(struct evhttp *http, const char *uri,
2443 void (*cb)(struct evhttp_request *, void *), void *cbarg)
2444 {
2445 struct evhttp_cb *http_cb;
2446
2447 if ((http_cb = calloc(1, sizeof(struct evhttp_cb))) == NULL)
2448 event_err(1, "%s: calloc", __func__);
2449
2450 http_cb->what = strdup(uri);
2451 http_cb->cb = cb;
2452 http_cb->cbarg = cbarg;
2453
2454 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
2455 }
2456
2457 int
2458 evhttp_del_cb(struct evhttp *http, const char *uri)
2459 {
2460 struct evhttp_cb *http_cb;
2461
2462 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
2463 if (strcmp(http_cb->what, uri) == 0)
2464 break;
2465 }
2466 if (http_cb == NULL)
2467 return (-1);
2468
2469 TAILQ_REMOVE(&http->callbacks, http_cb, next);
2470 free(http_cb->what);
2471 free(http_cb);
2472
2473 return (0);
2474 }
2475
2476 void
2477 evhttp_set_gencb(struct evhttp *http,
2478 void (*cb)(struct evhttp_request *, void *), void *cbarg)
2479 {
2480 http->gencb = cb;
2481 http->gencbarg = cbarg;
2482 }
2483
2484 /*
2485 * Request related functions
2486 */
2487
2488 struct evhttp_request *
2489 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
2490 {
2491 struct evhttp_request *req = NULL;
2492
2493 /* Allocate request structure */
2494 if ((req = calloc(1, sizeof(struct evhttp_request))) == NULL) {
2495 event_warn("%s: calloc", __func__);
2496 goto error;
2497 }
2498
2499 req->kind = EVHTTP_RESPONSE;
2500 req->input_headers = calloc(1, sizeof(struct evkeyvalq));
2501 if (req->input_headers == NULL) {
2502 event_warn("%s: calloc", __func__);
2503 goto error;
2504 }
2505 TAILQ_INIT(req->input_headers);
2506
2507 req->output_headers = calloc(1, sizeof(struct evkeyvalq));
2508 if (req->output_headers == NULL) {
2509 event_warn("%s: calloc", __func__);
2510 goto error;
2511 }
2512 TAILQ_INIT(req->output_headers);
2513
2514 if ((req->input_buffer = evbuffer_new()) == NULL) {
2515 event_warn("%s: evbuffer_new", __func__);
2516 goto error;
2517 }
2518
2519 if ((req->output_buffer = evbuffer_new()) == NULL) {
2520 event_warn("%s: evbuffer_new", __func__);
2521 goto error;
2522 }
2523
2524 req->cb = cb;
2525 req->cb_arg = arg;
2526
2527 return (req);
2528
2529 error:
2530 if (req != NULL)
2531 evhttp_request_free(req);
2532 return (NULL);
2533 }
2534
2535 void
2536 evhttp_request_free(struct evhttp_request *req)
2537 {
2538 if (req->remote_host != NULL)
2539 free(req->remote_host);
2540 if (req->uri != NULL)
2541 free(req->uri);
2542 if (req->response_code_line != NULL)
2543 free(req->response_code_line);
2544
2545 evhttp_clear_headers(req->input_headers);
2546 free(req->input_headers);
2547
2548 evhttp_clear_headers(req->output_headers);
2549 free(req->output_headers);
2550
2551 if (req->input_buffer != NULL)
2552 evbuffer_free(req->input_buffer);
2553
2554 if (req->output_buffer != NULL)
2555 evbuffer_free(req->output_buffer);
2556
2557 free(req);
2558 }
2559
2560 struct evhttp_connection *
2561 evhttp_request_get_connection(struct evhttp_request *req)
2562 {
2563 return req->evcon;
2564 }
2565
2566
2567 void
2568 evhttp_request_set_chunked_cb(struct evhttp_request *req,
2569 void (*cb)(struct evhttp_request *, void *))
2570 {
2571 req->chunk_cb = cb;
2572 }
2573
2574 /*
2575 * Allows for inspection of the request URI
2576 */
2577
2578 const char *
2579 evhttp_request_uri(struct evhttp_request *req) {
2580 if (req->uri == NULL)
2581 event_debug(("%s: request %p has no uri\n", __func__, req));
2582 return (req->uri);
2583 }
2584
2585 /*
2586 * Takes a file descriptor to read a request from.
2587 * The callback is executed once the whole request has been read.
2588 */
2589
2590 static struct evhttp_connection*
2591 evhttp_get_request_connection(
2592 struct evhttp* http,
2593 int fd, struct sockaddr *sa, socklen_t salen)
2594 {
2595 struct evhttp_connection *evcon;
2596 char *hostname = NULL, *portname = NULL;
2597
2598 name_from_addr(sa, salen, &hostname, &portname);
2599 if (hostname == NULL || portname == NULL) {
2600 if (hostname) free(hostname);
2601 if (portname) free(portname);
2602 return (NULL);
2603 }
2604
2605 event_debug(("%s: new request from %s:%s on %d\n",
2606 __func__, hostname, portname, fd));
2607
2608 /* we need a connection object to put the http request on */
2609 evcon = evhttp_connection_new(hostname, atoi(portname));
2610 free(hostname);
2611 free(portname);
2612 if (evcon == NULL)
2613 return (NULL);
2614
2615 /* associate the base if we have one*/
2616 evhttp_connection_set_base(evcon, http->base);
2617
2618 evcon->flags |= EVHTTP_CON_INCOMING;
2619 evcon->state = EVCON_READING_FIRSTLINE;
2620
2621 evcon->fd = fd;
2622
2623 return (evcon);
2624 }
2625
2626 static int
2627 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
2628 {
2629 struct evhttp *http = evcon->http_server;
2630 struct evhttp_request *req;
2631 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
2632 return (-1);
2633
2634 req->evcon = evcon; /* the request ends up owning the connection */
2635 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
2636
2637 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2638
2639 req->kind = EVHTTP_REQUEST;
2640
2641 if ((req->remote_host = strdup(evcon->address)) == NULL)
2642 event_err(1, "%s: strdup", __func__);
2643 req->remote_port = evcon->port;
2644
2645 evhttp_start_read(evcon);
2646
2647 return (0);
2648 }
2649
2650 void
2651 evhttp_get_request(struct evhttp *http, int fd,
2652 struct sockaddr *sa, socklen_t salen)
2653 {
2654 struct evhttp_connection *evcon;
2655
2656 evcon = evhttp_get_request_connection(http, fd, sa, salen);
2657 if (evcon == NULL)
2658 return;
2659
2660 /* the timeout can be used by the server to close idle connections */
2661 if (http->timeout != -1)
2662 evhttp_connection_set_timeout(evcon, http->timeout);
2663
2664 /*
2665 * if we want to accept more than one request on a connection,
2666 * we need to know which http server it belongs to.
2667 */
2668 evcon->http_server = http;
2669 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
2670
2671 if (evhttp_associate_new_request_with_connection(evcon) == -1)
2672 evhttp_connection_free(evcon);
2673 }
2674
2675
2676 /*
2677 * Network helper functions that we do not want to export to the rest of
2678 * the world.
2679 */
2680 #if 0 /* Unused */
2681 static struct addrinfo *
2682 addr_from_name(char *address)
2683 {
2684 #ifdef HAVE_GETADDRINFO
2685 struct addrinfo ai, *aitop;
2686 int ai_result;
2687
2688 memset(&ai, 0, sizeof(ai));
2689 ai.ai_family = AF_INET;
2690 ai.ai_socktype = SOCK_RAW;
2691 ai.ai_flags = 0;
2692 if ((ai_result = getaddrinfo(address, NULL, &ai, &aitop)) != 0) {
2693 if ( ai_result == EAI_SYSTEM )
2694 event_warn("getaddrinfo");
2695 else
2696 event_warnx("getaddrinfo: %s", gai_strerror(ai_result));
2697 }
2698
2699 return (aitop);
2700 #else
2701 assert(0);
2702 return NULL; /* XXXXX Use gethostbyname, if this function is ever used. */
2703 #endif
2704 }
2705 #endif
2706
2707 static void
2708 name_from_addr(struct sockaddr *sa, socklen_t salen,
2709 char **phost, char **pport)
2710 {
2711 char ntop[NI_MAXHOST];
2712 char strport[NI_MAXSERV];
2713 int ni_result;
2714
2715 #ifdef HAVE_GETNAMEINFO
2716 ni_result = getnameinfo(sa, salen,
2717 ntop, sizeof(ntop), strport, sizeof(strport),
2718 NI_NUMERICHOST|NI_NUMERICSERV);
2719
2720 if (ni_result != 0) {
2721 if (ni_result == EAI_SYSTEM)
2722 event_err(1, "getnameinfo failed");
2723 else
2724 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_ result));
2725 return;
2726 }
2727 #else
2728 ni_result = fake_getnameinfo(sa, salen,
2729 ntop, sizeof(ntop), strport, sizeof(strport),
2730 NI_NUMERICHOST|NI_NUMERICSERV);
2731 if (ni_result != 0)
2732 return;
2733 #endif
2734 *phost = strdup(ntop);
2735 *pport = strdup(strport);
2736 }
2737
2738 /* Create a non-blocking socket and bind it */
2739 /* todo: rename this function */
2740 static int
2741 bind_socket_ai(struct addrinfo *ai, int reuse)
2742 {
2743 int fd, on = 1, r;
2744 int serrno;
2745
2746 /* Create listen socket */
2747 fd = socket(AF_INET, SOCK_STREAM, 0);
2748 if (fd == -1) {
2749 event_warn("socket");
2750 return (-1);
2751 }
2752
2753 if (evutil_make_socket_nonblocking(fd) < 0)
2754 goto out;
2755
2756 #ifndef WIN32
2757 if (fcntl(fd, F_SETFD, 1) == -1) {
2758 event_warn("fcntl(F_SETFD)");
2759 goto out;
2760 }
2761 #endif
2762
2763 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
2764 if (reuse) {
2765 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
2766 (void *)&on, sizeof(on));
2767 }
2768
2769 if (ai != NULL) {
2770 r = bind(fd, ai->ai_addr, ai->ai_addrlen);
2771 if (r == -1)
2772 goto out;
2773 }
2774
2775 return (fd);
2776
2777 out:
2778 serrno = EVUTIL_SOCKET_ERROR();
2779 EVUTIL_CLOSESOCKET(fd);
2780 EVUTIL_SET_SOCKET_ERROR(serrno);
2781 return (-1);
2782 }
2783
2784 static struct addrinfo *
2785 make_addrinfo(const char *address, u_short port)
2786 {
2787 struct addrinfo *aitop = NULL;
2788
2789 #ifdef HAVE_GETADDRINFO
2790 struct addrinfo ai;
2791 char strport[NI_MAXSERV];
2792 int ai_result;
2793
2794 memset(&ai, 0, sizeof(ai));
2795 ai.ai_family = AF_INET;
2796 ai.ai_socktype = SOCK_STREAM;
2797 ai.ai_flags = AI_PASSIVE; /* turn NULL host name into INADDR_ANY */
2798 evutil_snprintf(strport, sizeof(strport), "%d", port);
2799 if ((ai_result = getaddrinfo(address, strport, &ai, &aitop)) != 0) {
2800 if ( ai_result == EAI_SYSTEM )
2801 event_warn("getaddrinfo");
2802 else
2803 event_warnx("getaddrinfo: %s", gai_strerror(ai_result));
2804 return (NULL);
2805 }
2806 #else
2807 static int cur;
2808 static struct addrinfo ai[2]; /* We will be returning the address of som e of this memory so it has to last even after this call. */
2809 if (++cur == 2) cur = 0; /* allow calling this function twice */
2810
2811 if (fake_getaddrinfo(address, &ai[cur]) < 0) {
2812 event_warn("fake_getaddrinfo");
2813 return (NULL);
2814 }
2815 aitop = &ai[cur];
2816 ((struct sockaddr_in *) aitop->ai_addr)->sin_port = htons(port);
2817 #endif
2818
2819 return (aitop);
2820 }
2821
2822 static int
2823 bind_socket(const char *address, u_short port, int reuse)
2824 {
2825 int fd;
2826 struct addrinfo *aitop = NULL;
2827
2828 /* just create an unbound socket */
2829 if (address == NULL && port == 0)
2830 return bind_socket_ai(NULL, 0);
2831
2832 aitop = make_addrinfo(address, port);
2833
2834 if (aitop == NULL)
2835 return (-1);
2836
2837 fd = bind_socket_ai(aitop, reuse);
2838
2839 #ifdef HAVE_GETADDRINFO
2840 freeaddrinfo(aitop);
2841 #else
2842 fake_freeaddrinfo(aitop);
2843 #endif
2844
2845 return (fd);
2846 }
2847
2848 static int
2849 socket_connect(int fd, const char *address, unsigned short port)
2850 {
2851 struct addrinfo *ai = make_addrinfo(address, port);
2852 int res = -1;
2853
2854 if (ai == NULL) {
2855 event_debug(("%s: make_addrinfo: \"%s:%d\"",
2856 __func__, address, port));
2857 return (-1);
2858 }
2859
2860 if (connect(fd, ai->ai_addr, ai->ai_addrlen) == -1) {
2861 #ifdef WIN32
2862 int tmp_error = WSAGetLastError();
2863 if (tmp_error != WSAEWOULDBLOCK && tmp_error != WSAEINVAL &&
2864 tmp_error != WSAEINPROGRESS) {
2865 goto out;
2866 }
2867 #else
2868 if (errno != EINPROGRESS) {
2869 goto out;
2870 }
2871 #endif
2872 }
2873
2874 /* everything is fine */
2875 res = 0;
2876
2877 out:
2878 #ifdef HAVE_GETADDRINFO
2879 freeaddrinfo(ai);
2880 #else
2881 fake_freeaddrinfo(ai);
2882 #endif
2883
2884 return (res);
2885 }
OLDNEW
« no previous file with comments | « third_party/libevent/freebsd/event-config.h ('k') | third_party/libevent/http-internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698