Making panels stacking order aware of launcher alignment
[chromium-blink-merge.git] / third_party / libevent / http.c
blobb04ad54bab023fec84fc7ff2c32657a353f7eb91
1 /*
2 * Copyright (c) 2002-2006 Niels Provos <provos@citi.umich.edu>
3 * All rights reserved.
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.
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.
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
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
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
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
53 #include <sys/queue.h>
55 #ifndef WIN32
56 #include <netinet/in.h>
57 #include <netdb.h>
58 #endif
60 #ifdef WIN32
61 #include <winsock2.h>
62 #endif
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
82 #undef timeout_pending
83 #undef timeout_initialized
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"
92 #ifdef WIN32
93 #define strcasecmp _stricmp
94 #define strncasecmp _strnicmp
95 #define strdup _strdup
96 #endif
98 #ifndef HAVE_GETNAMEINFO
99 #define NI_MAXSERV 32
100 #define NI_MAXHOST 1025
102 #define NI_NUMERICHOST 1
103 #define NI_NUMERICSERV 2
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)
109 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
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);
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);
133 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
134 return (-1);
135 else
136 return (0);
139 return (0);
142 #endif
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;
153 static int
154 fake_getaddrinfo(const char *hostname, struct addrinfo *ai)
156 struct hostent *he = NULL;
157 struct sockaddr_in *sa;
158 if (hostname) {
159 he = gethostbyname(hostname);
160 if (!he)
161 return (-1);
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;
178 ai->ai_next = NULL;
179 return (0);
181 static void
182 fake_freeaddrinfo(struct addrinfo *ai)
184 free(ai->ai_addr);
186 #endif
188 #ifndef MIN
189 #define MIN(a,b) (((a)<(b))?(a):(b))
190 #endif
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)
197 extern int debug;
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);
219 void evhttp_read(int, short, void *);
220 void evhttp_write(int, short, void *);
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)
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;
241 #endif
243 static const char *
244 html_replace(char ch, char *buf)
246 switch (ch) {
247 case '<':
248 return "&lt;";
249 case '>':
250 return "&gt;";
251 case '"':
252 return "&quot;";
253 case '\'':
254 return "&#039;";
255 case '&':
256 return "&amp;";
257 default:
258 break;
261 /* Echo the character back */
262 buf[0] = ch;
263 buf[1] = '\0';
265 return buf;
269 * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
270 * &#039; and &amp; correspondingly.
272 * The returned string needs to be freed by the caller.
275 char *
276 evhttp_htmlescape(const char *html)
278 int i, new_size = 0, old_size = strlen(html);
279 char *escaped_html, *p;
280 char scratch_space[2];
282 for (i = 0; i < old_size; ++i)
283 new_size += strlen(html_replace(html[i], scratch_space));
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);
295 *p = '\0';
297 return (escaped_html);
300 static const char *
301 evhttp_method(enum evhttp_cmd_type type)
303 const char *method;
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;
320 return (method);
323 static void
324 evhttp_add_event(struct event *ev, int timeout, int default_timeout)
326 if (timeout != 0) {
327 struct timeval tv;
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);
337 void
338 evhttp_write_buffer(struct evhttp_connection *evcon,
339 void (*cb)(struct evhttp_connection *, void *), void *arg)
341 event_debug(("%s: preparing to write buffer\n", __func__));
343 /* Set call back */
344 evcon->cb = cb;
345 evcon->cb_arg = arg;
347 /* check if the event is already pending */
348 if (event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL))
349 event_del(&evcon->ev);
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);
356 static int
357 evhttp_connected(struct evhttp_connection *evcon)
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);
375 * Create the headers needed for an HTTP request
377 static void
378 evhttp_make_header_request(struct evhttp_connection *evcon,
379 struct evhttp_request *req)
381 const char *method;
383 evhttp_remove_header(req->output_headers, "Proxy-Connection");
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);
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);
400 static int
401 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
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);
413 static int
414 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
416 const char *connection = evhttp_find_header(headers, "Connection");
417 return (connection != NULL
418 && strncasecmp(connection, "keep-alive", 10) == 0);
421 static void
422 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
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);
444 static void
445 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
446 long content_length)
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);
457 * Create the headers needed for an HTTP reply
460 static void
461 evhttp_make_header_response(struct evhttp_connection *evcon,
462 struct evhttp_request *req)
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);
469 if (req->major == 1) {
470 if (req->minor == 1)
471 evhttp_maybe_add_date_header(req->output_headers);
474 * if the protocol is 1.0; and the connection was keep-alive
475 * we need to add a keep-alive header, too.
477 if (req->minor == 0 && is_keepalive)
478 evhttp_add_header(req->output_headers,
479 "Connection", "keep-alive");
481 if (req->minor == 1 || is_keepalive) {
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.
487 evhttp_maybe_add_content_length_header(
488 req->output_headers,
489 (long)EVBUFFER_LENGTH(req->output_buffer));
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");
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");
511 void
512 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
514 struct evkeyval *header;
517 * Depending if this is a HTTP request or response, we might need to
518 * add some new headers or remove existing headers.
520 if (req->kind == EVHTTP_REQUEST) {
521 evhttp_make_header_request(evcon, req);
522 } else {
523 evhttp_make_header_response(evcon, req);
526 TAILQ_FOREACH(header, req->output_headers, next) {
527 evbuffer_add_printf(evcon->output_buffer, "%s: %s\r\n",
528 header->key, header->value);
530 evbuffer_add(evcon->output_buffer, "\r\n", 2);
532 if (EVBUFFER_LENGTH(req->output_buffer) > 0) {
534 * For a request, we add the POST data, for a reply, this
535 * is the regular data.
537 evbuffer_add_buffer(evcon->output_buffer, req->output_buffer);
541 /* Separated host, port and file from URI */
544 evhttp_hostportfile(char *url, char **phost, u_short *pport, char **pfile)
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;
554 len = strlen(HTTP_PREFIX);
555 if (strncasecmp(url, HTTP_PREFIX, len))
556 return (-1);
558 url += len;
560 /* We might overrun */
561 if (strlcpy(host, url, sizeof (host)) >= sizeof(host))
562 return (-1);
564 p = strchr(host, '/');
565 if (p != NULL) {
566 *p = '\0';
567 p2 = p + 1;
568 } else
569 p2 = NULL;
571 if (pfile != NULL) {
572 /* Generate request file */
573 if (p2 == NULL)
574 p2 = "";
575 evutil_snprintf(file, sizeof(file), "/%s", p2);
578 p = strchr(host, ':');
579 if (p != NULL) {
580 *p = '\0';
581 port = atoi(p + 1);
583 if (port == 0)
584 return (-1);
585 } else
586 port = HTTP_DEFAULTPORT;
588 if (phost != NULL)
589 *phost = host;
590 if (pport != NULL)
591 *pport = port;
592 if (pfile != NULL)
593 *pfile = file;
595 return (0);
598 static int
599 evhttp_connection_incoming_fail(struct evhttp_request *req,
600 enum evhttp_connection_error error)
602 switch (error) {
603 case EVCON_HTTP_TIMEOUT:
604 case EVCON_HTTP_EOF:
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.
611 return (-1);
612 case EVCON_HTTP_INVALID_HEADER:
613 default: /* xxx: probably should just error on default */
614 /* the callback looks at the uri to determine errors */
615 if (req->uri) {
616 free(req->uri);
617 req->uri = NULL;
621 * the callback needs to send a reply, once the reply has
622 * been send, the connection should get freed.
624 (*req->cb)(req, req->cb_arg);
627 return (0);
630 void
631 evhttp_connection_fail(struct evhttp_connection *evcon,
632 enum evhttp_connection_error error)
634 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
635 void (*cb)(struct evhttp_request *, void *);
636 void *cb_arg;
637 assert(req != NULL);
639 if (evcon->flags & EVHTTP_CON_INCOMING) {
641 * for incoming requests, there are two different
642 * failure cases. it's either a network level error
643 * or an http layer error. for problems on the network
644 * layer like timeouts we just drop the connections.
645 * For HTTP problems, we might have to send back a
646 * reply before the connection can be freed.
648 if (evhttp_connection_incoming_fail(req, error) == -1)
649 evhttp_connection_free(evcon);
650 return;
653 /* save the callback for later; the cb might free our object */
654 cb = req->cb;
655 cb_arg = req->cb_arg;
657 TAILQ_REMOVE(&evcon->requests, req, next);
658 evhttp_request_free(req);
660 /* xxx: maybe we should fail all requests??? */
662 /* reset the connection */
663 evhttp_connection_reset(evcon);
665 /* We are trying the next request that was queued on us */
666 if (TAILQ_FIRST(&evcon->requests) != NULL)
667 evhttp_connection_connect(evcon);
669 /* inform the user */
670 if (cb != NULL)
671 (*cb)(NULL, cb_arg);
674 void
675 evhttp_write(int fd, short what, void *arg)
677 struct evhttp_connection *evcon = arg;
678 int n;
680 if (what == EV_TIMEOUT) {
681 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
682 return;
685 n = evbuffer_write(evcon->output_buffer, fd);
686 if (n == -1) {
687 event_debug(("%s: evbuffer_write", __func__));
688 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
689 return;
692 if (n == 0) {
693 event_debug(("%s: write nothing", __func__));
694 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
695 return;
698 if (EVBUFFER_LENGTH(evcon->output_buffer) != 0) {
699 evhttp_add_event(&evcon->ev,
700 evcon->timeout, HTTP_WRITE_TIMEOUT);
701 return;
704 /* Activate our call back */
705 if (evcon->cb != NULL)
706 (*evcon->cb)(evcon, evcon->cb_arg);
710 * Advance the connection state.
711 * - If this is an outgoing connection, we've just processed the response;
712 * idle or close the connection.
713 * - If this is an incoming connection, we've just processed the request;
714 * respond.
716 static void
717 evhttp_connection_done(struct evhttp_connection *evcon)
719 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
720 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
722 if (con_outgoing) {
723 /* idle or close the connection */
724 int need_close;
725 TAILQ_REMOVE(&evcon->requests, req, next);
726 req->evcon = NULL;
728 evcon->state = EVCON_IDLE;
730 need_close =
731 evhttp_is_connection_close(req->flags, req->input_headers)||
732 evhttp_is_connection_close(req->flags, req->output_headers);
734 /* check if we got asked to close the connection */
735 if (need_close)
736 evhttp_connection_reset(evcon);
738 if (TAILQ_FIRST(&evcon->requests) != NULL) {
740 * We have more requests; reset the connection
741 * and deal with the next request.
743 if (!evhttp_connected(evcon))
744 evhttp_connection_connect(evcon);
745 else
746 evhttp_request_dispatch(evcon);
747 } else if (!need_close) {
749 * The connection is going to be persistent, but we
750 * need to detect if the other side closes it.
752 evhttp_connection_start_detectclose(evcon);
754 } else {
756 * incoming connection - we need to leave the request on the
757 * connection so that we can reply to it.
759 evcon->state = EVCON_WRITING;
762 /* notify the user of the request */
763 (*req->cb)(req, req->cb_arg);
765 /* if this was an outgoing request, we own and it's done. so free it */
766 if (con_outgoing) {
767 evhttp_request_free(req);
772 * Handles reading from a chunked request.
773 * return ALL_DATA_READ:
774 * all data has been read
775 * return MORE_DATA_EXPECTED:
776 * more data is expected
777 * return DATA_CORRUPTED:
778 * data is corrupted
779 * return REQUEST_CANCLED:
780 * request was canceled by the user calling evhttp_cancel_request
783 static enum message_read_status
784 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
786 int len;
788 while ((len = EVBUFFER_LENGTH(buf)) > 0) {
789 if (req->ntoread < 0) {
790 /* Read chunk size */
791 ev_int64_t ntoread;
792 char *p = evbuffer_readline(buf);
793 char *endp;
794 int error;
795 if (p == NULL)
796 break;
797 /* the last chunk is on a new line? */
798 if (strlen(p) == 0) {
799 free(p);
800 continue;
802 ntoread = evutil_strtoll(p, &endp, 16);
803 error = (*p == '\0' ||
804 (*endp != '\0' && *endp != ' ') ||
805 ntoread < 0);
806 free(p);
807 if (error) {
808 /* could not get chunk size */
809 return (DATA_CORRUPTED);
811 req->ntoread = ntoread;
812 if (req->ntoread == 0) {
813 /* Last chunk */
814 return (ALL_DATA_READ);
816 continue;
819 /* don't have enough to complete a chunk; wait for more */
820 if (len < req->ntoread)
821 return (MORE_DATA_EXPECTED);
823 /* Completed chunk */
824 evbuffer_add(req->input_buffer,
825 EVBUFFER_DATA(buf), (size_t)req->ntoread);
826 evbuffer_drain(buf, (size_t)req->ntoread);
827 req->ntoread = -1;
828 if (req->chunk_cb != NULL) {
829 (*req->chunk_cb)(req, req->cb_arg);
830 evbuffer_drain(req->input_buffer,
831 EVBUFFER_LENGTH(req->input_buffer));
835 return (MORE_DATA_EXPECTED);
838 static void
839 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
841 struct evbuffer *buf = evcon->input_buffer;
843 switch (evhttp_parse_headers(req, buf)) {
844 case DATA_CORRUPTED:
845 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
846 break;
847 case ALL_DATA_READ:
848 event_del(&evcon->ev);
849 evhttp_connection_done(evcon);
850 break;
851 case MORE_DATA_EXPECTED:
852 default:
853 evhttp_add_event(&evcon->ev, evcon->timeout,
854 HTTP_READ_TIMEOUT);
855 break;
859 static void
860 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
862 struct evbuffer *buf = evcon->input_buffer;
864 if (req->chunked) {
865 switch (evhttp_handle_chunked_read(req, buf)) {
866 case ALL_DATA_READ:
867 /* finished last chunk */
868 evcon->state = EVCON_READING_TRAILER;
869 evhttp_read_trailer(evcon, req);
870 return;
871 case DATA_CORRUPTED:
872 /* corrupted data */
873 evhttp_connection_fail(evcon,
874 EVCON_HTTP_INVALID_HEADER);
875 return;
876 case REQUEST_CANCELED:
877 /* request canceled */
878 evhttp_request_free(req);
879 return;
880 case MORE_DATA_EXPECTED:
881 default:
882 break;
884 } else if (req->ntoread < 0) {
885 /* Read until connection close. */
886 evbuffer_add_buffer(req->input_buffer, buf);
887 } else if (EVBUFFER_LENGTH(buf) >= req->ntoread) {
888 /* Completed content length */
889 evbuffer_add(req->input_buffer, EVBUFFER_DATA(buf),
890 (size_t)req->ntoread);
891 evbuffer_drain(buf, (size_t)req->ntoread);
892 req->ntoread = 0;
893 evhttp_connection_done(evcon);
894 return;
896 /* Read more! */
897 event_set(&evcon->ev, evcon->fd, EV_READ, evhttp_read, evcon);
898 EVHTTP_BASE_SET(evcon, &evcon->ev);
899 evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
903 * Reads data into a buffer structure until no more data
904 * can be read on the file descriptor or we have read all
905 * the data that we wanted to read.
906 * Execute callback when done.
909 void
910 evhttp_read(int fd, short what, void *arg)
912 struct evhttp_connection *evcon = arg;
913 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
914 struct evbuffer *buf = evcon->input_buffer;
915 int n, len;
917 if (what == EV_TIMEOUT) {
918 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
919 return;
921 n = evbuffer_read(buf, fd, -1);
922 len = EVBUFFER_LENGTH(buf);
923 event_debug(("%s: got %d on %d\n", __func__, n, fd));
925 if (n == -1) {
926 if (errno != EINTR && errno != EAGAIN) {
927 event_debug(("%s: evbuffer_read", __func__));
928 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
929 } else {
930 evhttp_add_event(&evcon->ev, evcon->timeout,
931 HTTP_READ_TIMEOUT);
933 return;
934 } else if (n == 0) {
935 /* Connection closed */
936 evhttp_connection_done(evcon);
937 return;
940 switch (evcon->state) {
941 case EVCON_READING_FIRSTLINE:
942 evhttp_read_firstline(evcon, req);
943 break;
944 case EVCON_READING_HEADERS:
945 evhttp_read_header(evcon, req);
946 break;
947 case EVCON_READING_BODY:
948 evhttp_read_body(evcon, req);
949 break;
950 case EVCON_READING_TRAILER:
951 evhttp_read_trailer(evcon, req);
952 break;
953 case EVCON_DISCONNECTED:
954 case EVCON_CONNECTING:
955 case EVCON_IDLE:
956 case EVCON_WRITING:
957 default:
958 event_errx(1, "%s: illegal connection state %d",
959 __func__, evcon->state);
963 static void
964 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
966 /* This is after writing the request to the server */
967 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
968 assert(req != NULL);
970 assert(evcon->state == EVCON_WRITING);
972 /* We are done writing our header and are now expecting the response */
973 req->kind = EVHTTP_RESPONSE;
975 evhttp_start_read(evcon);
979 * Clean up a connection object
982 void
983 evhttp_connection_free(struct evhttp_connection *evcon)
985 struct evhttp_request *req;
987 /* notify interested parties that this connection is going down */
988 if (evcon->fd != -1) {
989 if (evhttp_connected(evcon) && evcon->closecb != NULL)
990 (*evcon->closecb)(evcon, evcon->closecb_arg);
993 /* remove all requests that might be queued on this connection */
994 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
995 TAILQ_REMOVE(&evcon->requests, req, next);
996 evhttp_request_free(req);
999 if (evcon->http_server != NULL) {
1000 struct evhttp *http = evcon->http_server;
1001 TAILQ_REMOVE(&http->connections, evcon, next);
1004 if (event_initialized(&evcon->close_ev))
1005 event_del(&evcon->close_ev);
1007 if (event_initialized(&evcon->ev))
1008 event_del(&evcon->ev);
1010 if (evcon->fd != -1)
1011 EVUTIL_CLOSESOCKET(evcon->fd);
1013 if (evcon->bind_address != NULL)
1014 free(evcon->bind_address);
1016 if (evcon->address != NULL)
1017 free(evcon->address);
1019 if (evcon->input_buffer != NULL)
1020 evbuffer_free(evcon->input_buffer);
1022 if (evcon->output_buffer != NULL)
1023 evbuffer_free(evcon->output_buffer);
1025 free(evcon);
1028 void
1029 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1030 const char *address)
1032 assert(evcon->state == EVCON_DISCONNECTED);
1033 if (evcon->bind_address)
1034 free(evcon->bind_address);
1035 if ((evcon->bind_address = strdup(address)) == NULL)
1036 event_err(1, "%s: strdup", __func__);
1039 void
1040 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1041 unsigned short port)
1043 assert(evcon->state == EVCON_DISCONNECTED);
1044 evcon->bind_port = port;
1047 static void
1048 evhttp_request_dispatch(struct evhttp_connection* evcon)
1050 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1052 /* this should not usually happy but it's possible */
1053 if (req == NULL)
1054 return;
1056 /* delete possible close detection events */
1057 evhttp_connection_stop_detectclose(evcon);
1059 /* we assume that the connection is connected already */
1060 assert(evcon->state == EVCON_IDLE);
1062 evcon->state = EVCON_WRITING;
1064 /* Create the header from the store arguments */
1065 evhttp_make_header(evcon, req);
1067 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1070 /* Reset our connection state */
1071 void
1072 evhttp_connection_reset(struct evhttp_connection *evcon)
1074 if (event_initialized(&evcon->ev))
1075 event_del(&evcon->ev);
1077 if (evcon->fd != -1) {
1078 /* inform interested parties about connection close */
1079 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1080 (*evcon->closecb)(evcon, evcon->closecb_arg);
1082 EVUTIL_CLOSESOCKET(evcon->fd);
1083 evcon->fd = -1;
1085 evcon->state = EVCON_DISCONNECTED;
1087 evbuffer_drain(evcon->input_buffer,
1088 EVBUFFER_LENGTH(evcon->input_buffer));
1089 evbuffer_drain(evcon->output_buffer,
1090 EVBUFFER_LENGTH(evcon->output_buffer));
1093 static void
1094 evhttp_detect_close_cb(int fd, short what, void *arg)
1096 struct evhttp_connection *evcon = arg;
1097 evhttp_connection_reset(evcon);
1100 static void
1101 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1103 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1105 if (event_initialized(&evcon->close_ev))
1106 event_del(&evcon->close_ev);
1107 event_set(&evcon->close_ev, evcon->fd, EV_READ,
1108 evhttp_detect_close_cb, evcon);
1109 EVHTTP_BASE_SET(evcon, &evcon->close_ev);
1110 event_add(&evcon->close_ev, NULL);
1113 static void
1114 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1116 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1117 event_del(&evcon->close_ev);
1120 static void
1121 evhttp_connection_retry(int fd, short what, void *arg)
1123 struct evhttp_connection *evcon = arg;
1125 evcon->state = EVCON_DISCONNECTED;
1126 evhttp_connection_connect(evcon);
1130 * Call back for asynchronous connection attempt.
1133 static void
1134 evhttp_connectioncb(int fd, short what, void *arg)
1136 struct evhttp_connection *evcon = arg;
1137 int error;
1138 socklen_t errsz = sizeof(error);
1140 if (what == EV_TIMEOUT) {
1141 event_debug(("%s: connection timeout for \"%s:%d\" on %d",
1142 __func__, evcon->address, evcon->port, evcon->fd));
1143 goto cleanup;
1146 /* Check if the connection completed */
1147 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1148 &errsz) == -1) {
1149 event_debug(("%s: getsockopt for \"%s:%d\" on %d",
1150 __func__, evcon->address, evcon->port, evcon->fd));
1151 goto cleanup;
1154 if (error) {
1155 event_debug(("%s: connect failed for \"%s:%d\" on %d: %s",
1156 __func__, evcon->address, evcon->port, evcon->fd,
1157 strerror(error)));
1158 goto cleanup;
1161 /* We are connected to the server now */
1162 event_debug(("%s: connected to \"%s:%d\" on %d\n",
1163 __func__, evcon->address, evcon->port, evcon->fd));
1165 /* Reset the retry count as we were successful in connecting */
1166 evcon->retry_cnt = 0;
1167 evcon->state = EVCON_IDLE;
1169 /* try to start requests that have queued up on this connection */
1170 evhttp_request_dispatch(evcon);
1171 return;
1173 cleanup:
1174 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1175 evtimer_set(&evcon->ev, evhttp_connection_retry, evcon);
1176 EVHTTP_BASE_SET(evcon, &evcon->ev);
1177 evhttp_add_event(&evcon->ev, MIN(3600, 2 << evcon->retry_cnt),
1178 HTTP_CONNECT_TIMEOUT);
1179 evcon->retry_cnt++;
1180 return;
1182 evhttp_connection_reset(evcon);
1184 /* for now, we just signal all requests by executing their callbacks */
1185 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1186 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1187 TAILQ_REMOVE(&evcon->requests, request, next);
1188 request->evcon = NULL;
1190 /* we might want to set an error here */
1191 request->cb(request, request->cb_arg);
1192 evhttp_request_free(request);
1197 * Check if we got a valid response code.
1200 static int
1201 evhttp_valid_response_code(int code)
1203 if (code == 0)
1204 return (0);
1206 return (1);
1209 /* Parses the status line of a web server */
1211 static int
1212 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1214 char *protocol;
1215 char *number;
1216 char *readable;
1218 protocol = strsep(&line, " ");
1219 if (line == NULL)
1220 return (-1);
1221 number = strsep(&line, " ");
1222 if (line == NULL)
1223 return (-1);
1224 readable = line;
1226 if (strcmp(protocol, "HTTP/1.0") == 0) {
1227 req->major = 1;
1228 req->minor = 0;
1229 } else if (strcmp(protocol, "HTTP/1.1") == 0) {
1230 req->major = 1;
1231 req->minor = 1;
1232 } else {
1233 event_debug(("%s: bad protocol \"%s\"",
1234 __func__, protocol));
1235 return (-1);
1238 req->response_code = atoi(number);
1239 if (!evhttp_valid_response_code(req->response_code)) {
1240 event_debug(("%s: bad response code \"%s\"",
1241 __func__, number));
1242 return (-1);
1245 if ((req->response_code_line = strdup(readable)) == NULL)
1246 event_err(1, "%s: strdup", __func__);
1248 return (0);
1251 /* Parse the first line of a HTTP request */
1253 static int
1254 evhttp_parse_request_line(struct evhttp_request *req, char *line)
1256 char *method;
1257 char *uri;
1258 char *version;
1260 /* Parse the request line */
1261 method = strsep(&line, " ");
1262 if (line == NULL)
1263 return (-1);
1264 uri = strsep(&line, " ");
1265 if (line == NULL)
1266 return (-1);
1267 version = strsep(&line, " ");
1268 if (line != NULL)
1269 return (-1);
1271 /* First line */
1272 if (strcmp(method, "GET") == 0) {
1273 req->type = EVHTTP_REQ_GET;
1274 } else if (strcmp(method, "POST") == 0) {
1275 req->type = EVHTTP_REQ_POST;
1276 } else if (strcmp(method, "HEAD") == 0) {
1277 req->type = EVHTTP_REQ_HEAD;
1278 } else {
1279 event_debug(("%s: bad method %s on request %p from %s",
1280 __func__, method, req, req->remote_host));
1281 return (-1);
1284 if (strcmp(version, "HTTP/1.0") == 0) {
1285 req->major = 1;
1286 req->minor = 0;
1287 } else if (strcmp(version, "HTTP/1.1") == 0) {
1288 req->major = 1;
1289 req->minor = 1;
1290 } else {
1291 event_debug(("%s: bad version %s on request %p from %s",
1292 __func__, version, req, req->remote_host));
1293 return (-1);
1296 if ((req->uri = strdup(uri)) == NULL) {
1297 event_debug(("%s: evhttp_decode_uri", __func__));
1298 return (-1);
1301 /* determine if it's a proxy request */
1302 if (strlen(req->uri) > 0 && req->uri[0] != '/')
1303 req->flags |= EVHTTP_PROXY_REQUEST;
1305 return (0);
1308 const char *
1309 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1311 struct evkeyval *header;
1313 TAILQ_FOREACH(header, headers, next) {
1314 if (strcasecmp(header->key, key) == 0)
1315 return (header->value);
1318 return (NULL);
1321 void
1322 evhttp_clear_headers(struct evkeyvalq *headers)
1324 struct evkeyval *header;
1326 for (header = TAILQ_FIRST(headers);
1327 header != NULL;
1328 header = TAILQ_FIRST(headers)) {
1329 TAILQ_REMOVE(headers, header, next);
1330 free(header->key);
1331 free(header->value);
1332 free(header);
1337 * Returns 0, if the header was successfully removed.
1338 * Returns -1, if the header could not be found.
1342 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1344 struct evkeyval *header;
1346 TAILQ_FOREACH(header, headers, next) {
1347 if (strcasecmp(header->key, key) == 0)
1348 break;
1351 if (header == NULL)
1352 return (-1);
1354 /* Free and remove the header that we found */
1355 TAILQ_REMOVE(headers, header, next);
1356 free(header->key);
1357 free(header->value);
1358 free(header);
1360 return (0);
1363 static int
1364 evhttp_header_is_valid_value(const char *value)
1366 const char *p = value;
1368 while ((p = strpbrk(p, "\r\n")) != NULL) {
1369 /* we really expect only one new line */
1370 p += strspn(p, "\r\n");
1371 /* we expect a space or tab for continuation */
1372 if (*p != ' ' && *p != '\t')
1373 return (0);
1375 return (1);
1379 evhttp_add_header(struct evkeyvalq *headers,
1380 const char *key, const char *value)
1382 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1384 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1385 /* drop illegal headers */
1386 event_debug(("%s: dropping illegal header key\n", __func__));
1387 return (-1);
1390 if (!evhttp_header_is_valid_value(value)) {
1391 event_debug(("%s: dropping illegal header value\n", __func__));
1392 return (-1);
1395 return (evhttp_add_header_internal(headers, key, value));
1398 static int
1399 evhttp_add_header_internal(struct evkeyvalq *headers,
1400 const char *key, const char *value)
1402 struct evkeyval *header = calloc(1, sizeof(struct evkeyval));
1403 if (header == NULL) {
1404 event_warn("%s: calloc", __func__);
1405 return (-1);
1407 if ((header->key = strdup(key)) == NULL) {
1408 free(header);
1409 event_warn("%s: strdup", __func__);
1410 return (-1);
1412 if ((header->value = strdup(value)) == NULL) {
1413 free(header->key);
1414 free(header);
1415 event_warn("%s: strdup", __func__);
1416 return (-1);
1419 TAILQ_INSERT_TAIL(headers, header, next);
1421 return (0);
1425 * Parses header lines from a request or a response into the specified
1426 * request object given an event buffer.
1428 * Returns
1429 * DATA_CORRUPTED on error
1430 * MORE_DATA_EXPECTED when we need to read more headers
1431 * ALL_DATA_READ when all headers have been read.
1434 enum message_read_status
1435 evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
1437 char *line;
1438 enum message_read_status status = ALL_DATA_READ;
1440 line = evbuffer_readline(buffer);
1441 if (line == NULL)
1442 return (MORE_DATA_EXPECTED);
1444 switch (req->kind) {
1445 case EVHTTP_REQUEST:
1446 if (evhttp_parse_request_line(req, line) == -1)
1447 status = DATA_CORRUPTED;
1448 break;
1449 case EVHTTP_RESPONSE:
1450 if (evhttp_parse_response_line(req, line) == -1)
1451 status = DATA_CORRUPTED;
1452 break;
1453 default:
1454 status = DATA_CORRUPTED;
1457 free(line);
1458 return (status);
1461 static int
1462 evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
1464 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
1465 char *newval;
1466 size_t old_len, line_len;
1468 if (header == NULL)
1469 return (-1);
1471 old_len = strlen(header->value);
1472 line_len = strlen(line);
1474 newval = realloc(header->value, old_len + line_len + 1);
1475 if (newval == NULL)
1476 return (-1);
1478 memcpy(newval + old_len, line, line_len + 1);
1479 header->value = newval;
1481 return (0);
1484 enum message_read_status
1485 evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
1487 char *line;
1488 enum message_read_status status = MORE_DATA_EXPECTED;
1490 struct evkeyvalq* headers = req->input_headers;
1491 while ((line = evbuffer_readline(buffer))
1492 != NULL) {
1493 char *skey, *svalue;
1495 if (*line == '\0') { /* Last header - Done */
1496 status = ALL_DATA_READ;
1497 free(line);
1498 break;
1501 /* Check if this is a continuation line */
1502 if (*line == ' ' || *line == '\t') {
1503 if (evhttp_append_to_last_header(headers, line) == -1)
1504 goto error;
1505 free(line);
1506 continue;
1509 /* Processing of header lines */
1510 svalue = line;
1511 skey = strsep(&svalue, ":");
1512 if (svalue == NULL)
1513 goto error;
1515 svalue += strspn(svalue, " ");
1517 if (evhttp_add_header(headers, skey, svalue) == -1)
1518 goto error;
1520 free(line);
1523 return (status);
1525 error:
1526 free(line);
1527 return (DATA_CORRUPTED);
1530 static int
1531 evhttp_get_body_length(struct evhttp_request *req)
1533 struct evkeyvalq *headers = req->input_headers;
1534 const char *content_length;
1535 const char *connection;
1537 content_length = evhttp_find_header(headers, "Content-Length");
1538 connection = evhttp_find_header(headers, "Connection");
1540 if (content_length == NULL && connection == NULL)
1541 req->ntoread = -1;
1542 else if (content_length == NULL &&
1543 strcasecmp(connection, "Close") != 0) {
1544 /* Bad combination, we don't know when it will end */
1545 event_warnx("%s: we got no content length, but the "
1546 "server wants to keep the connection open: %s.",
1547 __func__, connection);
1548 return (-1);
1549 } else if (content_length == NULL) {
1550 req->ntoread = -1;
1551 } else {
1552 char *endp;
1553 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
1554 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
1555 event_debug(("%s: illegal content length: %s",
1556 __func__, content_length));
1557 return (-1);
1559 req->ntoread = ntoread;
1562 event_debug(("%s: bytes to read: %lld (in buffer %ld)\n",
1563 __func__, req->ntoread,
1564 EVBUFFER_LENGTH(req->evcon->input_buffer)));
1566 return (0);
1569 static void
1570 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1572 const char *xfer_enc;
1574 /* If this is a request without a body, then we are done */
1575 if (req->kind == EVHTTP_REQUEST && req->type != EVHTTP_REQ_POST) {
1576 evhttp_connection_done(evcon);
1577 return;
1579 evcon->state = EVCON_READING_BODY;
1580 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
1581 if (xfer_enc != NULL && strcasecmp(xfer_enc, "chunked") == 0) {
1582 req->chunked = 1;
1583 req->ntoread = -1;
1584 } else {
1585 if (evhttp_get_body_length(req) == -1) {
1586 evhttp_connection_fail(evcon,
1587 EVCON_HTTP_INVALID_HEADER);
1588 return;
1591 evhttp_read_body(evcon, req);
1594 static void
1595 evhttp_read_firstline(struct evhttp_connection *evcon,
1596 struct evhttp_request *req)
1598 enum message_read_status res;
1600 res = evhttp_parse_firstline(req, evcon->input_buffer);
1601 if (res == DATA_CORRUPTED) {
1602 /* Error while reading, terminate */
1603 event_debug(("%s: bad header lines on %d\n",
1604 __func__, evcon->fd));
1605 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1606 return;
1607 } else if (res == MORE_DATA_EXPECTED) {
1608 /* Need more header lines */
1609 evhttp_add_event(&evcon->ev,
1610 evcon->timeout, HTTP_READ_TIMEOUT);
1611 return;
1614 evcon->state = EVCON_READING_HEADERS;
1615 evhttp_read_header(evcon, req);
1618 static void
1619 evhttp_read_header(struct evhttp_connection *evcon, struct evhttp_request *req)
1621 enum message_read_status res;
1622 int fd = evcon->fd;
1624 res = evhttp_parse_headers(req, evcon->input_buffer);
1625 if (res == DATA_CORRUPTED) {
1626 /* Error while reading, terminate */
1627 event_debug(("%s: bad header lines on %d\n", __func__, fd));
1628 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1629 return;
1630 } else if (res == MORE_DATA_EXPECTED) {
1631 /* Need more header lines */
1632 evhttp_add_event(&evcon->ev,
1633 evcon->timeout, HTTP_READ_TIMEOUT);
1634 return;
1637 /* Done reading headers, do the real work */
1638 switch (req->kind) {
1639 case EVHTTP_REQUEST:
1640 event_debug(("%s: checking for post data on %d\n",
1641 __func__, fd));
1642 evhttp_get_body(evcon, req);
1643 break;
1645 case EVHTTP_RESPONSE:
1646 if (req->response_code == HTTP_NOCONTENT ||
1647 req->response_code == HTTP_NOTMODIFIED ||
1648 (req->response_code >= 100 && req->response_code < 200)) {
1649 event_debug(("%s: skipping body for code %d\n",
1650 __func__, req->response_code));
1651 evhttp_connection_done(evcon);
1652 } else {
1653 event_debug(("%s: start of read body for %s on %d\n",
1654 __func__, req->remote_host, fd));
1655 evhttp_get_body(evcon, req);
1657 break;
1659 default:
1660 event_warnx("%s: bad header on %d", __func__, fd);
1661 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1662 break;
1667 * Creates a TCP connection to the specified port and executes a callback
1668 * when finished. Failure or sucess is indicate by the passed connection
1669 * object.
1671 * Although this interface accepts a hostname, it is intended to take
1672 * only numeric hostnames so that non-blocking DNS resolution can
1673 * happen elsewhere.
1676 struct evhttp_connection *
1677 evhttp_connection_new(const char *address, unsigned short port)
1679 struct evhttp_connection *evcon = NULL;
1681 event_debug(("Attempting connection to %s:%d\n", address, port));
1683 if ((evcon = calloc(1, sizeof(struct evhttp_connection))) == NULL) {
1684 event_warn("%s: calloc failed", __func__);
1685 goto error;
1688 evcon->fd = -1;
1689 evcon->port = port;
1691 evcon->timeout = -1;
1692 evcon->retry_cnt = evcon->retry_max = 0;
1694 if ((evcon->address = strdup(address)) == NULL) {
1695 event_warn("%s: strdup failed", __func__);
1696 goto error;
1699 if ((evcon->input_buffer = evbuffer_new()) == NULL) {
1700 event_warn("%s: evbuffer_new failed", __func__);
1701 goto error;
1704 if ((evcon->output_buffer = evbuffer_new()) == NULL) {
1705 event_warn("%s: evbuffer_new failed", __func__);
1706 goto error;
1709 evcon->state = EVCON_DISCONNECTED;
1710 TAILQ_INIT(&evcon->requests);
1712 return (evcon);
1714 error:
1715 if (evcon != NULL)
1716 evhttp_connection_free(evcon);
1717 return (NULL);
1720 void evhttp_connection_set_base(struct evhttp_connection *evcon,
1721 struct event_base *base)
1723 assert(evcon->base == NULL);
1724 assert(evcon->state == EVCON_DISCONNECTED);
1725 evcon->base = base;
1728 void
1729 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
1730 int timeout_in_secs)
1732 evcon->timeout = timeout_in_secs;
1735 void
1736 evhttp_connection_set_retries(struct evhttp_connection *evcon,
1737 int retry_max)
1739 evcon->retry_max = retry_max;
1742 void
1743 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
1744 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
1746 evcon->closecb = cb;
1747 evcon->closecb_arg = cbarg;
1750 void
1751 evhttp_connection_get_peer(struct evhttp_connection *evcon,
1752 char **address, u_short *port)
1754 *address = evcon->address;
1755 *port = evcon->port;
1759 evhttp_connection_connect(struct evhttp_connection *evcon)
1761 if (evcon->state == EVCON_CONNECTING)
1762 return (0);
1764 evhttp_connection_reset(evcon);
1766 assert(!(evcon->flags & EVHTTP_CON_INCOMING));
1767 evcon->flags |= EVHTTP_CON_OUTGOING;
1769 evcon->fd = bind_socket(
1770 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
1771 if (evcon->fd == -1) {
1772 event_debug(("%s: failed to bind to \"%s\"",
1773 __func__, evcon->bind_address));
1774 return (-1);
1777 if (socket_connect(evcon->fd, evcon->address, evcon->port) == -1) {
1778 EVUTIL_CLOSESOCKET(evcon->fd); evcon->fd = -1;
1779 return (-1);
1782 /* Set up a callback for successful connection setup */
1783 event_set(&evcon->ev, evcon->fd, EV_WRITE, evhttp_connectioncb, evcon);
1784 EVHTTP_BASE_SET(evcon, &evcon->ev);
1785 evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_CONNECT_TIMEOUT);
1787 evcon->state = EVCON_CONNECTING;
1789 return (0);
1793 * Starts an HTTP request on the provided evhttp_connection object.
1794 * If the connection object is not connected to the web server already,
1795 * this will start the connection.
1799 evhttp_make_request(struct evhttp_connection *evcon,
1800 struct evhttp_request *req,
1801 enum evhttp_cmd_type type, const char *uri)
1803 /* We are making a request */
1804 req->kind = EVHTTP_REQUEST;
1805 req->type = type;
1806 if (req->uri != NULL)
1807 free(req->uri);
1808 if ((req->uri = strdup(uri)) == NULL)
1809 event_err(1, "%s: strdup", __func__);
1811 /* Set the protocol version if it is not supplied */
1812 if (!req->major && !req->minor) {
1813 req->major = 1;
1814 req->minor = 1;
1817 assert(req->evcon == NULL);
1818 req->evcon = evcon;
1819 assert(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
1821 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
1823 /* If the connection object is not connected; make it so */
1824 if (!evhttp_connected(evcon))
1825 return (evhttp_connection_connect(evcon));
1828 * If it's connected already and we are the first in the queue,
1829 * then we can dispatch this request immediately. Otherwise, it
1830 * will be dispatched once the pending requests are completed.
1832 if (TAILQ_FIRST(&evcon->requests) == req)
1833 evhttp_request_dispatch(evcon);
1835 return (0);
1839 * Reads data from file descriptor into request structure
1840 * Request structure needs to be set up correctly.
1843 void
1844 evhttp_start_read(struct evhttp_connection *evcon)
1846 /* Set up an event to read the headers */
1847 if (event_initialized(&evcon->ev))
1848 event_del(&evcon->ev);
1849 event_set(&evcon->ev, evcon->fd, EV_READ, evhttp_read, evcon);
1850 EVHTTP_BASE_SET(evcon, &evcon->ev);
1852 evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
1853 evcon->state = EVCON_READING_FIRSTLINE;
1856 static void
1857 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
1859 int need_close;
1860 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1861 TAILQ_REMOVE(&evcon->requests, req, next);
1863 /* delete possible close detection events */
1864 evhttp_connection_stop_detectclose(evcon);
1866 need_close =
1867 (req->minor == 0 &&
1868 !evhttp_is_connection_keepalive(req->input_headers))||
1869 evhttp_is_connection_close(req->flags, req->input_headers) ||
1870 evhttp_is_connection_close(req->flags, req->output_headers);
1872 assert(req->flags & EVHTTP_REQ_OWN_CONNECTION);
1873 evhttp_request_free(req);
1875 if (need_close) {
1876 evhttp_connection_free(evcon);
1877 return;
1880 /* we have a persistent connection; try to accept another request. */
1881 if (evhttp_associate_new_request_with_connection(evcon) == -1)
1882 evhttp_connection_free(evcon);
1886 * Returns an error page.
1889 void
1890 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
1892 #define ERR_FORMAT "<HTML><HEAD>\n" \
1893 "<TITLE>%d %s</TITLE>\n" \
1894 "</HEAD><BODY>\n" \
1895 "<H1>Method Not Implemented</H1>\n" \
1896 "Invalid method in request<P>\n" \
1897 "</BODY></HTML>\n"
1899 struct evbuffer *buf = evbuffer_new();
1901 /* close the connection on error */
1902 evhttp_add_header(req->output_headers, "Connection", "close");
1904 evhttp_response_code(req, error, reason);
1906 evbuffer_add_printf(buf, ERR_FORMAT, error, reason);
1908 evhttp_send_page(req, buf);
1910 evbuffer_free(buf);
1911 #undef ERR_FORMAT
1914 /* Requires that headers and response code are already set up */
1916 static inline void
1917 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
1919 struct evhttp_connection *evcon = req->evcon;
1921 assert(TAILQ_FIRST(&evcon->requests) == req);
1923 /* xxx: not sure if we really should expose the data buffer this way */
1924 if (databuf != NULL)
1925 evbuffer_add_buffer(req->output_buffer, databuf);
1927 /* Adds headers to the response */
1928 evhttp_make_header(evcon, req);
1930 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
1933 void
1934 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
1935 struct evbuffer *databuf)
1937 evhttp_response_code(req, code, reason);
1939 evhttp_send(req, databuf);
1942 void
1943 evhttp_send_reply_start(struct evhttp_request *req, int code,
1944 const char *reason)
1946 evhttp_response_code(req, code, reason);
1947 if (req->major == 1 && req->minor == 1) {
1948 /* use chunked encoding for HTTP/1.1 */
1949 evhttp_add_header(req->output_headers, "Transfer-Encoding",
1950 "chunked");
1951 req->chunked = 1;
1953 evhttp_make_header(req->evcon, req);
1954 evhttp_write_buffer(req->evcon, NULL, NULL);
1957 void
1958 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
1960 if (req->chunked) {
1961 evbuffer_add_printf(req->evcon->output_buffer, "%x\r\n",
1962 (unsigned)EVBUFFER_LENGTH(databuf));
1964 evbuffer_add_buffer(req->evcon->output_buffer, databuf);
1965 if (req->chunked) {
1966 evbuffer_add(req->evcon->output_buffer, "\r\n", 2);
1968 evhttp_write_buffer(req->evcon, NULL, NULL);
1971 void
1972 evhttp_send_reply_end(struct evhttp_request *req)
1974 struct evhttp_connection *evcon = req->evcon;
1976 if (req->chunked) {
1977 evbuffer_add(req->evcon->output_buffer, "0\r\n\r\n", 5);
1978 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
1979 req->chunked = 0;
1980 } else if (!event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL)) {
1981 /* let the connection know that we are done with the request */
1982 evhttp_send_done(evcon, NULL);
1983 } else {
1984 /* make the callback execute after all data has been written */
1985 evcon->cb = evhttp_send_done;
1986 evcon->cb_arg = NULL;
1990 void
1991 evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
1993 req->kind = EVHTTP_RESPONSE;
1994 req->response_code = code;
1995 if (req->response_code_line != NULL)
1996 free(req->response_code_line);
1997 req->response_code_line = strdup(reason);
2000 void
2001 evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
2003 if (!req->major || !req->minor) {
2004 req->major = 1;
2005 req->minor = 1;
2008 if (req->kind != EVHTTP_RESPONSE)
2009 evhttp_response_code(req, 200, "OK");
2011 evhttp_clear_headers(req->output_headers);
2012 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
2013 evhttp_add_header(req->output_headers, "Connection", "close");
2015 evhttp_send(req, databuf);
2018 static const char uri_chars[256] = {
2019 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2020 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2021 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2022 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0,
2023 /* 64 */
2024 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2025 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
2026 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2027 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
2028 /* 128 */
2029 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2030 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2031 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2032 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2033 /* 192 */
2034 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2035 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2036 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2037 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2041 * Helper functions to encode/decode a URI.
2042 * The returned string must be freed by the caller.
2044 char *
2045 evhttp_encode_uri(const char *uri)
2047 struct evbuffer *buf = evbuffer_new();
2048 char *p;
2050 for (p = (char *)uri; *p != '\0'; p++) {
2051 if (uri_chars[(u_char)(*p)]) {
2052 evbuffer_add(buf, p, 1);
2053 } else {
2054 evbuffer_add_printf(buf, "%%%02X", (u_char)(*p));
2057 evbuffer_add(buf, "", 1);
2058 p = strdup((char *)EVBUFFER_DATA(buf));
2059 evbuffer_free(buf);
2061 return (p);
2065 * @param always_decode_plus: when true we transform plus to space even
2066 * if we have not seen a ?.
2068 static int
2069 evhttp_decode_uri_internal(
2070 const char *uri, size_t length, char *ret, int always_decode_plus)
2072 char c;
2073 int i, j, in_query = always_decode_plus;
2075 for (i = j = 0; uri[i] != '\0'; i++) {
2076 c = uri[i];
2077 if (c == '?') {
2078 in_query = 1;
2079 } else if (c == '+' && in_query) {
2080 c = ' ';
2081 } else if (c == '%' && isxdigit((unsigned char)uri[i+1]) &&
2082 isxdigit((unsigned char)uri[i+2])) {
2083 char tmp[] = { uri[i+1], uri[i+2], '\0' };
2084 c = (char)strtol(tmp, NULL, 16);
2085 i += 2;
2087 ret[j++] = c;
2089 ret[j] = '\0';
2091 return (j);
2094 char *
2095 evhttp_decode_uri(const char *uri)
2097 char *ret;
2099 if ((ret = malloc(strlen(uri) + 1)) == NULL)
2100 event_err(1, "%s: malloc(%lu)", __func__,
2101 (unsigned long)(strlen(uri) + 1));
2103 evhttp_decode_uri_internal(uri, strlen(uri),
2104 ret, 0 /*always_decode_plus*/);
2106 return (ret);
2110 * Helper function to parse out arguments in a query.
2111 * The arguments are separated by key and value.
2114 void
2115 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
2117 char *line;
2118 char *argument;
2119 char *p;
2121 TAILQ_INIT(headers);
2123 /* No arguments - we are done */
2124 if (strchr(uri, '?') == NULL)
2125 return;
2127 if ((line = strdup(uri)) == NULL)
2128 event_err(1, "%s: strdup", __func__);
2131 argument = line;
2133 /* We already know that there has to be a ? */
2134 strsep(&argument, "?");
2136 p = argument;
2137 while (p != NULL && *p != '\0') {
2138 char *key, *value, *decoded_value;
2139 argument = strsep(&p, "&");
2141 value = argument;
2142 key = strsep(&value, "=");
2143 if (value == NULL)
2144 goto error;
2146 if ((decoded_value = malloc(strlen(value) + 1)) == NULL)
2147 event_err(1, "%s: malloc", __func__);
2149 evhttp_decode_uri_internal(value, strlen(value),
2150 decoded_value, 1 /*always_decode_plus*/);
2151 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
2152 evhttp_add_header_internal(headers, key, decoded_value);
2153 free(decoded_value);
2156 error:
2157 free(line);
2160 static struct evhttp_cb *
2161 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
2163 struct evhttp_cb *cb;
2164 size_t offset = 0;
2166 /* Test for different URLs */
2167 char *p = strchr(req->uri, '?');
2168 if (p != NULL)
2169 offset = (size_t)(p - req->uri);
2171 TAILQ_FOREACH(cb, callbacks, next) {
2172 int res = 0;
2173 if (p == NULL) {
2174 res = strcmp(cb->what, req->uri) == 0;
2175 } else {
2176 res = ((strncmp(cb->what, req->uri, offset) == 0) &&
2177 (cb->what[offset] == '\0'));
2180 if (res)
2181 return (cb);
2184 return (NULL);
2187 static void
2188 evhttp_handle_request(struct evhttp_request *req, void *arg)
2190 struct evhttp *http = arg;
2191 struct evhttp_cb *cb = NULL;
2193 if (req->uri == NULL) {
2194 evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
2195 return;
2198 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
2199 (*cb->cb)(req, cb->cbarg);
2200 return;
2203 /* Generic call back */
2204 if (http->gencb) {
2205 (*http->gencb)(req, http->gencbarg);
2206 return;
2207 } else {
2208 /* We need to send a 404 here */
2209 #define ERR_FORMAT "<html><head>" \
2210 "<title>404 Not Found</title>" \
2211 "</head><body>" \
2212 "<h1>Not Found</h1>" \
2213 "<p>The requested URL %s was not found on this server.</p>"\
2214 "</body></html>\n"
2216 char *escaped_html = evhttp_htmlescape(req->uri);
2217 struct evbuffer *buf = evbuffer_new();
2219 evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
2221 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
2223 free(escaped_html);
2225 evhttp_send_page(req, buf);
2227 evbuffer_free(buf);
2228 #undef ERR_FORMAT
2232 static void
2233 accept_socket(int fd, short what, void *arg)
2235 struct evhttp *http = arg;
2236 struct sockaddr_storage ss;
2237 socklen_t addrlen = sizeof(ss);
2238 int nfd;
2240 if ((nfd = accept(fd, (struct sockaddr *)&ss, &addrlen)) == -1) {
2241 if (errno != EAGAIN && errno != EINTR)
2242 event_warn("%s: bad accept", __func__);
2243 return;
2245 if (evutil_make_socket_nonblocking(nfd) < 0)
2246 return;
2248 evhttp_get_request(http, nfd, (struct sockaddr *)&ss, addrlen);
2252 evhttp_bind_socket(struct evhttp *http, const char *address, u_short port)
2254 int fd;
2255 int res;
2257 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
2258 return (-1);
2260 if (listen(fd, 128) == -1) {
2261 event_warn("%s: listen", __func__);
2262 EVUTIL_CLOSESOCKET(fd);
2263 return (-1);
2266 res = evhttp_accept_socket(http, fd);
2268 if (res != -1)
2269 event_debug(("Bound to port %d - Awaiting connections ... ",
2270 port));
2272 return (res);
2276 evhttp_accept_socket(struct evhttp *http, int fd)
2278 struct evhttp_bound_socket *bound;
2279 struct event *ev;
2280 int res;
2282 bound = malloc(sizeof(struct evhttp_bound_socket));
2283 if (bound == NULL)
2284 return (-1);
2286 ev = &bound->bind_ev;
2288 /* Schedule the socket for accepting */
2289 event_set(ev, fd, EV_READ | EV_PERSIST, accept_socket, http);
2290 EVHTTP_BASE_SET(http, ev);
2292 res = event_add(ev, NULL);
2294 if (res == -1) {
2295 free(bound);
2296 return (-1);
2299 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
2301 return (0);
2304 static struct evhttp*
2305 evhttp_new_object(void)
2307 struct evhttp *http = NULL;
2309 if ((http = calloc(1, sizeof(struct evhttp))) == NULL) {
2310 event_warn("%s: calloc", __func__);
2311 return (NULL);
2314 http->timeout = -1;
2316 TAILQ_INIT(&http->sockets);
2317 TAILQ_INIT(&http->callbacks);
2318 TAILQ_INIT(&http->connections);
2320 return (http);
2323 struct evhttp *
2324 evhttp_new(struct event_base *base)
2326 struct evhttp *http = evhttp_new_object();
2328 http->base = base;
2330 return (http);
2334 * Start a web server on the specified address and port.
2337 struct evhttp *
2338 evhttp_start(const char *address, u_short port)
2340 struct evhttp *http = evhttp_new_object();
2342 if (evhttp_bind_socket(http, address, port) == -1) {
2343 free(http);
2344 return (NULL);
2347 return (http);
2350 void
2351 evhttp_free(struct evhttp* http)
2353 struct evhttp_cb *http_cb;
2354 struct evhttp_connection *evcon;
2355 struct evhttp_bound_socket *bound;
2356 int fd;
2358 /* Remove the accepting part */
2359 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
2360 TAILQ_REMOVE(&http->sockets, bound, next);
2362 fd = bound->bind_ev.ev_fd;
2363 event_del(&bound->bind_ev);
2364 EVUTIL_CLOSESOCKET(fd);
2366 free(bound);
2369 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
2370 /* evhttp_connection_free removes the connection */
2371 evhttp_connection_free(evcon);
2374 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
2375 TAILQ_REMOVE(&http->callbacks, http_cb, next);
2376 free(http_cb->what);
2377 free(http_cb);
2380 free(http);
2383 void
2384 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
2386 http->timeout = timeout_in_secs;
2389 void
2390 evhttp_set_cb(struct evhttp *http, const char *uri,
2391 void (*cb)(struct evhttp_request *, void *), void *cbarg)
2393 struct evhttp_cb *http_cb;
2395 if ((http_cb = calloc(1, sizeof(struct evhttp_cb))) == NULL)
2396 event_err(1, "%s: calloc", __func__);
2398 http_cb->what = strdup(uri);
2399 http_cb->cb = cb;
2400 http_cb->cbarg = cbarg;
2402 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
2406 evhttp_del_cb(struct evhttp *http, const char *uri)
2408 struct evhttp_cb *http_cb;
2410 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
2411 if (strcmp(http_cb->what, uri) == 0)
2412 break;
2414 if (http_cb == NULL)
2415 return (-1);
2417 TAILQ_REMOVE(&http->callbacks, http_cb, next);
2418 free(http_cb->what);
2419 free(http_cb);
2421 return (0);
2424 void
2425 evhttp_set_gencb(struct evhttp *http,
2426 void (*cb)(struct evhttp_request *, void *), void *cbarg)
2428 http->gencb = cb;
2429 http->gencbarg = cbarg;
2433 * Request related functions
2436 struct evhttp_request *
2437 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
2439 struct evhttp_request *req = NULL;
2441 /* Allocate request structure */
2442 if ((req = calloc(1, sizeof(struct evhttp_request))) == NULL) {
2443 event_warn("%s: calloc", __func__);
2444 goto error;
2447 req->kind = EVHTTP_RESPONSE;
2448 req->input_headers = calloc(1, sizeof(struct evkeyvalq));
2449 if (req->input_headers == NULL) {
2450 event_warn("%s: calloc", __func__);
2451 goto error;
2453 TAILQ_INIT(req->input_headers);
2455 req->output_headers = calloc(1, sizeof(struct evkeyvalq));
2456 if (req->output_headers == NULL) {
2457 event_warn("%s: calloc", __func__);
2458 goto error;
2460 TAILQ_INIT(req->output_headers);
2462 if ((req->input_buffer = evbuffer_new()) == NULL) {
2463 event_warn("%s: evbuffer_new", __func__);
2464 goto error;
2467 if ((req->output_buffer = evbuffer_new()) == NULL) {
2468 event_warn("%s: evbuffer_new", __func__);
2469 goto error;
2472 req->cb = cb;
2473 req->cb_arg = arg;
2475 return (req);
2477 error:
2478 if (req != NULL)
2479 evhttp_request_free(req);
2480 return (NULL);
2483 void
2484 evhttp_request_free(struct evhttp_request *req)
2486 if (req->remote_host != NULL)
2487 free(req->remote_host);
2488 if (req->uri != NULL)
2489 free(req->uri);
2490 if (req->response_code_line != NULL)
2491 free(req->response_code_line);
2493 evhttp_clear_headers(req->input_headers);
2494 free(req->input_headers);
2496 evhttp_clear_headers(req->output_headers);
2497 free(req->output_headers);
2499 if (req->input_buffer != NULL)
2500 evbuffer_free(req->input_buffer);
2502 if (req->output_buffer != NULL)
2503 evbuffer_free(req->output_buffer);
2505 free(req);
2508 void
2509 evhttp_request_set_chunked_cb(struct evhttp_request *req,
2510 void (*cb)(struct evhttp_request *, void *))
2512 req->chunk_cb = cb;
2516 * Allows for inspection of the request URI
2519 const char *
2520 evhttp_request_uri(struct evhttp_request *req) {
2521 if (req->uri == NULL)
2522 event_debug(("%s: request %p has no uri\n", __func__, req));
2523 return (req->uri);
2527 * Takes a file descriptor to read a request from.
2528 * The callback is executed once the whole request has been read.
2531 static struct evhttp_connection*
2532 evhttp_get_request_connection(
2533 struct evhttp* http,
2534 int fd, struct sockaddr *sa, socklen_t salen)
2536 struct evhttp_connection *evcon;
2537 char *hostname = NULL, *portname = NULL;
2539 name_from_addr(sa, salen, &hostname, &portname);
2540 if (hostname == NULL || portname == NULL) {
2541 if (hostname) free(hostname);
2542 if (portname) free(portname);
2543 return (NULL);
2546 event_debug(("%s: new request from %s:%s on %d\n",
2547 __func__, hostname, portname, fd));
2549 /* we need a connection object to put the http request on */
2550 evcon = evhttp_connection_new(hostname, atoi(portname));
2551 free(hostname);
2552 free(portname);
2553 if (evcon == NULL)
2554 return (NULL);
2556 /* associate the base if we have one*/
2557 evhttp_connection_set_base(evcon, http->base);
2559 evcon->flags |= EVHTTP_CON_INCOMING;
2560 evcon->state = EVCON_READING_FIRSTLINE;
2562 evcon->fd = fd;
2564 return (evcon);
2567 static int
2568 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
2570 struct evhttp *http = evcon->http_server;
2571 struct evhttp_request *req;
2572 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
2573 return (-1);
2575 req->evcon = evcon; /* the request ends up owning the connection */
2576 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
2578 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2580 req->kind = EVHTTP_REQUEST;
2582 if ((req->remote_host = strdup(evcon->address)) == NULL)
2583 event_err(1, "%s: strdup", __func__);
2584 req->remote_port = evcon->port;
2586 evhttp_start_read(evcon);
2588 return (0);
2591 void
2592 evhttp_get_request(struct evhttp *http, int fd,
2593 struct sockaddr *sa, socklen_t salen)
2595 struct evhttp_connection *evcon;
2597 evcon = evhttp_get_request_connection(http, fd, sa, salen);
2598 if (evcon == NULL)
2599 return;
2601 /* the timeout can be used by the server to close idle connections */
2602 if (http->timeout != -1)
2603 evhttp_connection_set_timeout(evcon, http->timeout);
2606 * if we want to accept more than one request on a connection,
2607 * we need to know which http server it belongs to.
2609 evcon->http_server = http;
2610 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
2612 if (evhttp_associate_new_request_with_connection(evcon) == -1)
2613 evhttp_connection_free(evcon);
2618 * Network helper functions that we do not want to export to the rest of
2619 * the world.
2621 #if 0 /* Unused */
2622 static struct addrinfo *
2623 addr_from_name(char *address)
2625 #ifdef HAVE_GETADDRINFO
2626 struct addrinfo ai, *aitop;
2627 int ai_result;
2629 memset(&ai, 0, sizeof(ai));
2630 ai.ai_family = AF_INET;
2631 ai.ai_socktype = SOCK_RAW;
2632 ai.ai_flags = 0;
2633 if ((ai_result = getaddrinfo(address, NULL, &ai, &aitop)) != 0) {
2634 if ( ai_result == EAI_SYSTEM )
2635 event_warn("getaddrinfo");
2636 else
2637 event_warnx("getaddrinfo: %s", gai_strerror(ai_result));
2640 return (aitop);
2641 #else
2642 assert(0);
2643 return NULL; /* XXXXX Use gethostbyname, if this function is ever used. */
2644 #endif
2646 #endif
2648 static void
2649 name_from_addr(struct sockaddr *sa, socklen_t salen,
2650 char **phost, char **pport)
2652 char ntop[NI_MAXHOST];
2653 char strport[NI_MAXSERV];
2654 int ni_result;
2656 #ifdef HAVE_GETNAMEINFO
2657 ni_result = getnameinfo(sa, salen,
2658 ntop, sizeof(ntop), strport, sizeof(strport),
2659 NI_NUMERICHOST|NI_NUMERICSERV);
2661 if (ni_result != 0) {
2662 if (ni_result == EAI_SYSTEM)
2663 event_err(1, "getnameinfo failed");
2664 else
2665 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
2666 return;
2668 #else
2669 ni_result = fake_getnameinfo(sa, salen,
2670 ntop, sizeof(ntop), strport, sizeof(strport),
2671 NI_NUMERICHOST|NI_NUMERICSERV);
2672 if (ni_result != 0)
2673 return;
2674 #endif
2675 *phost = strdup(ntop);
2676 *pport = strdup(strport);
2679 /* Create a non-blocking socket and bind it */
2680 /* todo: rename this function */
2681 static int
2682 bind_socket_ai(struct addrinfo *ai, int reuse)
2684 int fd, on = 1, r;
2685 int serrno;
2687 /* Create listen socket */
2688 fd = socket(AF_INET, SOCK_STREAM, 0);
2689 if (fd == -1) {
2690 event_warn("socket");
2691 return (-1);
2694 if (evutil_make_socket_nonblocking(fd) < 0)
2695 goto out;
2697 #ifndef WIN32
2698 if (fcntl(fd, F_SETFD, 1) == -1) {
2699 event_warn("fcntl(F_SETFD)");
2700 goto out;
2702 #endif
2704 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
2705 if (reuse) {
2706 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
2707 (void *)&on, sizeof(on));
2710 if (ai != NULL) {
2711 r = bind(fd, ai->ai_addr, ai->ai_addrlen);
2712 if (r == -1)
2713 goto out;
2716 return (fd);
2718 out:
2719 serrno = EVUTIL_SOCKET_ERROR();
2720 EVUTIL_CLOSESOCKET(fd);
2721 EVUTIL_SET_SOCKET_ERROR(serrno);
2722 return (-1);
2725 static struct addrinfo *
2726 make_addrinfo(const char *address, u_short port)
2728 struct addrinfo *aitop = NULL;
2730 #ifdef HAVE_GETADDRINFO
2731 struct addrinfo ai;
2732 char strport[NI_MAXSERV];
2733 int ai_result;
2735 memset(&ai, 0, sizeof(ai));
2736 ai.ai_family = AF_INET;
2737 ai.ai_socktype = SOCK_STREAM;
2738 ai.ai_flags = AI_PASSIVE; /* turn NULL host name into INADDR_ANY */
2739 evutil_snprintf(strport, sizeof(strport), "%d", port);
2740 if ((ai_result = getaddrinfo(address, strport, &ai, &aitop)) != 0) {
2741 if ( ai_result == EAI_SYSTEM )
2742 event_warn("getaddrinfo");
2743 else
2744 event_warnx("getaddrinfo: %s", gai_strerror(ai_result));
2745 return (NULL);
2747 #else
2748 static int cur;
2749 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. */
2750 if (++cur == 2) cur = 0; /* allow calling this function twice */
2752 if (fake_getaddrinfo(address, &ai[cur]) < 0) {
2753 event_warn("fake_getaddrinfo");
2754 return (NULL);
2756 aitop = &ai[cur];
2757 ((struct sockaddr_in *) aitop->ai_addr)->sin_port = htons(port);
2758 #endif
2760 return (aitop);
2763 static int
2764 bind_socket(const char *address, u_short port, int reuse)
2766 int fd;
2767 struct addrinfo *aitop = NULL;
2769 /* just create an unbound socket */
2770 if (address == NULL && port == 0)
2771 return bind_socket_ai(NULL, 0);
2773 aitop = make_addrinfo(address, port);
2775 if (aitop == NULL)
2776 return (-1);
2778 fd = bind_socket_ai(aitop, reuse);
2780 #ifdef HAVE_GETADDRINFO
2781 freeaddrinfo(aitop);
2782 #else
2783 fake_freeaddrinfo(aitop);
2784 #endif
2786 return (fd);
2789 static int
2790 socket_connect(int fd, const char *address, unsigned short port)
2792 struct addrinfo *ai = make_addrinfo(address, port);
2793 int res = -1;
2795 if (ai == NULL) {
2796 event_debug(("%s: make_addrinfo: \"%s:%d\"",
2797 __func__, address, port));
2798 return (-1);
2801 if (connect(fd, ai->ai_addr, ai->ai_addrlen) == -1) {
2802 #ifdef WIN32
2803 int tmp_error = WSAGetLastError();
2804 if (tmp_error != WSAEWOULDBLOCK && tmp_error != WSAEINVAL &&
2805 tmp_error != WSAEINPROGRESS) {
2806 goto out;
2808 #else
2809 if (errno != EINPROGRESS) {
2810 goto out;
2812 #endif
2815 /* everything is fine */
2816 res = 0;
2818 out:
2819 #ifdef HAVE_GETADDRINFO
2820 freeaddrinfo(ai);
2821 #else
2822 fake_freeaddrinfo(ai);
2823 #endif
2825 return (res);