Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / bsd / libevent / dist / http.c
blob71e97d1fd235918621d9d552a40172230a43de84
1 /* $NetBSD$ */
2 /*
3 * Copyright (c) 2002-2006 Niels Provos <provos@citi.umich.edu>
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
33 #ifdef HAVE_SYS_PARAM_H
34 #include <sys/param.h>
35 #endif
36 #ifdef HAVE_SYS_TYPES_H
37 #include <sys/types.h>
38 #endif
40 #ifdef HAVE_SYS_TIME_H
41 #include <sys/time.h>
42 #endif
43 #ifdef HAVE_SYS_IOCCOM_H
44 #include <sys/ioccom.h>
45 #endif
47 #ifndef WIN32
48 #include <sys/resource.h>
49 #include <sys/socket.h>
50 #include <sys/stat.h>
51 #include <sys/wait.h>
52 #endif
54 #include <sys/queue.h>
56 #ifndef WIN32
57 #include <netinet/in.h>
58 #include <netdb.h>
59 #endif
61 #ifdef WIN32
62 #include <winsock2.h>
63 #endif
65 #include <assert.h>
66 #include <ctype.h>
67 #include <errno.h>
68 #include <stdio.h>
69 #include <stdlib.h>
70 #include <string.h>
71 #ifndef WIN32
72 #include <syslog.h>
73 #endif
74 #include <signal.h>
75 #include <time.h>
76 #ifdef HAVE_UNISTD_H
77 #include <unistd.h>
78 #endif
79 #ifdef HAVE_FCNTL_H
80 #include <fcntl.h>
81 #endif
83 #undef timeout_pending
84 #undef timeout_initialized
86 #include "strlcpy-internal.h"
87 #include "event.h"
88 #include "evhttp.h"
89 #include "evutil.h"
90 #include "log.h"
91 #include "http-internal.h"
93 #ifdef WIN32
94 #define strcasecmp _stricmp
95 #define strncasecmp _strnicmp
96 #define strdup _strdup
97 #endif
99 #ifndef HAVE_GETNAMEINFO
100 #define NI_MAXSERV 32
101 #define NI_MAXHOST 1025
103 #define NI_NUMERICHOST 1
104 #define NI_NUMERICSERV 2
106 static int
107 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
108 size_t hostlen, char *serv, size_t servlen, int flags)
110 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
112 if (serv != NULL) {
113 char tmpserv[16];
114 evutil_snprintf(tmpserv, sizeof(tmpserv),
115 "%d", ntohs(sin->sin_port));
116 if (strlcpy(serv, tmpserv, servlen) >= servlen)
117 return (-1);
120 if (host != NULL) {
121 if (flags & NI_NUMERICHOST) {
122 if (strlcpy(host, inet_ntoa(sin->sin_addr),
123 hostlen) >= hostlen)
124 return (-1);
125 else
126 return (0);
127 } else {
128 struct hostent *hp;
129 hp = gethostbyaddr((char *)&sin->sin_addr,
130 sizeof(struct in_addr), AF_INET);
131 if (hp == NULL)
132 return (-2);
134 if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
135 return (-1);
136 else
137 return (0);
140 return (0);
143 #endif
145 #ifndef HAVE_GETADDRINFO
146 struct addrinfo {
147 int ai_family;
148 int ai_socktype;
149 int ai_protocol;
150 size_t ai_addrlen;
151 struct sockaddr *ai_addr;
152 struct addrinfo *ai_next;
154 static int
155 fake_getaddrinfo(const char *hostname, struct addrinfo *ai)
157 struct hostent *he = NULL;
158 struct sockaddr_in *sa;
159 if (hostname) {
160 he = gethostbyname(hostname);
161 if (!he)
162 return (-1);
164 ai->ai_family = he ? he->h_addrtype : AF_INET;
165 ai->ai_socktype = SOCK_STREAM;
166 ai->ai_protocol = 0;
167 ai->ai_addrlen = sizeof(struct sockaddr_in);
168 if (NULL == (ai->ai_addr = malloc(ai->ai_addrlen)))
169 return (-1);
170 sa = (struct sockaddr_in*)ai->ai_addr;
171 memset(sa, 0, ai->ai_addrlen);
172 if (he) {
173 sa->sin_family = he->h_addrtype;
174 memcpy(&sa->sin_addr, he->h_addr_list[0], he->h_length);
175 } else {
176 sa->sin_family = AF_INET;
177 sa->sin_addr.s_addr = INADDR_ANY;
179 ai->ai_next = NULL;
180 return (0);
182 static void
183 fake_freeaddrinfo(struct addrinfo *ai)
185 free(ai->ai_addr);
187 #endif
189 #ifndef MIN
190 #define MIN(a,b) (((a)<(b))?(a):(b))
191 #endif
193 /* wrapper for setting the base from the http server */
194 #define EVHTTP_BASE_SET(x, y) do { \
195 if ((x)->base != NULL) event_base_set((x)->base, y); \
196 } while (0)
198 extern int debug;
200 static int socket_connect(int fd, const char *address, unsigned short port);
201 static int bind_socket_ai(struct addrinfo *, int reuse);
202 static int bind_socket(const char *, u_short, int reuse);
203 static void name_from_addr(struct sockaddr *, socklen_t, char **, char **);
204 static int evhttp_associate_new_request_with_connection(
205 struct evhttp_connection *evcon);
206 static void evhttp_connection_start_detectclose(
207 struct evhttp_connection *evcon);
208 static void evhttp_connection_stop_detectclose(
209 struct evhttp_connection *evcon);
210 static void evhttp_request_dispatch(struct evhttp_connection* evcon);
211 static void evhttp_read_firstline(struct evhttp_connection *evcon,
212 struct evhttp_request *req);
213 static void evhttp_read_header(struct evhttp_connection *evcon,
214 struct evhttp_request *req);
215 static int evhttp_add_header_internal(struct evkeyvalq *headers,
216 const char *key, const char *value);
217 static int evhttp_decode_uri_internal(const char *uri, size_t length,
218 char *ret, int always_decode_plus);
220 void evhttp_read(int, short, void *);
221 void evhttp_write(int, short, void *);
223 #ifndef HAVE_STRSEP
224 /* strsep replacement for platforms that lack it. Only works if
225 * del is one character long. */
226 static char *
227 strsep(char **s, const char *del)
229 char *d, *tok;
230 assert(strlen(del) == 1);
231 if (!s || !*s)
232 return NULL;
233 tok = *s;
234 d = strstr(tok, del);
235 if (d) {
236 *d = '\0';
237 *s = d + 1;
238 } else
239 *s = NULL;
240 return tok;
242 #endif
244 static const char *
245 html_replace(char ch, char *buf)
247 switch (ch) {
248 case '<':
249 return "&lt;";
250 case '>':
251 return "&gt;";
252 case '"':
253 return "&quot;";
254 case '\'':
255 return "&#039;";
256 case '&':
257 return "&amp;";
258 default:
259 break;
262 /* Echo the character back */
263 buf[0] = ch;
264 buf[1] = '\0';
266 return buf;
270 * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
271 * &#039; and &amp; correspondingly.
273 * The returned string needs to be freed by the caller.
276 char *
277 evhttp_htmlescape(const char *html)
279 int i, new_size = 0, old_size = strlen(html);
280 char *escaped_html, *p;
281 char scratch_space[2];
283 for (i = 0; i < old_size; ++i)
284 new_size += strlen(html_replace(html[i], scratch_space));
286 p = escaped_html = malloc(new_size + 1);
287 if (escaped_html == NULL)
288 event_err(1, "%s: malloc(%d)", __func__, new_size + 1);
289 for (i = 0; i < old_size; ++i) {
290 const char *replaced = html_replace(html[i], scratch_space);
291 /* this is length checked */
292 strcpy(p, replaced);
293 p += strlen(replaced);
296 *p = '\0';
298 return (escaped_html);
301 static const char *
302 evhttp_method(enum evhttp_cmd_type type)
304 const char *method;
306 switch (type) {
307 case EVHTTP_REQ_GET:
308 method = "GET";
309 break;
310 case EVHTTP_REQ_POST:
311 method = "POST";
312 break;
313 case EVHTTP_REQ_HEAD:
314 method = "HEAD";
315 break;
316 default:
317 method = NULL;
318 break;
321 return (method);
324 static void
325 evhttp_add_event(struct event *ev, int timeout, int default_timeout)
327 if (timeout != 0) {
328 struct timeval tv;
330 evutil_timerclear(&tv);
331 tv.tv_sec = timeout != -1 ? timeout : default_timeout;
332 event_add(ev, &tv);
333 } else {
334 event_add(ev, NULL);
338 void
339 evhttp_write_buffer(struct evhttp_connection *evcon,
340 void (*cb)(struct evhttp_connection *, void *), void *arg)
342 event_debug(("%s: preparing to write buffer\n", __func__));
344 /* Set call back */
345 evcon->cb = cb;
346 evcon->cb_arg = arg;
348 /* check if the event is already pending */
349 if (event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL))
350 event_del(&evcon->ev);
352 event_set(&evcon->ev, evcon->fd, EV_WRITE, evhttp_write, evcon);
353 EVHTTP_BASE_SET(evcon, &evcon->ev);
354 evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_WRITE_TIMEOUT);
357 static int
358 evhttp_connected(struct evhttp_connection *evcon)
360 switch (evcon->state) {
361 case EVCON_DISCONNECTED:
362 case EVCON_CONNECTING:
363 return (0);
364 case EVCON_IDLE:
365 case EVCON_READING_FIRSTLINE:
366 case EVCON_READING_HEADERS:
367 case EVCON_READING_BODY:
368 case EVCON_READING_TRAILER:
369 case EVCON_WRITING:
370 default:
371 return (1);
376 * Create the headers needed for an HTTP request
378 static void
379 evhttp_make_header_request(struct evhttp_connection *evcon,
380 struct evhttp_request *req)
382 const char *method;
384 evhttp_remove_header(req->output_headers, "Proxy-Connection");
386 /* Generate request line */
387 method = evhttp_method(req->type);
388 evbuffer_add_printf(evcon->output_buffer, "%s %s HTTP/%d.%d\r\n",
389 method, req->uri, req->major, req->minor);
391 /* Add the content length on a post request if missing */
392 if (req->type == EVHTTP_REQ_POST &&
393 evhttp_find_header(req->output_headers, "Content-Length") == NULL){
394 char size[12];
395 evutil_snprintf(size, sizeof(size), "%ld",
396 (long)EVBUFFER_LENGTH(req->output_buffer));
397 evhttp_add_header(req->output_headers, "Content-Length", size);
401 static int
402 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
404 if (flags & EVHTTP_PROXY_REQUEST) {
405 /* proxy connection */
406 const char *connection = evhttp_find_header(headers, "Proxy-Connection");
407 return (connection == NULL || strcasecmp(connection, "keep-alive") != 0);
408 } else {
409 const char *connection = evhttp_find_header(headers, "Connection");
410 return (connection != NULL && strcasecmp(connection, "close") == 0);
414 static int
415 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
417 const char *connection = evhttp_find_header(headers, "Connection");
418 return (connection != NULL
419 && strncasecmp(connection, "keep-alive", 10) == 0);
422 static void
423 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
425 if (evhttp_find_header(headers, "Date") == NULL) {
426 char date[50];
427 #ifndef WIN32
428 struct tm cur;
429 #endif
430 struct tm *cur_p;
431 time_t t = time(NULL);
432 #ifdef WIN32
433 cur_p = gmtime(&t);
434 #else
435 gmtime_r(&t, &cur);
436 cur_p = &cur;
437 #endif
438 if (strftime(date, sizeof(date),
439 "%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) {
440 evhttp_add_header(headers, "Date", date);
445 static void
446 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
447 long content_length)
449 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
450 evhttp_find_header(headers, "Content-Length") == NULL) {
451 char len[12];
452 evutil_snprintf(len, sizeof(len), "%ld", content_length);
453 evhttp_add_header(headers, "Content-Length", len);
458 * Create the headers needed for an HTTP reply
461 static void
462 evhttp_make_header_response(struct evhttp_connection *evcon,
463 struct evhttp_request *req)
465 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers);
466 evbuffer_add_printf(evcon->output_buffer, "HTTP/%d.%d %d %s\r\n",
467 req->major, req->minor, req->response_code,
468 req->response_code_line);
470 if (req->major == 1) {
471 if (req->minor == 1)
472 evhttp_maybe_add_date_header(req->output_headers);
475 * if the protocol is 1.0; and the connection was keep-alive
476 * we need to add a keep-alive header, too.
478 if (req->minor == 0 && is_keepalive)
479 evhttp_add_header(req->output_headers,
480 "Connection", "keep-alive");
482 if (req->minor == 1 || is_keepalive) {
484 * we need to add the content length if the
485 * user did not give it, this is required for
486 * persistent connections to work.
488 evhttp_maybe_add_content_length_header(
489 req->output_headers,
490 (long)EVBUFFER_LENGTH(req->output_buffer));
494 /* Potentially add headers for unidentified content. */
495 if (EVBUFFER_LENGTH(req->output_buffer)) {
496 if (evhttp_find_header(req->output_headers,
497 "Content-Type") == NULL) {
498 evhttp_add_header(req->output_headers,
499 "Content-Type", "text/html; charset=ISO-8859-1");
503 /* if the request asked for a close, we send a close, too */
504 if (evhttp_is_connection_close(req->flags, req->input_headers)) {
505 evhttp_remove_header(req->output_headers, "Connection");
506 if (!(req->flags & EVHTTP_PROXY_REQUEST))
507 evhttp_add_header(req->output_headers, "Connection", "close");
508 evhttp_remove_header(req->output_headers, "Proxy-Connection");
512 void
513 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
515 struct evkeyval *header;
518 * Depending if this is a HTTP request or response, we might need to
519 * add some new headers or remove existing headers.
521 if (req->kind == EVHTTP_REQUEST) {
522 evhttp_make_header_request(evcon, req);
523 } else {
524 evhttp_make_header_response(evcon, req);
527 TAILQ_FOREACH(header, req->output_headers, next) {
528 evbuffer_add_printf(evcon->output_buffer, "%s: %s\r\n",
529 header->key, header->value);
531 evbuffer_add(evcon->output_buffer, "\r\n", 2);
533 if (EVBUFFER_LENGTH(req->output_buffer) > 0) {
535 * For a request, we add the POST data, for a reply, this
536 * is the regular data.
538 evbuffer_add_buffer(evcon->output_buffer, req->output_buffer);
542 /* Separated host, port and file from URI */
545 evhttp_hostportfile(char *url, char **phost, u_short *pport, char **pfile)
547 /* XXX not threadsafe. */
548 static char host[1024];
549 static char file[1024];
550 char *p;
551 const char *p2;
552 int len;
553 u_short port;
555 len = strlen(HTTP_PREFIX);
556 if (strncasecmp(url, HTTP_PREFIX, len))
557 return (-1);
559 url += len;
561 /* We might overrun */
562 if (strlcpy(host, url, sizeof (host)) >= sizeof(host))
563 return (-1);
565 p = strchr(host, '/');
566 if (p != NULL) {
567 *p = '\0';
568 p2 = p + 1;
569 } else
570 p2 = NULL;
572 if (pfile != NULL) {
573 /* Generate request file */
574 if (p2 == NULL)
575 p2 = "";
576 evutil_snprintf(file, sizeof(file), "/%s", p2);
579 p = strchr(host, ':');
580 if (p != NULL) {
581 *p = '\0';
582 port = atoi(p + 1);
584 if (port == 0)
585 return (-1);
586 } else
587 port = HTTP_DEFAULTPORT;
589 if (phost != NULL)
590 *phost = host;
591 if (pport != NULL)
592 *pport = port;
593 if (pfile != NULL)
594 *pfile = file;
596 return (0);
599 static int
600 evhttp_connection_incoming_fail(struct evhttp_request *req,
601 enum evhttp_connection_error error)
603 switch (error) {
604 case EVCON_HTTP_TIMEOUT:
605 case EVCON_HTTP_EOF:
607 * these are cases in which we probably should just
608 * close the connection and not send a reply. this
609 * case may happen when a browser keeps a persistent
610 * connection open and we timeout on the read.
612 return (-1);
613 case EVCON_HTTP_INVALID_HEADER:
614 default: /* xxx: probably should just error on default */
615 /* the callback looks at the uri to determine errors */
616 if (req->uri) {
617 free(req->uri);
618 req->uri = NULL;
622 * the callback needs to send a reply, once the reply has
623 * been send, the connection should get freed.
625 (*req->cb)(req, req->cb_arg);
628 return (0);
631 void
632 evhttp_connection_fail(struct evhttp_connection *evcon,
633 enum evhttp_connection_error error)
635 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
636 void (*cb)(struct evhttp_request *, void *);
637 void *cb_arg;
638 assert(req != NULL);
640 if (evcon->flags & EVHTTP_CON_INCOMING) {
642 * for incoming requests, there are two different
643 * failure cases. it's either a network level error
644 * or an http layer error. for problems on the network
645 * layer like timeouts we just drop the connections.
646 * For HTTP problems, we might have to send back a
647 * reply before the connection can be freed.
649 if (evhttp_connection_incoming_fail(req, error) == -1)
650 evhttp_connection_free(evcon);
651 return;
654 /* save the callback for later; the cb might free our object */
655 cb = req->cb;
656 cb_arg = req->cb_arg;
658 TAILQ_REMOVE(&evcon->requests, req, next);
659 evhttp_request_free(req);
661 /* xxx: maybe we should fail all requests??? */
663 /* reset the connection */
664 evhttp_connection_reset(evcon);
666 /* We are trying the next request that was queued on us */
667 if (TAILQ_FIRST(&evcon->requests) != NULL)
668 evhttp_connection_connect(evcon);
670 /* inform the user */
671 if (cb != NULL)
672 (*cb)(NULL, cb_arg);
675 void
676 evhttp_write(int fd, short what, void *arg)
678 struct evhttp_connection *evcon = arg;
679 int n;
681 if (what == EV_TIMEOUT) {
682 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
683 return;
686 n = evbuffer_write(evcon->output_buffer, fd);
687 if (n == -1) {
688 event_debug(("%s: evbuffer_write", __func__));
689 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
690 return;
693 if (n == 0) {
694 event_debug(("%s: write nothing", __func__));
695 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
696 return;
699 if (EVBUFFER_LENGTH(evcon->output_buffer) != 0) {
700 evhttp_add_event(&evcon->ev,
701 evcon->timeout, HTTP_WRITE_TIMEOUT);
702 return;
705 /* Activate our call back */
706 if (evcon->cb != NULL)
707 (*evcon->cb)(evcon, evcon->cb_arg);
711 * Advance the connection state.
712 * - If this is an outgoing connection, we've just processed the response;
713 * idle or close the connection.
714 * - If this is an incoming connection, we've just processed the request;
715 * respond.
717 static void
718 evhttp_connection_done(struct evhttp_connection *evcon)
720 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
721 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
723 if (con_outgoing) {
724 /* idle or close the connection */
725 int need_close;
726 TAILQ_REMOVE(&evcon->requests, req, next);
727 req->evcon = NULL;
729 evcon->state = EVCON_IDLE;
731 need_close =
732 evhttp_is_connection_close(req->flags, req->input_headers)||
733 evhttp_is_connection_close(req->flags, req->output_headers);
735 /* check if we got asked to close the connection */
736 if (need_close)
737 evhttp_connection_reset(evcon);
739 if (TAILQ_FIRST(&evcon->requests) != NULL) {
741 * We have more requests; reset the connection
742 * and deal with the next request.
744 if (!evhttp_connected(evcon))
745 evhttp_connection_connect(evcon);
746 else
747 evhttp_request_dispatch(evcon);
748 } else if (!need_close) {
750 * The connection is going to be persistent, but we
751 * need to detect if the other side closes it.
753 evhttp_connection_start_detectclose(evcon);
755 } else {
757 * incoming connection - we need to leave the request on the
758 * connection so that we can reply to it.
760 evcon->state = EVCON_WRITING;
763 /* notify the user of the request */
764 (*req->cb)(req, req->cb_arg);
766 /* if this was an outgoing request, we own and it's done. so free it */
767 if (con_outgoing) {
768 evhttp_request_free(req);
773 * Handles reading from a chunked request.
774 * return ALL_DATA_READ:
775 * all data has been read
776 * return MORE_DATA_EXPECTED:
777 * more data is expected
778 * return DATA_CORRUPTED:
779 * data is corrupted
780 * return REQUEST_CANCLED:
781 * request was canceled by the user calling evhttp_cancel_request
784 static enum message_read_status
785 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
787 int len;
789 while ((len = EVBUFFER_LENGTH(buf)) > 0) {
790 if (req->ntoread < 0) {
791 /* Read chunk size */
792 ev_int64_t ntoread;
793 char *p = evbuffer_readline(buf);
794 char *endp;
795 int error;
796 if (p == NULL)
797 break;
798 /* the last chunk is on a new line? */
799 if (strlen(p) == 0) {
800 free(p);
801 continue;
803 ntoread = evutil_strtoll(p, &endp, 16);
804 error = (*p == '\0' ||
805 (*endp != '\0' && *endp != ' ') ||
806 ntoread < 0);
807 free(p);
808 if (error) {
809 /* could not get chunk size */
810 return (DATA_CORRUPTED);
812 req->ntoread = ntoread;
813 if (req->ntoread == 0) {
814 /* Last chunk */
815 return (ALL_DATA_READ);
817 continue;
820 /* don't have enough to complete a chunk; wait for more */
821 if (len < req->ntoread)
822 return (MORE_DATA_EXPECTED);
824 /* Completed chunk */
825 evbuffer_add(req->input_buffer,
826 EVBUFFER_DATA(buf), (size_t)req->ntoread);
827 evbuffer_drain(buf, (size_t)req->ntoread);
828 req->ntoread = -1;
829 if (req->chunk_cb != NULL) {
830 (*req->chunk_cb)(req, req->cb_arg);
831 evbuffer_drain(req->input_buffer,
832 EVBUFFER_LENGTH(req->input_buffer));
836 return (MORE_DATA_EXPECTED);
839 static void
840 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
842 struct evbuffer *buf = evcon->input_buffer;
844 switch (evhttp_parse_headers(req, buf)) {
845 case DATA_CORRUPTED:
846 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
847 break;
848 case ALL_DATA_READ:
849 event_del(&evcon->ev);
850 evhttp_connection_done(evcon);
851 break;
852 case MORE_DATA_EXPECTED:
853 default:
854 evhttp_add_event(&evcon->ev, evcon->timeout,
855 HTTP_READ_TIMEOUT);
856 break;
860 static void
861 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
863 struct evbuffer *buf = evcon->input_buffer;
865 if (req->chunked) {
866 switch (evhttp_handle_chunked_read(req, buf)) {
867 case ALL_DATA_READ:
868 /* finished last chunk */
869 evcon->state = EVCON_READING_TRAILER;
870 evhttp_read_trailer(evcon, req);
871 return;
872 case DATA_CORRUPTED:
873 /* corrupted data */
874 evhttp_connection_fail(evcon,
875 EVCON_HTTP_INVALID_HEADER);
876 return;
877 case REQUEST_CANCELED:
878 /* request canceled */
879 evhttp_request_free(req);
880 return;
881 case MORE_DATA_EXPECTED:
882 default:
883 break;
885 } else if (req->ntoread < 0) {
886 /* Read until connection close. */
887 evbuffer_add_buffer(req->input_buffer, buf);
888 } else if (EVBUFFER_LENGTH(buf) >= req->ntoread) {
889 /* Completed content length */
890 evbuffer_add(req->input_buffer, EVBUFFER_DATA(buf),
891 (size_t)req->ntoread);
892 evbuffer_drain(buf, (size_t)req->ntoread);
893 req->ntoread = 0;
894 evhttp_connection_done(evcon);
895 return;
897 /* Read more! */
898 event_set(&evcon->ev, evcon->fd, EV_READ, evhttp_read, evcon);
899 EVHTTP_BASE_SET(evcon, &evcon->ev);
900 evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
904 * Reads data into a buffer structure until no more data
905 * can be read on the file descriptor or we have read all
906 * the data that we wanted to read.
907 * Execute callback when done.
910 void
911 evhttp_read(int fd, short what, void *arg)
913 struct evhttp_connection *evcon = arg;
914 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
915 struct evbuffer *buf = evcon->input_buffer;
916 int n, len;
918 if (what == EV_TIMEOUT) {
919 evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
920 return;
922 n = evbuffer_read(buf, fd, -1);
923 len = EVBUFFER_LENGTH(buf);
924 event_debug(("%s: got %d on %d\n", __func__, n, fd));
926 if (n == -1) {
927 if (errno != EINTR && errno != EAGAIN) {
928 event_debug(("%s: evbuffer_read", __func__));
929 evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
930 } else {
931 evhttp_add_event(&evcon->ev, evcon->timeout,
932 HTTP_READ_TIMEOUT);
934 return;
935 } else if (n == 0) {
936 /* Connection closed */
937 evhttp_connection_done(evcon);
938 return;
941 switch (evcon->state) {
942 case EVCON_READING_FIRSTLINE:
943 evhttp_read_firstline(evcon, req);
944 break;
945 case EVCON_READING_HEADERS:
946 evhttp_read_header(evcon, req);
947 break;
948 case EVCON_READING_BODY:
949 evhttp_read_body(evcon, req);
950 break;
951 case EVCON_READING_TRAILER:
952 evhttp_read_trailer(evcon, req);
953 break;
954 case EVCON_DISCONNECTED:
955 case EVCON_CONNECTING:
956 case EVCON_IDLE:
957 case EVCON_WRITING:
958 default:
959 event_errx(1, "%s: illegal connection state %d",
960 __func__, evcon->state);
964 static void
965 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
967 /* This is after writing the request to the server */
968 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
969 assert(req != NULL);
971 assert(evcon->state == EVCON_WRITING);
973 /* We are done writing our header and are now expecting the response */
974 req->kind = EVHTTP_RESPONSE;
976 evhttp_start_read(evcon);
980 * Clean up a connection object
983 void
984 evhttp_connection_free(struct evhttp_connection *evcon)
986 struct evhttp_request *req;
988 /* notify interested parties that this connection is going down */
989 if (evcon->fd != -1) {
990 if (evhttp_connected(evcon) && evcon->closecb != NULL)
991 (*evcon->closecb)(evcon, evcon->closecb_arg);
994 /* remove all requests that might be queued on this connection */
995 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) {
996 TAILQ_REMOVE(&evcon->requests, req, next);
997 evhttp_request_free(req);
1000 if (evcon->http_server != NULL) {
1001 struct evhttp *http = evcon->http_server;
1002 TAILQ_REMOVE(&http->connections, evcon, next);
1005 if (event_initialized(&evcon->close_ev))
1006 event_del(&evcon->close_ev);
1008 if (event_initialized(&evcon->ev))
1009 event_del(&evcon->ev);
1011 if (evcon->fd != -1)
1012 EVUTIL_CLOSESOCKET(evcon->fd);
1014 if (evcon->bind_address != NULL)
1015 free(evcon->bind_address);
1017 if (evcon->address != NULL)
1018 free(evcon->address);
1020 if (evcon->input_buffer != NULL)
1021 evbuffer_free(evcon->input_buffer);
1023 if (evcon->output_buffer != NULL)
1024 evbuffer_free(evcon->output_buffer);
1026 free(evcon);
1029 void
1030 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1031 const char *address)
1033 assert(evcon->state == EVCON_DISCONNECTED);
1034 if (evcon->bind_address)
1035 free(evcon->bind_address);
1036 if ((evcon->bind_address = strdup(address)) == NULL)
1037 event_err(1, "%s: strdup", __func__);
1040 void
1041 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1042 unsigned short port)
1044 assert(evcon->state == EVCON_DISCONNECTED);
1045 evcon->bind_port = port;
1048 static void
1049 evhttp_request_dispatch(struct evhttp_connection* evcon)
1051 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1053 /* this should not usually happy but it's possible */
1054 if (req == NULL)
1055 return;
1057 /* delete possible close detection events */
1058 evhttp_connection_stop_detectclose(evcon);
1060 /* we assume that the connection is connected already */
1061 assert(evcon->state == EVCON_IDLE);
1063 evcon->state = EVCON_WRITING;
1065 /* Create the header from the store arguments */
1066 evhttp_make_header(evcon, req);
1068 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1071 /* Reset our connection state */
1072 void
1073 evhttp_connection_reset(struct evhttp_connection *evcon)
1075 if (event_initialized(&evcon->ev))
1076 event_del(&evcon->ev);
1078 if (evcon->fd != -1) {
1079 /* inform interested parties about connection close */
1080 if (evhttp_connected(evcon) && evcon->closecb != NULL)
1081 (*evcon->closecb)(evcon, evcon->closecb_arg);
1083 EVUTIL_CLOSESOCKET(evcon->fd);
1084 evcon->fd = -1;
1086 evcon->state = EVCON_DISCONNECTED;
1088 evbuffer_drain(evcon->input_buffer,
1089 EVBUFFER_LENGTH(evcon->input_buffer));
1090 evbuffer_drain(evcon->output_buffer,
1091 EVBUFFER_LENGTH(evcon->output_buffer));
1094 static void
1095 evhttp_detect_close_cb(int fd, short what, void *arg)
1097 struct evhttp_connection *evcon = arg;
1098 evhttp_connection_reset(evcon);
1101 static void
1102 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1104 evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1106 if (event_initialized(&evcon->close_ev))
1107 event_del(&evcon->close_ev);
1108 event_set(&evcon->close_ev, evcon->fd, EV_READ,
1109 evhttp_detect_close_cb, evcon);
1110 EVHTTP_BASE_SET(evcon, &evcon->close_ev);
1111 event_add(&evcon->close_ev, NULL);
1114 static void
1115 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1117 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1118 event_del(&evcon->close_ev);
1121 static void
1122 evhttp_connection_retry(int fd, short what, void *arg)
1124 struct evhttp_connection *evcon = arg;
1126 evcon->state = EVCON_DISCONNECTED;
1127 evhttp_connection_connect(evcon);
1131 * Call back for asynchronous connection attempt.
1134 static void
1135 evhttp_connectioncb(int fd, short what, void *arg)
1137 struct evhttp_connection *evcon = arg;
1138 int error;
1139 socklen_t errsz = sizeof(error);
1141 if (what == EV_TIMEOUT) {
1142 event_debug(("%s: connection timeout for \"%s:%d\" on %d",
1143 __func__, evcon->address, evcon->port, evcon->fd));
1144 goto cleanup;
1147 /* Check if the connection completed */
1148 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
1149 &errsz) == -1) {
1150 event_debug(("%s: getsockopt for \"%s:%d\" on %d",
1151 __func__, evcon->address, evcon->port, evcon->fd));
1152 goto cleanup;
1155 if (error) {
1156 event_debug(("%s: connect failed for \"%s:%d\" on %d: %s",
1157 __func__, evcon->address, evcon->port, evcon->fd,
1158 strerror(error)));
1159 goto cleanup;
1162 /* We are connected to the server now */
1163 event_debug(("%s: connected to \"%s:%d\" on %d\n",
1164 __func__, evcon->address, evcon->port, evcon->fd));
1166 /* Reset the retry count as we were successful in connecting */
1167 evcon->retry_cnt = 0;
1168 evcon->state = EVCON_IDLE;
1170 /* try to start requests that have queued up on this connection */
1171 evhttp_request_dispatch(evcon);
1172 return;
1174 cleanup:
1175 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
1176 evtimer_set(&evcon->ev, evhttp_connection_retry, evcon);
1177 EVHTTP_BASE_SET(evcon, &evcon->ev);
1178 evhttp_add_event(&evcon->ev, MIN(3600, 2 << evcon->retry_cnt),
1179 HTTP_CONNECT_TIMEOUT);
1180 evcon->retry_cnt++;
1181 return;
1183 evhttp_connection_reset(evcon);
1185 /* for now, we just signal all requests by executing their callbacks */
1186 while (TAILQ_FIRST(&evcon->requests) != NULL) {
1187 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests);
1188 TAILQ_REMOVE(&evcon->requests, request, next);
1189 request->evcon = NULL;
1191 /* we might want to set an error here */
1192 request->cb(request, request->cb_arg);
1193 evhttp_request_free(request);
1198 * Check if we got a valid response code.
1201 static int
1202 evhttp_valid_response_code(int code)
1204 if (code == 0)
1205 return (0);
1207 return (1);
1210 /* Parses the status line of a web server */
1212 static int
1213 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1215 char *protocol;
1216 char *number;
1217 char *readable;
1219 protocol = strsep(&line, " ");
1220 if (line == NULL)
1221 return (-1);
1222 number = strsep(&line, " ");
1223 if (line == NULL)
1224 return (-1);
1225 readable = line;
1227 if (strcmp(protocol, "HTTP/1.0") == 0) {
1228 req->major = 1;
1229 req->minor = 0;
1230 } else if (strcmp(protocol, "HTTP/1.1") == 0) {
1231 req->major = 1;
1232 req->minor = 1;
1233 } else {
1234 event_debug(("%s: bad protocol \"%s\"",
1235 __func__, protocol));
1236 return (-1);
1239 req->response_code = atoi(number);
1240 if (!evhttp_valid_response_code(req->response_code)) {
1241 event_debug(("%s: bad response code \"%s\"",
1242 __func__, number));
1243 return (-1);
1246 if ((req->response_code_line = strdup(readable)) == NULL)
1247 event_err(1, "%s: strdup", __func__);
1249 return (0);
1252 /* Parse the first line of a HTTP request */
1254 static int
1255 evhttp_parse_request_line(struct evhttp_request *req, char *line)
1257 char *method;
1258 char *uri;
1259 char *version;
1261 /* Parse the request line */
1262 method = strsep(&line, " ");
1263 if (line == NULL)
1264 return (-1);
1265 uri = strsep(&line, " ");
1266 if (line == NULL)
1267 return (-1);
1268 version = strsep(&line, " ");
1269 if (line != NULL)
1270 return (-1);
1272 /* First line */
1273 if (strcmp(method, "GET") == 0) {
1274 req->type = EVHTTP_REQ_GET;
1275 } else if (strcmp(method, "POST") == 0) {
1276 req->type = EVHTTP_REQ_POST;
1277 } else if (strcmp(method, "HEAD") == 0) {
1278 req->type = EVHTTP_REQ_HEAD;
1279 } else {
1280 event_debug(("%s: bad method %s on request %p from %s",
1281 __func__, method, req, req->remote_host));
1282 return (-1);
1285 if (strcmp(version, "HTTP/1.0") == 0) {
1286 req->major = 1;
1287 req->minor = 0;
1288 } else if (strcmp(version, "HTTP/1.1") == 0) {
1289 req->major = 1;
1290 req->minor = 1;
1291 } else {
1292 event_debug(("%s: bad version %s on request %p from %s",
1293 __func__, version, req, req->remote_host));
1294 return (-1);
1297 if ((req->uri = strdup(uri)) == NULL) {
1298 event_debug(("%s: evhttp_decode_uri", __func__));
1299 return (-1);
1302 /* determine if it's a proxy request */
1303 if (strlen(req->uri) > 0 && req->uri[0] != '/')
1304 req->flags |= EVHTTP_PROXY_REQUEST;
1306 return (0);
1309 const char *
1310 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1312 struct evkeyval *header;
1314 TAILQ_FOREACH(header, headers, next) {
1315 if (strcasecmp(header->key, key) == 0)
1316 return (header->value);
1319 return (NULL);
1322 void
1323 evhttp_clear_headers(struct evkeyvalq *headers)
1325 struct evkeyval *header;
1327 for (header = TAILQ_FIRST(headers);
1328 header != NULL;
1329 header = TAILQ_FIRST(headers)) {
1330 TAILQ_REMOVE(headers, header, next);
1331 free(header->key);
1332 free(header->value);
1333 free(header);
1338 * Returns 0, if the header was successfully removed.
1339 * Returns -1, if the header could not be found.
1343 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1345 struct evkeyval *header;
1347 TAILQ_FOREACH(header, headers, next) {
1348 if (strcasecmp(header->key, key) == 0)
1349 break;
1352 if (header == NULL)
1353 return (-1);
1355 /* Free and remove the header that we found */
1356 TAILQ_REMOVE(headers, header, next);
1357 free(header->key);
1358 free(header->value);
1359 free(header);
1361 return (0);
1364 static int
1365 evhttp_header_is_valid_value(const char *value)
1367 const char *p = value;
1369 while ((p = strpbrk(p, "\r\n")) != NULL) {
1370 /* we really expect only one new line */
1371 p += strspn(p, "\r\n");
1372 /* we expect a space or tab for continuation */
1373 if (*p != ' ' && *p != '\t')
1374 return (0);
1376 return (1);
1380 evhttp_add_header(struct evkeyvalq *headers,
1381 const char *key, const char *value)
1383 event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1385 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) {
1386 /* drop illegal headers */
1387 event_debug(("%s: dropping illegal header key\n", __func__));
1388 return (-1);
1391 if (!evhttp_header_is_valid_value(value)) {
1392 event_debug(("%s: dropping illegal header value\n", __func__));
1393 return (-1);
1396 return (evhttp_add_header_internal(headers, key, value));
1399 static int
1400 evhttp_add_header_internal(struct evkeyvalq *headers,
1401 const char *key, const char *value)
1403 struct evkeyval *header = calloc(1, sizeof(struct evkeyval));
1404 if (header == NULL) {
1405 event_warn("%s: calloc", __func__);
1406 return (-1);
1408 if ((header->key = strdup(key)) == NULL) {
1409 free(header);
1410 event_warn("%s: strdup", __func__);
1411 return (-1);
1413 if ((header->value = strdup(value)) == NULL) {
1414 free(header->key);
1415 free(header);
1416 event_warn("%s: strdup", __func__);
1417 return (-1);
1420 TAILQ_INSERT_TAIL(headers, header, next);
1422 return (0);
1426 * Parses header lines from a request or a response into the specified
1427 * request object given an event buffer.
1429 * Returns
1430 * DATA_CORRUPTED on error
1431 * MORE_DATA_EXPECTED when we need to read more headers
1432 * ALL_DATA_READ when all headers have been read.
1435 enum message_read_status
1436 evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
1438 char *line;
1439 enum message_read_status status = ALL_DATA_READ;
1441 line = evbuffer_readline(buffer);
1442 if (line == NULL)
1443 return (MORE_DATA_EXPECTED);
1445 switch (req->kind) {
1446 case EVHTTP_REQUEST:
1447 if (evhttp_parse_request_line(req, line) == -1)
1448 status = DATA_CORRUPTED;
1449 break;
1450 case EVHTTP_RESPONSE:
1451 if (evhttp_parse_response_line(req, line) == -1)
1452 status = DATA_CORRUPTED;
1453 break;
1454 default:
1455 status = DATA_CORRUPTED;
1458 free(line);
1459 return (status);
1462 static int
1463 evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
1465 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
1466 char *newval;
1467 size_t old_len, line_len;
1469 if (header == NULL)
1470 return (-1);
1472 old_len = strlen(header->value);
1473 line_len = strlen(line);
1475 newval = realloc(header->value, old_len + line_len + 1);
1476 if (newval == NULL)
1477 return (-1);
1479 memcpy(newval + old_len, line, line_len + 1);
1480 header->value = newval;
1482 return (0);
1485 enum message_read_status
1486 evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
1488 char *line;
1489 enum message_read_status status = MORE_DATA_EXPECTED;
1491 struct evkeyvalq* headers = req->input_headers;
1492 while ((line = evbuffer_readline(buffer))
1493 != NULL) {
1494 char *skey, *svalue;
1496 if (*line == '\0') { /* Last header - Done */
1497 status = ALL_DATA_READ;
1498 free(line);
1499 break;
1502 /* Check if this is a continuation line */
1503 if (*line == ' ' || *line == '\t') {
1504 if (evhttp_append_to_last_header(headers, line) == -1)
1505 goto error;
1506 free(line);
1507 continue;
1510 /* Processing of header lines */
1511 svalue = line;
1512 skey = strsep(&svalue, ":");
1513 if (svalue == NULL)
1514 goto error;
1516 svalue += strspn(svalue, " ");
1518 if (evhttp_add_header(headers, skey, svalue) == -1)
1519 goto error;
1521 free(line);
1524 return (status);
1526 error:
1527 free(line);
1528 return (DATA_CORRUPTED);
1531 static int
1532 evhttp_get_body_length(struct evhttp_request *req)
1534 struct evkeyvalq *headers = req->input_headers;
1535 const char *content_length;
1536 const char *connection;
1538 content_length = evhttp_find_header(headers, "Content-Length");
1539 connection = evhttp_find_header(headers, "Connection");
1541 if (content_length == NULL && connection == NULL)
1542 req->ntoread = -1;
1543 else if (content_length == NULL &&
1544 strcasecmp(connection, "Close") != 0) {
1545 /* Bad combination, we don't know when it will end */
1546 event_warnx("%s: we got no content length, but the "
1547 "server wants to keep the connection open: %s.",
1548 __func__, connection);
1549 return (-1);
1550 } else if (content_length == NULL) {
1551 req->ntoread = -1;
1552 } else {
1553 char *endp;
1554 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
1555 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
1556 event_debug(("%s: illegal content length: %s",
1557 __func__, content_length));
1558 return (-1);
1560 req->ntoread = ntoread;
1563 event_debug(("%s: bytes to read: %lld (in buffer %ld)\n",
1564 __func__, req->ntoread,
1565 EVBUFFER_LENGTH(req->evcon->input_buffer)));
1567 return (0);
1570 static void
1571 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1573 const char *xfer_enc;
1575 /* If this is a request without a body, then we are done */
1576 if (req->kind == EVHTTP_REQUEST && req->type != EVHTTP_REQ_POST) {
1577 evhttp_connection_done(evcon);
1578 return;
1580 evcon->state = EVCON_READING_BODY;
1581 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding");
1582 if (xfer_enc != NULL && strcasecmp(xfer_enc, "chunked") == 0) {
1583 req->chunked = 1;
1584 req->ntoread = -1;
1585 } else {
1586 if (evhttp_get_body_length(req) == -1) {
1587 evhttp_connection_fail(evcon,
1588 EVCON_HTTP_INVALID_HEADER);
1589 return;
1592 evhttp_read_body(evcon, req);
1595 static void
1596 evhttp_read_firstline(struct evhttp_connection *evcon,
1597 struct evhttp_request *req)
1599 enum message_read_status res;
1601 res = evhttp_parse_firstline(req, evcon->input_buffer);
1602 if (res == DATA_CORRUPTED) {
1603 /* Error while reading, terminate */
1604 event_debug(("%s: bad header lines on %d\n",
1605 __func__, evcon->fd));
1606 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1607 return;
1608 } else if (res == MORE_DATA_EXPECTED) {
1609 /* Need more header lines */
1610 evhttp_add_event(&evcon->ev,
1611 evcon->timeout, HTTP_READ_TIMEOUT);
1612 return;
1615 evcon->state = EVCON_READING_HEADERS;
1616 evhttp_read_header(evcon, req);
1619 static void
1620 evhttp_read_header(struct evhttp_connection *evcon, struct evhttp_request *req)
1622 enum message_read_status res;
1623 int fd = evcon->fd;
1625 res = evhttp_parse_headers(req, evcon->input_buffer);
1626 if (res == DATA_CORRUPTED) {
1627 /* Error while reading, terminate */
1628 event_debug(("%s: bad header lines on %d\n", __func__, fd));
1629 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1630 return;
1631 } else if (res == MORE_DATA_EXPECTED) {
1632 /* Need more header lines */
1633 evhttp_add_event(&evcon->ev,
1634 evcon->timeout, HTTP_READ_TIMEOUT);
1635 return;
1638 /* Done reading headers, do the real work */
1639 switch (req->kind) {
1640 case EVHTTP_REQUEST:
1641 event_debug(("%s: checking for post data on %d\n",
1642 __func__, fd));
1643 evhttp_get_body(evcon, req);
1644 break;
1646 case EVHTTP_RESPONSE:
1647 if (req->response_code == HTTP_NOCONTENT ||
1648 req->response_code == HTTP_NOTMODIFIED ||
1649 (req->response_code >= 100 && req->response_code < 200)) {
1650 event_debug(("%s: skipping body for code %d\n",
1651 __func__, req->response_code));
1652 evhttp_connection_done(evcon);
1653 } else {
1654 event_debug(("%s: start of read body for %s on %d\n",
1655 __func__, req->remote_host, fd));
1656 evhttp_get_body(evcon, req);
1658 break;
1660 default:
1661 event_warnx("%s: bad header on %d", __func__, fd);
1662 evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1663 break;
1668 * Creates a TCP connection to the specified port and executes a callback
1669 * when finished. Failure or sucess is indicate by the passed connection
1670 * object.
1672 * Although this interface accepts a hostname, it is intended to take
1673 * only numeric hostnames so that non-blocking DNS resolution can
1674 * happen elsewhere.
1677 struct evhttp_connection *
1678 evhttp_connection_new(const char *address, unsigned short port)
1680 struct evhttp_connection *evcon = NULL;
1682 event_debug(("Attempting connection to %s:%d\n", address, port));
1684 if ((evcon = calloc(1, sizeof(struct evhttp_connection))) == NULL) {
1685 event_warn("%s: calloc failed", __func__);
1686 goto error;
1689 evcon->fd = -1;
1690 evcon->port = port;
1692 evcon->timeout = -1;
1693 evcon->retry_cnt = evcon->retry_max = 0;
1695 if ((evcon->address = strdup(address)) == NULL) {
1696 event_warn("%s: strdup failed", __func__);
1697 goto error;
1700 if ((evcon->input_buffer = evbuffer_new()) == NULL) {
1701 event_warn("%s: evbuffer_new failed", __func__);
1702 goto error;
1705 if ((evcon->output_buffer = evbuffer_new()) == NULL) {
1706 event_warn("%s: evbuffer_new failed", __func__);
1707 goto error;
1710 evcon->state = EVCON_DISCONNECTED;
1711 TAILQ_INIT(&evcon->requests);
1713 return (evcon);
1715 error:
1716 if (evcon != NULL)
1717 evhttp_connection_free(evcon);
1718 return (NULL);
1721 void evhttp_connection_set_base(struct evhttp_connection *evcon,
1722 struct event_base *base)
1724 assert(evcon->base == NULL);
1725 assert(evcon->state == EVCON_DISCONNECTED);
1726 evcon->base = base;
1729 void
1730 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
1731 int timeout_in_secs)
1733 evcon->timeout = timeout_in_secs;
1736 void
1737 evhttp_connection_set_retries(struct evhttp_connection *evcon,
1738 int retry_max)
1740 evcon->retry_max = retry_max;
1743 void
1744 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
1745 void (*cb)(struct evhttp_connection *, void *), void *cbarg)
1747 evcon->closecb = cb;
1748 evcon->closecb_arg = cbarg;
1751 void
1752 evhttp_connection_get_peer(struct evhttp_connection *evcon,
1753 char **address, u_short *port)
1755 *address = evcon->address;
1756 *port = evcon->port;
1760 evhttp_connection_connect(struct evhttp_connection *evcon)
1762 if (evcon->state == EVCON_CONNECTING)
1763 return (0);
1765 evhttp_connection_reset(evcon);
1767 assert(!(evcon->flags & EVHTTP_CON_INCOMING));
1768 evcon->flags |= EVHTTP_CON_OUTGOING;
1770 evcon->fd = bind_socket(
1771 evcon->bind_address, evcon->bind_port, 0 /*reuse*/);
1772 if (evcon->fd == -1) {
1773 event_debug(("%s: failed to bind to \"%s\"",
1774 __func__, evcon->bind_address));
1775 return (-1);
1778 if (socket_connect(evcon->fd, evcon->address, evcon->port) == -1) {
1779 EVUTIL_CLOSESOCKET(evcon->fd); evcon->fd = -1;
1780 return (-1);
1783 /* Set up a callback for successful connection setup */
1784 event_set(&evcon->ev, evcon->fd, EV_WRITE, evhttp_connectioncb, evcon);
1785 EVHTTP_BASE_SET(evcon, &evcon->ev);
1786 evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_CONNECT_TIMEOUT);
1788 evcon->state = EVCON_CONNECTING;
1790 return (0);
1794 * Starts an HTTP request on the provided evhttp_connection object.
1795 * If the connection object is not connected to the web server already,
1796 * this will start the connection.
1800 evhttp_make_request(struct evhttp_connection *evcon,
1801 struct evhttp_request *req,
1802 enum evhttp_cmd_type type, const char *uri)
1804 /* We are making a request */
1805 req->kind = EVHTTP_REQUEST;
1806 req->type = type;
1807 if (req->uri != NULL)
1808 free(req->uri);
1809 if ((req->uri = strdup(uri)) == NULL)
1810 event_err(1, "%s: strdup", __func__);
1812 /* Set the protocol version if it is not supplied */
1813 if (!req->major && !req->minor) {
1814 req->major = 1;
1815 req->minor = 1;
1818 assert(req->evcon == NULL);
1819 req->evcon = evcon;
1820 assert(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
1822 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
1824 /* If the connection object is not connected; make it so */
1825 if (!evhttp_connected(evcon))
1826 return (evhttp_connection_connect(evcon));
1829 * If it's connected already and we are the first in the queue,
1830 * then we can dispatch this request immediately. Otherwise, it
1831 * will be dispatched once the pending requests are completed.
1833 if (TAILQ_FIRST(&evcon->requests) == req)
1834 evhttp_request_dispatch(evcon);
1836 return (0);
1840 * Reads data from file descriptor into request structure
1841 * Request structure needs to be set up correctly.
1844 void
1845 evhttp_start_read(struct evhttp_connection *evcon)
1847 /* Set up an event to read the headers */
1848 if (event_initialized(&evcon->ev))
1849 event_del(&evcon->ev);
1850 event_set(&evcon->ev, evcon->fd, EV_READ, evhttp_read, evcon);
1851 EVHTTP_BASE_SET(evcon, &evcon->ev);
1853 evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
1854 evcon->state = EVCON_READING_FIRSTLINE;
1857 static void
1858 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
1860 int need_close;
1861 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1862 TAILQ_REMOVE(&evcon->requests, req, next);
1864 /* delete possible close detection events */
1865 evhttp_connection_stop_detectclose(evcon);
1867 need_close =
1868 (req->minor == 0 &&
1869 !evhttp_is_connection_keepalive(req->input_headers))||
1870 evhttp_is_connection_close(req->flags, req->input_headers) ||
1871 evhttp_is_connection_close(req->flags, req->output_headers);
1873 assert(req->flags & EVHTTP_REQ_OWN_CONNECTION);
1874 evhttp_request_free(req);
1876 if (need_close) {
1877 evhttp_connection_free(evcon);
1878 return;
1881 /* we have a persistent connection; try to accept another request. */
1882 if (evhttp_associate_new_request_with_connection(evcon) == -1)
1883 evhttp_connection_free(evcon);
1887 * Returns an error page.
1890 void
1891 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
1893 #define ERR_FORMAT "<HTML><HEAD>\n" \
1894 "<TITLE>%d %s</TITLE>\n" \
1895 "</HEAD><BODY>\n" \
1896 "<H1>Method Not Implemented</H1>\n" \
1897 "Invalid method in request<P>\n" \
1898 "</BODY></HTML>\n"
1900 struct evbuffer *buf = evbuffer_new();
1902 /* close the connection on error */
1903 evhttp_add_header(req->output_headers, "Connection", "close");
1905 evhttp_response_code(req, error, reason);
1907 evbuffer_add_printf(buf, ERR_FORMAT, error, reason);
1909 evhttp_send_page(req, buf);
1911 evbuffer_free(buf);
1912 #undef ERR_FORMAT
1915 /* Requires that headers and response code are already set up */
1917 static inline void
1918 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
1920 struct evhttp_connection *evcon = req->evcon;
1922 assert(TAILQ_FIRST(&evcon->requests) == req);
1924 /* xxx: not sure if we really should expose the data buffer this way */
1925 if (databuf != NULL)
1926 evbuffer_add_buffer(req->output_buffer, databuf);
1928 /* Adds headers to the response */
1929 evhttp_make_header(evcon, req);
1931 evhttp_write_buffer(evcon, evhttp_send_done, NULL);
1934 void
1935 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
1936 struct evbuffer *databuf)
1938 evhttp_response_code(req, code, reason);
1940 evhttp_send(req, databuf);
1943 void
1944 evhttp_send_reply_start(struct evhttp_request *req, int code,
1945 const char *reason)
1947 evhttp_response_code(req, code, reason);
1948 if (req->major == 1 && req->minor == 1) {
1949 /* use chunked encoding for HTTP/1.1 */
1950 evhttp_add_header(req->output_headers, "Transfer-Encoding",
1951 "chunked");
1952 req->chunked = 1;
1954 evhttp_make_header(req->evcon, req);
1955 evhttp_write_buffer(req->evcon, NULL, NULL);
1958 void
1959 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
1961 if (req->chunked) {
1962 evbuffer_add_printf(req->evcon->output_buffer, "%x\r\n",
1963 (unsigned)EVBUFFER_LENGTH(databuf));
1965 evbuffer_add_buffer(req->evcon->output_buffer, databuf);
1966 if (req->chunked) {
1967 evbuffer_add(req->evcon->output_buffer, "\r\n", 2);
1969 evhttp_write_buffer(req->evcon, NULL, NULL);
1972 void
1973 evhttp_send_reply_end(struct evhttp_request *req)
1975 struct evhttp_connection *evcon = req->evcon;
1977 if (req->chunked) {
1978 evbuffer_add(req->evcon->output_buffer, "0\r\n\r\n", 5);
1979 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL);
1980 req->chunked = 0;
1981 } else if (!event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL)) {
1982 /* let the connection know that we are done with the request */
1983 evhttp_send_done(evcon, NULL);
1984 } else {
1985 /* make the callback execute after all data has been written */
1986 evcon->cb = evhttp_send_done;
1987 evcon->cb_arg = NULL;
1991 void
1992 evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
1994 req->kind = EVHTTP_RESPONSE;
1995 req->response_code = code;
1996 if (req->response_code_line != NULL)
1997 free(req->response_code_line);
1998 req->response_code_line = strdup(reason);
2001 void
2002 evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
2004 if (!req->major || !req->minor) {
2005 req->major = 1;
2006 req->minor = 1;
2009 if (req->kind != EVHTTP_RESPONSE)
2010 evhttp_response_code(req, 200, "OK");
2012 evhttp_clear_headers(req->output_headers);
2013 evhttp_add_header(req->output_headers, "Content-Type", "text/html");
2014 evhttp_add_header(req->output_headers, "Connection", "close");
2016 evhttp_send(req, databuf);
2019 static const char uri_chars[256] = {
2020 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2021 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2022 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2023 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0,
2024 /* 64 */
2025 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2026 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
2027 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2028 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
2029 /* 128 */
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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2034 /* 192 */
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,
2038 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2042 * Helper functions to encode/decode a URI.
2043 * The returned string must be freed by the caller.
2045 char *
2046 evhttp_encode_uri(const char *uri)
2048 struct evbuffer *buf = evbuffer_new();
2049 char *p;
2051 for (p = (char *)uri; *p != '\0'; p++) {
2052 if (uri_chars[(u_char)(*p)]) {
2053 evbuffer_add(buf, p, 1);
2054 } else {
2055 evbuffer_add_printf(buf, "%%%02X", (u_char)(*p));
2058 evbuffer_add(buf, "", 1);
2059 p = strdup((char *)EVBUFFER_DATA(buf));
2060 evbuffer_free(buf);
2062 return (p);
2066 * @param always_decode_plus: when true we transform plus to space even
2067 * if we have not seen a ?.
2069 static int
2070 evhttp_decode_uri_internal(
2071 const char *uri, size_t length, char *ret, int always_decode_plus)
2073 char c;
2074 int i, j, in_query = always_decode_plus;
2076 for (i = j = 0; uri[i] != '\0'; i++) {
2077 c = uri[i];
2078 if (c == '?') {
2079 in_query = 1;
2080 } else if (c == '+' && in_query) {
2081 c = ' ';
2082 } else if (c == '%' && isxdigit((unsigned char)uri[i+1]) &&
2083 isxdigit((unsigned char)uri[i+2])) {
2084 char tmp[] = { uri[i+1], uri[i+2], '\0' };
2085 c = (char)strtol(tmp, NULL, 16);
2086 i += 2;
2088 ret[j++] = c;
2090 ret[j] = '\0';
2092 return (j);
2095 char *
2096 evhttp_decode_uri(const char *uri)
2098 char *ret;
2100 if ((ret = malloc(strlen(uri) + 1)) == NULL)
2101 event_err(1, "%s: malloc(%lu)", __func__,
2102 (unsigned long)(strlen(uri) + 1));
2104 evhttp_decode_uri_internal(uri, strlen(uri),
2105 ret, 0 /*always_decode_plus*/);
2107 return (ret);
2111 * Helper function to parse out arguments in a query.
2112 * The arguments are separated by key and value.
2115 void
2116 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
2118 char *line;
2119 char *argument;
2120 char *p;
2122 TAILQ_INIT(headers);
2124 /* No arguments - we are done */
2125 if (strchr(uri, '?') == NULL)
2126 return;
2128 if ((line = strdup(uri)) == NULL)
2129 event_err(1, "%s: strdup", __func__);
2132 argument = line;
2134 /* We already know that there has to be a ? */
2135 strsep(&argument, "?");
2137 p = argument;
2138 while (p != NULL && *p != '\0') {
2139 char *key, *value, *decoded_value;
2140 argument = strsep(&p, "&");
2142 value = argument;
2143 key = strsep(&value, "=");
2144 if (value == NULL)
2145 goto error;
2147 if ((decoded_value = malloc(strlen(value) + 1)) == NULL)
2148 event_err(1, "%s: malloc", __func__);
2150 evhttp_decode_uri_internal(value, strlen(value),
2151 decoded_value, 1 /*always_decode_plus*/);
2152 event_debug(("Query Param: %s -> %s\n", key, decoded_value));
2153 evhttp_add_header_internal(headers, key, decoded_value);
2154 free(decoded_value);
2157 error:
2158 free(line);
2161 static struct evhttp_cb *
2162 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
2164 struct evhttp_cb *cb;
2165 size_t offset = 0;
2167 /* Test for different URLs */
2168 char *p = strchr(req->uri, '?');
2169 if (p != NULL)
2170 offset = (size_t)(p - req->uri);
2172 TAILQ_FOREACH(cb, callbacks, next) {
2173 int res = 0;
2174 if (p == NULL) {
2175 res = strcmp(cb->what, req->uri) == 0;
2176 } else {
2177 res = ((strncmp(cb->what, req->uri, offset) == 0) &&
2178 (cb->what[offset] == '\0'));
2181 if (res)
2182 return (cb);
2185 return (NULL);
2188 static void
2189 evhttp_handle_request(struct evhttp_request *req, void *arg)
2191 struct evhttp *http = arg;
2192 struct evhttp_cb *cb = NULL;
2194 if (req->uri == NULL) {
2195 evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
2196 return;
2199 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
2200 (*cb->cb)(req, cb->cbarg);
2201 return;
2204 /* Generic call back */
2205 if (http->gencb) {
2206 (*http->gencb)(req, http->gencbarg);
2207 return;
2208 } else {
2209 /* We need to send a 404 here */
2210 #define ERR_FORMAT "<html><head>" \
2211 "<title>404 Not Found</title>" \
2212 "</head><body>" \
2213 "<h1>Not Found</h1>" \
2214 "<p>The requested URL %s was not found on this server.</p>"\
2215 "</body></html>\n"
2217 char *escaped_html = evhttp_htmlescape(req->uri);
2218 struct evbuffer *buf = evbuffer_new();
2220 evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
2222 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
2224 free(escaped_html);
2226 evhttp_send_page(req, buf);
2228 evbuffer_free(buf);
2229 #undef ERR_FORMAT
2233 static void
2234 accept_socket(int fd, short what, void *arg)
2236 struct evhttp *http = arg;
2237 struct sockaddr_storage ss;
2238 socklen_t addrlen = sizeof(ss);
2239 int nfd;
2241 if ((nfd = accept(fd, (struct sockaddr *)&ss, &addrlen)) == -1) {
2242 if (errno != EAGAIN && errno != EINTR)
2243 event_warn("%s: bad accept", __func__);
2244 return;
2246 if (evutil_make_socket_nonblocking(nfd) < 0)
2247 return;
2249 evhttp_get_request(http, nfd, (struct sockaddr *)&ss, addrlen);
2253 evhttp_bind_socket(struct evhttp *http, const char *address, u_short port)
2255 int fd;
2256 int res;
2258 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
2259 return (-1);
2261 if (listen(fd, 128) == -1) {
2262 event_warn("%s: listen", __func__);
2263 EVUTIL_CLOSESOCKET(fd);
2264 return (-1);
2267 res = evhttp_accept_socket(http, fd);
2269 if (res != -1)
2270 event_debug(("Bound to port %d - Awaiting connections ... ",
2271 port));
2273 return (res);
2277 evhttp_accept_socket(struct evhttp *http, int fd)
2279 struct evhttp_bound_socket *bound;
2280 struct event *ev;
2281 int res;
2283 bound = malloc(sizeof(struct evhttp_bound_socket));
2284 if (bound == NULL)
2285 return (-1);
2287 ev = &bound->bind_ev;
2289 /* Schedule the socket for accepting */
2290 event_set(ev, fd, EV_READ | EV_PERSIST, accept_socket, http);
2291 EVHTTP_BASE_SET(http, ev);
2293 res = event_add(ev, NULL);
2295 if (res == -1) {
2296 free(bound);
2297 return (-1);
2300 TAILQ_INSERT_TAIL(&http->sockets, bound, next);
2302 return (0);
2305 static struct evhttp*
2306 evhttp_new_object(void)
2308 struct evhttp *http = NULL;
2310 if ((http = calloc(1, sizeof(struct evhttp))) == NULL) {
2311 event_warn("%s: calloc", __func__);
2312 return (NULL);
2315 http->timeout = -1;
2317 TAILQ_INIT(&http->sockets);
2318 TAILQ_INIT(&http->callbacks);
2319 TAILQ_INIT(&http->connections);
2321 return (http);
2324 struct evhttp *
2325 evhttp_new(struct event_base *base)
2327 struct evhttp *http = evhttp_new_object();
2329 http->base = base;
2331 return (http);
2335 * Start a web server on the specified address and port.
2338 struct evhttp *
2339 evhttp_start(const char *address, u_short port)
2341 struct evhttp *http = evhttp_new_object();
2343 if (evhttp_bind_socket(http, address, port) == -1) {
2344 free(http);
2345 return (NULL);
2348 return (http);
2351 void
2352 evhttp_free(struct evhttp* http)
2354 struct evhttp_cb *http_cb;
2355 struct evhttp_connection *evcon;
2356 struct evhttp_bound_socket *bound;
2357 int fd;
2359 /* Remove the accepting part */
2360 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
2361 TAILQ_REMOVE(&http->sockets, bound, next);
2363 fd = bound->bind_ev.ev_fd;
2364 event_del(&bound->bind_ev);
2365 EVUTIL_CLOSESOCKET(fd);
2367 free(bound);
2370 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
2371 /* evhttp_connection_free removes the connection */
2372 evhttp_connection_free(evcon);
2375 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) {
2376 TAILQ_REMOVE(&http->callbacks, http_cb, next);
2377 free(http_cb->what);
2378 free(http_cb);
2381 free(http);
2384 void
2385 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
2387 http->timeout = timeout_in_secs;
2390 void
2391 evhttp_set_cb(struct evhttp *http, const char *uri,
2392 void (*cb)(struct evhttp_request *, void *), void *cbarg)
2394 struct evhttp_cb *http_cb;
2396 if ((http_cb = calloc(1, sizeof(struct evhttp_cb))) == NULL)
2397 event_err(1, "%s: calloc", __func__);
2399 http_cb->what = strdup(uri);
2400 http_cb->cb = cb;
2401 http_cb->cbarg = cbarg;
2403 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
2407 evhttp_del_cb(struct evhttp *http, const char *uri)
2409 struct evhttp_cb *http_cb;
2411 TAILQ_FOREACH(http_cb, &http->callbacks, next) {
2412 if (strcmp(http_cb->what, uri) == 0)
2413 break;
2415 if (http_cb == NULL)
2416 return (-1);
2418 TAILQ_REMOVE(&http->callbacks, http_cb, next);
2419 free(http_cb->what);
2420 free(http_cb);
2422 return (0);
2425 void
2426 evhttp_set_gencb(struct evhttp *http,
2427 void (*cb)(struct evhttp_request *, void *), void *cbarg)
2429 http->gencb = cb;
2430 http->gencbarg = cbarg;
2434 * Request related functions
2437 struct evhttp_request *
2438 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
2440 struct evhttp_request *req = NULL;
2442 /* Allocate request structure */
2443 if ((req = calloc(1, sizeof(struct evhttp_request))) == NULL) {
2444 event_warn("%s: calloc", __func__);
2445 goto error;
2448 req->kind = EVHTTP_RESPONSE;
2449 req->input_headers = calloc(1, sizeof(struct evkeyvalq));
2450 if (req->input_headers == NULL) {
2451 event_warn("%s: calloc", __func__);
2452 goto error;
2454 TAILQ_INIT(req->input_headers);
2456 req->output_headers = calloc(1, sizeof(struct evkeyvalq));
2457 if (req->output_headers == NULL) {
2458 event_warn("%s: calloc", __func__);
2459 goto error;
2461 TAILQ_INIT(req->output_headers);
2463 if ((req->input_buffer = evbuffer_new()) == NULL) {
2464 event_warn("%s: evbuffer_new", __func__);
2465 goto error;
2468 if ((req->output_buffer = evbuffer_new()) == NULL) {
2469 event_warn("%s: evbuffer_new", __func__);
2470 goto error;
2473 req->cb = cb;
2474 req->cb_arg = arg;
2476 return (req);
2478 error:
2479 if (req != NULL)
2480 evhttp_request_free(req);
2481 return (NULL);
2484 void
2485 evhttp_request_free(struct evhttp_request *req)
2487 if (req->remote_host != NULL)
2488 free(req->remote_host);
2489 if (req->uri != NULL)
2490 free(req->uri);
2491 if (req->response_code_line != NULL)
2492 free(req->response_code_line);
2494 evhttp_clear_headers(req->input_headers);
2495 free(req->input_headers);
2497 evhttp_clear_headers(req->output_headers);
2498 free(req->output_headers);
2500 if (req->input_buffer != NULL)
2501 evbuffer_free(req->input_buffer);
2503 if (req->output_buffer != NULL)
2504 evbuffer_free(req->output_buffer);
2506 free(req);
2509 void
2510 evhttp_request_set_chunked_cb(struct evhttp_request *req,
2511 void (*cb)(struct evhttp_request *, void *))
2513 req->chunk_cb = cb;
2517 * Allows for inspection of the request URI
2520 const char *
2521 evhttp_request_uri(struct evhttp_request *req) {
2522 if (req->uri == NULL)
2523 event_debug(("%s: request %p has no uri\n", __func__, req));
2524 return (req->uri);
2528 * Takes a file descriptor to read a request from.
2529 * The callback is executed once the whole request has been read.
2532 static struct evhttp_connection*
2533 evhttp_get_request_connection(
2534 struct evhttp* http,
2535 int fd, struct sockaddr *sa, socklen_t salen)
2537 struct evhttp_connection *evcon;
2538 char *hostname = NULL, *portname = NULL;
2540 name_from_addr(sa, salen, &hostname, &portname);
2541 if (hostname == NULL || portname == NULL) {
2542 if (hostname) free(hostname);
2543 if (portname) free(portname);
2544 return (NULL);
2547 event_debug(("%s: new request from %s:%s on %d\n",
2548 __func__, hostname, portname, fd));
2550 /* we need a connection object to put the http request on */
2551 evcon = evhttp_connection_new(hostname, atoi(portname));
2552 free(hostname);
2553 free(portname);
2554 if (evcon == NULL)
2555 return (NULL);
2557 /* associate the base if we have one*/
2558 evhttp_connection_set_base(evcon, http->base);
2560 evcon->flags |= EVHTTP_CON_INCOMING;
2561 evcon->state = EVCON_READING_FIRSTLINE;
2563 evcon->fd = fd;
2565 return (evcon);
2568 static int
2569 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
2571 struct evhttp *http = evcon->http_server;
2572 struct evhttp_request *req;
2573 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL)
2574 return (-1);
2576 req->evcon = evcon; /* the request ends up owning the connection */
2577 req->flags |= EVHTTP_REQ_OWN_CONNECTION;
2579 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2581 req->kind = EVHTTP_REQUEST;
2583 if ((req->remote_host = strdup(evcon->address)) == NULL)
2584 event_err(1, "%s: strdup", __func__);
2585 req->remote_port = evcon->port;
2587 evhttp_start_read(evcon);
2589 return (0);
2592 void
2593 evhttp_get_request(struct evhttp *http, int fd,
2594 struct sockaddr *sa, socklen_t salen)
2596 struct evhttp_connection *evcon;
2598 evcon = evhttp_get_request_connection(http, fd, sa, salen);
2599 if (evcon == NULL)
2600 return;
2602 /* the timeout can be used by the server to close idle connections */
2603 if (http->timeout != -1)
2604 evhttp_connection_set_timeout(evcon, http->timeout);
2607 * if we want to accept more than one request on a connection,
2608 * we need to know which http server it belongs to.
2610 evcon->http_server = http;
2611 TAILQ_INSERT_TAIL(&http->connections, evcon, next);
2613 if (evhttp_associate_new_request_with_connection(evcon) == -1)
2614 evhttp_connection_free(evcon);
2619 * Network helper functions that we do not want to export to the rest of
2620 * the world.
2622 #if 0 /* Unused */
2623 static struct addrinfo *
2624 addr_from_name(char *address)
2626 #ifdef HAVE_GETADDRINFO
2627 struct addrinfo ai, *aitop;
2628 int ai_result;
2630 memset(&ai, 0, sizeof(ai));
2631 ai.ai_family = AF_INET;
2632 ai.ai_socktype = SOCK_RAW;
2633 ai.ai_flags = 0;
2634 if ((ai_result = getaddrinfo(address, NULL, &ai, &aitop)) != 0) {
2635 if ( ai_result == EAI_SYSTEM )
2636 event_warn("getaddrinfo");
2637 else
2638 event_warnx("getaddrinfo: %s", gai_strerror(ai_result));
2641 return (aitop);
2642 #else
2643 assert(0);
2644 return NULL; /* XXXXX Use gethostbyname, if this function is ever used. */
2645 #endif
2647 #endif
2649 static void
2650 name_from_addr(struct sockaddr *sa, socklen_t salen,
2651 char **phost, char **pport)
2653 char ntop[NI_MAXHOST];
2654 char strport[NI_MAXSERV];
2655 int ni_result;
2657 #ifdef HAVE_GETNAMEINFO
2658 ni_result = getnameinfo(sa, salen,
2659 ntop, sizeof(ntop), strport, sizeof(strport),
2660 NI_NUMERICHOST|NI_NUMERICSERV);
2662 if (ni_result != 0) {
2663 if (ni_result == EAI_SYSTEM)
2664 event_err(1, "getnameinfo failed");
2665 else
2666 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result));
2667 return;
2669 #else
2670 ni_result = fake_getnameinfo(sa, salen,
2671 ntop, sizeof(ntop), strport, sizeof(strport),
2672 NI_NUMERICHOST|NI_NUMERICSERV);
2673 if (ni_result != 0)
2674 return;
2675 #endif
2676 *phost = strdup(ntop);
2677 *pport = strdup(strport);
2680 /* Create a non-blocking socket and bind it */
2681 /* todo: rename this function */
2682 static int
2683 bind_socket_ai(struct addrinfo *ai, int reuse)
2685 int fd, on = 1, r;
2686 int serrno;
2688 /* Create listen socket */
2689 fd = socket(AF_INET, SOCK_STREAM, 0);
2690 if (fd == -1) {
2691 event_warn("socket");
2692 return (-1);
2695 if (evutil_make_socket_nonblocking(fd) < 0)
2696 goto out;
2698 #ifndef WIN32
2699 if (fcntl(fd, F_SETFD, 1) == -1) {
2700 event_warn("fcntl(F_SETFD)");
2701 goto out;
2703 #endif
2705 setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on));
2706 if (reuse) {
2707 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
2708 (void *)&on, sizeof(on));
2711 if (ai != NULL) {
2712 r = bind(fd, ai->ai_addr, ai->ai_addrlen);
2713 if (r == -1)
2714 goto out;
2717 return (fd);
2719 out:
2720 serrno = EVUTIL_SOCKET_ERROR();
2721 EVUTIL_CLOSESOCKET(fd);
2722 EVUTIL_SET_SOCKET_ERROR(serrno);
2723 return (-1);
2726 static struct addrinfo *
2727 make_addrinfo(const char *address, u_short port)
2729 struct addrinfo *aitop = NULL;
2731 #ifdef HAVE_GETADDRINFO
2732 struct addrinfo ai;
2733 char strport[NI_MAXSERV];
2734 int ai_result;
2736 memset(&ai, 0, sizeof(ai));
2737 ai.ai_family = AF_INET;
2738 ai.ai_socktype = SOCK_STREAM;
2739 ai.ai_flags = AI_PASSIVE; /* turn NULL host name into INADDR_ANY */
2740 evutil_snprintf(strport, sizeof(strport), "%d", port);
2741 if ((ai_result = getaddrinfo(address, strport, &ai, &aitop)) != 0) {
2742 if ( ai_result == EAI_SYSTEM )
2743 event_warn("getaddrinfo");
2744 else
2745 event_warnx("getaddrinfo: %s", gai_strerror(ai_result));
2746 return (NULL);
2748 #else
2749 static int cur;
2750 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. */
2751 if (++cur == 2) cur = 0; /* allow calling this function twice */
2753 if (fake_getaddrinfo(address, &ai[cur]) < 0) {
2754 event_warn("fake_getaddrinfo");
2755 return (NULL);
2757 aitop = &ai[cur];
2758 ((struct sockaddr_in *) aitop->ai_addr)->sin_port = htons(port);
2759 #endif
2761 return (aitop);
2764 static int
2765 bind_socket(const char *address, u_short port, int reuse)
2767 int fd;
2768 struct addrinfo *aitop = NULL;
2770 /* just create an unbound socket */
2771 if (address == NULL && port == 0)
2772 return bind_socket_ai(NULL, 0);
2774 aitop = make_addrinfo(address, port);
2776 if (aitop == NULL)
2777 return (-1);
2779 fd = bind_socket_ai(aitop, reuse);
2781 #ifdef HAVE_GETADDRINFO
2782 freeaddrinfo(aitop);
2783 #else
2784 fake_freeaddrinfo(aitop);
2785 #endif
2787 return (fd);
2790 static int
2791 socket_connect(int fd, const char *address, unsigned short port)
2793 struct addrinfo *ai = make_addrinfo(address, port);
2794 int res = -1;
2796 if (ai == NULL) {
2797 event_debug(("%s: make_addrinfo: \"%s:%d\"",
2798 __func__, address, port));
2799 return (-1);
2802 if (connect(fd, ai->ai_addr, ai->ai_addrlen) == -1) {
2803 #ifdef WIN32
2804 int tmp_error = WSAGetLastError();
2805 if (tmp_error != WSAEWOULDBLOCK && tmp_error != WSAEINVAL &&
2806 tmp_error != WSAEINPROGRESS) {
2807 goto out;
2809 #else
2810 if (errno != EINPROGRESS) {
2811 goto out;
2813 #endif
2816 /* everything is fine */
2817 res = 0;
2819 out:
2820 #ifdef HAVE_GETADDRINFO
2821 freeaddrinfo(ai);
2822 #else
2823 fake_freeaddrinfo(ai);
2824 #endif
2826 return (res);