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