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