1/* $NetBSD$ */ 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 106static int 107fake_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 146struct 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}; 154static int 155fake_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} 182static void 183fake_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 198extern int debug; 199 200static int socket_connect(int fd, const char *address, unsigned short port); 201static int bind_socket_ai(struct addrinfo *, int reuse); 202static int bind_socket(const char *, u_short, int reuse); 203static void name_from_addr(struct sockaddr *, socklen_t, char **, char **); 204static int evhttp_associate_new_request_with_connection( 205 struct evhttp_connection *evcon); 206static void evhttp_connection_start_detectclose( 207 struct evhttp_connection *evcon); 208static void evhttp_connection_stop_detectclose( 209 struct evhttp_connection *evcon); 210static void evhttp_request_dispatch(struct evhttp_connection* evcon); 211static void evhttp_read_firstline(struct evhttp_connection *evcon, 212 struct evhttp_request *req); 213static void evhttp_read_header(struct evhttp_connection *evcon, 214 struct evhttp_request *req); 215static int evhttp_add_header_internal(struct evkeyvalq *headers, 216 const char *key, const char *value); 217static int evhttp_decode_uri_internal(const char *uri, size_t length, 218 char *ret, int always_decode_plus); 219 220void evhttp_read(int, short, void *); 221void 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. */ 226static char * 227strsep(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 244static const char * 245html_replace(char ch, char *buf) 246{ 247 switch (ch) { 248 case '<': 249 return "<"; 250 case '>': 251 return ">"; 252 case '"': 253 return """; 254 case '\'': 255 return "'"; 256 case '&': 257 return "&"; 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 <, >, ", 271 * ' and & correspondingly. 272 * 273 * The returned string needs to be freed by the caller. 274 */ 275 276char * 277evhttp_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 301static const char * 302evhttp_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 324static void 325evhttp_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 338void 339evhttp_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 357static int 358evhttp_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 */ 378static void 379evhttp_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 401static int 402evhttp_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 414static int 415evhttp_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 422static void 423evhttp_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 445static void 446evhttp_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 461static void 462evhttp_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 512void 513evhttp_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 544int 545evhttp_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 599static int 600evhttp_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 631void 632evhttp_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 675void 676evhttp_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 */ 717static void 718evhttp_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 784static enum message_read_status 785evhttp_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 839static void 840evhttp_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 860static void 861evhttp_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 910void 911evhttp_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 964static void 965evhttp_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 983void 984evhttp_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 1029void 1030evhttp_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 1040void 1041evhttp_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 1048static void 1049evhttp_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 */ 1072void 1073evhttp_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 1094static void 1095evhttp_detect_close_cb(int fd, short what, void *arg) 1096{ 1097 struct evhttp_connection *evcon = arg; 1098 evhttp_connection_reset(evcon); 1099} 1100 1101static void 1102evhttp_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 1114static void 1115evhttp_connection_stop_detectclose(struct evhttp_connection *evcon) 1116{ 1117 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT; 1118 event_del(&evcon->close_ev); 1119} 1120 1121static void 1122evhttp_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 1134static void 1135evhttp_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 1201static int 1202evhttp_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 1212static int 1213evhttp_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 1254static int 1255evhttp_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 1309const char * 1310evhttp_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 1322void 1323evhttp_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 1342int 1343evhttp_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 1364static int 1365evhttp_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 1379int 1380evhttp_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 1399static int 1400evhttp_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 1435enum message_read_status 1436evhttp_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 1462static int 1463evhttp_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 1485enum message_read_status 1486evhttp_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 1531static int 1532evhttp_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 1570static void 1571evhttp_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 1595static void 1596evhttp_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 1619static void 1620evhttp_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 1677struct evhttp_connection * 1678evhttp_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 1721void 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 1729void 1730evhttp_connection_set_timeout(struct evhttp_connection *evcon, 1731 int timeout_in_secs) 1732{ 1733 evcon->timeout = timeout_in_secs; 1734} 1735 1736void 1737evhttp_connection_set_retries(struct evhttp_connection *evcon, 1738 int retry_max) 1739{ 1740 evcon->retry_max = retry_max; 1741} 1742 1743void 1744evhttp_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 1751void 1752evhttp_connection_get_peer(struct evhttp_connection *evcon, 1753 char **address, u_short *port) 1754{ 1755 *address = evcon->address; 1756 *port = evcon->port; 1757} 1758 1759int 1760evhttp_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 1799int 1800evhttp_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 1844void 1845evhttp_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 1857static void 1858evhttp_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 1890void 1891evhttp_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 1917static inline void 1918evhttp_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 1934void 1935evhttp_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 1943void 1944evhttp_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 1958void 1959evhttp_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 1972void 1973evhttp_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 1991void 1992evhttp_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 2001void 2002evhttp_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 2019static 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 */ 2045char * 2046evhttp_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 */ 2069static int 2070evhttp_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 2095char * 2096evhttp_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 2115void 2116evhttp_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 2161static struct evhttp_cb * 2162evhttp_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 2188static void 2189evhttp_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 2233static void 2234accept_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 2252int 2253evhttp_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 2276int 2277evhttp_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 2305static struct evhttp* 2306evhttp_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 2324struct evhttp * 2325evhttp_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 2338struct evhttp * 2339evhttp_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 2351void 2352evhttp_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 2384void 2385evhttp_set_timeout(struct evhttp* http, int timeout_in_secs) 2386{ 2387 http->timeout = timeout_in_secs; 2388} 2389 2390void 2391evhttp_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 2406int 2407evhttp_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 2425void 2426evhttp_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 2437struct evhttp_request * 2438evhttp_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 2484void 2485evhttp_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 2509void 2510evhttp_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 2520const char * 2521evhttp_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 2532static struct evhttp_connection* 2533evhttp_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 2568static int 2569evhttp_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 2592void 2593evhttp_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 */ 2623static struct addrinfo * 2624addr_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 2649static void 2650name_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 */ 2682static int 2683bind_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 2726static struct addrinfo * 2727make_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 2764static int 2765bind_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 2790static int 2791socket_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 2819out: 2820#ifdef HAVE_GETADDRINFO 2821 freeaddrinfo(ai); 2822#else 2823 fake_freeaddrinfo(ai); 2824#endif 2825 2826 return (res); 2827} 2828