xref: /netbsd/external/bsd/libevent/dist/http.c (revision 6550d01e)
1 /*	$NetBSD: http.c,v 1.1.1.1 2009/11/02 10:01:01 plunky Exp $	*/
2 /*
3  * Copyright (c) 2002-2006 Niels Provos <provos@citi.umich.edu>
4  * All rights reserved.
5  *
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.
16  *
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.
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
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
39 
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
46 
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
53 
54 #include <sys/queue.h>
55 
56 #ifndef WIN32
57 #include <netinet/in.h>
58 #include <netdb.h>
59 #endif
60 
61 #ifdef WIN32
62 #include <winsock2.h>
63 #endif
64 
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
82 
83 #undef timeout_pending
84 #undef timeout_initialized
85 
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"
92 
93 #ifdef WIN32
94 #define strcasecmp _stricmp
95 #define strncasecmp _strnicmp
96 #define strdup _strdup
97 #endif
98 
99 #ifndef HAVE_GETNAMEINFO
100 #define NI_MAXSERV 32
101 #define NI_MAXHOST 1025
102 
103 #define NI_NUMERICHOST 1
104 #define NI_NUMERICSERV 2
105 
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)
109 {
110         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
111 
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);
118         }
119 
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);
133 
134                         if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
135                                 return (-1);
136                         else
137                                 return (0);
138                 }
139         }
140         return (0);
141 }
142 
143 #endif
144 
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;
153 };
154 static int
155 fake_getaddrinfo(const char *hostname, struct addrinfo *ai)
156 {
157 	struct hostent *he = NULL;
158 	struct sockaddr_in *sa;
159 	if (hostname) {
160 		he = gethostbyname(hostname);
161 		if (!he)
162 			return (-1);
163 	}
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;
178 	}
179 	ai->ai_next = NULL;
180 	return (0);
181 }
182 static void
183 fake_freeaddrinfo(struct addrinfo *ai)
184 {
185 	free(ai->ai_addr);
186 }
187 #endif
188 
189 #ifndef MIN
190 #define MIN(a,b) (((a)<(b))?(a):(b))
191 #endif
192 
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)
197 
198 extern int debug;
199 
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);
219 
220 void evhttp_read(int, short, void *);
221 void evhttp_write(int, short, void *);
222 
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)
228 {
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;
241 }
242 #endif
243 
244 static const char *
245 html_replace(char ch, char *buf)
246 {
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;
260 	}
261 
262 	/* Echo the character back */
263 	buf[0] = ch;
264 	buf[1] = '\0';
265 
266 	return buf;
267 }
268 
269 /*
270  * Replaces <, >, ", ' and & with &lt;, &gt;, &quot;,
271  * &#039; and &amp; correspondingly.
272  *
273  * The returned string needs to be freed by the caller.
274  */
275 
276 char *
277 evhttp_htmlescape(const char *html)
278 {
279 	int i, new_size = 0, old_size = strlen(html);
280 	char *escaped_html, *p;
281 	char scratch_space[2];
282 
283 	for (i = 0; i < old_size; ++i)
284           new_size += strlen(html_replace(html[i], scratch_space));
285 
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);
294 	}
295 
296 	*p = '\0';
297 
298 	return (escaped_html);
299 }
300 
301 static const char *
302 evhttp_method(enum evhttp_cmd_type type)
303 {
304 	const char *method;
305 
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;
319 	}
320 
321 	return (method);
322 }
323 
324 static void
325 evhttp_add_event(struct event *ev, int timeout, int default_timeout)
326 {
327 	if (timeout != 0) {
328 		struct timeval tv;
329 
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);
335 	}
336 }
337 
338 void
339 evhttp_write_buffer(struct evhttp_connection *evcon,
340     void (*cb)(struct evhttp_connection *, void *), void *arg)
341 {
342 	event_debug(("%s: preparing to write buffer\n", __func__));
343 
344 	/* Set call back */
345 	evcon->cb = cb;
346 	evcon->cb_arg = arg;
347 
348 	/* check if the event is already pending */
349 	if (event_pending(&evcon->ev, EV_WRITE|EV_TIMEOUT, NULL))
350 		event_del(&evcon->ev);
351 
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);
355 }
356 
357 static int
358 evhttp_connected(struct evhttp_connection *evcon)
359 {
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);
372 	}
373 }
374 
375 /*
376  * Create the headers needed for an HTTP request
377  */
378 static void
379 evhttp_make_header_request(struct evhttp_connection *evcon,
380     struct evhttp_request *req)
381 {
382 	const char *method;
383 
384 	evhttp_remove_header(req->output_headers, "Proxy-Connection");
385 
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);
390 
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);
398 	}
399 }
400 
401 static int
402 evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
403 {
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);
411 	}
412 }
413 
414 static int
415 evhttp_is_connection_keepalive(struct evkeyvalq* headers)
416 {
417 	const char *connection = evhttp_find_header(headers, "Connection");
418 	return (connection != NULL
419 	    && strncasecmp(connection, "keep-alive", 10) == 0);
420 }
421 
422 static void
423 evhttp_maybe_add_date_header(struct evkeyvalq *headers)
424 {
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);
441 		}
442 	}
443 }
444 
445 static void
446 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
447     long content_length)
448 {
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);
454 	}
455 }
456 
457 /*
458  * Create the headers needed for an HTTP reply
459  */
460 
461 static void
462 evhttp_make_header_response(struct evhttp_connection *evcon,
463     struct evhttp_request *req)
464 {
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);
469 
470 	if (req->major == 1) {
471 		if (req->minor == 1)
472 			evhttp_maybe_add_date_header(req->output_headers);
473 
474 		/*
475 		 * if the protocol is 1.0; and the connection was keep-alive
476 		 * we need to add a keep-alive header, too.
477 		 */
478 		if (req->minor == 0 && is_keepalive)
479 			evhttp_add_header(req->output_headers,
480 			    "Connection", "keep-alive");
481 
482 		if (req->minor == 1 || is_keepalive) {
483 			/*
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.
487 			 */
488 			evhttp_maybe_add_content_length_header(
489 				req->output_headers,
490 				(long)EVBUFFER_LENGTH(req->output_buffer));
491 		}
492 	}
493 
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");
500 		}
501 	}
502 
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");
509 	}
510 }
511 
512 void
513 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
514 {
515 	struct evkeyval *header;
516 
517 	/*
518 	 * Depending if this is a HTTP request or response, we might need to
519 	 * add some new headers or remove existing headers.
520 	 */
521 	if (req->kind == EVHTTP_REQUEST) {
522 		evhttp_make_header_request(evcon, req);
523 	} else {
524 		evhttp_make_header_response(evcon, req);
525 	}
526 
527 	TAILQ_FOREACH(header, req->output_headers, next) {
528 		evbuffer_add_printf(evcon->output_buffer, "%s: %s\r\n",
529 		    header->key, header->value);
530 	}
531 	evbuffer_add(evcon->output_buffer, "\r\n", 2);
532 
533 	if (EVBUFFER_LENGTH(req->output_buffer) > 0) {
534 		/*
535 		 * For a request, we add the POST data, for a reply, this
536 		 * is the regular data.
537 		 */
538 		evbuffer_add_buffer(evcon->output_buffer, req->output_buffer);
539 	}
540 }
541 
542 /* Separated host, port and file from URI */
543 
544 int
545 evhttp_hostportfile(char *url, char **phost, u_short *pport, char **pfile)
546 {
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;
554 
555 	len = strlen(HTTP_PREFIX);
556 	if (strncasecmp(url, HTTP_PREFIX, len))
557 		return (-1);
558 
559 	url += len;
560 
561 	/* We might overrun */
562 	if (strlcpy(host, url, sizeof (host)) >= sizeof(host))
563 		return (-1);
564 
565 	p = strchr(host, '/');
566 	if (p != NULL) {
567 		*p = '\0';
568 		p2 = p + 1;
569 	} else
570 		p2 = NULL;
571 
572 	if (pfile != NULL) {
573 		/* Generate request file */
574 		if (p2 == NULL)
575 			p2 = "";
576 		evutil_snprintf(file, sizeof(file), "/%s", p2);
577 	}
578 
579 	p = strchr(host, ':');
580 	if (p != NULL) {
581 		*p = '\0';
582 		port = atoi(p + 1);
583 
584 		if (port == 0)
585 			return (-1);
586 	} else
587 		port = HTTP_DEFAULTPORT;
588 
589 	if (phost != NULL)
590 		*phost = host;
591 	if (pport != NULL)
592 		*pport = port;
593 	if (pfile != NULL)
594 		*pfile = file;
595 
596 	return (0);
597 }
598 
599 static int
600 evhttp_connection_incoming_fail(struct evhttp_request *req,
601     enum evhttp_connection_error error)
602 {
603 	switch (error) {
604 	case EVCON_HTTP_TIMEOUT:
605 	case EVCON_HTTP_EOF:
606 		/*
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.
611 		 */
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;
619 		}
620 
621 		/*
622 		 * the callback needs to send a reply, once the reply has
623 		 * been send, the connection should get freed.
624 		 */
625 		(*req->cb)(req, req->cb_arg);
626 	}
627 
628 	return (0);
629 }
630 
631 void
632 evhttp_connection_fail(struct evhttp_connection *evcon,
633     enum evhttp_connection_error error)
634 {
635 	struct evhttp_request* req = TAILQ_FIRST(&evcon->requests);
636 	void (*cb)(struct evhttp_request *, void *);
637 	void *cb_arg;
638 	assert(req != NULL);
639 
640 	if (evcon->flags & EVHTTP_CON_INCOMING) {
641 		/*
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.
648 		 */
649 		if (evhttp_connection_incoming_fail(req, error) == -1)
650 			evhttp_connection_free(evcon);
651 		return;
652 	}
653 
654 	/* save the callback for later; the cb might free our object */
655 	cb = req->cb;
656 	cb_arg = req->cb_arg;
657 
658 	TAILQ_REMOVE(&evcon->requests, req, next);
659 	evhttp_request_free(req);
660 
661 	/* xxx: maybe we should fail all requests??? */
662 
663 	/* reset the connection */
664 	evhttp_connection_reset(evcon);
665 
666 	/* We are trying the next request that was queued on us */
667 	if (TAILQ_FIRST(&evcon->requests) != NULL)
668 		evhttp_connection_connect(evcon);
669 
670 	/* inform the user */
671 	if (cb != NULL)
672 		(*cb)(NULL, cb_arg);
673 }
674 
675 void
676 evhttp_write(int fd, short what, void *arg)
677 {
678 	struct evhttp_connection *evcon = arg;
679 	int n;
680 
681 	if (what == EV_TIMEOUT) {
682 		evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
683 		return;
684 	}
685 
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;
691 	}
692 
693 	if (n == 0) {
694 		event_debug(("%s: write nothing", __func__));
695 		evhttp_connection_fail(evcon, EVCON_HTTP_EOF);
696 		return;
697 	}
698 
699 	if (EVBUFFER_LENGTH(evcon->output_buffer) != 0) {
700 		evhttp_add_event(&evcon->ev,
701 		    evcon->timeout, HTTP_WRITE_TIMEOUT);
702 		return;
703 	}
704 
705 	/* Activate our call back */
706 	if (evcon->cb != NULL)
707 		(*evcon->cb)(evcon, evcon->cb_arg);
708 }
709 
710 /**
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.
716  */
717 static void
718 evhttp_connection_done(struct evhttp_connection *evcon)
719 {
720 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
721 	int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING;
722 
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;
728 
729 		evcon->state = EVCON_IDLE;
730 
731 		need_close =
732 		    evhttp_is_connection_close(req->flags, req->input_headers)||
733 		    evhttp_is_connection_close(req->flags, req->output_headers);
734 
735 		/* check if we got asked to close the connection */
736 		if (need_close)
737 			evhttp_connection_reset(evcon);
738 
739 		if (TAILQ_FIRST(&evcon->requests) != NULL) {
740 			/*
741 			 * We have more requests; reset the connection
742 			 * and deal with the next request.
743 			 */
744 			if (!evhttp_connected(evcon))
745 				evhttp_connection_connect(evcon);
746 			else
747 				evhttp_request_dispatch(evcon);
748 		} else if (!need_close) {
749 			/*
750 			 * The connection is going to be persistent, but we
751 			 * need to detect if the other side closes it.
752 			 */
753 			evhttp_connection_start_detectclose(evcon);
754 		}
755 	} else {
756 		/*
757 		 * incoming connection - we need to leave the request on the
758 		 * connection so that we can reply to it.
759 		 */
760 		evcon->state = EVCON_WRITING;
761 	}
762 
763 	/* notify the user of the request */
764 	(*req->cb)(req, req->cb_arg);
765 
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);
769 	}
770 }
771 
772 /*
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
782  */
783 
784 static enum message_read_status
785 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
786 {
787 	int len;
788 
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;
802 			}
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);
811 			}
812 			req->ntoread = ntoread;
813 			if (req->ntoread == 0) {
814 				/* Last chunk */
815 				return (ALL_DATA_READ);
816 			}
817 			continue;
818 		}
819 
820 		/* don't have enough to complete a chunk; wait for more */
821 		if (len < req->ntoread)
822 			return (MORE_DATA_EXPECTED);
823 
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));
833 		}
834 	}
835 
836 	return (MORE_DATA_EXPECTED);
837 }
838 
839 static void
840 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req)
841 {
842 	struct evbuffer *buf = evcon->input_buffer;
843 
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;
857 	}
858 }
859 
860 static void
861 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req)
862 {
863 	struct evbuffer *buf = evcon->input_buffer;
864 
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;
884 		}
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;
896 	}
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);
901 }
902 
903 /*
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.
908  */
909 
910 void
911 evhttp_read(int fd, short what, void *arg)
912 {
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;
917 
918 	if (what == EV_TIMEOUT) {
919 		evhttp_connection_fail(evcon, EVCON_HTTP_TIMEOUT);
920 		return;
921 	}
922 	n = evbuffer_read(buf, fd, -1);
923 	len = EVBUFFER_LENGTH(buf);
924 	event_debug(("%s: got %d on %d\n", __func__, n, fd));
925 
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);
933 		}
934 		return;
935 	} else if (n == 0) {
936 		/* Connection closed */
937 		evhttp_connection_done(evcon);
938 		return;
939 	}
940 
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);
961 	}
962 }
963 
964 static void
965 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg)
966 {
967 	/* This is after writing the request to the server */
968 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
969 	assert(req != NULL);
970 
971 	assert(evcon->state == EVCON_WRITING);
972 
973 	/* We are done writing our header and are now expecting the response */
974 	req->kind = EVHTTP_RESPONSE;
975 
976 	evhttp_start_read(evcon);
977 }
978 
979 /*
980  * Clean up a connection object
981  */
982 
983 void
984 evhttp_connection_free(struct evhttp_connection *evcon)
985 {
986 	struct evhttp_request *req;
987 
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);
992 	}
993 
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);
998 	}
999 
1000 	if (evcon->http_server != NULL) {
1001 		struct evhttp *http = evcon->http_server;
1002 		TAILQ_REMOVE(&http->connections, evcon, next);
1003 	}
1004 
1005 	if (event_initialized(&evcon->close_ev))
1006 		event_del(&evcon->close_ev);
1007 
1008 	if (event_initialized(&evcon->ev))
1009 		event_del(&evcon->ev);
1010 
1011 	if (evcon->fd != -1)
1012 		EVUTIL_CLOSESOCKET(evcon->fd);
1013 
1014 	if (evcon->bind_address != NULL)
1015 		free(evcon->bind_address);
1016 
1017 	if (evcon->address != NULL)
1018 		free(evcon->address);
1019 
1020 	if (evcon->input_buffer != NULL)
1021 		evbuffer_free(evcon->input_buffer);
1022 
1023 	if (evcon->output_buffer != NULL)
1024 		evbuffer_free(evcon->output_buffer);
1025 
1026 	free(evcon);
1027 }
1028 
1029 void
1030 evhttp_connection_set_local_address(struct evhttp_connection *evcon,
1031     const char *address)
1032 {
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__);
1038 }
1039 
1040 void
1041 evhttp_connection_set_local_port(struct evhttp_connection *evcon,
1042     unsigned short port)
1043 {
1044 	assert(evcon->state == EVCON_DISCONNECTED);
1045 	evcon->bind_port = port;
1046 }
1047 
1048 static void
1049 evhttp_request_dispatch(struct evhttp_connection* evcon)
1050 {
1051 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1052 
1053 	/* this should not usually happy but it's possible */
1054 	if (req == NULL)
1055 		return;
1056 
1057 	/* delete possible close detection events */
1058 	evhttp_connection_stop_detectclose(evcon);
1059 
1060 	/* we assume that the connection is connected already */
1061 	assert(evcon->state == EVCON_IDLE);
1062 
1063 	evcon->state = EVCON_WRITING;
1064 
1065 	/* Create the header from the store arguments */
1066 	evhttp_make_header(evcon, req);
1067 
1068 	evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL);
1069 }
1070 
1071 /* Reset our connection state */
1072 void
1073 evhttp_connection_reset(struct evhttp_connection *evcon)
1074 {
1075 	if (event_initialized(&evcon->ev))
1076 		event_del(&evcon->ev);
1077 
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);
1082 
1083 		EVUTIL_CLOSESOCKET(evcon->fd);
1084 		evcon->fd = -1;
1085 	}
1086 	evcon->state = EVCON_DISCONNECTED;
1087 
1088 	evbuffer_drain(evcon->input_buffer,
1089 	    EVBUFFER_LENGTH(evcon->input_buffer));
1090 	evbuffer_drain(evcon->output_buffer,
1091 	    EVBUFFER_LENGTH(evcon->output_buffer));
1092 }
1093 
1094 static void
1095 evhttp_detect_close_cb(int fd, short what, void *arg)
1096 {
1097 	struct evhttp_connection *evcon = arg;
1098 	evhttp_connection_reset(evcon);
1099 }
1100 
1101 static void
1102 evhttp_connection_start_detectclose(struct evhttp_connection *evcon)
1103 {
1104 	evcon->flags |= EVHTTP_CON_CLOSEDETECT;
1105 
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);
1112 }
1113 
1114 static void
1115 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon)
1116 {
1117 	evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
1118 	event_del(&evcon->close_ev);
1119 }
1120 
1121 static void
1122 evhttp_connection_retry(int fd, short what, void *arg)
1123 {
1124 	struct evhttp_connection *evcon = arg;
1125 
1126 	evcon->state = EVCON_DISCONNECTED;
1127 	evhttp_connection_connect(evcon);
1128 }
1129 
1130 /*
1131  * Call back for asynchronous connection attempt.
1132  */
1133 
1134 static void
1135 evhttp_connectioncb(int fd, short what, void *arg)
1136 {
1137 	struct evhttp_connection *evcon = arg;
1138 	int error;
1139 	socklen_t errsz = sizeof(error);
1140 
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;
1145 	}
1146 
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;
1153 	}
1154 
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;
1160 	}
1161 
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));
1165 
1166 	/* Reset the retry count as we were successful in connecting */
1167 	evcon->retry_cnt = 0;
1168 	evcon->state = EVCON_IDLE;
1169 
1170 	/* try to start requests that have queued up on this connection */
1171 	evhttp_request_dispatch(evcon);
1172 	return;
1173 
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;
1182 	}
1183 	evhttp_connection_reset(evcon);
1184 
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;
1190 
1191 		/* we might want to set an error here */
1192 		request->cb(request, request->cb_arg);
1193 		evhttp_request_free(request);
1194 	}
1195 }
1196 
1197 /*
1198  * Check if we got a valid response code.
1199  */
1200 
1201 static int
1202 evhttp_valid_response_code(int code)
1203 {
1204 	if (code == 0)
1205 		return (0);
1206 
1207 	return (1);
1208 }
1209 
1210 /* Parses the status line of a web server */
1211 
1212 static int
1213 evhttp_parse_response_line(struct evhttp_request *req, char *line)
1214 {
1215 	char *protocol;
1216 	char *number;
1217 	char *readable;
1218 
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;
1226 
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);
1237 	}
1238 
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);
1244 	}
1245 
1246 	if ((req->response_code_line = strdup(readable)) == NULL)
1247 		event_err(1, "%s: strdup", __func__);
1248 
1249 	return (0);
1250 }
1251 
1252 /* Parse the first line of a HTTP request */
1253 
1254 static int
1255 evhttp_parse_request_line(struct evhttp_request *req, char *line)
1256 {
1257 	char *method;
1258 	char *uri;
1259 	char *version;
1260 
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);
1271 
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);
1283 	}
1284 
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);
1295 	}
1296 
1297 	if ((req->uri = strdup(uri)) == NULL) {
1298 		event_debug(("%s: evhttp_decode_uri", __func__));
1299 		return (-1);
1300 	}
1301 
1302 	/* determine if it's a proxy request */
1303 	if (strlen(req->uri) > 0 && req->uri[0] != '/')
1304 		req->flags |= EVHTTP_PROXY_REQUEST;
1305 
1306 	return (0);
1307 }
1308 
1309 const char *
1310 evhttp_find_header(const struct evkeyvalq *headers, const char *key)
1311 {
1312 	struct evkeyval *header;
1313 
1314 	TAILQ_FOREACH(header, headers, next) {
1315 		if (strcasecmp(header->key, key) == 0)
1316 			return (header->value);
1317 	}
1318 
1319 	return (NULL);
1320 }
1321 
1322 void
1323 evhttp_clear_headers(struct evkeyvalq *headers)
1324 {
1325 	struct evkeyval *header;
1326 
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);
1334 	}
1335 }
1336 
1337 /*
1338  * Returns 0,  if the header was successfully removed.
1339  * Returns -1, if the header could not be found.
1340  */
1341 
1342 int
1343 evhttp_remove_header(struct evkeyvalq *headers, const char *key)
1344 {
1345 	struct evkeyval *header;
1346 
1347 	TAILQ_FOREACH(header, headers, next) {
1348 		if (strcasecmp(header->key, key) == 0)
1349 			break;
1350 	}
1351 
1352 	if (header == NULL)
1353 		return (-1);
1354 
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);
1360 
1361 	return (0);
1362 }
1363 
1364 static int
1365 evhttp_header_is_valid_value(const char *value)
1366 {
1367 	const char *p = value;
1368 
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);
1375 	}
1376 	return (1);
1377 }
1378 
1379 int
1380 evhttp_add_header(struct evkeyvalq *headers,
1381     const char *key, const char *value)
1382 {
1383 	event_debug(("%s: key: %s val: %s\n", __func__, key, value));
1384 
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);
1389 	}
1390 
1391 	if (!evhttp_header_is_valid_value(value)) {
1392 		event_debug(("%s: dropping illegal header value\n", __func__));
1393 		return (-1);
1394 	}
1395 
1396 	return (evhttp_add_header_internal(headers, key, value));
1397 }
1398 
1399 static int
1400 evhttp_add_header_internal(struct evkeyvalq *headers,
1401     const char *key, const char *value)
1402 {
1403 	struct evkeyval *header = calloc(1, sizeof(struct evkeyval));
1404 	if (header == NULL) {
1405 		event_warn("%s: calloc", __func__);
1406 		return (-1);
1407 	}
1408 	if ((header->key = strdup(key)) == NULL) {
1409 		free(header);
1410 		event_warn("%s: strdup", __func__);
1411 		return (-1);
1412 	}
1413 	if ((header->value = strdup(value)) == NULL) {
1414 		free(header->key);
1415 		free(header);
1416 		event_warn("%s: strdup", __func__);
1417 		return (-1);
1418 	}
1419 
1420 	TAILQ_INSERT_TAIL(headers, header, next);
1421 
1422 	return (0);
1423 }
1424 
1425 /*
1426  * Parses header lines from a request or a response into the specified
1427  * request object given an event buffer.
1428  *
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.
1433  */
1434 
1435 enum message_read_status
1436 evhttp_parse_firstline(struct evhttp_request *req, struct evbuffer *buffer)
1437 {
1438 	char *line;
1439 	enum message_read_status status = ALL_DATA_READ;
1440 
1441 	line = evbuffer_readline(buffer);
1442 	if (line == NULL)
1443 		return (MORE_DATA_EXPECTED);
1444 
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;
1456 	}
1457 
1458 	free(line);
1459 	return (status);
1460 }
1461 
1462 static int
1463 evhttp_append_to_last_header(struct evkeyvalq *headers, const char *line)
1464 {
1465 	struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq);
1466 	char *newval;
1467 	size_t old_len, line_len;
1468 
1469 	if (header == NULL)
1470 		return (-1);
1471 
1472 	old_len = strlen(header->value);
1473 	line_len = strlen(line);
1474 
1475 	newval = realloc(header->value, old_len + line_len + 1);
1476 	if (newval == NULL)
1477 		return (-1);
1478 
1479 	memcpy(newval + old_len, line, line_len + 1);
1480 	header->value = newval;
1481 
1482 	return (0);
1483 }
1484 
1485 enum message_read_status
1486 evhttp_parse_headers(struct evhttp_request *req, struct evbuffer* buffer)
1487 {
1488 	char *line;
1489 	enum message_read_status status = MORE_DATA_EXPECTED;
1490 
1491 	struct evkeyvalq* headers = req->input_headers;
1492 	while ((line = evbuffer_readline(buffer))
1493 	       != NULL) {
1494 		char *skey, *svalue;
1495 
1496 		if (*line == '\0') { /* Last header - Done */
1497 			status = ALL_DATA_READ;
1498 			free(line);
1499 			break;
1500 		}
1501 
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;
1508 		}
1509 
1510 		/* Processing of header lines */
1511 		svalue = line;
1512 		skey = strsep(&svalue, ":");
1513 		if (svalue == NULL)
1514 			goto error;
1515 
1516 		svalue += strspn(svalue, " ");
1517 
1518 		if (evhttp_add_header(headers, skey, svalue) == -1)
1519 			goto error;
1520 
1521 		free(line);
1522 	}
1523 
1524 	return (status);
1525 
1526  error:
1527 	free(line);
1528 	return (DATA_CORRUPTED);
1529 }
1530 
1531 static int
1532 evhttp_get_body_length(struct evhttp_request *req)
1533 {
1534 	struct evkeyvalq *headers = req->input_headers;
1535 	const char *content_length;
1536 	const char *connection;
1537 
1538 	content_length = evhttp_find_header(headers, "Content-Length");
1539 	connection = evhttp_find_header(headers, "Connection");
1540 
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);
1559 		}
1560 		req->ntoread = ntoread;
1561 	}
1562 
1563 	event_debug(("%s: bytes to read: %lld (in buffer %ld)\n",
1564 		__func__, req->ntoread,
1565 		EVBUFFER_LENGTH(req->evcon->input_buffer)));
1566 
1567 	return (0);
1568 }
1569 
1570 static void
1571 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
1572 {
1573 	const char *xfer_enc;
1574 
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;
1579 	}
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;
1590 		}
1591 	}
1592 	evhttp_read_body(evcon, req);
1593 }
1594 
1595 static void
1596 evhttp_read_firstline(struct evhttp_connection *evcon,
1597 		      struct evhttp_request *req)
1598 {
1599 	enum message_read_status res;
1600 
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;
1613 	}
1614 
1615 	evcon->state = EVCON_READING_HEADERS;
1616 	evhttp_read_header(evcon, req);
1617 }
1618 
1619 static void
1620 evhttp_read_header(struct evhttp_connection *evcon, struct evhttp_request *req)
1621 {
1622 	enum message_read_status res;
1623 	int fd = evcon->fd;
1624 
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;
1636 	}
1637 
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;
1645 
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);
1657 		}
1658 		break;
1659 
1660 	default:
1661 		event_warnx("%s: bad header on %d", __func__, fd);
1662 		evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
1663 		break;
1664 	}
1665 }
1666 
1667 /*
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.
1671  *
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.
1675  */
1676 
1677 struct evhttp_connection *
1678 evhttp_connection_new(const char *address, unsigned short port)
1679 {
1680 	struct evhttp_connection *evcon = NULL;
1681 
1682 	event_debug(("Attempting connection to %s:%d\n", address, port));
1683 
1684 	if ((evcon = calloc(1, sizeof(struct evhttp_connection))) == NULL) {
1685 		event_warn("%s: calloc failed", __func__);
1686 		goto error;
1687 	}
1688 
1689 	evcon->fd = -1;
1690 	evcon->port = port;
1691 
1692 	evcon->timeout = -1;
1693 	evcon->retry_cnt = evcon->retry_max = 0;
1694 
1695 	if ((evcon->address = strdup(address)) == NULL) {
1696 		event_warn("%s: strdup failed", __func__);
1697 		goto error;
1698 	}
1699 
1700 	if ((evcon->input_buffer = evbuffer_new()) == NULL) {
1701 		event_warn("%s: evbuffer_new failed", __func__);
1702 		goto error;
1703 	}
1704 
1705 	if ((evcon->output_buffer = evbuffer_new()) == NULL) {
1706 		event_warn("%s: evbuffer_new failed", __func__);
1707 		goto error;
1708 	}
1709 
1710 	evcon->state = EVCON_DISCONNECTED;
1711 	TAILQ_INIT(&evcon->requests);
1712 
1713 	return (evcon);
1714 
1715  error:
1716 	if (evcon != NULL)
1717 		evhttp_connection_free(evcon);
1718 	return (NULL);
1719 }
1720 
1721 void evhttp_connection_set_base(struct evhttp_connection *evcon,
1722     struct event_base *base)
1723 {
1724 	assert(evcon->base == NULL);
1725 	assert(evcon->state == EVCON_DISCONNECTED);
1726 	evcon->base = base;
1727 }
1728 
1729 void
1730 evhttp_connection_set_timeout(struct evhttp_connection *evcon,
1731     int timeout_in_secs)
1732 {
1733 	evcon->timeout = timeout_in_secs;
1734 }
1735 
1736 void
1737 evhttp_connection_set_retries(struct evhttp_connection *evcon,
1738     int retry_max)
1739 {
1740 	evcon->retry_max = retry_max;
1741 }
1742 
1743 void
1744 evhttp_connection_set_closecb(struct evhttp_connection *evcon,
1745     void (*cb)(struct evhttp_connection *, void *), void *cbarg)
1746 {
1747 	evcon->closecb = cb;
1748 	evcon->closecb_arg = cbarg;
1749 }
1750 
1751 void
1752 evhttp_connection_get_peer(struct evhttp_connection *evcon,
1753     char **address, u_short *port)
1754 {
1755 	*address = evcon->address;
1756 	*port = evcon->port;
1757 }
1758 
1759 int
1760 evhttp_connection_connect(struct evhttp_connection *evcon)
1761 {
1762 	if (evcon->state == EVCON_CONNECTING)
1763 		return (0);
1764 
1765 	evhttp_connection_reset(evcon);
1766 
1767 	assert(!(evcon->flags & EVHTTP_CON_INCOMING));
1768 	evcon->flags |= EVHTTP_CON_OUTGOING;
1769 
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);
1776 	}
1777 
1778 	if (socket_connect(evcon->fd, evcon->address, evcon->port) == -1) {
1779 		EVUTIL_CLOSESOCKET(evcon->fd); evcon->fd = -1;
1780 		return (-1);
1781 	}
1782 
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);
1787 
1788 	evcon->state = EVCON_CONNECTING;
1789 
1790 	return (0);
1791 }
1792 
1793 /*
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.
1797  */
1798 
1799 int
1800 evhttp_make_request(struct evhttp_connection *evcon,
1801     struct evhttp_request *req,
1802     enum evhttp_cmd_type type, const char *uri)
1803 {
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__);
1811 
1812 	/* Set the protocol version if it is not supplied */
1813 	if (!req->major && !req->minor) {
1814 		req->major = 1;
1815 		req->minor = 1;
1816 	}
1817 
1818 	assert(req->evcon == NULL);
1819 	req->evcon = evcon;
1820 	assert(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
1821 
1822 	TAILQ_INSERT_TAIL(&evcon->requests, req, next);
1823 
1824 	/* If the connection object is not connected; make it so */
1825 	if (!evhttp_connected(evcon))
1826 		return (evhttp_connection_connect(evcon));
1827 
1828 	/*
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.
1832 	 */
1833 	if (TAILQ_FIRST(&evcon->requests) == req)
1834 		evhttp_request_dispatch(evcon);
1835 
1836 	return (0);
1837 }
1838 
1839 /*
1840  * Reads data from file descriptor into request structure
1841  * Request structure needs to be set up correctly.
1842  */
1843 
1844 void
1845 evhttp_start_read(struct evhttp_connection *evcon)
1846 {
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);
1852 
1853 	evhttp_add_event(&evcon->ev, evcon->timeout, HTTP_READ_TIMEOUT);
1854 	evcon->state = EVCON_READING_FIRSTLINE;
1855 }
1856 
1857 static void
1858 evhttp_send_done(struct evhttp_connection *evcon, void *arg)
1859 {
1860 	int need_close;
1861 	struct evhttp_request *req = TAILQ_FIRST(&evcon->requests);
1862 	TAILQ_REMOVE(&evcon->requests, req, next);
1863 
1864 	/* delete possible close detection events */
1865 	evhttp_connection_stop_detectclose(evcon);
1866 
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);
1872 
1873 	assert(req->flags & EVHTTP_REQ_OWN_CONNECTION);
1874 	evhttp_request_free(req);
1875 
1876 	if (need_close) {
1877 		evhttp_connection_free(evcon);
1878 		return;
1879 	}
1880 
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);
1884 }
1885 
1886 /*
1887  * Returns an error page.
1888  */
1889 
1890 void
1891 evhttp_send_error(struct evhttp_request *req, int error, const char *reason)
1892 {
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"
1899 
1900 	struct evbuffer *buf = evbuffer_new();
1901 
1902 	/* close the connection on error */
1903 	evhttp_add_header(req->output_headers, "Connection", "close");
1904 
1905 	evhttp_response_code(req, error, reason);
1906 
1907 	evbuffer_add_printf(buf, ERR_FORMAT, error, reason);
1908 
1909 	evhttp_send_page(req, buf);
1910 
1911 	evbuffer_free(buf);
1912 #undef ERR_FORMAT
1913 }
1914 
1915 /* Requires that headers and response code are already set up */
1916 
1917 static inline void
1918 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf)
1919 {
1920 	struct evhttp_connection *evcon = req->evcon;
1921 
1922 	assert(TAILQ_FIRST(&evcon->requests) == req);
1923 
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);
1927 
1928 	/* Adds headers to the response */
1929 	evhttp_make_header(evcon, req);
1930 
1931 	evhttp_write_buffer(evcon, evhttp_send_done, NULL);
1932 }
1933 
1934 void
1935 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason,
1936     struct evbuffer *databuf)
1937 {
1938 	evhttp_response_code(req, code, reason);
1939 
1940 	evhttp_send(req, databuf);
1941 }
1942 
1943 void
1944 evhttp_send_reply_start(struct evhttp_request *req, int code,
1945     const char *reason)
1946 {
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;
1953 	}
1954 	evhttp_make_header(req->evcon, req);
1955 	evhttp_write_buffer(req->evcon, NULL, NULL);
1956 }
1957 
1958 void
1959 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf)
1960 {
1961 	if (req->chunked) {
1962 		evbuffer_add_printf(req->evcon->output_buffer, "%x\r\n",
1963 				    (unsigned)EVBUFFER_LENGTH(databuf));
1964 	}
1965 	evbuffer_add_buffer(req->evcon->output_buffer, databuf);
1966 	if (req->chunked) {
1967 		evbuffer_add(req->evcon->output_buffer, "\r\n", 2);
1968 	}
1969 	evhttp_write_buffer(req->evcon, NULL, NULL);
1970 }
1971 
1972 void
1973 evhttp_send_reply_end(struct evhttp_request *req)
1974 {
1975 	struct evhttp_connection *evcon = req->evcon;
1976 
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;
1988 	}
1989 }
1990 
1991 void
1992 evhttp_response_code(struct evhttp_request *req, int code, const char *reason)
1993 {
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);
1999 }
2000 
2001 void
2002 evhttp_send_page(struct evhttp_request *req, struct evbuffer *databuf)
2003 {
2004 	if (!req->major || !req->minor) {
2005 		req->major = 1;
2006 		req->minor = 1;
2007 	}
2008 
2009 	if (req->kind != EVHTTP_RESPONSE)
2010 		evhttp_response_code(req, 200, "OK");
2011 
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");
2015 
2016 	evhttp_send(req, databuf);
2017 }
2018 
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,
2039 };
2040 
2041 /*
2042  * Helper functions to encode/decode a URI.
2043  * The returned string must be freed by the caller.
2044  */
2045 char *
2046 evhttp_encode_uri(const char *uri)
2047 {
2048 	struct evbuffer *buf = evbuffer_new();
2049 	char *p;
2050 
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));
2056 		}
2057 	}
2058 	evbuffer_add(buf, "", 1);
2059 	p = strdup((char *)EVBUFFER_DATA(buf));
2060 	evbuffer_free(buf);
2061 
2062 	return (p);
2063 }
2064 
2065 /*
2066  * @param always_decode_plus: when true we transform plus to space even
2067  *     if we have not seen a ?.
2068  */
2069 static int
2070 evhttp_decode_uri_internal(
2071 	const char *uri, size_t length, char *ret, int always_decode_plus)
2072 {
2073 	char c;
2074 	int i, j, in_query = always_decode_plus;
2075 
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;
2087 		}
2088 		ret[j++] = c;
2089 	}
2090 	ret[j] = '\0';
2091 
2092 	return (j);
2093 }
2094 
2095 char *
2096 evhttp_decode_uri(const char *uri)
2097 {
2098 	char *ret;
2099 
2100 	if ((ret = malloc(strlen(uri) + 1)) == NULL)
2101 		event_err(1, "%s: malloc(%lu)", __func__,
2102 			  (unsigned long)(strlen(uri) + 1));
2103 
2104 	evhttp_decode_uri_internal(uri, strlen(uri),
2105 	    ret, 0 /*always_decode_plus*/);
2106 
2107 	return (ret);
2108 }
2109 
2110 /*
2111  * Helper function to parse out arguments in a query.
2112  * The arguments are separated by key and value.
2113  */
2114 
2115 void
2116 evhttp_parse_query(const char *uri, struct evkeyvalq *headers)
2117 {
2118 	char *line;
2119 	char *argument;
2120 	char *p;
2121 
2122 	TAILQ_INIT(headers);
2123 
2124 	/* No arguments - we are done */
2125 	if (strchr(uri, '?') == NULL)
2126 		return;
2127 
2128 	if ((line = strdup(uri)) == NULL)
2129 		event_err(1, "%s: strdup", __func__);
2130 
2131 
2132 	argument = line;
2133 
2134 	/* We already know that there has to be a ? */
2135 	strsep(&argument, "?");
2136 
2137 	p = argument;
2138 	while (p != NULL && *p != '\0') {
2139 		char *key, *value, *decoded_value;
2140 		argument = strsep(&p, "&");
2141 
2142 		value = argument;
2143 		key = strsep(&value, "=");
2144 		if (value == NULL)
2145 			goto error;
2146 
2147 		if ((decoded_value = malloc(strlen(value) + 1)) == NULL)
2148 			event_err(1, "%s: malloc", __func__);
2149 
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);
2155 	}
2156 
2157  error:
2158 	free(line);
2159 }
2160 
2161 static struct evhttp_cb *
2162 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req)
2163 {
2164 	struct evhttp_cb *cb;
2165 	size_t offset = 0;
2166 
2167 	/* Test for different URLs */
2168 	char *p = strchr(req->uri, '?');
2169 	if (p != NULL)
2170 		offset = (size_t)(p - req->uri);
2171 
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'));
2179 		}
2180 
2181 		if (res)
2182 			return (cb);
2183 	}
2184 
2185 	return (NULL);
2186 }
2187 
2188 static void
2189 evhttp_handle_request(struct evhttp_request *req, void *arg)
2190 {
2191 	struct evhttp *http = arg;
2192 	struct evhttp_cb *cb = NULL;
2193 
2194 	if (req->uri == NULL) {
2195 		evhttp_send_error(req, HTTP_BADREQUEST, "Bad Request");
2196 		return;
2197 	}
2198 
2199 	if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) {
2200 		(*cb->cb)(req, cb->cbarg);
2201 		return;
2202 	}
2203 
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"
2216 
2217 		char *escaped_html = evhttp_htmlescape(req->uri);
2218 		struct evbuffer *buf = evbuffer_new();
2219 
2220 		evhttp_response_code(req, HTTP_NOTFOUND, "Not Found");
2221 
2222 		evbuffer_add_printf(buf, ERR_FORMAT, escaped_html);
2223 
2224 		free(escaped_html);
2225 
2226 		evhttp_send_page(req, buf);
2227 
2228 		evbuffer_free(buf);
2229 #undef ERR_FORMAT
2230 	}
2231 }
2232 
2233 static void
2234 accept_socket(int fd, short what, void *arg)
2235 {
2236 	struct evhttp *http = arg;
2237 	struct sockaddr_storage ss;
2238 	socklen_t addrlen = sizeof(ss);
2239 	int nfd;
2240 
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;
2245 	}
2246 	if (evutil_make_socket_nonblocking(nfd) < 0)
2247 		return;
2248 
2249 	evhttp_get_request(http, nfd, (struct sockaddr *)&ss, addrlen);
2250 }
2251 
2252 int
2253 evhttp_bind_socket(struct evhttp *http, const char *address, u_short port)
2254 {
2255 	int fd;
2256 	int res;
2257 
2258 	if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1)
2259 		return (-1);
2260 
2261 	if (listen(fd, 128) == -1) {
2262 		event_warn("%s: listen", __func__);
2263 		EVUTIL_CLOSESOCKET(fd);
2264 		return (-1);
2265 	}
2266 
2267 	res = evhttp_accept_socket(http, fd);
2268 
2269 	if (res != -1)
2270 		event_debug(("Bound to port %d - Awaiting connections ... ",
2271 			port));
2272 
2273 	return (res);
2274 }
2275 
2276 int
2277 evhttp_accept_socket(struct evhttp *http, int fd)
2278 {
2279 	struct evhttp_bound_socket *bound;
2280 	struct event *ev;
2281 	int res;
2282 
2283 	bound = malloc(sizeof(struct evhttp_bound_socket));
2284 	if (bound == NULL)
2285 		return (-1);
2286 
2287 	ev = &bound->bind_ev;
2288 
2289 	/* Schedule the socket for accepting */
2290 	event_set(ev, fd, EV_READ | EV_PERSIST, accept_socket, http);
2291 	EVHTTP_BASE_SET(http, ev);
2292 
2293 	res = event_add(ev, NULL);
2294 
2295 	if (res == -1) {
2296 		free(bound);
2297 		return (-1);
2298 	}
2299 
2300 	TAILQ_INSERT_TAIL(&http->sockets, bound, next);
2301 
2302 	return (0);
2303 }
2304 
2305 static struct evhttp*
2306 evhttp_new_object(void)
2307 {
2308 	struct evhttp *http = NULL;
2309 
2310 	if ((http = calloc(1, sizeof(struct evhttp))) == NULL) {
2311 		event_warn("%s: calloc", __func__);
2312 		return (NULL);
2313 	}
2314 
2315 	http->timeout = -1;
2316 
2317 	TAILQ_INIT(&http->sockets);
2318 	TAILQ_INIT(&http->callbacks);
2319 	TAILQ_INIT(&http->connections);
2320 
2321 	return (http);
2322 }
2323 
2324 struct evhttp *
2325 evhttp_new(struct event_base *base)
2326 {
2327 	struct evhttp *http = evhttp_new_object();
2328 
2329 	http->base = base;
2330 
2331 	return (http);
2332 }
2333 
2334 /*
2335  * Start a web server on the specified address and port.
2336  */
2337 
2338 struct evhttp *
2339 evhttp_start(const char *address, u_short port)
2340 {
2341 	struct evhttp *http = evhttp_new_object();
2342 
2343 	if (evhttp_bind_socket(http, address, port) == -1) {
2344 		free(http);
2345 		return (NULL);
2346 	}
2347 
2348 	return (http);
2349 }
2350 
2351 void
2352 evhttp_free(struct evhttp* http)
2353 {
2354 	struct evhttp_cb *http_cb;
2355 	struct evhttp_connection *evcon;
2356 	struct evhttp_bound_socket *bound;
2357 	int fd;
2358 
2359 	/* Remove the accepting part */
2360 	while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
2361 		TAILQ_REMOVE(&http->sockets, bound, next);
2362 
2363 		fd = bound->bind_ev.ev_fd;
2364 		event_del(&bound->bind_ev);
2365 		EVUTIL_CLOSESOCKET(fd);
2366 
2367 		free(bound);
2368 	}
2369 
2370 	while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
2371 		/* evhttp_connection_free removes the connection */
2372 		evhttp_connection_free(evcon);
2373 	}
2374 
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);
2379 	}
2380 
2381 	free(http);
2382 }
2383 
2384 void
2385 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs)
2386 {
2387 	http->timeout = timeout_in_secs;
2388 }
2389 
2390 void
2391 evhttp_set_cb(struct evhttp *http, const char *uri,
2392     void (*cb)(struct evhttp_request *, void *), void *cbarg)
2393 {
2394 	struct evhttp_cb *http_cb;
2395 
2396 	if ((http_cb = calloc(1, sizeof(struct evhttp_cb))) == NULL)
2397 		event_err(1, "%s: calloc", __func__);
2398 
2399 	http_cb->what = strdup(uri);
2400 	http_cb->cb = cb;
2401 	http_cb->cbarg = cbarg;
2402 
2403 	TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next);
2404 }
2405 
2406 int
2407 evhttp_del_cb(struct evhttp *http, const char *uri)
2408 {
2409 	struct evhttp_cb *http_cb;
2410 
2411 	TAILQ_FOREACH(http_cb, &http->callbacks, next) {
2412 		if (strcmp(http_cb->what, uri) == 0)
2413 			break;
2414 	}
2415 	if (http_cb == NULL)
2416 		return (-1);
2417 
2418 	TAILQ_REMOVE(&http->callbacks, http_cb, next);
2419 	free(http_cb->what);
2420 	free(http_cb);
2421 
2422 	return (0);
2423 }
2424 
2425 void
2426 evhttp_set_gencb(struct evhttp *http,
2427     void (*cb)(struct evhttp_request *, void *), void *cbarg)
2428 {
2429 	http->gencb = cb;
2430 	http->gencbarg = cbarg;
2431 }
2432 
2433 /*
2434  * Request related functions
2435  */
2436 
2437 struct evhttp_request *
2438 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg)
2439 {
2440 	struct evhttp_request *req = NULL;
2441 
2442 	/* Allocate request structure */
2443 	if ((req = calloc(1, sizeof(struct evhttp_request))) == NULL) {
2444 		event_warn("%s: calloc", __func__);
2445 		goto error;
2446 	}
2447 
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;
2453 	}
2454 	TAILQ_INIT(req->input_headers);
2455 
2456 	req->output_headers = calloc(1, sizeof(struct evkeyvalq));
2457 	if (req->output_headers == NULL) {
2458 		event_warn("%s: calloc", __func__);
2459 		goto error;
2460 	}
2461 	TAILQ_INIT(req->output_headers);
2462 
2463 	if ((req->input_buffer = evbuffer_new()) == NULL) {
2464 		event_warn("%s: evbuffer_new", __func__);
2465 		goto error;
2466 	}
2467 
2468 	if ((req->output_buffer = evbuffer_new()) == NULL) {
2469 		event_warn("%s: evbuffer_new", __func__);
2470 		goto error;
2471 	}
2472 
2473 	req->cb = cb;
2474 	req->cb_arg = arg;
2475 
2476 	return (req);
2477 
2478  error:
2479 	if (req != NULL)
2480 		evhttp_request_free(req);
2481 	return (NULL);
2482 }
2483 
2484 void
2485 evhttp_request_free(struct evhttp_request *req)
2486 {
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);
2493 
2494 	evhttp_clear_headers(req->input_headers);
2495 	free(req->input_headers);
2496 
2497 	evhttp_clear_headers(req->output_headers);
2498 	free(req->output_headers);
2499 
2500 	if (req->input_buffer != NULL)
2501 		evbuffer_free(req->input_buffer);
2502 
2503 	if (req->output_buffer != NULL)
2504 		evbuffer_free(req->output_buffer);
2505 
2506 	free(req);
2507 }
2508 
2509 void
2510 evhttp_request_set_chunked_cb(struct evhttp_request *req,
2511     void (*cb)(struct evhttp_request *, void *))
2512 {
2513 	req->chunk_cb = cb;
2514 }
2515 
2516 /*
2517  * Allows for inspection of the request URI
2518  */
2519 
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);
2525 }
2526 
2527 /*
2528  * Takes a file descriptor to read a request from.
2529  * The callback is executed once the whole request has been read.
2530  */
2531 
2532 static struct evhttp_connection*
2533 evhttp_get_request_connection(
2534 	struct evhttp* http,
2535 	int fd, struct sockaddr *sa, socklen_t salen)
2536 {
2537 	struct evhttp_connection *evcon;
2538 	char *hostname = NULL, *portname = NULL;
2539 
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);
2545 	}
2546 
2547 	event_debug(("%s: new request from %s:%s on %d\n",
2548 			__func__, hostname, portname, fd));
2549 
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);
2556 
2557 	/* associate the base if we have one*/
2558 	evhttp_connection_set_base(evcon, http->base);
2559 
2560 	evcon->flags |= EVHTTP_CON_INCOMING;
2561 	evcon->state = EVCON_READING_FIRSTLINE;
2562 
2563 	evcon->fd = fd;
2564 
2565 	return (evcon);
2566 }
2567 
2568 static int
2569 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon)
2570 {
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);
2575 
2576 	req->evcon = evcon;	/* the request ends up owning the connection */
2577 	req->flags |= EVHTTP_REQ_OWN_CONNECTION;
2578 
2579 	TAILQ_INSERT_TAIL(&evcon->requests, req, next);
2580 
2581 	req->kind = EVHTTP_REQUEST;
2582 
2583 	if ((req->remote_host = strdup(evcon->address)) == NULL)
2584 		event_err(1, "%s: strdup", __func__);
2585 	req->remote_port = evcon->port;
2586 
2587 	evhttp_start_read(evcon);
2588 
2589 	return (0);
2590 }
2591 
2592 void
2593 evhttp_get_request(struct evhttp *http, int fd,
2594     struct sockaddr *sa, socklen_t salen)
2595 {
2596 	struct evhttp_connection *evcon;
2597 
2598 	evcon = evhttp_get_request_connection(http, fd, sa, salen);
2599 	if (evcon == NULL)
2600 		return;
2601 
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);
2605 
2606 	/*
2607 	 * if we want to accept more than one request on a connection,
2608 	 * we need to know which http server it belongs to.
2609 	 */
2610 	evcon->http_server = http;
2611 	TAILQ_INSERT_TAIL(&http->connections, evcon, next);
2612 
2613 	if (evhttp_associate_new_request_with_connection(evcon) == -1)
2614 		evhttp_connection_free(evcon);
2615 }
2616 
2617 
2618 /*
2619  * Network helper functions that we do not want to export to the rest of
2620  * the world.
2621  */
2622 #if 0 /* Unused */
2623 static struct addrinfo *
2624 addr_from_name(char *address)
2625 {
2626 #ifdef HAVE_GETADDRINFO
2627         struct addrinfo ai, *aitop;
2628         int ai_result;
2629 
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));
2639         }
2640 
2641 	return (aitop);
2642 #else
2643 	assert(0);
2644 	return NULL; /* XXXXX Use gethostbyname, if this function is ever used. */
2645 #endif
2646 }
2647 #endif
2648 
2649 static void
2650 name_from_addr(struct sockaddr *sa, socklen_t salen,
2651     char **phost, char **pport)
2652 {
2653 	char ntop[NI_MAXHOST];
2654 	char strport[NI_MAXSERV];
2655 	int ni_result;
2656 
2657 #ifdef HAVE_GETNAMEINFO
2658 	ni_result = getnameinfo(sa, salen,
2659 		ntop, sizeof(ntop), strport, sizeof(strport),
2660 		NI_NUMERICHOST|NI_NUMERICSERV);
2661 
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;
2668 	}
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);
2678 }
2679 
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)
2684 {
2685         int fd, on = 1, r;
2686 	int serrno;
2687 
2688         /* Create listen socket */
2689         fd = socket(AF_INET, SOCK_STREAM, 0);
2690         if (fd == -1) {
2691                 event_warn("socket");
2692                 return (-1);
2693         }
2694 
2695         if (evutil_make_socket_nonblocking(fd) < 0)
2696                 goto out;
2697 
2698 #ifndef WIN32
2699         if (fcntl(fd, F_SETFD, 1) == -1) {
2700                 event_warn("fcntl(F_SETFD)");
2701                 goto out;
2702         }
2703 #endif
2704 
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));
2709 	}
2710 
2711 	if (ai != NULL) {
2712 		r = bind(fd, ai->ai_addr, ai->ai_addrlen);
2713 		if (r == -1)
2714 			goto out;
2715 	}
2716 
2717 	return (fd);
2718 
2719  out:
2720 	serrno = EVUTIL_SOCKET_ERROR();
2721 	EVUTIL_CLOSESOCKET(fd);
2722 	EVUTIL_SET_SOCKET_ERROR(serrno);
2723 	return (-1);
2724 }
2725 
2726 static struct addrinfo *
2727 make_addrinfo(const char *address, u_short port)
2728 {
2729         struct addrinfo *aitop = NULL;
2730 
2731 #ifdef HAVE_GETADDRINFO
2732         struct addrinfo ai;
2733         char strport[NI_MAXSERV];
2734         int ai_result;
2735 
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);
2747         }
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 */
2752 
2753 	if (fake_getaddrinfo(address, &ai[cur]) < 0) {
2754 		event_warn("fake_getaddrinfo");
2755 		return (NULL);
2756 	}
2757 	aitop = &ai[cur];
2758 	((struct sockaddr_in *) aitop->ai_addr)->sin_port = htons(port);
2759 #endif
2760 
2761 	return (aitop);
2762 }
2763 
2764 static int
2765 bind_socket(const char *address, u_short port, int reuse)
2766 {
2767 	int fd;
2768 	struct addrinfo *aitop = NULL;
2769 
2770 	/* just create an unbound socket */
2771 	if (address == NULL && port == 0)
2772 		return bind_socket_ai(NULL, 0);
2773 
2774 	aitop = make_addrinfo(address, port);
2775 
2776 	if (aitop == NULL)
2777 		return (-1);
2778 
2779 	fd = bind_socket_ai(aitop, reuse);
2780 
2781 #ifdef HAVE_GETADDRINFO
2782 	freeaddrinfo(aitop);
2783 #else
2784 	fake_freeaddrinfo(aitop);
2785 #endif
2786 
2787 	return (fd);
2788 }
2789 
2790 static int
2791 socket_connect(int fd, const char *address, unsigned short port)
2792 {
2793 	struct addrinfo *ai = make_addrinfo(address, port);
2794 	int res = -1;
2795 
2796 	if (ai == NULL) {
2797 		event_debug(("%s: make_addrinfo: \"%s:%d\"",
2798 			__func__, address, port));
2799 		return (-1);
2800 	}
2801 
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;
2808 		}
2809 #else
2810 		if (errno != EINPROGRESS) {
2811 			goto out;
2812 		}
2813 #endif
2814 	}
2815 
2816 	/* everything is fine */
2817 	res = 0;
2818 
2819 out:
2820 #ifdef HAVE_GETADDRINFO
2821 	freeaddrinfo(ai);
2822 #else
2823 	fake_freeaddrinfo(ai);
2824 #endif
2825 
2826 	return (res);
2827 }
2828