1 /* $NetBSD: http.c,v 1.1.1.1 2013/12/27 23:31:17 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu> 5 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "event2/event-config.h" 31 #include "evconfig-private.h" 32 33 #ifdef EVENT__HAVE_SYS_PARAM_H 34 #include <sys/param.h> 35 #endif 36 #ifdef EVENT__HAVE_SYS_TYPES_H 37 #include <sys/types.h> 38 #endif 39 40 #ifdef EVENT__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 #else 53 #include <winsock2.h> 54 #include <ws2tcpip.h> 55 #endif 56 57 #include <sys/queue.h> 58 59 #ifdef EVENT__HAVE_NETINET_IN_H 60 #include <netinet/in.h> 61 #endif 62 #ifdef EVENT__HAVE_ARPA_INET_H 63 #include <arpa/inet.h> 64 #endif 65 #ifdef EVENT__HAVE_NETDB_H 66 #include <netdb.h> 67 #endif 68 69 #ifdef _WIN32 70 #include <winsock2.h> 71 #endif 72 73 #include <errno.h> 74 #include <stdio.h> 75 #include <stdlib.h> 76 #include <string.h> 77 #ifndef _WIN32 78 #include <syslog.h> 79 #endif 80 #include <signal.h> 81 #include <time.h> 82 #ifdef EVENT__HAVE_UNISTD_H 83 #include <unistd.h> 84 #endif 85 #ifdef EVENT__HAVE_FCNTL_H 86 #include <fcntl.h> 87 #endif 88 89 #undef timeout_pending 90 #undef timeout_initialized 91 92 #include "strlcpy-internal.h" 93 #include "event2/http.h" 94 #include "event2/event.h" 95 #include "event2/buffer.h" 96 #include "event2/bufferevent.h" 97 #include "event2/http_struct.h" 98 #include "event2/http_compat.h" 99 #include "event2/util.h" 100 #include "event2/listener.h" 101 #include "log-internal.h" 102 #include "util-internal.h" 103 #include "http-internal.h" 104 #include "mm-internal.h" 105 #include "bufferevent-internal.h" 106 107 #ifndef EVENT__HAVE_GETNAMEINFO 108 #define NI_MAXSERV 32 109 #define NI_MAXHOST 1025 110 111 #ifndef NI_NUMERICHOST 112 #define NI_NUMERICHOST 1 113 #endif 114 115 #ifndef NI_NUMERICSERV 116 #define NI_NUMERICSERV 2 117 #endif 118 119 static int 120 fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, 121 size_t hostlen, char *serv, size_t servlen, int flags) 122 { 123 struct sockaddr_in *sin = (struct sockaddr_in *)sa; 124 125 if (serv != NULL) { 126 char tmpserv[16]; 127 evutil_snprintf(tmpserv, sizeof(tmpserv), 128 "%d", ntohs(sin->sin_port)); 129 if (strlcpy(serv, tmpserv, servlen) >= servlen) 130 return (-1); 131 } 132 133 if (host != NULL) { 134 if (flags & NI_NUMERICHOST) { 135 if (strlcpy(host, inet_ntoa(sin->sin_addr), 136 hostlen) >= hostlen) 137 return (-1); 138 else 139 return (0); 140 } else { 141 struct hostent *hp; 142 hp = gethostbyaddr((char *)&sin->sin_addr, 143 sizeof(struct in_addr), AF_INET); 144 if (hp == NULL) 145 return (-2); 146 147 if (strlcpy(host, hp->h_name, hostlen) >= hostlen) 148 return (-1); 149 else 150 return (0); 151 } 152 } 153 return (0); 154 } 155 156 #endif 157 158 #define REQ_VERSION_BEFORE(req, major_v, minor_v) \ 159 ((req)->major < (major_v) || \ 160 ((req)->major == (major_v) && (req)->minor < (minor_v))) 161 162 #define REQ_VERSION_ATLEAST(req, major_v, minor_v) \ 163 ((req)->major > (major_v) || \ 164 ((req)->major == (major_v) && (req)->minor >= (minor_v))) 165 166 #ifndef MIN 167 #define MIN(a,b) (((a)<(b))?(a):(b)) 168 #endif 169 170 extern int debug; 171 172 static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse); 173 static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse); 174 static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **); 175 static int evhttp_associate_new_request_with_connection( 176 struct evhttp_connection *evcon); 177 static void evhttp_connection_start_detectclose( 178 struct evhttp_connection *evcon); 179 static void evhttp_connection_stop_detectclose( 180 struct evhttp_connection *evcon); 181 static void evhttp_request_dispatch(struct evhttp_connection* evcon); 182 static void evhttp_read_firstline(struct evhttp_connection *evcon, 183 struct evhttp_request *req); 184 static void evhttp_read_header(struct evhttp_connection *evcon, 185 struct evhttp_request *req); 186 static int evhttp_add_header_internal(struct evkeyvalq *headers, 187 const char *key, const char *value); 188 static const char *evhttp_response_phrase_internal(int code); 189 static void evhttp_get_request(struct evhttp *, evutil_socket_t, struct sockaddr *, ev_socklen_t); 190 static void evhttp_write_buffer(struct evhttp_connection *, 191 void (*)(struct evhttp_connection *, void *), void *); 192 static void evhttp_make_header(struct evhttp_connection *, struct evhttp_request *); 193 194 /* callbacks for bufferevent */ 195 static void evhttp_read_cb(struct bufferevent *, void *); 196 static void evhttp_write_cb(struct bufferevent *, void *); 197 static void evhttp_error_cb(struct bufferevent *bufev, short what, void *arg); 198 static int evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp, 199 const char *hostname); 200 201 #ifndef EVENT__HAVE_STRSEP 202 /* strsep replacement for platforms that lack it. Only works if 203 * del is one character long. */ 204 static char * 205 strsep(char **s, const char *del) 206 { 207 char *d, *tok; 208 EVUTIL_ASSERT(strlen(del) == 1); 209 if (!s || !*s) 210 return NULL; 211 tok = *s; 212 d = strstr(tok, del); 213 if (d) { 214 *d = '\0'; 215 *s = d + 1; 216 } else 217 *s = NULL; 218 return tok; 219 } 220 #endif 221 222 static size_t 223 html_replace(const char ch, const char **escaped) 224 { 225 switch (ch) { 226 case '<': 227 *escaped = "<"; 228 return 4; 229 case '>': 230 *escaped = ">"; 231 return 4; 232 case '"': 233 *escaped = """; 234 return 6; 235 case '\'': 236 *escaped = "'"; 237 return 6; 238 case '&': 239 *escaped = "&"; 240 return 5; 241 default: 242 break; 243 } 244 245 return 1; 246 } 247 248 /* 249 * Replaces <, >, ", ' and & with <, >, ", 250 * ' and & correspondingly. 251 * 252 * The returned string needs to be freed by the caller. 253 */ 254 255 char * 256 evhttp_htmlescape(const char *html) 257 { 258 size_t i; 259 size_t new_size = 0, old_size = 0; 260 char *escaped_html, *p; 261 262 if (html == NULL) 263 return (NULL); 264 265 old_size = strlen(html); 266 for (i = 0; i < old_size; ++i) { 267 const char *replaced = NULL; 268 const size_t replace_size = html_replace(html[i], &replaced); 269 if (replace_size > EV_SIZE_MAX - new_size) { 270 event_warn("%s: html_replace overflow", __func__); 271 return (NULL); 272 } 273 new_size += replace_size; 274 } 275 276 if (new_size == EV_SIZE_MAX) 277 return (NULL); 278 p = escaped_html = mm_malloc(new_size + 1); 279 if (escaped_html == NULL) { 280 event_warn("%s: malloc(%lu)", __func__, 281 (unsigned long)(new_size + 1)); 282 return (NULL); 283 } 284 for (i = 0; i < old_size; ++i) { 285 const char *replaced = &html[i]; 286 const size_t len = html_replace(html[i], &replaced); 287 memcpy(p, replaced, len); 288 p += len; 289 } 290 291 *p = '\0'; 292 293 return (escaped_html); 294 } 295 296 /** Given an evhttp_cmd_type, returns a constant string containing the 297 * equivalent HTTP command, or NULL if the evhttp_command_type is 298 * unrecognized. */ 299 static const char * 300 evhttp_method(enum evhttp_cmd_type type) 301 { 302 const char *method; 303 304 switch (type) { 305 case EVHTTP_REQ_GET: 306 method = "GET"; 307 break; 308 case EVHTTP_REQ_POST: 309 method = "POST"; 310 break; 311 case EVHTTP_REQ_HEAD: 312 method = "HEAD"; 313 break; 314 case EVHTTP_REQ_PUT: 315 method = "PUT"; 316 break; 317 case EVHTTP_REQ_DELETE: 318 method = "DELETE"; 319 break; 320 case EVHTTP_REQ_OPTIONS: 321 method = "OPTIONS"; 322 break; 323 case EVHTTP_REQ_TRACE: 324 method = "TRACE"; 325 break; 326 case EVHTTP_REQ_CONNECT: 327 method = "CONNECT"; 328 break; 329 case EVHTTP_REQ_PATCH: 330 method = "PATCH"; 331 break; 332 default: 333 method = NULL; 334 break; 335 } 336 337 return (method); 338 } 339 340 /** 341 * Determines if a response should have a body. 342 * Follows the rules in RFC 2616 section 4.3. 343 * @return 1 if the response MUST have a body; 0 if the response MUST NOT have 344 * a body. 345 */ 346 static int 347 evhttp_response_needs_body(struct evhttp_request *req) 348 { 349 return (req->response_code != HTTP_NOCONTENT && 350 req->response_code != HTTP_NOTMODIFIED && 351 (req->response_code < 100 || req->response_code >= 200) && 352 req->type != EVHTTP_REQ_HEAD); 353 } 354 355 /** Helper: called after we've added some data to an evcon's bufferevent's 356 * output buffer. Sets the evconn's writing-is-done callback, and puts 357 * the bufferevent into writing mode. 358 */ 359 static void 360 evhttp_write_buffer(struct evhttp_connection *evcon, 361 void (*cb)(struct evhttp_connection *, void *), void *arg) 362 { 363 event_debug(("%s: preparing to write buffer\n", __func__)); 364 365 /* Set call back */ 366 evcon->cb = cb; 367 evcon->cb_arg = arg; 368 369 bufferevent_enable(evcon->bufev, EV_WRITE); 370 371 /* Disable the read callback: we don't actually care about data; 372 * we only care about close detection. (We don't disable reading, 373 * since we *do* want to learn about any close events.) */ 374 bufferevent_setcb(evcon->bufev, 375 NULL, /*read*/ 376 evhttp_write_cb, 377 evhttp_error_cb, 378 evcon); 379 } 380 381 static void 382 evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg) 383 { 384 bufferevent_disable(evcon->bufev, EV_WRITE); 385 } 386 387 static void 388 evhttp_send_continue(struct evhttp_connection *evcon, 389 struct evhttp_request *req) 390 { 391 bufferevent_enable(evcon->bufev, EV_WRITE); 392 evbuffer_add_printf(bufferevent_get_output(evcon->bufev), 393 "HTTP/%d.%d 100 Continue\r\n\r\n", 394 req->major, req->minor); 395 evcon->cb = evhttp_send_continue_done; 396 evcon->cb_arg = NULL; 397 bufferevent_setcb(evcon->bufev, 398 evhttp_read_cb, 399 evhttp_write_cb, 400 evhttp_error_cb, 401 evcon); 402 } 403 404 /** Helper: returns true iff evconn is in any connected state. */ 405 static int 406 evhttp_connected(struct evhttp_connection *evcon) 407 { 408 switch (evcon->state) { 409 case EVCON_DISCONNECTED: 410 case EVCON_CONNECTING: 411 return (0); 412 case EVCON_IDLE: 413 case EVCON_READING_FIRSTLINE: 414 case EVCON_READING_HEADERS: 415 case EVCON_READING_BODY: 416 case EVCON_READING_TRAILER: 417 case EVCON_WRITING: 418 default: 419 return (1); 420 } 421 } 422 423 /* Create the headers needed for an outgoing HTTP request, adds them to 424 * the request's header list, and writes the request line to the 425 * connection's output buffer. 426 */ 427 static void 428 evhttp_make_header_request(struct evhttp_connection *evcon, 429 struct evhttp_request *req) 430 { 431 const char *method; 432 433 evhttp_remove_header(req->output_headers, "Proxy-Connection"); 434 435 /* Generate request line */ 436 method = evhttp_method(req->type); 437 evbuffer_add_printf(bufferevent_get_output(evcon->bufev), 438 "%s %s HTTP/%d.%d\r\n", 439 method, req->uri, req->major, req->minor); 440 441 /* Add the content length on a post or put request if missing */ 442 if ((req->type == EVHTTP_REQ_POST || req->type == EVHTTP_REQ_PUT) && 443 evhttp_find_header(req->output_headers, "Content-Length") == NULL){ 444 char size[22]; 445 evutil_snprintf(size, sizeof(size), EV_SIZE_FMT, 446 EV_SIZE_ARG(evbuffer_get_length(req->output_buffer))); 447 evhttp_add_header(req->output_headers, "Content-Length", size); 448 } 449 } 450 451 /** Return true if the list of headers in 'headers', intepreted with respect 452 * to flags, means that we should send a "connection: close" when the request 453 * is done. */ 454 static int 455 evhttp_is_connection_close(int flags, struct evkeyvalq* headers) 456 { 457 if (flags & EVHTTP_PROXY_REQUEST) { 458 /* proxy connection */ 459 const char *connection = evhttp_find_header(headers, "Proxy-Connection"); 460 return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0); 461 } else { 462 const char *connection = evhttp_find_header(headers, "Connection"); 463 return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0); 464 } 465 } 466 467 /* Return true iff 'headers' contains 'Connection: keep-alive' */ 468 static int 469 evhttp_is_connection_keepalive(struct evkeyvalq* headers) 470 { 471 const char *connection = evhttp_find_header(headers, "Connection"); 472 return (connection != NULL 473 && evutil_ascii_strncasecmp(connection, "keep-alive", 10) == 0); 474 } 475 476 /* Add a correct "Date" header to headers, unless it already has one. */ 477 static void 478 evhttp_maybe_add_date_header(struct evkeyvalq *headers) 479 { 480 if (evhttp_find_header(headers, "Date") == NULL) { 481 char date[50]; 482 #ifndef _WIN32 483 struct tm cur; 484 #endif 485 struct tm *cur_p; 486 time_t t = time(NULL); 487 #ifdef _WIN32 488 cur_p = gmtime(&t); 489 #else 490 gmtime_r(&t, &cur); 491 cur_p = &cur; 492 #endif 493 if (strftime(date, sizeof(date), 494 "%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) { 495 evhttp_add_header(headers, "Date", date); 496 } 497 } 498 } 499 500 /* Add a "Content-Length" header with value 'content_length' to headers, 501 * unless it already has a content-length or transfer-encoding header. */ 502 static void 503 evhttp_maybe_add_content_length_header(struct evkeyvalq *headers, 504 size_t content_length) 505 { 506 if (evhttp_find_header(headers, "Transfer-Encoding") == NULL && 507 evhttp_find_header(headers, "Content-Length") == NULL) { 508 char len[22]; 509 evutil_snprintf(len, sizeof(len), EV_SIZE_FMT, 510 EV_SIZE_ARG(content_length)); 511 evhttp_add_header(headers, "Content-Length", len); 512 } 513 } 514 515 /* 516 * Create the headers needed for an HTTP reply in req->output_headers, 517 * and write the first HTTP response for req line to evcon. 518 */ 519 static void 520 evhttp_make_header_response(struct evhttp_connection *evcon, 521 struct evhttp_request *req) 522 { 523 int is_keepalive = evhttp_is_connection_keepalive(req->input_headers); 524 evbuffer_add_printf(bufferevent_get_output(evcon->bufev), 525 "HTTP/%d.%d %d %s\r\n", 526 req->major, req->minor, req->response_code, 527 req->response_code_line); 528 529 if (req->major == 1) { 530 if (req->minor >= 1) 531 evhttp_maybe_add_date_header(req->output_headers); 532 533 /* 534 * if the protocol is 1.0; and the connection was keep-alive 535 * we need to add a keep-alive header, too. 536 */ 537 if (req->minor == 0 && is_keepalive) 538 evhttp_add_header(req->output_headers, 539 "Connection", "keep-alive"); 540 541 if ((req->minor >= 1 || is_keepalive) && 542 evhttp_response_needs_body(req)) { 543 /* 544 * we need to add the content length if the 545 * user did not give it, this is required for 546 * persistent connections to work. 547 */ 548 evhttp_maybe_add_content_length_header( 549 req->output_headers, 550 evbuffer_get_length(req->output_buffer)); 551 } 552 } 553 554 /* Potentially add headers for unidentified content. */ 555 if (evhttp_response_needs_body(req)) { 556 if (evhttp_find_header(req->output_headers, 557 "Content-Type") == NULL) { 558 evhttp_add_header(req->output_headers, 559 "Content-Type", "text/html; charset=ISO-8859-1"); 560 } 561 } 562 563 /* if the request asked for a close, we send a close, too */ 564 if (evhttp_is_connection_close(req->flags, req->input_headers)) { 565 evhttp_remove_header(req->output_headers, "Connection"); 566 if (!(req->flags & EVHTTP_PROXY_REQUEST)) 567 evhttp_add_header(req->output_headers, "Connection", "close"); 568 evhttp_remove_header(req->output_headers, "Proxy-Connection"); 569 } 570 } 571 572 /** Generate all headers appropriate for sending the http request in req (or 573 * the response, if we're sending a response), and write them to evcon's 574 * bufferevent. Also writes all data from req->output_buffer */ 575 static void 576 evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req) 577 { 578 struct evkeyval *header; 579 struct evbuffer *output = bufferevent_get_output(evcon->bufev); 580 581 /* 582 * Depending if this is a HTTP request or response, we might need to 583 * add some new headers or remove existing headers. 584 */ 585 if (req->kind == EVHTTP_REQUEST) { 586 evhttp_make_header_request(evcon, req); 587 } else { 588 evhttp_make_header_response(evcon, req); 589 } 590 591 TAILQ_FOREACH(header, req->output_headers, next) { 592 evbuffer_add_printf(output, "%s: %s\r\n", 593 header->key, header->value); 594 } 595 evbuffer_add(output, "\r\n", 2); 596 597 if (evbuffer_get_length(req->output_buffer) > 0) { 598 /* 599 * For a request, we add the POST data, for a reply, this 600 * is the regular data. 601 */ 602 /* XXX We might want to support waiting (a limited amount of 603 time) for a continue status line from the server before 604 sending POST/PUT message bodies. */ 605 evbuffer_add_buffer(output, req->output_buffer); 606 } 607 } 608 609 void 610 evhttp_connection_set_max_headers_size(struct evhttp_connection *evcon, 611 ev_ssize_t new_max_headers_size) 612 { 613 if (new_max_headers_size<0) 614 evcon->max_headers_size = EV_SIZE_MAX; 615 else 616 evcon->max_headers_size = new_max_headers_size; 617 } 618 void 619 evhttp_connection_set_max_body_size(struct evhttp_connection* evcon, 620 ev_ssize_t new_max_body_size) 621 { 622 if (new_max_body_size<0) 623 evcon->max_body_size = EV_UINT64_MAX; 624 else 625 evcon->max_body_size = new_max_body_size; 626 } 627 628 static int 629 evhttp_connection_incoming_fail(struct evhttp_request *req, 630 enum evhttp_connection_error error) 631 { 632 switch (error) { 633 case EVCON_HTTP_TIMEOUT: 634 case EVCON_HTTP_EOF: 635 /* 636 * these are cases in which we probably should just 637 * close the connection and not send a reply. this 638 * case may happen when a browser keeps a persistent 639 * connection open and we timeout on the read. when 640 * the request is still being used for sending, we 641 * need to disassociated it from the connection here. 642 */ 643 if (!req->userdone) { 644 /* remove it so that it will not be freed */ 645 TAILQ_REMOVE(&req->evcon->requests, req, next); 646 /* indicate that this request no longer has a 647 * connection object 648 */ 649 req->evcon = NULL; 650 } 651 return (-1); 652 case EVCON_HTTP_INVALID_HEADER: 653 case EVCON_HTTP_BUFFER_ERROR: 654 case EVCON_HTTP_REQUEST_CANCEL: 655 default: /* xxx: probably should just error on default */ 656 /* the callback looks at the uri to determine errors */ 657 if (req->uri) { 658 mm_free(req->uri); 659 req->uri = NULL; 660 } 661 if (req->uri_elems) { 662 evhttp_uri_free(req->uri_elems); 663 req->uri_elems = NULL; 664 } 665 666 /* 667 * the callback needs to send a reply, once the reply has 668 * been send, the connection should get freed. 669 */ 670 (*req->cb)(req, req->cb_arg); 671 } 672 673 return (0); 674 } 675 676 /* Called when evcon has experienced a (non-recoverable? -NM) error, as 677 * given in error. If it's an outgoing connection, reset the connection, 678 * retry any pending requests, and inform the user. If it's incoming, 679 * delegates to evhttp_connection_incoming_fail(). */ 680 void 681 evhttp_connection_fail_(struct evhttp_connection *evcon, 682 enum evhttp_connection_error error) 683 { 684 const int errsave = EVUTIL_SOCKET_ERROR(); 685 struct evhttp_request* req = TAILQ_FIRST(&evcon->requests); 686 void (*cb)(struct evhttp_request *, void *); 687 void *cb_arg; 688 EVUTIL_ASSERT(req != NULL); 689 690 bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE); 691 692 if (evcon->flags & EVHTTP_CON_INCOMING) { 693 /* 694 * for incoming requests, there are two different 695 * failure cases. it's either a network level error 696 * or an http layer error. for problems on the network 697 * layer like timeouts we just drop the connections. 698 * For HTTP problems, we might have to send back a 699 * reply before the connection can be freed. 700 */ 701 if (evhttp_connection_incoming_fail(req, error) == -1) 702 evhttp_connection_free(evcon); 703 return; 704 } 705 706 /* when the request was canceled, the callback is not executed */ 707 if (error != EVCON_HTTP_REQUEST_CANCEL) { 708 /* save the callback for later; the cb might free our object */ 709 cb = req->cb; 710 cb_arg = req->cb_arg; 711 } else { 712 cb = NULL; 713 cb_arg = NULL; 714 } 715 716 /* do not fail all requests; the next request is going to get 717 * send over a new connection. when a user cancels a request, 718 * all other pending requests should be processed as normal 719 */ 720 TAILQ_REMOVE(&evcon->requests, req, next); 721 evhttp_request_free(req); 722 723 /* reset the connection */ 724 evhttp_connection_reset_(evcon); 725 726 /* We are trying the next request that was queued on us */ 727 if (TAILQ_FIRST(&evcon->requests) != NULL) 728 evhttp_connection_connect_(evcon); 729 730 /* The call to evhttp_connection_reset_ overwrote errno. 731 * Let's restore the original errno, so that the user's 732 * callback can have a better idea of what the error was. 733 */ 734 EVUTIL_SET_SOCKET_ERROR(errsave); 735 736 /* inform the user */ 737 if (cb != NULL) 738 (*cb)(NULL, cb_arg); 739 } 740 741 /* Bufferevent callback: invoked when any data has been written from an 742 * http connection's bufferevent */ 743 static void 744 evhttp_write_cb(struct bufferevent *bufev, void *arg) 745 { 746 struct evhttp_connection *evcon = arg; 747 748 /* Activate our call back */ 749 if (evcon->cb != NULL) 750 (*evcon->cb)(evcon, evcon->cb_arg); 751 } 752 753 /** 754 * Advance the connection state. 755 * - If this is an outgoing connection, we've just processed the response; 756 * idle or close the connection. 757 * - If this is an incoming connection, we've just processed the request; 758 * respond. 759 */ 760 static void 761 evhttp_connection_done(struct evhttp_connection *evcon) 762 { 763 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests); 764 int con_outgoing = evcon->flags & EVHTTP_CON_OUTGOING; 765 766 if (con_outgoing) { 767 /* idle or close the connection */ 768 int need_close; 769 TAILQ_REMOVE(&evcon->requests, req, next); 770 req->evcon = NULL; 771 772 evcon->state = EVCON_IDLE; 773 774 need_close = 775 evhttp_is_connection_close(req->flags, req->input_headers)|| 776 evhttp_is_connection_close(req->flags, req->output_headers); 777 778 /* check if we got asked to close the connection */ 779 if (need_close) 780 evhttp_connection_reset_(evcon); 781 782 if (TAILQ_FIRST(&evcon->requests) != NULL) { 783 /* 784 * We have more requests; reset the connection 785 * and deal with the next request. 786 */ 787 if (!evhttp_connected(evcon)) 788 evhttp_connection_connect_(evcon); 789 else 790 evhttp_request_dispatch(evcon); 791 } else if (!need_close) { 792 /* 793 * The connection is going to be persistent, but we 794 * need to detect if the other side closes it. 795 */ 796 evhttp_connection_start_detectclose(evcon); 797 } 798 } else { 799 /* 800 * incoming connection - we need to leave the request on the 801 * connection so that we can reply to it. 802 */ 803 evcon->state = EVCON_WRITING; 804 } 805 806 /* notify the user of the request */ 807 (*req->cb)(req, req->cb_arg); 808 809 /* if this was an outgoing request, we own and it's done. so free it. 810 * unless the callback specifically requested to own the request. 811 */ 812 if (con_outgoing && ((req->flags & EVHTTP_USER_OWNED) == 0)) { 813 evhttp_request_free(req); 814 } 815 } 816 817 /* 818 * Handles reading from a chunked request. 819 * return ALL_DATA_READ: 820 * all data has been read 821 * return MORE_DATA_EXPECTED: 822 * more data is expected 823 * return DATA_CORRUPTED: 824 * data is corrupted 825 * return REQUEST_CANCELED: 826 * request was canceled by the user calling evhttp_cancel_request 827 * return DATA_TOO_LONG: 828 * ran over the maximum limit 829 */ 830 831 static enum message_read_status 832 evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf) 833 { 834 if (req == NULL || buf == NULL) { 835 return DATA_CORRUPTED; 836 } 837 838 while (1) { 839 size_t buflen; 840 841 if ((buflen = evbuffer_get_length(buf)) == 0) { 842 break; 843 } 844 845 /* evbuffer_get_length returns size_t, but len variable is ssize_t, 846 * check for overflow conditions */ 847 if (buflen > EV_SSIZE_MAX) { 848 return DATA_CORRUPTED; 849 } 850 851 if (req->ntoread < 0) { 852 /* Read chunk size */ 853 ev_int64_t ntoread; 854 char *p = evbuffer_readln(buf, NULL, EVBUFFER_EOL_CRLF); 855 char *endp; 856 int error; 857 if (p == NULL) 858 break; 859 /* the last chunk is on a new line? */ 860 if (strlen(p) == 0) { 861 mm_free(p); 862 continue; 863 } 864 ntoread = evutil_strtoll(p, &endp, 16); 865 error = (*p == '\0' || 866 (*endp != '\0' && *endp != ' ') || 867 ntoread < 0); 868 mm_free(p); 869 if (error) { 870 /* could not get chunk size */ 871 return (DATA_CORRUPTED); 872 } 873 874 /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */ 875 if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) { 876 return DATA_CORRUPTED; 877 } 878 879 if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) { 880 /* failed body length test */ 881 event_debug(("Request body is too long")); 882 return (DATA_TOO_LONG); 883 } 884 885 req->body_size += (size_t)ntoread; 886 req->ntoread = ntoread; 887 if (req->ntoread == 0) { 888 /* Last chunk */ 889 return (ALL_DATA_READ); 890 } 891 continue; 892 } 893 894 /* req->ntoread is signed int64, len is ssize_t, based on arch, 895 * ssize_t could only be 32b, check for these conditions */ 896 if (req->ntoread > EV_SSIZE_MAX) { 897 return DATA_CORRUPTED; 898 } 899 900 /* don't have enough to complete a chunk; wait for more */ 901 if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread) 902 return (MORE_DATA_EXPECTED); 903 904 /* Completed chunk */ 905 evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread); 906 req->ntoread = -1; 907 if (req->chunk_cb != NULL) { 908 req->flags |= EVHTTP_REQ_DEFER_FREE; 909 (*req->chunk_cb)(req, req->cb_arg); 910 evbuffer_drain(req->input_buffer, 911 evbuffer_get_length(req->input_buffer)); 912 req->flags &= ~EVHTTP_REQ_DEFER_FREE; 913 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) { 914 return (REQUEST_CANCELED); 915 } 916 } 917 } 918 919 return (MORE_DATA_EXPECTED); 920 } 921 922 static void 923 evhttp_read_trailer(struct evhttp_connection *evcon, struct evhttp_request *req) 924 { 925 struct evbuffer *buf = bufferevent_get_input(evcon->bufev); 926 927 switch (evhttp_parse_headers_(req, buf)) { 928 case DATA_CORRUPTED: 929 case DATA_TOO_LONG: 930 evhttp_connection_fail_(evcon, EVCON_HTTP_INVALID_HEADER); 931 break; 932 case ALL_DATA_READ: 933 bufferevent_disable(evcon->bufev, EV_READ); 934 evhttp_connection_done(evcon); 935 break; 936 case MORE_DATA_EXPECTED: 937 case REQUEST_CANCELED: /* ??? */ 938 default: 939 bufferevent_enable(evcon->bufev, EV_READ); 940 break; 941 } 942 } 943 944 static void 945 evhttp_read_body(struct evhttp_connection *evcon, struct evhttp_request *req) 946 { 947 struct evbuffer *buf = bufferevent_get_input(evcon->bufev); 948 949 if (req->chunked) { 950 switch (evhttp_handle_chunked_read(req, buf)) { 951 case ALL_DATA_READ: 952 /* finished last chunk */ 953 evcon->state = EVCON_READING_TRAILER; 954 evhttp_read_trailer(evcon, req); 955 return; 956 case DATA_CORRUPTED: 957 case DATA_TOO_LONG:/*separate error for this? XXX */ 958 /* corrupted data */ 959 evhttp_connection_fail_(evcon, 960 EVCON_HTTP_INVALID_HEADER); 961 return; 962 case REQUEST_CANCELED: 963 /* request canceled */ 964 evhttp_request_free(req); 965 return; 966 case MORE_DATA_EXPECTED: 967 default: 968 break; 969 } 970 } else if (req->ntoread < 0) { 971 /* Read until connection close. */ 972 if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) { 973 evhttp_connection_fail_(evcon, EVCON_HTTP_INVALID_HEADER); 974 return; 975 } 976 977 req->body_size += evbuffer_get_length(buf); 978 evbuffer_add_buffer(req->input_buffer, buf); 979 } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) { 980 /* XXX: the above get_length comparison has to be fixed for overflow conditions! */ 981 /* We've postponed moving the data until now, but we're 982 * about to use it. */ 983 size_t n = evbuffer_get_length(buf); 984 985 if (n > (size_t) req->ntoread) 986 n = (size_t) req->ntoread; 987 req->ntoread -= n; 988 req->body_size += n; 989 evbuffer_remove_buffer(buf, req->input_buffer, n); 990 } 991 992 if (req->body_size > req->evcon->max_body_size || 993 (!req->chunked && req->ntoread >= 0 && 994 (size_t)req->ntoread > req->evcon->max_body_size)) { 995 /* XXX: The above casted comparison must checked for overflow */ 996 /* failed body length test */ 997 event_debug(("Request body is too long")); 998 evhttp_connection_fail_(evcon, 999 EVCON_HTTP_INVALID_HEADER); 1000 return; 1001 } 1002 1003 if (evbuffer_get_length(req->input_buffer) > 0 && req->chunk_cb != NULL) { 1004 req->flags |= EVHTTP_REQ_DEFER_FREE; 1005 (*req->chunk_cb)(req, req->cb_arg); 1006 req->flags &= ~EVHTTP_REQ_DEFER_FREE; 1007 evbuffer_drain(req->input_buffer, 1008 evbuffer_get_length(req->input_buffer)); 1009 if ((req->flags & EVHTTP_REQ_NEEDS_FREE) != 0) { 1010 evhttp_request_free(req); 1011 return; 1012 } 1013 } 1014 1015 if (req->ntoread == 0) { 1016 bufferevent_disable(evcon->bufev, EV_READ); 1017 /* Completed content length */ 1018 evhttp_connection_done(evcon); 1019 return; 1020 } 1021 1022 /* Read more! */ 1023 bufferevent_enable(evcon->bufev, EV_READ); 1024 } 1025 1026 #define get_deferred_queue(evcon) \ 1027 ((evcon)->base) 1028 1029 /* 1030 * Gets called when more data becomes available 1031 */ 1032 1033 static void 1034 evhttp_read_cb(struct bufferevent *bufev, void *arg) 1035 { 1036 struct evhttp_connection *evcon = arg; 1037 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests); 1038 1039 /* Cancel if it's pending. */ 1040 event_deferred_cb_cancel_(get_deferred_queue(evcon), 1041 &evcon->read_more_deferred_cb); 1042 1043 switch (evcon->state) { 1044 case EVCON_READING_FIRSTLINE: 1045 evhttp_read_firstline(evcon, req); 1046 /* note the request may have been freed in 1047 * evhttp_read_body */ 1048 break; 1049 case EVCON_READING_HEADERS: 1050 evhttp_read_header(evcon, req); 1051 /* note the request may have been freed in 1052 * evhttp_read_body */ 1053 break; 1054 case EVCON_READING_BODY: 1055 evhttp_read_body(evcon, req); 1056 /* note the request may have been freed in 1057 * evhttp_read_body */ 1058 break; 1059 case EVCON_READING_TRAILER: 1060 evhttp_read_trailer(evcon, req); 1061 break; 1062 case EVCON_IDLE: 1063 { 1064 #ifdef USE_DEBUG 1065 struct evbuffer *input; 1066 size_t total_len; 1067 1068 input = bufferevent_get_input(evcon->bufev); 1069 total_len = evbuffer_get_length(input); 1070 event_debug(("%s: read "EV_SIZE_FMT 1071 " bytes in EVCON_IDLE state," 1072 " resetting connection", 1073 __func__, EV_SIZE_ARG(total_len))); 1074 #endif 1075 1076 evhttp_connection_reset_(evcon); 1077 } 1078 break; 1079 case EVCON_DISCONNECTED: 1080 case EVCON_CONNECTING: 1081 case EVCON_WRITING: 1082 default: 1083 event_errx(1, "%s: illegal connection state %d", 1084 __func__, evcon->state); 1085 } 1086 } 1087 1088 static void 1089 evhttp_deferred_read_cb(struct event_callback *cb, void *data) 1090 { 1091 struct evhttp_connection *evcon = data; 1092 evhttp_read_cb(evcon->bufev, evcon); 1093 } 1094 1095 static void 1096 evhttp_write_connectioncb(struct evhttp_connection *evcon, void *arg) 1097 { 1098 /* This is after writing the request to the server */ 1099 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests); 1100 EVUTIL_ASSERT(req != NULL); 1101 1102 EVUTIL_ASSERT(evcon->state == EVCON_WRITING); 1103 1104 /* We are done writing our header and are now expecting the response */ 1105 req->kind = EVHTTP_RESPONSE; 1106 1107 evhttp_start_read_(evcon); 1108 } 1109 1110 /* 1111 * Clean up a connection object 1112 */ 1113 1114 void 1115 evhttp_connection_free(struct evhttp_connection *evcon) 1116 { 1117 struct evhttp_request *req; 1118 1119 /* notify interested parties that this connection is going down */ 1120 if (evcon->fd != -1) { 1121 if (evhttp_connected(evcon) && evcon->closecb != NULL) 1122 (*evcon->closecb)(evcon, evcon->closecb_arg); 1123 } 1124 1125 /* remove all requests that might be queued on this 1126 * connection. for server connections, this should be empty. 1127 * because it gets dequeued either in evhttp_connection_done or 1128 * evhttp_connection_fail_. 1129 */ 1130 while ((req = TAILQ_FIRST(&evcon->requests)) != NULL) { 1131 TAILQ_REMOVE(&evcon->requests, req, next); 1132 evhttp_request_free(req); 1133 } 1134 1135 if (evcon->http_server != NULL) { 1136 struct evhttp *http = evcon->http_server; 1137 TAILQ_REMOVE(&http->connections, evcon, next); 1138 } 1139 1140 if (event_initialized(&evcon->retry_ev)) { 1141 event_del(&evcon->retry_ev); 1142 event_debug_unassign(&evcon->retry_ev); 1143 } 1144 1145 if (evcon->bufev != NULL) 1146 bufferevent_free(evcon->bufev); 1147 1148 event_deferred_cb_cancel_(get_deferred_queue(evcon), 1149 &evcon->read_more_deferred_cb); 1150 1151 if (evcon->fd != -1) { 1152 shutdown(evcon->fd, EVUTIL_SHUT_WR); 1153 evutil_closesocket(evcon->fd); 1154 } 1155 1156 if (evcon->bind_address != NULL) 1157 mm_free(evcon->bind_address); 1158 1159 if (evcon->address != NULL) 1160 mm_free(evcon->address); 1161 1162 mm_free(evcon); 1163 } 1164 1165 void 1166 evhttp_connection_set_local_address(struct evhttp_connection *evcon, 1167 const char *address) 1168 { 1169 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED); 1170 if (evcon->bind_address) 1171 mm_free(evcon->bind_address); 1172 if ((evcon->bind_address = mm_strdup(address)) == NULL) 1173 event_warn("%s: strdup", __func__); 1174 } 1175 1176 void 1177 evhttp_connection_set_local_port(struct evhttp_connection *evcon, 1178 ev_uint16_t port) 1179 { 1180 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED); 1181 evcon->bind_port = port; 1182 } 1183 1184 static void 1185 evhttp_request_dispatch(struct evhttp_connection* evcon) 1186 { 1187 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests); 1188 1189 /* this should not usually happy but it's possible */ 1190 if (req == NULL) 1191 return; 1192 1193 /* delete possible close detection events */ 1194 evhttp_connection_stop_detectclose(evcon); 1195 1196 /* we assume that the connection is connected already */ 1197 EVUTIL_ASSERT(evcon->state == EVCON_IDLE); 1198 1199 evcon->state = EVCON_WRITING; 1200 1201 /* Create the header from the store arguments */ 1202 evhttp_make_header(evcon, req); 1203 1204 evhttp_write_buffer(evcon, evhttp_write_connectioncb, NULL); 1205 } 1206 1207 /* Reset our connection state: disables reading/writing, closes our fd (if 1208 * any), clears out buffers, and puts us in state DISCONNECTED. */ 1209 void 1210 evhttp_connection_reset_(struct evhttp_connection *evcon) 1211 { 1212 struct evbuffer *tmp; 1213 1214 /* XXXX This is not actually an optimal fix. Instead we ought to have 1215 an API for "stop connecting", or use bufferevent_setfd to turn off 1216 connecting. But for Libevent 2.0, this seems like a minimal change 1217 least likely to disrupt the rest of the bufferevent and http code. 1218 1219 Why is this here? If the fd is set in the bufferevent, and the 1220 bufferevent is connecting, then you can't actually stop the 1221 bufferevent from trying to connect with bufferevent_disable(). The 1222 connect will never trigger, since we close the fd, but the timeout 1223 might. That caused an assertion failure in evhttp_connection_fail_. 1224 */ 1225 bufferevent_disable_hard_(evcon->bufev, EV_READ|EV_WRITE); 1226 1227 if (evcon->fd != -1) { 1228 /* inform interested parties about connection close */ 1229 if (evhttp_connected(evcon) && evcon->closecb != NULL) 1230 (*evcon->closecb)(evcon, evcon->closecb_arg); 1231 1232 shutdown(evcon->fd, EVUTIL_SHUT_WR); 1233 evutil_closesocket(evcon->fd); 1234 evcon->fd = -1; 1235 } 1236 1237 /* we need to clean up any buffered data */ 1238 tmp = bufferevent_get_output(evcon->bufev); 1239 evbuffer_drain(tmp, evbuffer_get_length(tmp)); 1240 tmp = bufferevent_get_input(evcon->bufev); 1241 evbuffer_drain(tmp, evbuffer_get_length(tmp)); 1242 1243 evcon->state = EVCON_DISCONNECTED; 1244 } 1245 1246 static void 1247 evhttp_connection_start_detectclose(struct evhttp_connection *evcon) 1248 { 1249 evcon->flags |= EVHTTP_CON_CLOSEDETECT; 1250 1251 bufferevent_enable(evcon->bufev, EV_READ); 1252 } 1253 1254 static void 1255 evhttp_connection_stop_detectclose(struct evhttp_connection *evcon) 1256 { 1257 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT; 1258 1259 bufferevent_disable(evcon->bufev, EV_READ); 1260 } 1261 1262 static void 1263 evhttp_connection_retry(evutil_socket_t fd, short what, void *arg) 1264 { 1265 struct evhttp_connection *evcon = arg; 1266 1267 evcon->state = EVCON_DISCONNECTED; 1268 evhttp_connection_connect_(evcon); 1269 } 1270 1271 static void 1272 evhttp_connection_cb_cleanup(struct evhttp_connection *evcon) 1273 { 1274 struct evcon_requestq requests; 1275 1276 if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) { 1277 struct timeval tv_retry = evcon->initial_retry_timeout; 1278 int i; 1279 evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon); 1280 /* XXXX handle failure from evhttp_add_event */ 1281 for (i=0; i < evcon->retry_cnt; ++i) { 1282 tv_retry.tv_usec *= 2; 1283 if (tv_retry.tv_usec > 1000000) { 1284 tv_retry.tv_usec -= 1000000; 1285 tv_retry.tv_sec += 1; 1286 } 1287 tv_retry.tv_sec *= 2; 1288 if (tv_retry.tv_sec > 3600) { 1289 tv_retry.tv_sec = 3600; 1290 tv_retry.tv_usec = 0; 1291 } 1292 } 1293 event_add(&evcon->retry_ev, &tv_retry); 1294 evcon->retry_cnt++; 1295 return; 1296 } 1297 evhttp_connection_reset_(evcon); 1298 1299 /* 1300 * User callback can do evhttp_make_request() on the same 1301 * evcon so new request will be added to evcon->requests. To 1302 * avoid freeing it prematurely we iterate over the copy of 1303 * the queue. 1304 */ 1305 TAILQ_INIT(&requests); 1306 while (TAILQ_FIRST(&evcon->requests) != NULL) { 1307 struct evhttp_request *request = TAILQ_FIRST(&evcon->requests); 1308 TAILQ_REMOVE(&evcon->requests, request, next); 1309 TAILQ_INSERT_TAIL(&requests, request, next); 1310 } 1311 1312 /* for now, we just signal all requests by executing their callbacks */ 1313 while (TAILQ_FIRST(&requests) != NULL) { 1314 struct evhttp_request *request = TAILQ_FIRST(&requests); 1315 TAILQ_REMOVE(&requests, request, next); 1316 request->evcon = NULL; 1317 1318 /* we might want to set an error here */ 1319 request->cb(request, request->cb_arg); 1320 evhttp_request_free(request); 1321 } 1322 } 1323 1324 static void 1325 evhttp_error_cb(struct bufferevent *bufev, short what, void *arg) 1326 { 1327 struct evhttp_connection *evcon = arg; 1328 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests); 1329 1330 if (evcon->fd == -1) 1331 evcon->fd = bufferevent_getfd(bufev); 1332 1333 switch (evcon->state) { 1334 case EVCON_CONNECTING: 1335 if (what & BEV_EVENT_TIMEOUT) { 1336 event_debug(("%s: connection timeout for \"%s:%d\" on " 1337 EV_SOCK_FMT, 1338 __func__, evcon->address, evcon->port, 1339 EV_SOCK_ARG(evcon->fd))); 1340 evhttp_connection_cb_cleanup(evcon); 1341 return; 1342 } 1343 break; 1344 1345 case EVCON_READING_BODY: 1346 if (!req->chunked && req->ntoread < 0 1347 && what == (BEV_EVENT_READING|BEV_EVENT_EOF)) { 1348 /* EOF on read can be benign */ 1349 evhttp_connection_done(evcon); 1350 return; 1351 } 1352 break; 1353 1354 case EVCON_DISCONNECTED: 1355 case EVCON_IDLE: 1356 case EVCON_READING_FIRSTLINE: 1357 case EVCON_READING_HEADERS: 1358 case EVCON_READING_TRAILER: 1359 case EVCON_WRITING: 1360 default: 1361 break; 1362 } 1363 1364 /* when we are in close detect mode, a read error means that 1365 * the other side closed their connection. 1366 */ 1367 if (evcon->flags & EVHTTP_CON_CLOSEDETECT) { 1368 evcon->flags &= ~EVHTTP_CON_CLOSEDETECT; 1369 EVUTIL_ASSERT(evcon->http_server == NULL); 1370 /* For connections from the client, we just 1371 * reset the connection so that it becomes 1372 * disconnected. 1373 */ 1374 EVUTIL_ASSERT(evcon->state == EVCON_IDLE); 1375 evhttp_connection_reset_(evcon); 1376 return; 1377 } 1378 1379 if (what & BEV_EVENT_TIMEOUT) { 1380 evhttp_connection_fail_(evcon, EVCON_HTTP_TIMEOUT); 1381 } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) { 1382 evhttp_connection_fail_(evcon, EVCON_HTTP_EOF); 1383 } else if (what == BEV_EVENT_CONNECTED) { 1384 } else { 1385 evhttp_connection_fail_(evcon, EVCON_HTTP_BUFFER_ERROR); 1386 } 1387 } 1388 1389 /* 1390 * Event callback for asynchronous connection attempt. 1391 */ 1392 static void 1393 evhttp_connection_cb(struct bufferevent *bufev, short what, void *arg) 1394 { 1395 struct evhttp_connection *evcon = arg; 1396 int error; 1397 ev_socklen_t errsz = sizeof(error); 1398 1399 if (evcon->fd == -1) 1400 evcon->fd = bufferevent_getfd(bufev); 1401 1402 if (!(what & BEV_EVENT_CONNECTED)) { 1403 /* some operating systems return ECONNREFUSED immediately 1404 * when connecting to a local address. the cleanup is going 1405 * to reschedule this function call. 1406 */ 1407 #ifndef _WIN32 1408 if (errno == ECONNREFUSED) 1409 goto cleanup; 1410 #endif 1411 evhttp_error_cb(bufev, what, arg); 1412 return; 1413 } 1414 1415 /* Check if the connection completed */ 1416 if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error, 1417 &errsz) == -1) { 1418 event_debug(("%s: getsockopt for \"%s:%d\" on "EV_SOCK_FMT, 1419 __func__, evcon->address, evcon->port, 1420 EV_SOCK_ARG(evcon->fd))); 1421 goto cleanup; 1422 } 1423 1424 if (error) { 1425 event_debug(("%s: connect failed for \"%s:%d\" on " 1426 EV_SOCK_FMT": %s", 1427 __func__, evcon->address, evcon->port, 1428 EV_SOCK_ARG(evcon->fd), 1429 evutil_socket_error_to_string(error))); 1430 goto cleanup; 1431 } 1432 1433 /* We are connected to the server now */ 1434 event_debug(("%s: connected to \"%s:%d\" on "EV_SOCK_FMT"\n", 1435 __func__, evcon->address, evcon->port, 1436 EV_SOCK_ARG(evcon->fd))); 1437 1438 /* Reset the retry count as we were successful in connecting */ 1439 evcon->retry_cnt = 0; 1440 evcon->state = EVCON_IDLE; 1441 1442 /* reset the bufferevent cbs */ 1443 bufferevent_setcb(evcon->bufev, 1444 evhttp_read_cb, 1445 evhttp_write_cb, 1446 evhttp_error_cb, 1447 evcon); 1448 1449 if (!evutil_timerisset(&evcon->timeout)) { 1450 const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 }; 1451 const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 }; 1452 bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv); 1453 } else { 1454 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout); 1455 } 1456 1457 /* try to start requests that have queued up on this connection */ 1458 evhttp_request_dispatch(evcon); 1459 return; 1460 1461 cleanup: 1462 evhttp_connection_cb_cleanup(evcon); 1463 } 1464 1465 /* 1466 * Check if we got a valid response code. 1467 */ 1468 1469 static int 1470 evhttp_valid_response_code(int code) 1471 { 1472 if (code == 0) 1473 return (0); 1474 1475 return (1); 1476 } 1477 1478 static int 1479 evhttp_parse_http_version(const char *version, struct evhttp_request *req) 1480 { 1481 int major, minor; 1482 char ch; 1483 int n = sscanf(version, "HTTP/%d.%d%c", &major, &minor, &ch); 1484 if (n != 2 || major > 1) { 1485 event_debug(("%s: bad version %s on message %p from %s", 1486 __func__, version, req, req->remote_host)); 1487 return (-1); 1488 } 1489 req->major = major; 1490 req->minor = minor; 1491 return (0); 1492 } 1493 1494 /* Parses the status line of a web server */ 1495 1496 static int 1497 evhttp_parse_response_line(struct evhttp_request *req, char *line) 1498 { 1499 char *protocol; 1500 char *number; 1501 const char *readable = ""; 1502 1503 protocol = strsep(&line, " "); 1504 if (line == NULL) 1505 return (-1); 1506 number = strsep(&line, " "); 1507 if (line != NULL) 1508 readable = line; 1509 1510 if (evhttp_parse_http_version(protocol, req) < 0) 1511 return (-1); 1512 1513 req->response_code = atoi(number); 1514 if (!evhttp_valid_response_code(req->response_code)) { 1515 event_debug(("%s: bad response code \"%s\"", 1516 __func__, number)); 1517 return (-1); 1518 } 1519 1520 if ((req->response_code_line = mm_strdup(readable)) == NULL) { 1521 event_warn("%s: strdup", __func__); 1522 return (-1); 1523 } 1524 1525 return (0); 1526 } 1527 1528 /* Parse the first line of a HTTP request */ 1529 1530 static int 1531 evhttp_parse_request_line(struct evhttp_request *req, char *line) 1532 { 1533 char *method; 1534 char *uri; 1535 char *version; 1536 const char *hostname; 1537 const char *scheme; 1538 size_t method_len; 1539 enum evhttp_cmd_type type; 1540 1541 /* Parse the request line */ 1542 method = strsep(&line, " "); 1543 if (line == NULL) 1544 return (-1); 1545 uri = strsep(&line, " "); 1546 if (line == NULL) 1547 return (-1); 1548 version = strsep(&line, " "); 1549 if (line != NULL) 1550 return (-1); 1551 1552 method_len = (uri - method) - 1; 1553 type = EVHTTP_REQ_UNKNOWN_; 1554 1555 /* First line */ 1556 switch (method_len) { 1557 case 3: 1558 /* The length of the method string is 3, meaning it can only be one of two methods: GET or PUT */ 1559 1560 /* Since both GET and PUT share the same character 'T' at the end, 1561 * if the string doesn't have 'T', we can immediately determine this 1562 * is an invalid HTTP method */ 1563 1564 if (method[2] != 'T') { 1565 break; 1566 } 1567 1568 switch (*method) { 1569 case 'G': 1570 /* This first byte is 'G', so make sure the next byte is 1571 * 'E', if it isn't then this isn't a valid method */ 1572 1573 if (method[1] == 'E') { 1574 type = EVHTTP_REQ_GET; 1575 } 1576 1577 break; 1578 case 'P': 1579 /* First byte is P, check second byte for 'U', if not, 1580 * we know it's an invalid method */ 1581 if (method[1] == 'U') { 1582 type = EVHTTP_REQ_PUT; 1583 } 1584 break; 1585 default: 1586 break; 1587 } 1588 break; 1589 case 4: 1590 /* The method length is 4 bytes, leaving only the methods "POST" and "HEAD" */ 1591 switch (*method) { 1592 case 'P': 1593 if (method[3] == 'T' && method[2] == 'S' && method[1] == 'O') { 1594 type = EVHTTP_REQ_POST; 1595 } 1596 break; 1597 case 'H': 1598 if (method[3] == 'D' && method[2] == 'A' && method[1] == 'E') { 1599 type = EVHTTP_REQ_HEAD; 1600 } 1601 break; 1602 default: 1603 break; 1604 } 1605 break; 1606 case 5: 1607 /* Method length is 5 bytes, which can only encompass PATCH and TRACE */ 1608 switch (*method) { 1609 case 'P': 1610 if (method[4] == 'H' && method[3] == 'C' && method[2] == 'T' && method[1] == 'A') { 1611 type = EVHTTP_REQ_PATCH; 1612 } 1613 break; 1614 case 'T': 1615 if (method[4] == 'E' && method[3] == 'C' && method[2] == 'A' && method[1] == 'R') { 1616 type = EVHTTP_REQ_TRACE; 1617 } 1618 1619 break; 1620 default: 1621 break; 1622 } 1623 break; 1624 case 6: 1625 /* Method length is 6, only valid method 6 bytes in length is DELEte */ 1626 1627 /* If the first byte isn't 'D' then it's invalid */ 1628 if (*method != 'D') { 1629 break; 1630 } 1631 1632 if (method[5] == 'E' && method[4] == 'T' && method[3] == 'E' && method[2] == 'L' && method[1] == 'E') { 1633 type = EVHTTP_REQ_DELETE; 1634 } 1635 1636 break; 1637 case 7: 1638 /* Method length is 7, only valid methods are "OPTIONS" and "CONNECT" */ 1639 switch (*method) { 1640 case 'O': 1641 if (method[6] == 'S' && method[5] == 'N' && method[4] == 'O' && 1642 method[3] == 'I' && method[2] == 'T' && method[1] == 'P') { 1643 type = EVHTTP_REQ_OPTIONS; 1644 } 1645 1646 break; 1647 case 'C': 1648 if (method[6] == 'T' && method[5] == 'C' && method[4] == 'E' && 1649 method[3] == 'N' && method[2] == 'N' && method[1] == 'O') { 1650 type = EVHTTP_REQ_CONNECT; 1651 } 1652 1653 break; 1654 default: 1655 break; 1656 } 1657 break; 1658 } /* switch */ 1659 1660 if ((int)type == EVHTTP_REQ_UNKNOWN_) { 1661 event_debug(("%s: bad method %s on request %p from %s", 1662 __func__, method, req, req->remote_host)); 1663 /* No error yet; we'll give a better error later when 1664 * we see that req->type is unsupported. */ 1665 } 1666 1667 req->type = type; 1668 1669 if (evhttp_parse_http_version(version, req) < 0) 1670 return (-1); 1671 1672 if ((req->uri = mm_strdup(uri)) == NULL) { 1673 event_debug(("%s: mm_strdup", __func__)); 1674 return (-1); 1675 } 1676 1677 if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri, 1678 EVHTTP_URI_NONCONFORMANT)) == NULL) { 1679 return -1; 1680 } 1681 1682 /* If we have an absolute-URI, check to see if it is an http request 1683 for a known vhost or server alias. If we don't know about this 1684 host, we consider it a proxy request. */ 1685 scheme = evhttp_uri_get_scheme(req->uri_elems); 1686 hostname = evhttp_uri_get_host(req->uri_elems); 1687 if (scheme && (!evutil_ascii_strcasecmp(scheme, "http") || 1688 !evutil_ascii_strcasecmp(scheme, "https")) && 1689 hostname && 1690 !evhttp_find_vhost(req->evcon->http_server, NULL, hostname)) 1691 req->flags |= EVHTTP_PROXY_REQUEST; 1692 1693 return (0); 1694 } 1695 1696 const char * 1697 evhttp_find_header(const struct evkeyvalq *headers, const char *key) 1698 { 1699 struct evkeyval *header; 1700 1701 TAILQ_FOREACH(header, headers, next) { 1702 if (evutil_ascii_strcasecmp(header->key, key) == 0) 1703 return (header->value); 1704 } 1705 1706 return (NULL); 1707 } 1708 1709 void 1710 evhttp_clear_headers(struct evkeyvalq *headers) 1711 { 1712 struct evkeyval *header; 1713 1714 for (header = TAILQ_FIRST(headers); 1715 header != NULL; 1716 header = TAILQ_FIRST(headers)) { 1717 TAILQ_REMOVE(headers, header, next); 1718 mm_free(header->key); 1719 mm_free(header->value); 1720 mm_free(header); 1721 } 1722 } 1723 1724 /* 1725 * Returns 0, if the header was successfully removed. 1726 * Returns -1, if the header could not be found. 1727 */ 1728 1729 int 1730 evhttp_remove_header(struct evkeyvalq *headers, const char *key) 1731 { 1732 struct evkeyval *header; 1733 1734 TAILQ_FOREACH(header, headers, next) { 1735 if (evutil_ascii_strcasecmp(header->key, key) == 0) 1736 break; 1737 } 1738 1739 if (header == NULL) 1740 return (-1); 1741 1742 /* Free and remove the header that we found */ 1743 TAILQ_REMOVE(headers, header, next); 1744 mm_free(header->key); 1745 mm_free(header->value); 1746 mm_free(header); 1747 1748 return (0); 1749 } 1750 1751 static int 1752 evhttp_header_is_valid_value(const char *value) 1753 { 1754 const char *p = value; 1755 1756 while ((p = strpbrk(p, "\r\n")) != NULL) { 1757 /* we really expect only one new line */ 1758 p += strspn(p, "\r\n"); 1759 /* we expect a space or tab for continuation */ 1760 if (*p != ' ' && *p != '\t') 1761 return (0); 1762 } 1763 return (1); 1764 } 1765 1766 int 1767 evhttp_add_header(struct evkeyvalq *headers, 1768 const char *key, const char *value) 1769 { 1770 event_debug(("%s: key: %s val: %s\n", __func__, key, value)); 1771 1772 if (strchr(key, '\r') != NULL || strchr(key, '\n') != NULL) { 1773 /* drop illegal headers */ 1774 event_debug(("%s: dropping illegal header key\n", __func__)); 1775 return (-1); 1776 } 1777 1778 if (!evhttp_header_is_valid_value(value)) { 1779 event_debug(("%s: dropping illegal header value\n", __func__)); 1780 return (-1); 1781 } 1782 1783 return (evhttp_add_header_internal(headers, key, value)); 1784 } 1785 1786 static int 1787 evhttp_add_header_internal(struct evkeyvalq *headers, 1788 const char *key, const char *value) 1789 { 1790 struct evkeyval *header = mm_calloc(1, sizeof(struct evkeyval)); 1791 if (header == NULL) { 1792 event_warn("%s: calloc", __func__); 1793 return (-1); 1794 } 1795 if ((header->key = mm_strdup(key)) == NULL) { 1796 mm_free(header); 1797 event_warn("%s: strdup", __func__); 1798 return (-1); 1799 } 1800 if ((header->value = mm_strdup(value)) == NULL) { 1801 mm_free(header->key); 1802 mm_free(header); 1803 event_warn("%s: strdup", __func__); 1804 return (-1); 1805 } 1806 1807 TAILQ_INSERT_TAIL(headers, header, next); 1808 1809 return (0); 1810 } 1811 1812 /* 1813 * Parses header lines from a request or a response into the specified 1814 * request object given an event buffer. 1815 * 1816 * Returns 1817 * DATA_CORRUPTED on error 1818 * MORE_DATA_EXPECTED when we need to read more headers 1819 * ALL_DATA_READ when all headers have been read. 1820 */ 1821 1822 enum message_read_status 1823 evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer) 1824 { 1825 char *line; 1826 enum message_read_status status = ALL_DATA_READ; 1827 1828 size_t line_length; 1829 /* XXX try */ 1830 line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF); 1831 if (line == NULL) { 1832 if (req->evcon != NULL && 1833 evbuffer_get_length(buffer) > req->evcon->max_headers_size) 1834 return (DATA_TOO_LONG); 1835 else 1836 return (MORE_DATA_EXPECTED); 1837 } 1838 1839 if (req->evcon != NULL && 1840 line_length > req->evcon->max_headers_size) { 1841 mm_free(line); 1842 return (DATA_TOO_LONG); 1843 } 1844 1845 req->headers_size = line_length; 1846 1847 switch (req->kind) { 1848 case EVHTTP_REQUEST: 1849 if (evhttp_parse_request_line(req, line) == -1) 1850 status = DATA_CORRUPTED; 1851 break; 1852 case EVHTTP_RESPONSE: 1853 if (evhttp_parse_response_line(req, line) == -1) 1854 status = DATA_CORRUPTED; 1855 break; 1856 default: 1857 status = DATA_CORRUPTED; 1858 } 1859 1860 mm_free(line); 1861 return (status); 1862 } 1863 1864 static int 1865 evhttp_append_to_last_header(struct evkeyvalq *headers, char *line) 1866 { 1867 struct evkeyval *header = TAILQ_LAST(headers, evkeyvalq); 1868 char *newval; 1869 size_t old_len, line_len; 1870 1871 if (header == NULL) 1872 return (-1); 1873 1874 old_len = strlen(header->value); 1875 1876 /* Strip space from start and end of line. */ 1877 while (*line == ' ' || *line == '\t') 1878 ++line; 1879 evutil_rtrim_lws_(line); 1880 1881 line_len = strlen(line); 1882 1883 newval = mm_realloc(header->value, old_len + line_len + 2); 1884 if (newval == NULL) 1885 return (-1); 1886 1887 newval[old_len] = ' '; 1888 memcpy(newval + old_len + 1, line, line_len + 1); 1889 header->value = newval; 1890 1891 return (0); 1892 } 1893 1894 enum message_read_status 1895 evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer) 1896 { 1897 enum message_read_status errcode = DATA_CORRUPTED; 1898 char *line; 1899 enum message_read_status status = MORE_DATA_EXPECTED; 1900 1901 struct evkeyvalq* headers = req->input_headers; 1902 size_t line_length; 1903 while ((line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF)) 1904 != NULL) { 1905 char *skey, *svalue; 1906 1907 req->headers_size += line_length; 1908 1909 if (req->evcon != NULL && 1910 req->headers_size > req->evcon->max_headers_size) { 1911 errcode = DATA_TOO_LONG; 1912 goto error; 1913 } 1914 1915 if (*line == '\0') { /* Last header - Done */ 1916 status = ALL_DATA_READ; 1917 mm_free(line); 1918 break; 1919 } 1920 1921 /* Check if this is a continuation line */ 1922 if (*line == ' ' || *line == '\t') { 1923 if (evhttp_append_to_last_header(headers, line) == -1) 1924 goto error; 1925 mm_free(line); 1926 continue; 1927 } 1928 1929 /* Processing of header lines */ 1930 svalue = line; 1931 skey = strsep(&svalue, ":"); 1932 if (svalue == NULL) 1933 goto error; 1934 1935 svalue += strspn(svalue, " "); 1936 evutil_rtrim_lws_(svalue); 1937 1938 if (evhttp_add_header(headers, skey, svalue) == -1) 1939 goto error; 1940 1941 mm_free(line); 1942 } 1943 1944 if (status == MORE_DATA_EXPECTED) { 1945 if (req->evcon != NULL && 1946 req->headers_size + evbuffer_get_length(buffer) > req->evcon->max_headers_size) 1947 return (DATA_TOO_LONG); 1948 } 1949 1950 return (status); 1951 1952 error: 1953 mm_free(line); 1954 return (errcode); 1955 } 1956 1957 static int 1958 evhttp_get_body_length(struct evhttp_request *req) 1959 { 1960 struct evkeyvalq *headers = req->input_headers; 1961 const char *content_length; 1962 const char *connection; 1963 1964 content_length = evhttp_find_header(headers, "Content-Length"); 1965 connection = evhttp_find_header(headers, "Connection"); 1966 1967 if (content_length == NULL && connection == NULL) 1968 req->ntoread = -1; 1969 else if (content_length == NULL && 1970 evutil_ascii_strcasecmp(connection, "Close") != 0) { 1971 /* Bad combination, we don't know when it will end */ 1972 event_warnx("%s: we got no content length, but the " 1973 "server wants to keep the connection open: %s.", 1974 __func__, connection); 1975 return (-1); 1976 } else if (content_length == NULL) { 1977 req->ntoread = -1; 1978 } else { 1979 char *endp; 1980 ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10); 1981 if (*content_length == '\0' || *endp != '\0' || ntoread < 0) { 1982 event_debug(("%s: illegal content length: %s", 1983 __func__, content_length)); 1984 return (-1); 1985 } 1986 req->ntoread = ntoread; 1987 } 1988 1989 event_debug(("%s: bytes to read: "EV_I64_FMT" (in buffer "EV_SIZE_FMT")\n", 1990 __func__, EV_I64_ARG(req->ntoread), 1991 EV_SIZE_ARG(evbuffer_get_length(bufferevent_get_input(req->evcon->bufev))))); 1992 1993 return (0); 1994 } 1995 1996 static int 1997 evhttp_method_may_have_body(enum evhttp_cmd_type type) 1998 { 1999 switch (type) { 2000 case EVHTTP_REQ_POST: 2001 case EVHTTP_REQ_PUT: 2002 case EVHTTP_REQ_PATCH: 2003 return 1; 2004 case EVHTTP_REQ_TRACE: 2005 return 0; 2006 /* XXX May any of the below methods have a body? */ 2007 case EVHTTP_REQ_GET: 2008 case EVHTTP_REQ_HEAD: 2009 case EVHTTP_REQ_DELETE: 2010 case EVHTTP_REQ_OPTIONS: 2011 case EVHTTP_REQ_CONNECT: 2012 return 0; 2013 default: 2014 return 0; 2015 } 2016 } 2017 2018 static void 2019 evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req) 2020 { 2021 const char *xfer_enc; 2022 2023 /* If this is a request without a body, then we are done */ 2024 if (req->kind == EVHTTP_REQUEST && 2025 !evhttp_method_may_have_body(req->type)) { 2026 evhttp_connection_done(evcon); 2027 return; 2028 } 2029 evcon->state = EVCON_READING_BODY; 2030 xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding"); 2031 if (xfer_enc != NULL && evutil_ascii_strcasecmp(xfer_enc, "chunked") == 0) { 2032 req->chunked = 1; 2033 req->ntoread = -1; 2034 } else { 2035 if (evhttp_get_body_length(req) == -1) { 2036 evhttp_connection_fail_(evcon, 2037 EVCON_HTTP_INVALID_HEADER); 2038 return; 2039 } 2040 if (req->kind == EVHTTP_REQUEST && req->ntoread < 1) { 2041 /* An incoming request with no content-length and no 2042 * transfer-encoding has no body. */ 2043 evhttp_connection_done(evcon); 2044 return; 2045 } 2046 } 2047 2048 /* Should we send a 100 Continue status line? */ 2049 if (req->kind == EVHTTP_REQUEST && REQ_VERSION_ATLEAST(req, 1, 1)) { 2050 const char *expect; 2051 2052 expect = evhttp_find_header(req->input_headers, "Expect"); 2053 if (expect) { 2054 if (!evutil_ascii_strcasecmp(expect, "100-continue")) { 2055 /* XXX It would be nice to do some sanity 2056 checking here. Does the resource exist? 2057 Should the resource accept post requests? If 2058 no, we should respond with an error. For 2059 now, just optimistically tell the client to 2060 send their message body. */ 2061 if (req->ntoread > 0) { 2062 /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */ 2063 if ((req->evcon->max_body_size <= EV_INT64_MAX) && (ev_uint64_t)req->ntoread > req->evcon->max_body_size) { 2064 evhttp_send_error(req, HTTP_ENTITYTOOLARGE, NULL); 2065 return; 2066 } 2067 } 2068 if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev))) 2069 evhttp_send_continue(evcon, req); 2070 } else { 2071 evhttp_send_error(req, HTTP_EXPECTATIONFAILED, 2072 NULL); 2073 return; 2074 } 2075 } 2076 } 2077 2078 evhttp_read_body(evcon, req); 2079 /* note the request may have been freed in evhttp_read_body */ 2080 } 2081 2082 static void 2083 evhttp_read_firstline(struct evhttp_connection *evcon, 2084 struct evhttp_request *req) 2085 { 2086 enum message_read_status res; 2087 2088 res = evhttp_parse_firstline_(req, bufferevent_get_input(evcon->bufev)); 2089 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) { 2090 /* Error while reading, terminate */ 2091 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n", 2092 __func__, EV_SOCK_ARG(evcon->fd))); 2093 evhttp_connection_fail_(evcon, EVCON_HTTP_INVALID_HEADER); 2094 return; 2095 } else if (res == MORE_DATA_EXPECTED) { 2096 /* Need more header lines */ 2097 return; 2098 } 2099 2100 evcon->state = EVCON_READING_HEADERS; 2101 evhttp_read_header(evcon, req); 2102 } 2103 2104 static void 2105 evhttp_read_header(struct evhttp_connection *evcon, 2106 struct evhttp_request *req) 2107 { 2108 enum message_read_status res; 2109 evutil_socket_t fd = evcon->fd; 2110 2111 res = evhttp_parse_headers_(req, bufferevent_get_input(evcon->bufev)); 2112 if (res == DATA_CORRUPTED || res == DATA_TOO_LONG) { 2113 /* Error while reading, terminate */ 2114 event_debug(("%s: bad header lines on "EV_SOCK_FMT"\n", 2115 __func__, EV_SOCK_ARG(fd))); 2116 evhttp_connection_fail_(evcon, EVCON_HTTP_INVALID_HEADER); 2117 return; 2118 } else if (res == MORE_DATA_EXPECTED) { 2119 /* Need more header lines */ 2120 return; 2121 } 2122 2123 /* Disable reading for now */ 2124 bufferevent_disable(evcon->bufev, EV_READ); 2125 2126 /* Done reading headers, do the real work */ 2127 switch (req->kind) { 2128 case EVHTTP_REQUEST: 2129 event_debug(("%s: checking for post data on "EV_SOCK_FMT"\n", 2130 __func__, EV_SOCK_ARG(fd))); 2131 evhttp_get_body(evcon, req); 2132 /* note the request may have been freed in evhttp_get_body */ 2133 break; 2134 2135 case EVHTTP_RESPONSE: 2136 /* Start over if we got a 100 Continue response. */ 2137 if (req->response_code == 100) { 2138 evhttp_start_read_(evcon); 2139 return; 2140 } 2141 if (!evhttp_response_needs_body(req)) { 2142 event_debug(("%s: skipping body for code %d\n", 2143 __func__, req->response_code)); 2144 evhttp_connection_done(evcon); 2145 } else { 2146 event_debug(("%s: start of read body for %s on " 2147 EV_SOCK_FMT"\n", 2148 __func__, req->remote_host, EV_SOCK_ARG(fd))); 2149 evhttp_get_body(evcon, req); 2150 /* note the request may have been freed in 2151 * evhttp_get_body */ 2152 } 2153 break; 2154 2155 default: 2156 event_warnx("%s: bad header on "EV_SOCK_FMT, __func__, 2157 EV_SOCK_ARG(fd)); 2158 evhttp_connection_fail_(evcon, EVCON_HTTP_INVALID_HEADER); 2159 break; 2160 } 2161 /* request may have been freed above */ 2162 } 2163 2164 /* 2165 * Creates a TCP connection to the specified port and executes a callback 2166 * when finished. Failure or success is indicate by the passed connection 2167 * object. 2168 * 2169 * Although this interface accepts a hostname, it is intended to take 2170 * only numeric hostnames so that non-blocking DNS resolution can 2171 * happen elsewhere. 2172 */ 2173 2174 struct evhttp_connection * 2175 evhttp_connection_new(const char *address, unsigned short port) 2176 { 2177 return (evhttp_connection_base_new(NULL, NULL, address, port)); 2178 } 2179 2180 struct evhttp_connection * 2181 evhttp_connection_base_bufferevent_new(struct event_base *base, struct evdns_base *dnsbase, struct bufferevent* bev, 2182 const char *address, unsigned short port) 2183 { 2184 struct evhttp_connection *evcon = NULL; 2185 2186 event_debug(("Attempting connection to %s:%d\n", address, port)); 2187 2188 if ((evcon = mm_calloc(1, sizeof(struct evhttp_connection))) == NULL) { 2189 event_warn("%s: calloc failed", __func__); 2190 goto error; 2191 } 2192 2193 evcon->fd = -1; 2194 evcon->port = port; 2195 2196 evcon->max_headers_size = EV_SIZE_MAX; 2197 evcon->max_body_size = EV_SIZE_MAX; 2198 2199 evutil_timerclear(&evcon->timeout); 2200 evcon->retry_cnt = evcon->retry_max = 0; 2201 2202 if ((evcon->address = mm_strdup(address)) == NULL) { 2203 event_warn("%s: strdup failed", __func__); 2204 goto error; 2205 } 2206 2207 if (bev == NULL) { 2208 if (!(bev = bufferevent_socket_new(base, -1, 0))) { 2209 event_warn("%s: bufferevent_socket_new failed", __func__); 2210 goto error; 2211 } 2212 } 2213 2214 bufferevent_setcb(bev, evhttp_read_cb, evhttp_write_cb, evhttp_error_cb, evcon); 2215 evcon->bufev = bev; 2216 2217 evcon->state = EVCON_DISCONNECTED; 2218 TAILQ_INIT(&evcon->requests); 2219 2220 evcon->initial_retry_timeout.tv_sec = 2; 2221 evcon->initial_retry_timeout.tv_usec = 0; 2222 2223 if (base != NULL) { 2224 evcon->base = base; 2225 if (bufferevent_get_base(bev) != base) 2226 bufferevent_base_set(base, evcon->bufev); 2227 } 2228 2229 event_deferred_cb_init_( 2230 &evcon->read_more_deferred_cb, 2231 bufferevent_get_priority(bev), 2232 evhttp_deferred_read_cb, evcon); 2233 2234 evcon->dns_base = dnsbase; 2235 2236 return (evcon); 2237 2238 error: 2239 if (evcon != NULL) 2240 evhttp_connection_free(evcon); 2241 return (NULL); 2242 } 2243 2244 struct bufferevent* evhttp_connection_get_bufferevent(struct evhttp_connection *evcon) 2245 { 2246 return evcon->bufev; 2247 } 2248 2249 struct evhttp_connection * 2250 evhttp_connection_base_new(struct event_base *base, struct evdns_base *dnsbase, 2251 const char *address, unsigned short port) 2252 { 2253 return evhttp_connection_base_bufferevent_new(base, dnsbase, NULL, address, port); 2254 } 2255 2256 void 2257 evhttp_connection_set_base(struct evhttp_connection *evcon, 2258 struct event_base *base) 2259 { 2260 EVUTIL_ASSERT(evcon->base == NULL); 2261 EVUTIL_ASSERT(evcon->state == EVCON_DISCONNECTED); 2262 evcon->base = base; 2263 bufferevent_base_set(base, evcon->bufev); 2264 } 2265 2266 void 2267 evhttp_connection_set_timeout(struct evhttp_connection *evcon, 2268 int timeout_in_secs) 2269 { 2270 if (timeout_in_secs == -1) 2271 evhttp_connection_set_timeout_tv(evcon, NULL); 2272 else { 2273 struct timeval tv; 2274 tv.tv_sec = timeout_in_secs; 2275 tv.tv_usec = 0; 2276 evhttp_connection_set_timeout_tv(evcon, &tv); 2277 } 2278 } 2279 2280 void 2281 evhttp_connection_set_timeout_tv(struct evhttp_connection *evcon, 2282 const struct timeval* tv) 2283 { 2284 if (tv) { 2285 evcon->timeout = *tv; 2286 bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout); 2287 } else { 2288 const struct timeval read_tv = { HTTP_READ_TIMEOUT, 0 }; 2289 const struct timeval write_tv = { HTTP_WRITE_TIMEOUT, 0 }; 2290 evutil_timerclear(&evcon->timeout); 2291 bufferevent_set_timeouts(evcon->bufev, &read_tv, &write_tv); 2292 } 2293 } 2294 2295 void 2296 evhttp_connection_set_initial_retry_tv(struct evhttp_connection *evcon, 2297 const struct timeval *tv) 2298 { 2299 if (tv) { 2300 evcon->initial_retry_timeout = *tv; 2301 } else { 2302 evutil_timerclear(&evcon->initial_retry_timeout); 2303 evcon->initial_retry_timeout.tv_sec = 2; 2304 } 2305 } 2306 2307 void 2308 evhttp_connection_set_retries(struct evhttp_connection *evcon, 2309 int retry_max) 2310 { 2311 evcon->retry_max = retry_max; 2312 } 2313 2314 void 2315 evhttp_connection_set_closecb(struct evhttp_connection *evcon, 2316 void (*cb)(struct evhttp_connection *, void *), void *cbarg) 2317 { 2318 evcon->closecb = cb; 2319 evcon->closecb_arg = cbarg; 2320 } 2321 2322 void 2323 evhttp_connection_get_peer(struct evhttp_connection *evcon, 2324 char **address, ev_uint16_t *port) 2325 { 2326 *address = evcon->address; 2327 *port = evcon->port; 2328 } 2329 2330 int 2331 evhttp_connection_connect_(struct evhttp_connection *evcon) 2332 { 2333 int old_state = evcon->state; 2334 2335 if (evcon->state == EVCON_CONNECTING) 2336 return (0); 2337 2338 evhttp_connection_reset_(evcon); 2339 2340 EVUTIL_ASSERT(!(evcon->flags & EVHTTP_CON_INCOMING)); 2341 evcon->flags |= EVHTTP_CON_OUTGOING; 2342 2343 if (evcon->bind_address || evcon->bind_port) { 2344 evcon->fd = bind_socket( 2345 evcon->bind_address, evcon->bind_port, 0 /*reuse*/); 2346 if (evcon->fd == -1) { 2347 event_debug(("%s: failed to bind to \"%s\"", 2348 __func__, evcon->bind_address)); 2349 return (-1); 2350 } 2351 2352 bufferevent_setfd(evcon->bufev, evcon->fd); 2353 } else { 2354 bufferevent_setfd(evcon->bufev, -1); 2355 } 2356 2357 /* Set up a callback for successful connection setup */ 2358 bufferevent_setcb(evcon->bufev, 2359 NULL /* evhttp_read_cb */, 2360 NULL /* evhttp_write_cb */, 2361 evhttp_connection_cb, 2362 evcon); 2363 if (!evutil_timerisset(&evcon->timeout)) { 2364 const struct timeval conn_tv = { HTTP_CONNECT_TIMEOUT, 0 }; 2365 bufferevent_set_timeouts(evcon->bufev, NULL, &conn_tv); 2366 } else { 2367 bufferevent_set_timeouts(evcon->bufev, NULL, &evcon->timeout); 2368 } 2369 /* make sure that we get a write callback */ 2370 bufferevent_enable(evcon->bufev, EV_WRITE); 2371 2372 evcon->state = EVCON_CONNECTING; 2373 2374 if (bufferevent_socket_connect_hostname(evcon->bufev, evcon->dns_base, 2375 AF_UNSPEC, evcon->address, evcon->port) < 0) { 2376 evcon->state = old_state; 2377 event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed", 2378 __func__, evcon->address); 2379 /* some operating systems return ECONNREFUSED immediately 2380 * when connecting to a local address. the cleanup is going 2381 * to reschedule this function call. 2382 */ 2383 evhttp_connection_cb_cleanup(evcon); 2384 return (0); 2385 } 2386 2387 return (0); 2388 } 2389 2390 /* 2391 * Starts an HTTP request on the provided evhttp_connection object. 2392 * If the connection object is not connected to the web server already, 2393 * this will start the connection. 2394 */ 2395 2396 int 2397 evhttp_make_request(struct evhttp_connection *evcon, 2398 struct evhttp_request *req, 2399 enum evhttp_cmd_type type, const char *uri) 2400 { 2401 /* We are making a request */ 2402 req->kind = EVHTTP_REQUEST; 2403 req->type = type; 2404 if (req->uri != NULL) 2405 mm_free(req->uri); 2406 if ((req->uri = mm_strdup(uri)) == NULL) { 2407 event_warn("%s: strdup", __func__); 2408 evhttp_request_free(req); 2409 return (-1); 2410 } 2411 2412 /* Set the protocol version if it is not supplied */ 2413 if (!req->major && !req->minor) { 2414 req->major = 1; 2415 req->minor = 1; 2416 } 2417 2418 EVUTIL_ASSERT(req->evcon == NULL); 2419 req->evcon = evcon; 2420 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION)); 2421 2422 TAILQ_INSERT_TAIL(&evcon->requests, req, next); 2423 2424 /* If the connection object is not connected; make it so */ 2425 if (!evhttp_connected(evcon)) { 2426 int res = evhttp_connection_connect_(evcon); 2427 /* evhttp_connection_fail_(), which is called through 2428 * evhttp_connection_connect_(), assumes that req lies in 2429 * evcon->requests. Thus, enqueue the request in advance and 2430 * remove it in the error case. */ 2431 if (res != 0) 2432 TAILQ_REMOVE(&evcon->requests, req, next); 2433 2434 return res; 2435 } 2436 2437 /* 2438 * If it's connected already and we are the first in the queue, 2439 * then we can dispatch this request immediately. Otherwise, it 2440 * will be dispatched once the pending requests are completed. 2441 */ 2442 if (TAILQ_FIRST(&evcon->requests) == req) 2443 evhttp_request_dispatch(evcon); 2444 2445 return (0); 2446 } 2447 2448 void 2449 evhttp_cancel_request(struct evhttp_request *req) 2450 { 2451 struct evhttp_connection *evcon = req->evcon; 2452 if (evcon != NULL) { 2453 /* We need to remove it from the connection */ 2454 if (TAILQ_FIRST(&evcon->requests) == req) { 2455 /* it's currently being worked on, so reset 2456 * the connection. 2457 */ 2458 evhttp_connection_fail_(evcon, 2459 EVCON_HTTP_REQUEST_CANCEL); 2460 2461 /* connection fail freed the request */ 2462 return; 2463 } else { 2464 /* otherwise, we can just remove it from the 2465 * queue 2466 */ 2467 TAILQ_REMOVE(&evcon->requests, req, next); 2468 } 2469 } 2470 2471 evhttp_request_free(req); 2472 } 2473 2474 /* 2475 * Reads data from file descriptor into request structure 2476 * Request structure needs to be set up correctly. 2477 */ 2478 2479 void 2480 evhttp_start_read_(struct evhttp_connection *evcon) 2481 { 2482 /* Set up an event to read the headers */ 2483 bufferevent_disable(evcon->bufev, EV_WRITE); 2484 bufferevent_enable(evcon->bufev, EV_READ); 2485 evcon->state = EVCON_READING_FIRSTLINE; 2486 /* Reset the bufferevent callbacks */ 2487 bufferevent_setcb(evcon->bufev, 2488 evhttp_read_cb, 2489 evhttp_write_cb, 2490 evhttp_error_cb, 2491 evcon); 2492 2493 /* If there's still data pending, process it next time through the 2494 * loop. Don't do it now; that could get recusive. */ 2495 if (evbuffer_get_length(bufferevent_get_input(evcon->bufev))) { 2496 event_deferred_cb_schedule_(get_deferred_queue(evcon), 2497 &evcon->read_more_deferred_cb); 2498 } 2499 } 2500 2501 static void 2502 evhttp_send_done(struct evhttp_connection *evcon, void *arg) 2503 { 2504 int need_close; 2505 struct evhttp_request *req = TAILQ_FIRST(&evcon->requests); 2506 TAILQ_REMOVE(&evcon->requests, req, next); 2507 2508 need_close = 2509 (REQ_VERSION_BEFORE(req, 1, 1) && 2510 !evhttp_is_connection_keepalive(req->input_headers))|| 2511 evhttp_is_connection_close(req->flags, req->input_headers) || 2512 evhttp_is_connection_close(req->flags, req->output_headers); 2513 2514 EVUTIL_ASSERT(req->flags & EVHTTP_REQ_OWN_CONNECTION); 2515 evhttp_request_free(req); 2516 2517 if (need_close) { 2518 evhttp_connection_free(evcon); 2519 return; 2520 } 2521 2522 /* we have a persistent connection; try to accept another request. */ 2523 if (evhttp_associate_new_request_with_connection(evcon) == -1) { 2524 evhttp_connection_free(evcon); 2525 } 2526 } 2527 2528 /* 2529 * Returns an error page. 2530 */ 2531 2532 void 2533 evhttp_send_error(struct evhttp_request *req, int error, const char *reason) 2534 { 2535 2536 #define ERR_FORMAT "<HTML><HEAD>\n" \ 2537 "<TITLE>%d %s</TITLE>\n" \ 2538 "</HEAD><BODY>\n" \ 2539 "<H1>%s</H1>\n" \ 2540 "</BODY></HTML>\n" 2541 2542 struct evbuffer *buf = evbuffer_new(); 2543 if (buf == NULL) { 2544 /* if we cannot allocate memory; we just drop the connection */ 2545 evhttp_connection_free(req->evcon); 2546 return; 2547 } 2548 if (reason == NULL) { 2549 reason = evhttp_response_phrase_internal(error); 2550 } 2551 2552 evhttp_response_code_(req, error, reason); 2553 2554 evbuffer_add_printf(buf, ERR_FORMAT, error, reason, reason); 2555 2556 evhttp_send_page_(req, buf); 2557 2558 evbuffer_free(buf); 2559 #undef ERR_FORMAT 2560 } 2561 2562 /* Requires that headers and response code are already set up */ 2563 2564 static inline void 2565 evhttp_send(struct evhttp_request *req, struct evbuffer *databuf) 2566 { 2567 struct evhttp_connection *evcon = req->evcon; 2568 2569 if (evcon == NULL) { 2570 evhttp_request_free(req); 2571 return; 2572 } 2573 2574 EVUTIL_ASSERT(TAILQ_FIRST(&evcon->requests) == req); 2575 2576 /* we expect no more calls form the user on this request */ 2577 req->userdone = 1; 2578 2579 /* xxx: not sure if we really should expose the data buffer this way */ 2580 if (databuf != NULL) 2581 evbuffer_add_buffer(req->output_buffer, databuf); 2582 2583 /* Adds headers to the response */ 2584 evhttp_make_header(evcon, req); 2585 2586 evhttp_write_buffer(evcon, evhttp_send_done, NULL); 2587 } 2588 2589 void 2590 evhttp_send_reply(struct evhttp_request *req, int code, const char *reason, 2591 struct evbuffer *databuf) 2592 { 2593 evhttp_response_code_(req, code, reason); 2594 2595 evhttp_send(req, databuf); 2596 } 2597 2598 void 2599 evhttp_send_reply_start(struct evhttp_request *req, int code, 2600 const char *reason) 2601 { 2602 evhttp_response_code_(req, code, reason); 2603 if (evhttp_find_header(req->output_headers, "Content-Length") == NULL && 2604 REQ_VERSION_ATLEAST(req, 1, 1) && 2605 evhttp_response_needs_body(req)) { 2606 /* 2607 * prefer HTTP/1.1 chunked encoding to closing the connection; 2608 * note RFC 2616 section 4.4 forbids it with Content-Length: 2609 * and it's not necessary then anyway. 2610 */ 2611 evhttp_add_header(req->output_headers, "Transfer-Encoding", 2612 "chunked"); 2613 req->chunked = 1; 2614 } else { 2615 req->chunked = 0; 2616 } 2617 evhttp_make_header(req->evcon, req); 2618 evhttp_write_buffer(req->evcon, NULL, NULL); 2619 } 2620 2621 void 2622 evhttp_send_reply_chunk(struct evhttp_request *req, struct evbuffer *databuf) 2623 { 2624 struct evhttp_connection *evcon = req->evcon; 2625 struct evbuffer *output; 2626 2627 if (evcon == NULL) 2628 return; 2629 2630 output = bufferevent_get_output(evcon->bufev); 2631 2632 if (evbuffer_get_length(databuf) == 0) 2633 return; 2634 if (!evhttp_response_needs_body(req)) 2635 return; 2636 if (req->chunked) { 2637 evbuffer_add_printf(output, "%x\r\n", 2638 (unsigned)evbuffer_get_length(databuf)); 2639 } 2640 evbuffer_add_buffer(output, databuf); 2641 if (req->chunked) { 2642 evbuffer_add(output, "\r\n", 2); 2643 } 2644 evhttp_write_buffer(evcon, NULL, NULL); 2645 } 2646 2647 void 2648 evhttp_send_reply_end(struct evhttp_request *req) 2649 { 2650 struct evhttp_connection *evcon = req->evcon; 2651 struct evbuffer *output; 2652 2653 if (evcon == NULL) { 2654 evhttp_request_free(req); 2655 return; 2656 } 2657 2658 output = bufferevent_get_output(evcon->bufev); 2659 2660 /* we expect no more calls form the user on this request */ 2661 req->userdone = 1; 2662 2663 if (req->chunked) { 2664 evbuffer_add(output, "0\r\n\r\n", 5); 2665 evhttp_write_buffer(req->evcon, evhttp_send_done, NULL); 2666 req->chunked = 0; 2667 } else if (evbuffer_get_length(output) == 0) { 2668 /* let the connection know that we are done with the request */ 2669 evhttp_send_done(evcon, NULL); 2670 } else { 2671 /* make the callback execute after all data has been written */ 2672 evcon->cb = evhttp_send_done; 2673 evcon->cb_arg = NULL; 2674 } 2675 } 2676 2677 static const char *informational_phrases[] = { 2678 /* 100 */ "Continue", 2679 /* 101 */ "Switching Protocols" 2680 }; 2681 2682 static const char *success_phrases[] = { 2683 /* 200 */ "OK", 2684 /* 201 */ "Created", 2685 /* 202 */ "Accepted", 2686 /* 203 */ "Non-Authoritative Information", 2687 /* 204 */ "No Content", 2688 /* 205 */ "Reset Content", 2689 /* 206 */ "Partial Content" 2690 }; 2691 2692 static const char *redirection_phrases[] = { 2693 /* 300 */ "Multiple Choices", 2694 /* 301 */ "Moved Permanently", 2695 /* 302 */ "Found", 2696 /* 303 */ "See Other", 2697 /* 304 */ "Not Modified", 2698 /* 305 */ "Use Proxy", 2699 /* 307 */ "Temporary Redirect" 2700 }; 2701 2702 static const char *client_error_phrases[] = { 2703 /* 400 */ "Bad Request", 2704 /* 401 */ "Unauthorized", 2705 /* 402 */ "Payment Required", 2706 /* 403 */ "Forbidden", 2707 /* 404 */ "Not Found", 2708 /* 405 */ "Method Not Allowed", 2709 /* 406 */ "Not Acceptable", 2710 /* 407 */ "Proxy Authentication Required", 2711 /* 408 */ "Request Time-out", 2712 /* 409 */ "Conflict", 2713 /* 410 */ "Gone", 2714 /* 411 */ "Length Required", 2715 /* 412 */ "Precondition Failed", 2716 /* 413 */ "Request Entity Too Large", 2717 /* 414 */ "Request-URI Too Large", 2718 /* 415 */ "Unsupported Media Type", 2719 /* 416 */ "Requested range not satisfiable", 2720 /* 417 */ "Expectation Failed" 2721 }; 2722 2723 static const char *server_error_phrases[] = { 2724 /* 500 */ "Internal Server Error", 2725 /* 501 */ "Not Implemented", 2726 /* 502 */ "Bad Gateway", 2727 /* 503 */ "Service Unavailable", 2728 /* 504 */ "Gateway Time-out", 2729 /* 505 */ "HTTP Version not supported" 2730 }; 2731 2732 struct response_class { 2733 const char *name; 2734 size_t num_responses; 2735 const char **responses; 2736 }; 2737 2738 #ifndef MEMBERSOF 2739 #define MEMBERSOF(x) (sizeof(x)/sizeof(x[0])) 2740 #endif 2741 2742 static const struct response_class response_classes[] = { 2743 /* 1xx */ { "Informational", MEMBERSOF(informational_phrases), informational_phrases }, 2744 /* 2xx */ { "Success", MEMBERSOF(success_phrases), success_phrases }, 2745 /* 3xx */ { "Redirection", MEMBERSOF(redirection_phrases), redirection_phrases }, 2746 /* 4xx */ { "Client Error", MEMBERSOF(client_error_phrases), client_error_phrases }, 2747 /* 5xx */ { "Server Error", MEMBERSOF(server_error_phrases), server_error_phrases } 2748 }; 2749 2750 static const char * 2751 evhttp_response_phrase_internal(int code) 2752 { 2753 int klass = code / 100 - 1; 2754 int subcode = code % 100; 2755 2756 /* Unknown class - can't do any better here */ 2757 if (klass < 0 || klass >= (int) MEMBERSOF(response_classes)) 2758 return "Unknown Status Class"; 2759 2760 /* Unknown sub-code, return class name at least */ 2761 if (subcode >= (int) response_classes[klass].num_responses) 2762 return response_classes[klass].name; 2763 2764 return response_classes[klass].responses[subcode]; 2765 } 2766 2767 void 2768 evhttp_response_code_(struct evhttp_request *req, int code, const char *reason) 2769 { 2770 req->kind = EVHTTP_RESPONSE; 2771 req->response_code = code; 2772 if (req->response_code_line != NULL) 2773 mm_free(req->response_code_line); 2774 if (reason == NULL) 2775 reason = evhttp_response_phrase_internal(code); 2776 req->response_code_line = mm_strdup(reason); 2777 if (req->response_code_line == NULL) { 2778 event_warn("%s: strdup", __func__); 2779 /* XXX what else can we do? */ 2780 } 2781 } 2782 2783 void 2784 evhttp_send_page_(struct evhttp_request *req, struct evbuffer *databuf) 2785 { 2786 if (!req->major || !req->minor) { 2787 req->major = 1; 2788 req->minor = 1; 2789 } 2790 2791 if (req->kind != EVHTTP_RESPONSE) 2792 evhttp_response_code_(req, 200, "OK"); 2793 2794 evhttp_clear_headers(req->output_headers); 2795 evhttp_add_header(req->output_headers, "Content-Type", "text/html"); 2796 evhttp_add_header(req->output_headers, "Connection", "close"); 2797 2798 evhttp_send(req, databuf); 2799 } 2800 2801 static const char uri_chars[256] = { 2802 /* 0 */ 2803 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2804 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2805 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2806 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 2807 /* 64 */ 2808 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2809 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 2810 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2811 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 2812 /* 128 */ 2813 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2814 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2815 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2816 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2817 /* 192 */ 2818 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2819 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2820 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2821 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2822 }; 2823 2824 #define CHAR_IS_UNRESERVED(c) \ 2825 (uri_chars[(unsigned char)(c)]) 2826 2827 /* 2828 * Helper functions to encode/decode a string for inclusion in a URI. 2829 * The returned string must be freed by the caller. 2830 */ 2831 char * 2832 evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus) 2833 { 2834 struct evbuffer *buf = evbuffer_new(); 2835 const char *p, *end; 2836 char *result; 2837 2838 if (buf == NULL) 2839 return (NULL); 2840 2841 if (len >= 0) 2842 end = uri+len; 2843 else 2844 end = uri+strlen(uri); 2845 2846 for (p = uri; p < end; p++) { 2847 if (CHAR_IS_UNRESERVED(*p)) { 2848 evbuffer_add(buf, p, 1); 2849 } else if (*p == ' ' && space_as_plus) { 2850 evbuffer_add(buf, "+", 1); 2851 } else { 2852 evbuffer_add_printf(buf, "%%%02X", (unsigned char)(*p)); 2853 } 2854 } 2855 evbuffer_add(buf, "", 1); /* NUL-terminator. */ 2856 result = mm_malloc(evbuffer_get_length(buf)); 2857 if (result) 2858 evbuffer_remove(buf, result, evbuffer_get_length(buf)); 2859 evbuffer_free(buf); 2860 2861 return (result); 2862 } 2863 2864 char * 2865 evhttp_encode_uri(const char *str) 2866 { 2867 return evhttp_uriencode(str, -1, 0); 2868 } 2869 2870 /* 2871 * @param decode_plus_ctl: if 1, we decode plus into space. If 0, we don't. 2872 * If -1, when true we transform plus to space only after we've seen 2873 * a ?. -1 is deprecated. 2874 * @return the number of bytes written to 'ret'. 2875 */ 2876 int 2877 evhttp_decode_uri_internal( 2878 const char *uri, size_t length, char *ret, int decode_plus_ctl) 2879 { 2880 char c; 2881 int j; 2882 int decode_plus = (decode_plus_ctl == 1) ? 1: 0; 2883 unsigned i; 2884 2885 for (i = j = 0; i < length; i++) { 2886 c = uri[i]; 2887 if (c == '?') { 2888 if (decode_plus_ctl < 0) 2889 decode_plus = 1; 2890 } else if (c == '+' && decode_plus) { 2891 c = ' '; 2892 } else if ((i + 2) < length && c == '%' && 2893 EVUTIL_ISXDIGIT_(uri[i+1]) && EVUTIL_ISXDIGIT_(uri[i+2])) { 2894 char tmp[3]; 2895 tmp[0] = uri[i+1]; 2896 tmp[1] = uri[i+2]; 2897 tmp[2] = '\0'; 2898 c = (char)strtol(tmp, NULL, 16); 2899 i += 2; 2900 } 2901 ret[j++] = c; 2902 } 2903 ret[j] = '\0'; 2904 2905 return (j); 2906 } 2907 2908 /* deprecated */ 2909 char * 2910 evhttp_decode_uri(const char *uri) 2911 { 2912 char *ret; 2913 2914 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) { 2915 event_warn("%s: malloc(%lu)", __func__, 2916 (unsigned long)(strlen(uri) + 1)); 2917 return (NULL); 2918 } 2919 2920 evhttp_decode_uri_internal(uri, strlen(uri), 2921 ret, -1 /*always_decode_plus*/); 2922 2923 return (ret); 2924 } 2925 2926 char * 2927 evhttp_uridecode(const char *uri, int decode_plus, size_t *size_out) 2928 { 2929 char *ret; 2930 int n; 2931 2932 if ((ret = mm_malloc(strlen(uri) + 1)) == NULL) { 2933 event_warn("%s: malloc(%lu)", __func__, 2934 (unsigned long)(strlen(uri) + 1)); 2935 return (NULL); 2936 } 2937 2938 n = evhttp_decode_uri_internal(uri, strlen(uri), 2939 ret, !!decode_plus/*always_decode_plus*/); 2940 2941 if (size_out) { 2942 EVUTIL_ASSERT(n >= 0); 2943 *size_out = (size_t)n; 2944 } 2945 2946 return (ret); 2947 } 2948 2949 /* 2950 * Helper function to parse out arguments in a query. 2951 * The arguments are separated by key and value. 2952 */ 2953 2954 static int 2955 evhttp_parse_query_impl(const char *str, struct evkeyvalq *headers, 2956 int is_whole_uri) 2957 { 2958 char *line=NULL; 2959 char *argument; 2960 char *p; 2961 const char *query_part; 2962 int result = -1; 2963 struct evhttp_uri *uri=NULL; 2964 2965 TAILQ_INIT(headers); 2966 2967 if (is_whole_uri) { 2968 uri = evhttp_uri_parse(str); 2969 if (!uri) 2970 goto error; 2971 query_part = evhttp_uri_get_query(uri); 2972 } else { 2973 query_part = str; 2974 } 2975 2976 /* No arguments - we are done */ 2977 if (!query_part || !strlen(query_part)) { 2978 result = 0; 2979 goto done; 2980 } 2981 2982 if ((line = mm_strdup(query_part)) == NULL) { 2983 event_warn("%s: strdup", __func__); 2984 goto error; 2985 } 2986 2987 p = argument = line; 2988 while (p != NULL && *p != '\0') { 2989 char *key, *value, *decoded_value; 2990 argument = strsep(&p, "&"); 2991 2992 value = argument; 2993 key = strsep(&value, "="); 2994 if (value == NULL || *key == '\0') { 2995 goto error; 2996 } 2997 2998 if ((decoded_value = mm_malloc(strlen(value) + 1)) == NULL) { 2999 event_warn("%s: mm_malloc", __func__); 3000 goto error; 3001 } 3002 evhttp_decode_uri_internal(value, strlen(value), 3003 decoded_value, 1 /*always_decode_plus*/); 3004 event_debug(("Query Param: %s -> %s\n", key, decoded_value)); 3005 evhttp_add_header_internal(headers, key, decoded_value); 3006 mm_free(decoded_value); 3007 } 3008 3009 result = 0; 3010 goto done; 3011 error: 3012 evhttp_clear_headers(headers); 3013 done: 3014 if (line) 3015 mm_free(line); 3016 if (uri) 3017 evhttp_uri_free(uri); 3018 return result; 3019 } 3020 3021 int 3022 evhttp_parse_query(const char *uri, struct evkeyvalq *headers) 3023 { 3024 return evhttp_parse_query_impl(uri, headers, 1); 3025 } 3026 int 3027 evhttp_parse_query_str(const char *uri, struct evkeyvalq *headers) 3028 { 3029 return evhttp_parse_query_impl(uri, headers, 0); 3030 } 3031 3032 static struct evhttp_cb * 3033 evhttp_dispatch_callback(struct httpcbq *callbacks, struct evhttp_request *req) 3034 { 3035 struct evhttp_cb *cb; 3036 size_t offset = 0; 3037 char *translated; 3038 const char *path; 3039 3040 /* Test for different URLs */ 3041 path = evhttp_uri_get_path(req->uri_elems); 3042 offset = strlen(path); 3043 if ((translated = mm_malloc(offset + 1)) == NULL) 3044 return (NULL); 3045 evhttp_decode_uri_internal(path, offset, translated, 3046 0 /* decode_plus */); 3047 3048 TAILQ_FOREACH(cb, callbacks, next) { 3049 if (!strcmp(cb->what, translated)) { 3050 mm_free(translated); 3051 return (cb); 3052 } 3053 } 3054 3055 mm_free(translated); 3056 return (NULL); 3057 } 3058 3059 3060 static int 3061 prefix_suffix_match(const char *pattern, const char *name, int ignorecase) 3062 { 3063 char c; 3064 3065 while (1) { 3066 switch (c = *pattern++) { 3067 case '\0': 3068 return *name == '\0'; 3069 3070 case '*': 3071 while (*name != '\0') { 3072 if (prefix_suffix_match(pattern, name, 3073 ignorecase)) 3074 return (1); 3075 ++name; 3076 } 3077 return (0); 3078 default: 3079 if (c != *name) { 3080 if (!ignorecase || 3081 EVUTIL_TOLOWER_(c) != EVUTIL_TOLOWER_(*name)) 3082 return (0); 3083 } 3084 ++name; 3085 } 3086 } 3087 /* NOTREACHED */ 3088 } 3089 3090 /* 3091 Search the vhost hierarchy beginning with http for a server alias 3092 matching hostname. If a match is found, and outhttp is non-null, 3093 outhttp is set to the matching http object and 1 is returned. 3094 */ 3095 3096 static int 3097 evhttp_find_alias(struct evhttp *http, struct evhttp **outhttp, 3098 const char *hostname) 3099 { 3100 struct evhttp_server_alias *alias; 3101 struct evhttp *vhost; 3102 3103 TAILQ_FOREACH(alias, &http->aliases, next) { 3104 /* XXX Do we need to handle IP addresses? */ 3105 if (!evutil_ascii_strcasecmp(alias->alias, hostname)) { 3106 if (outhttp) 3107 *outhttp = http; 3108 return 1; 3109 } 3110 } 3111 3112 /* XXX It might be good to avoid recursion here, but I don't 3113 see a way to do that w/o a list. */ 3114 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) { 3115 if (evhttp_find_alias(vhost, outhttp, hostname)) 3116 return 1; 3117 } 3118 3119 return 0; 3120 } 3121 3122 /* 3123 Attempts to find the best http object to handle a request for a hostname. 3124 All aliases for the root http object and vhosts are searched for an exact 3125 match. Then, the vhost hierarchy is traversed again for a matching 3126 pattern. 3127 3128 If an alias or vhost is matched, 1 is returned, and outhttp, if non-null, 3129 is set with the best matching http object. If there are no matches, the 3130 root http object is stored in outhttp and 0 is returned. 3131 */ 3132 3133 static int 3134 evhttp_find_vhost(struct evhttp *http, struct evhttp **outhttp, 3135 const char *hostname) 3136 { 3137 struct evhttp *vhost; 3138 struct evhttp *oldhttp; 3139 int match_found = 0; 3140 3141 if (evhttp_find_alias(http, outhttp, hostname)) 3142 return 1; 3143 3144 do { 3145 oldhttp = http; 3146 TAILQ_FOREACH(vhost, &http->virtualhosts, next_vhost) { 3147 if (prefix_suffix_match(vhost->vhost_pattern, 3148 hostname, 1 /* ignorecase */)) { 3149 http = vhost; 3150 match_found = 1; 3151 break; 3152 } 3153 } 3154 } while (oldhttp != http); 3155 3156 if (outhttp) 3157 *outhttp = http; 3158 3159 return match_found; 3160 } 3161 3162 static void 3163 evhttp_handle_request(struct evhttp_request *req, void *arg) 3164 { 3165 struct evhttp *http = arg; 3166 struct evhttp_cb *cb = NULL; 3167 const char *hostname; 3168 3169 /* we have a new request on which the user needs to take action */ 3170 req->userdone = 0; 3171 3172 if (req->type == 0 || req->uri == NULL) { 3173 evhttp_send_error(req, HTTP_BADREQUEST, NULL); 3174 return; 3175 } 3176 3177 if ((http->allowed_methods & req->type) == 0) { 3178 event_debug(("Rejecting disallowed method %x (allowed: %x)\n", 3179 (unsigned)req->type, (unsigned)http->allowed_methods)); 3180 evhttp_send_error(req, HTTP_NOTIMPLEMENTED, NULL); 3181 return; 3182 } 3183 3184 /* handle potential virtual hosts */ 3185 hostname = evhttp_request_get_host(req); 3186 if (hostname != NULL) { 3187 evhttp_find_vhost(http, &http, hostname); 3188 } 3189 3190 if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) { 3191 (*cb->cb)(req, cb->cbarg); 3192 return; 3193 } 3194 3195 /* Generic call back */ 3196 if (http->gencb) { 3197 (*http->gencb)(req, http->gencbarg); 3198 return; 3199 } else { 3200 /* We need to send a 404 here */ 3201 #define ERR_FORMAT "<html><head>" \ 3202 "<title>404 Not Found</title>" \ 3203 "</head><body>" \ 3204 "<h1>Not Found</h1>" \ 3205 "<p>The requested URL %s was not found on this server.</p>"\ 3206 "</body></html>\n" 3207 3208 char *escaped_html; 3209 struct evbuffer *buf; 3210 3211 if ((escaped_html = evhttp_htmlescape(req->uri)) == NULL) { 3212 evhttp_connection_free(req->evcon); 3213 return; 3214 } 3215 3216 if ((buf = evbuffer_new()) == NULL) { 3217 mm_free(escaped_html); 3218 evhttp_connection_free(req->evcon); 3219 return; 3220 } 3221 3222 evhttp_response_code_(req, HTTP_NOTFOUND, "Not Found"); 3223 3224 evbuffer_add_printf(buf, ERR_FORMAT, escaped_html); 3225 3226 mm_free(escaped_html); 3227 3228 evhttp_send_page_(req, buf); 3229 3230 evbuffer_free(buf); 3231 #undef ERR_FORMAT 3232 } 3233 } 3234 3235 /* Listener callback when a connection arrives at a server. */ 3236 static void 3237 accept_socket_cb(struct evconnlistener *listener, evutil_socket_t nfd, struct sockaddr *peer_sa, int peer_socklen, void *arg) 3238 { 3239 struct evhttp *http = arg; 3240 3241 evhttp_get_request(http, nfd, peer_sa, peer_socklen); 3242 } 3243 3244 int 3245 evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port) 3246 { 3247 struct evhttp_bound_socket *bound = 3248 evhttp_bind_socket_with_handle(http, address, port); 3249 if (bound == NULL) 3250 return (-1); 3251 return (0); 3252 } 3253 3254 struct evhttp_bound_socket * 3255 evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port) 3256 { 3257 evutil_socket_t fd; 3258 struct evhttp_bound_socket *bound; 3259 3260 if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1) 3261 return (NULL); 3262 3263 if (listen(fd, 128) == -1) { 3264 event_sock_warn(fd, "%s: listen", __func__); 3265 evutil_closesocket(fd); 3266 return (NULL); 3267 } 3268 3269 bound = evhttp_accept_socket_with_handle(http, fd); 3270 3271 if (bound != NULL) { 3272 event_debug(("Bound to port %d - Awaiting connections ... ", 3273 port)); 3274 return (bound); 3275 } 3276 3277 return (NULL); 3278 } 3279 3280 int 3281 evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd) 3282 { 3283 struct evhttp_bound_socket *bound = 3284 evhttp_accept_socket_with_handle(http, fd); 3285 if (bound == NULL) 3286 return (-1); 3287 return (0); 3288 } 3289 3290 void 3291 evhttp_foreach_bound_socket(struct evhttp *http, 3292 evhttp_bound_socket_foreach_fn *function, 3293 void *argument) 3294 { 3295 struct evhttp_bound_socket *bound; 3296 3297 TAILQ_FOREACH(bound, &http->sockets, next) 3298 function(bound, argument); 3299 } 3300 3301 struct evhttp_bound_socket * 3302 evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd) 3303 { 3304 struct evhttp_bound_socket *bound; 3305 struct evconnlistener *listener; 3306 const int flags = 3307 LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE; 3308 3309 listener = evconnlistener_new(http->base, NULL, NULL, 3310 flags, 3311 0, /* Backlog is '0' because we already said 'listen' */ 3312 fd); 3313 if (!listener) 3314 return (NULL); 3315 3316 bound = evhttp_bind_listener(http, listener); 3317 if (!bound) { 3318 evconnlistener_free(listener); 3319 return (NULL); 3320 } 3321 return (bound); 3322 } 3323 3324 struct evhttp_bound_socket * 3325 evhttp_bind_listener(struct evhttp *http, struct evconnlistener *listener) 3326 { 3327 struct evhttp_bound_socket *bound; 3328 3329 bound = mm_malloc(sizeof(struct evhttp_bound_socket)); 3330 if (bound == NULL) 3331 return (NULL); 3332 3333 bound->listener = listener; 3334 TAILQ_INSERT_TAIL(&http->sockets, bound, next); 3335 3336 evconnlistener_set_cb(listener, accept_socket_cb, http); 3337 return bound; 3338 } 3339 3340 evutil_socket_t 3341 evhttp_bound_socket_get_fd(struct evhttp_bound_socket *bound) 3342 { 3343 return evconnlistener_get_fd(bound->listener); 3344 } 3345 3346 struct evconnlistener * 3347 evhttp_bound_socket_get_listener(struct evhttp_bound_socket *bound) 3348 { 3349 return bound->listener; 3350 } 3351 3352 void 3353 evhttp_del_accept_socket(struct evhttp *http, struct evhttp_bound_socket *bound) 3354 { 3355 TAILQ_REMOVE(&http->sockets, bound, next); 3356 evconnlistener_free(bound->listener); 3357 mm_free(bound); 3358 } 3359 3360 static struct evhttp* 3361 evhttp_new_object(void) 3362 { 3363 struct evhttp *http = NULL; 3364 3365 if ((http = mm_calloc(1, sizeof(struct evhttp))) == NULL) { 3366 event_warn("%s: calloc", __func__); 3367 return (NULL); 3368 } 3369 3370 evutil_timerclear(&http->timeout); 3371 evhttp_set_max_headers_size(http, EV_SIZE_MAX); 3372 evhttp_set_max_body_size(http, EV_SIZE_MAX); 3373 evhttp_set_allowed_methods(http, 3374 EVHTTP_REQ_GET | 3375 EVHTTP_REQ_POST | 3376 EVHTTP_REQ_HEAD | 3377 EVHTTP_REQ_PUT | 3378 EVHTTP_REQ_DELETE); 3379 3380 TAILQ_INIT(&http->sockets); 3381 TAILQ_INIT(&http->callbacks); 3382 TAILQ_INIT(&http->connections); 3383 TAILQ_INIT(&http->virtualhosts); 3384 TAILQ_INIT(&http->aliases); 3385 3386 return (http); 3387 } 3388 3389 struct evhttp * 3390 evhttp_new(struct event_base *base) 3391 { 3392 struct evhttp *http = NULL; 3393 3394 http = evhttp_new_object(); 3395 if (http == NULL) 3396 return (NULL); 3397 http->base = base; 3398 3399 return (http); 3400 } 3401 3402 /* 3403 * Start a web server on the specified address and port. 3404 */ 3405 3406 struct evhttp * 3407 evhttp_start(const char *address, unsigned short port) 3408 { 3409 struct evhttp *http = NULL; 3410 3411 http = evhttp_new_object(); 3412 if (http == NULL) 3413 return (NULL); 3414 if (evhttp_bind_socket(http, address, port) == -1) { 3415 mm_free(http); 3416 return (NULL); 3417 } 3418 3419 return (http); 3420 } 3421 3422 void 3423 evhttp_free(struct evhttp* http) 3424 { 3425 struct evhttp_cb *http_cb; 3426 struct evhttp_connection *evcon; 3427 struct evhttp_bound_socket *bound; 3428 struct evhttp* vhost; 3429 struct evhttp_server_alias *alias; 3430 3431 /* Remove the accepting part */ 3432 while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) { 3433 TAILQ_REMOVE(&http->sockets, bound, next); 3434 3435 evconnlistener_free(bound->listener); 3436 3437 mm_free(bound); 3438 } 3439 3440 while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) { 3441 /* evhttp_connection_free removes the connection */ 3442 evhttp_connection_free(evcon); 3443 } 3444 3445 while ((http_cb = TAILQ_FIRST(&http->callbacks)) != NULL) { 3446 TAILQ_REMOVE(&http->callbacks, http_cb, next); 3447 mm_free(http_cb->what); 3448 mm_free(http_cb); 3449 } 3450 3451 while ((vhost = TAILQ_FIRST(&http->virtualhosts)) != NULL) { 3452 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost); 3453 3454 evhttp_free(vhost); 3455 } 3456 3457 if (http->vhost_pattern != NULL) 3458 mm_free(http->vhost_pattern); 3459 3460 while ((alias = TAILQ_FIRST(&http->aliases)) != NULL) { 3461 TAILQ_REMOVE(&http->aliases, alias, next); 3462 mm_free(alias->alias); 3463 mm_free(alias); 3464 } 3465 3466 mm_free(http); 3467 } 3468 3469 int 3470 evhttp_add_virtual_host(struct evhttp* http, const char *pattern, 3471 struct evhttp* vhost) 3472 { 3473 /* a vhost can only be a vhost once and should not have bound sockets */ 3474 if (vhost->vhost_pattern != NULL || 3475 TAILQ_FIRST(&vhost->sockets) != NULL) 3476 return (-1); 3477 3478 vhost->vhost_pattern = mm_strdup(pattern); 3479 if (vhost->vhost_pattern == NULL) 3480 return (-1); 3481 3482 TAILQ_INSERT_TAIL(&http->virtualhosts, vhost, next_vhost); 3483 3484 return (0); 3485 } 3486 3487 int 3488 evhttp_remove_virtual_host(struct evhttp* http, struct evhttp* vhost) 3489 { 3490 if (vhost->vhost_pattern == NULL) 3491 return (-1); 3492 3493 TAILQ_REMOVE(&http->virtualhosts, vhost, next_vhost); 3494 3495 mm_free(vhost->vhost_pattern); 3496 vhost->vhost_pattern = NULL; 3497 3498 return (0); 3499 } 3500 3501 int 3502 evhttp_add_server_alias(struct evhttp *http, const char *alias) 3503 { 3504 struct evhttp_server_alias *evalias; 3505 3506 evalias = mm_calloc(1, sizeof(*evalias)); 3507 if (!evalias) 3508 return -1; 3509 3510 evalias->alias = mm_strdup(alias); 3511 if (!evalias->alias) { 3512 mm_free(evalias); 3513 return -1; 3514 } 3515 3516 TAILQ_INSERT_TAIL(&http->aliases, evalias, next); 3517 3518 return 0; 3519 } 3520 3521 int 3522 evhttp_remove_server_alias(struct evhttp *http, const char *alias) 3523 { 3524 struct evhttp_server_alias *evalias; 3525 3526 TAILQ_FOREACH(evalias, &http->aliases, next) { 3527 if (evutil_ascii_strcasecmp(evalias->alias, alias) == 0) { 3528 TAILQ_REMOVE(&http->aliases, evalias, next); 3529 mm_free(evalias->alias); 3530 mm_free(evalias); 3531 return 0; 3532 } 3533 } 3534 3535 return -1; 3536 } 3537 3538 void 3539 evhttp_set_timeout(struct evhttp* http, int timeout_in_secs) 3540 { 3541 if (timeout_in_secs == -1) { 3542 evhttp_set_timeout_tv(http, NULL); 3543 } else { 3544 struct timeval tv; 3545 tv.tv_sec = timeout_in_secs; 3546 tv.tv_usec = 0; 3547 evhttp_set_timeout_tv(http, &tv); 3548 } 3549 } 3550 3551 void 3552 evhttp_set_timeout_tv(struct evhttp* http, const struct timeval* tv) 3553 { 3554 if (tv) { 3555 http->timeout = *tv; 3556 } else { 3557 evutil_timerclear(&http->timeout); 3558 } 3559 } 3560 3561 void 3562 evhttp_set_max_headers_size(struct evhttp* http, ev_ssize_t max_headers_size) 3563 { 3564 if (max_headers_size < 0) 3565 http->default_max_headers_size = EV_SIZE_MAX; 3566 else 3567 http->default_max_headers_size = max_headers_size; 3568 } 3569 3570 void 3571 evhttp_set_max_body_size(struct evhttp* http, ev_ssize_t max_body_size) 3572 { 3573 if (max_body_size < 0) 3574 http->default_max_body_size = EV_UINT64_MAX; 3575 else 3576 http->default_max_body_size = max_body_size; 3577 } 3578 3579 void 3580 evhttp_set_allowed_methods(struct evhttp* http, ev_uint16_t methods) 3581 { 3582 http->allowed_methods = methods; 3583 } 3584 3585 int 3586 evhttp_set_cb(struct evhttp *http, const char *uri, 3587 void (*cb)(struct evhttp_request *, void *), void *cbarg) 3588 { 3589 struct evhttp_cb *http_cb; 3590 3591 TAILQ_FOREACH(http_cb, &http->callbacks, next) { 3592 if (strcmp(http_cb->what, uri) == 0) 3593 return (-1); 3594 } 3595 3596 if ((http_cb = mm_calloc(1, sizeof(struct evhttp_cb))) == NULL) { 3597 event_warn("%s: calloc", __func__); 3598 return (-2); 3599 } 3600 3601 http_cb->what = mm_strdup(uri); 3602 if (http_cb->what == NULL) { 3603 event_warn("%s: strdup", __func__); 3604 mm_free(http_cb); 3605 return (-3); 3606 } 3607 http_cb->cb = cb; 3608 http_cb->cbarg = cbarg; 3609 3610 TAILQ_INSERT_TAIL(&http->callbacks, http_cb, next); 3611 3612 return (0); 3613 } 3614 3615 int 3616 evhttp_del_cb(struct evhttp *http, const char *uri) 3617 { 3618 struct evhttp_cb *http_cb; 3619 3620 TAILQ_FOREACH(http_cb, &http->callbacks, next) { 3621 if (strcmp(http_cb->what, uri) == 0) 3622 break; 3623 } 3624 if (http_cb == NULL) 3625 return (-1); 3626 3627 TAILQ_REMOVE(&http->callbacks, http_cb, next); 3628 mm_free(http_cb->what); 3629 mm_free(http_cb); 3630 3631 return (0); 3632 } 3633 3634 void 3635 evhttp_set_gencb(struct evhttp *http, 3636 void (*cb)(struct evhttp_request *, void *), void *cbarg) 3637 { 3638 http->gencb = cb; 3639 http->gencbarg = cbarg; 3640 } 3641 3642 void 3643 evhttp_set_bevcb(struct evhttp *http, 3644 struct bufferevent* (*cb)(struct event_base *, void *), void *cbarg) 3645 { 3646 http->bevcb = cb; 3647 http->bevcbarg = cbarg; 3648 } 3649 3650 /* 3651 * Request related functions 3652 */ 3653 3654 struct evhttp_request * 3655 evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg) 3656 { 3657 struct evhttp_request *req = NULL; 3658 3659 /* Allocate request structure */ 3660 if ((req = mm_calloc(1, sizeof(struct evhttp_request))) == NULL) { 3661 event_warn("%s: calloc", __func__); 3662 goto error; 3663 } 3664 3665 req->headers_size = 0; 3666 req->body_size = 0; 3667 3668 req->kind = EVHTTP_RESPONSE; 3669 req->input_headers = mm_calloc(1, sizeof(struct evkeyvalq)); 3670 if (req->input_headers == NULL) { 3671 event_warn("%s: calloc", __func__); 3672 goto error; 3673 } 3674 TAILQ_INIT(req->input_headers); 3675 3676 req->output_headers = mm_calloc(1, sizeof(struct evkeyvalq)); 3677 if (req->output_headers == NULL) { 3678 event_warn("%s: calloc", __func__); 3679 goto error; 3680 } 3681 TAILQ_INIT(req->output_headers); 3682 3683 if ((req->input_buffer = evbuffer_new()) == NULL) { 3684 event_warn("%s: evbuffer_new", __func__); 3685 goto error; 3686 } 3687 3688 if ((req->output_buffer = evbuffer_new()) == NULL) { 3689 event_warn("%s: evbuffer_new", __func__); 3690 goto error; 3691 } 3692 3693 req->cb = cb; 3694 req->cb_arg = arg; 3695 3696 return (req); 3697 3698 error: 3699 if (req != NULL) 3700 evhttp_request_free(req); 3701 return (NULL); 3702 } 3703 3704 void 3705 evhttp_request_free(struct evhttp_request *req) 3706 { 3707 if ((req->flags & EVHTTP_REQ_DEFER_FREE) != 0) { 3708 req->flags |= EVHTTP_REQ_NEEDS_FREE; 3709 return; 3710 } 3711 3712 if (req->remote_host != NULL) 3713 mm_free(req->remote_host); 3714 if (req->uri != NULL) 3715 mm_free(req->uri); 3716 if (req->uri_elems != NULL) 3717 evhttp_uri_free(req->uri_elems); 3718 if (req->response_code_line != NULL) 3719 mm_free(req->response_code_line); 3720 if (req->host_cache != NULL) 3721 mm_free(req->host_cache); 3722 3723 evhttp_clear_headers(req->input_headers); 3724 mm_free(req->input_headers); 3725 3726 evhttp_clear_headers(req->output_headers); 3727 mm_free(req->output_headers); 3728 3729 if (req->input_buffer != NULL) 3730 evbuffer_free(req->input_buffer); 3731 3732 if (req->output_buffer != NULL) 3733 evbuffer_free(req->output_buffer); 3734 3735 mm_free(req); 3736 } 3737 3738 void 3739 evhttp_request_own(struct evhttp_request *req) 3740 { 3741 req->flags |= EVHTTP_USER_OWNED; 3742 } 3743 3744 int 3745 evhttp_request_is_owned(struct evhttp_request *req) 3746 { 3747 return (req->flags & EVHTTP_USER_OWNED) != 0; 3748 } 3749 3750 struct evhttp_connection * 3751 evhttp_request_get_connection(struct evhttp_request *req) 3752 { 3753 return req->evcon; 3754 } 3755 3756 struct event_base * 3757 evhttp_connection_get_base(struct evhttp_connection *conn) 3758 { 3759 return conn->base; 3760 } 3761 3762 void 3763 evhttp_request_set_chunked_cb(struct evhttp_request *req, 3764 void (*cb)(struct evhttp_request *, void *)) 3765 { 3766 req->chunk_cb = cb; 3767 } 3768 3769 /* 3770 * Allows for inspection of the request URI 3771 */ 3772 3773 const char * 3774 evhttp_request_get_uri(const struct evhttp_request *req) { 3775 if (req->uri == NULL) 3776 event_debug(("%s: request %p has no uri\n", __func__, req)); 3777 return (req->uri); 3778 } 3779 3780 const struct evhttp_uri * 3781 evhttp_request_get_evhttp_uri(const struct evhttp_request *req) { 3782 if (req->uri_elems == NULL) 3783 event_debug(("%s: request %p has no uri elems\n", 3784 __func__, req)); 3785 return (req->uri_elems); 3786 } 3787 3788 const char * 3789 evhttp_request_get_host(struct evhttp_request *req) 3790 { 3791 const char *host = NULL; 3792 3793 if (req->host_cache) 3794 return req->host_cache; 3795 3796 if (req->uri_elems) 3797 host = evhttp_uri_get_host(req->uri_elems); 3798 if (!host && req->input_headers) { 3799 const char *p; 3800 size_t len; 3801 3802 host = evhttp_find_header(req->input_headers, "Host"); 3803 /* The Host: header may include a port. Remove it here 3804 to be consistent with uri_elems case above. */ 3805 if (host) { 3806 p = host + strlen(host) - 1; 3807 while (p > host && EVUTIL_ISDIGIT_(*p)) 3808 --p; 3809 if (p > host && *p == ':') { 3810 len = p - host; 3811 req->host_cache = mm_malloc(len + 1); 3812 if (!req->host_cache) { 3813 event_warn("%s: malloc", __func__); 3814 return NULL; 3815 } 3816 memcpy(req->host_cache, host, len); 3817 req->host_cache[len] = '\0'; 3818 host = req->host_cache; 3819 } 3820 } 3821 } 3822 3823 return host; 3824 } 3825 3826 enum evhttp_cmd_type 3827 evhttp_request_get_command(const struct evhttp_request *req) { 3828 return (req->type); 3829 } 3830 3831 int 3832 evhttp_request_get_response_code(const struct evhttp_request *req) 3833 { 3834 return req->response_code; 3835 } 3836 3837 const char * 3838 evhttp_request_get_response_code_line(const struct evhttp_request *req) 3839 { 3840 return req->response_code_line; 3841 } 3842 3843 /** Returns the input headers */ 3844 struct evkeyvalq *evhttp_request_get_input_headers(struct evhttp_request *req) 3845 { 3846 return (req->input_headers); 3847 } 3848 3849 /** Returns the output headers */ 3850 struct evkeyvalq *evhttp_request_get_output_headers(struct evhttp_request *req) 3851 { 3852 return (req->output_headers); 3853 } 3854 3855 /** Returns the input buffer */ 3856 struct evbuffer *evhttp_request_get_input_buffer(struct evhttp_request *req) 3857 { 3858 return (req->input_buffer); 3859 } 3860 3861 /** Returns the output buffer */ 3862 struct evbuffer *evhttp_request_get_output_buffer(struct evhttp_request *req) 3863 { 3864 return (req->output_buffer); 3865 } 3866 3867 3868 /* 3869 * Takes a file descriptor to read a request from. 3870 * The callback is executed once the whole request has been read. 3871 */ 3872 3873 static struct evhttp_connection* 3874 evhttp_get_request_connection( 3875 struct evhttp* http, 3876 evutil_socket_t fd, struct sockaddr *sa, ev_socklen_t salen) 3877 { 3878 struct evhttp_connection *evcon; 3879 char *hostname = NULL, *portname = NULL; 3880 struct bufferevent* bev = NULL; 3881 3882 name_from_addr(sa, salen, &hostname, &portname); 3883 if (hostname == NULL || portname == NULL) { 3884 if (hostname) mm_free(hostname); 3885 if (portname) mm_free(portname); 3886 return (NULL); 3887 } 3888 3889 event_debug(("%s: new request from %s:%s on "EV_SOCK_FMT"\n", 3890 __func__, hostname, portname, EV_SOCK_ARG(fd))); 3891 3892 /* we need a connection object to put the http request on */ 3893 if (http->bevcb != NULL) { 3894 bev = (*http->bevcb)(http->base, http->bevcbarg); 3895 } 3896 evcon = evhttp_connection_base_bufferevent_new( 3897 http->base, NULL, bev, hostname, atoi(portname)); 3898 mm_free(hostname); 3899 mm_free(portname); 3900 if (evcon == NULL) 3901 return (NULL); 3902 3903 evcon->max_headers_size = http->default_max_headers_size; 3904 evcon->max_body_size = http->default_max_body_size; 3905 3906 evcon->flags |= EVHTTP_CON_INCOMING; 3907 evcon->state = EVCON_READING_FIRSTLINE; 3908 3909 evcon->fd = fd; 3910 3911 bufferevent_setfd(evcon->bufev, fd); 3912 3913 return (evcon); 3914 } 3915 3916 static int 3917 evhttp_associate_new_request_with_connection(struct evhttp_connection *evcon) 3918 { 3919 struct evhttp *http = evcon->http_server; 3920 struct evhttp_request *req; 3921 if ((req = evhttp_request_new(evhttp_handle_request, http)) == NULL) 3922 return (-1); 3923 3924 if ((req->remote_host = mm_strdup(evcon->address)) == NULL) { 3925 event_warn("%s: strdup", __func__); 3926 evhttp_request_free(req); 3927 return (-1); 3928 } 3929 req->remote_port = evcon->port; 3930 3931 req->evcon = evcon; /* the request ends up owning the connection */ 3932 req->flags |= EVHTTP_REQ_OWN_CONNECTION; 3933 3934 /* We did not present the request to the user user yet, so treat it as 3935 * if the user was done with the request. This allows us to free the 3936 * request on a persistent connection if the client drops it without 3937 * sending a request. 3938 */ 3939 req->userdone = 1; 3940 3941 TAILQ_INSERT_TAIL(&evcon->requests, req, next); 3942 3943 req->kind = EVHTTP_REQUEST; 3944 3945 3946 evhttp_start_read_(evcon); 3947 3948 return (0); 3949 } 3950 3951 static void 3952 evhttp_get_request(struct evhttp *http, evutil_socket_t fd, 3953 struct sockaddr *sa, ev_socklen_t salen) 3954 { 3955 struct evhttp_connection *evcon; 3956 3957 evcon = evhttp_get_request_connection(http, fd, sa, salen); 3958 if (evcon == NULL) { 3959 event_sock_warn(fd, "%s: cannot get connection on "EV_SOCK_FMT, 3960 __func__, EV_SOCK_ARG(fd)); 3961 evutil_closesocket(fd); 3962 return; 3963 } 3964 3965 /* the timeout can be used by the server to close idle connections */ 3966 if (evutil_timerisset(&http->timeout)) 3967 evhttp_connection_set_timeout_tv(evcon, &http->timeout); 3968 3969 /* 3970 * if we want to accept more than one request on a connection, 3971 * we need to know which http server it belongs to. 3972 */ 3973 evcon->http_server = http; 3974 TAILQ_INSERT_TAIL(&http->connections, evcon, next); 3975 3976 if (evhttp_associate_new_request_with_connection(evcon) == -1) 3977 evhttp_connection_free(evcon); 3978 } 3979 3980 3981 /* 3982 * Network helper functions that we do not want to export to the rest of 3983 * the world. 3984 */ 3985 3986 static void 3987 name_from_addr(struct sockaddr *sa, ev_socklen_t salen, 3988 char **phost, char **pport) 3989 { 3990 char ntop[NI_MAXHOST]; 3991 char strport[NI_MAXSERV]; 3992 int ni_result; 3993 3994 #ifdef EVENT__HAVE_GETNAMEINFO 3995 ni_result = getnameinfo(sa, salen, 3996 ntop, sizeof(ntop), strport, sizeof(strport), 3997 NI_NUMERICHOST|NI_NUMERICSERV); 3998 3999 if (ni_result != 0) { 4000 #ifdef EAI_SYSTEM 4001 /* Windows doesn't have an EAI_SYSTEM. */ 4002 if (ni_result == EAI_SYSTEM) 4003 event_err(1, "getnameinfo failed"); 4004 else 4005 #endif 4006 event_errx(1, "getnameinfo failed: %s", gai_strerror(ni_result)); 4007 return; 4008 } 4009 #else 4010 ni_result = fake_getnameinfo(sa, salen, 4011 ntop, sizeof(ntop), strport, sizeof(strport), 4012 NI_NUMERICHOST|NI_NUMERICSERV); 4013 if (ni_result != 0) 4014 return; 4015 #endif 4016 4017 *phost = mm_strdup(ntop); 4018 *pport = mm_strdup(strport); 4019 } 4020 4021 /* Create a non-blocking socket and bind it */ 4022 /* todo: rename this function */ 4023 static evutil_socket_t 4024 bind_socket_ai(struct evutil_addrinfo *ai, int reuse) 4025 { 4026 evutil_socket_t fd; 4027 4028 int on = 1, r; 4029 int serrno; 4030 4031 /* Create listen socket */ 4032 fd = evutil_socket_(ai ? ai->ai_family : AF_INET, 4033 SOCK_STREAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0); 4034 if (fd == -1) { 4035 event_sock_warn(-1, "socket"); 4036 return (-1); 4037 } 4038 4039 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on))<0) 4040 goto out; 4041 if (reuse) { 4042 if (evutil_make_listen_socket_reuseable(fd) < 0) 4043 goto out; 4044 } 4045 4046 if (ai != NULL) { 4047 r = bind(fd, ai->ai_addr, (ev_socklen_t)ai->ai_addrlen); 4048 if (r == -1) 4049 goto out; 4050 } 4051 4052 return (fd); 4053 4054 out: 4055 serrno = EVUTIL_SOCKET_ERROR(); 4056 evutil_closesocket(fd); 4057 EVUTIL_SET_SOCKET_ERROR(serrno); 4058 return (-1); 4059 } 4060 4061 static struct evutil_addrinfo * 4062 make_addrinfo(const char *address, ev_uint16_t port) 4063 { 4064 struct evutil_addrinfo *ai = NULL; 4065 4066 struct evutil_addrinfo hints; 4067 char strport[NI_MAXSERV]; 4068 int ai_result; 4069 4070 memset(&hints, 0, sizeof(hints)); 4071 hints.ai_family = AF_UNSPEC; 4072 hints.ai_socktype = SOCK_STREAM; 4073 /* turn NULL hostname into INADDR_ANY, and skip looking up any address 4074 * types we don't have an interface to connect to. */ 4075 hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG; 4076 evutil_snprintf(strport, sizeof(strport), "%d", port); 4077 if ((ai_result = evutil_getaddrinfo(address, strport, &hints, &ai)) 4078 != 0) { 4079 if (ai_result == EVUTIL_EAI_SYSTEM) 4080 event_warn("getaddrinfo"); 4081 else 4082 event_warnx("getaddrinfo: %s", 4083 evutil_gai_strerror(ai_result)); 4084 return (NULL); 4085 } 4086 4087 return (ai); 4088 } 4089 4090 static evutil_socket_t 4091 bind_socket(const char *address, ev_uint16_t port, int reuse) 4092 { 4093 evutil_socket_t fd; 4094 struct evutil_addrinfo *aitop = NULL; 4095 4096 /* just create an unbound socket */ 4097 if (address == NULL && port == 0) 4098 return bind_socket_ai(NULL, 0); 4099 4100 aitop = make_addrinfo(address, port); 4101 4102 if (aitop == NULL) 4103 return (-1); 4104 4105 fd = bind_socket_ai(aitop, reuse); 4106 4107 evutil_freeaddrinfo(aitop); 4108 4109 return (fd); 4110 } 4111 4112 struct evhttp_uri { 4113 unsigned flags; 4114 char *scheme; /* scheme; e.g http, ftp etc */ 4115 char *userinfo; /* userinfo (typically username:pass), or NULL */ 4116 char *host; /* hostname, IP address, or NULL */ 4117 int port; /* port, or zero */ 4118 char *path; /* path, or "". */ 4119 char *query; /* query, or NULL */ 4120 char *fragment; /* fragment or NULL */ 4121 }; 4122 4123 struct evhttp_uri * 4124 evhttp_uri_new(void) 4125 { 4126 struct evhttp_uri *uri = mm_calloc(sizeof(struct evhttp_uri), 1); 4127 if (uri) 4128 uri->port = -1; 4129 return uri; 4130 } 4131 4132 void 4133 evhttp_uri_set_flags(struct evhttp_uri *uri, unsigned flags) 4134 { 4135 uri->flags = flags; 4136 } 4137 4138 /* Return true if the string starting at s and ending immediately before eos 4139 * is a valid URI scheme according to RFC3986 4140 */ 4141 static int 4142 scheme_ok(const char *s, const char *eos) 4143 { 4144 /* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ 4145 EVUTIL_ASSERT(eos >= s); 4146 if (s == eos) 4147 return 0; 4148 if (!EVUTIL_ISALPHA_(*s)) 4149 return 0; 4150 while (++s < eos) { 4151 if (! EVUTIL_ISALNUM_(*s) && 4152 *s != '+' && *s != '-' && *s != '.') 4153 return 0; 4154 } 4155 return 1; 4156 } 4157 4158 #define SUBDELIMS "!$&'()*+,;=" 4159 4160 /* Return true iff [s..eos) is a valid userinfo */ 4161 static int 4162 userinfo_ok(const char *s, const char *eos) 4163 { 4164 while (s < eos) { 4165 if (CHAR_IS_UNRESERVED(*s) || 4166 strchr(SUBDELIMS, *s) || 4167 *s == ':') 4168 ++s; 4169 else if (*s == '%' && s+2 < eos && 4170 EVUTIL_ISXDIGIT_(s[1]) && 4171 EVUTIL_ISXDIGIT_(s[2])) 4172 s += 3; 4173 else 4174 return 0; 4175 } 4176 return 1; 4177 } 4178 4179 static int 4180 regname_ok(const char *s, const char *eos) 4181 { 4182 while (s && s<eos) { 4183 if (CHAR_IS_UNRESERVED(*s) || 4184 strchr(SUBDELIMS, *s)) 4185 ++s; 4186 else if (*s == '%' && 4187 EVUTIL_ISXDIGIT_(s[1]) && 4188 EVUTIL_ISXDIGIT_(s[2])) 4189 s += 3; 4190 else 4191 return 0; 4192 } 4193 return 1; 4194 } 4195 4196 static int 4197 parse_port(const char *s, const char *eos) 4198 { 4199 int portnum = 0; 4200 while (s < eos) { 4201 if (! EVUTIL_ISDIGIT_(*s)) 4202 return -1; 4203 portnum = (portnum * 10) + (*s - '0'); 4204 if (portnum < 0) 4205 return -1; 4206 ++s; 4207 } 4208 return portnum; 4209 } 4210 4211 /* returns 0 for bad, 1 for ipv6, 2 for IPvFuture */ 4212 static int 4213 bracket_addr_ok(const char *s, const char *eos) 4214 { 4215 if (s + 3 > eos || *s != '[' || *(eos-1) != ']') 4216 return 0; 4217 if (s[1] == 'v') { 4218 /* IPvFuture, or junk. 4219 "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) 4220 */ 4221 s += 2; /* skip [v */ 4222 --eos; 4223 if (!EVUTIL_ISXDIGIT_(*s)) /*require at least one*/ 4224 return 0; 4225 while (s < eos && *s != '.') { 4226 if (EVUTIL_ISXDIGIT_(*s)) 4227 ++s; 4228 else 4229 return 0; 4230 } 4231 if (*s != '.') 4232 return 0; 4233 ++s; 4234 while (s < eos) { 4235 if (CHAR_IS_UNRESERVED(*s) || 4236 strchr(SUBDELIMS, *s) || 4237 *s == ':') 4238 ++s; 4239 else 4240 return 0; 4241 } 4242 return 2; 4243 } else { 4244 /* IPv6, or junk */ 4245 char buf[64]; 4246 ev_ssize_t n_chars = eos-s-2; 4247 struct in6_addr in6; 4248 if (n_chars >= 64) /* way too long */ 4249 return 0; 4250 memcpy(buf, s+1, n_chars); 4251 buf[n_chars]='\0'; 4252 return (evutil_inet_pton(AF_INET6,buf,&in6)==1) ? 1 : 0; 4253 } 4254 } 4255 4256 static int 4257 parse_authority(struct evhttp_uri *uri, char *s, char *eos) 4258 { 4259 char *cp, *port; 4260 EVUTIL_ASSERT(eos); 4261 if (eos == s) { 4262 uri->host = mm_strdup(""); 4263 if (uri->host == NULL) { 4264 event_warn("%s: strdup", __func__); 4265 return -1; 4266 } 4267 return 0; 4268 } 4269 4270 /* Optionally, we start with "userinfo@" */ 4271 4272 cp = strchr(s, '@'); 4273 if (cp && cp < eos) { 4274 if (! userinfo_ok(s,cp)) 4275 return -1; 4276 *cp++ = '\0'; 4277 uri->userinfo = mm_strdup(s); 4278 if (uri->userinfo == NULL) { 4279 event_warn("%s: strdup", __func__); 4280 return -1; 4281 } 4282 } else { 4283 cp = s; 4284 } 4285 /* Optionally, we end with ":port" */ 4286 for (port=eos-1; port >= cp && EVUTIL_ISDIGIT_(*port); --port) 4287 ; 4288 if (port >= cp && *port == ':') { 4289 if (port+1 == eos) /* Leave port unspecified; the RFC allows a 4290 * nil port */ 4291 uri->port = -1; 4292 else if ((uri->port = parse_port(port+1, eos))<0) 4293 return -1; 4294 eos = port; 4295 } 4296 /* Now, cp..eos holds the "host" port, which can be an IPv4Address, 4297 * an IP-Literal, or a reg-name */ 4298 EVUTIL_ASSERT(eos >= cp); 4299 if (*cp == '[' && eos >= cp+2 && *(eos-1) == ']') { 4300 /* IPv6address, IP-Literal, or junk. */ 4301 if (! bracket_addr_ok(cp, eos)) 4302 return -1; 4303 } else { 4304 /* Make sure the host part is ok. */ 4305 if (! regname_ok(cp,eos)) /* Match IPv4Address or reg-name */ 4306 return -1; 4307 } 4308 uri->host = mm_malloc(eos-cp+1); 4309 if (uri->host == NULL) { 4310 event_warn("%s: malloc", __func__); 4311 return -1; 4312 } 4313 memcpy(uri->host, cp, eos-cp); 4314 uri->host[eos-cp] = '\0'; 4315 return 0; 4316 4317 } 4318 4319 static char * 4320 end_of_authority(char *cp) 4321 { 4322 while (*cp) { 4323 if (*cp == '?' || *cp == '#' || *cp == '/') 4324 return cp; 4325 ++cp; 4326 } 4327 return cp; 4328 } 4329 4330 enum uri_part { 4331 PART_PATH, 4332 PART_QUERY, 4333 PART_FRAGMENT 4334 }; 4335 4336 /* Return the character after the longest prefix of 'cp' that matches... 4337 * *pchar / "/" if allow_qchars is false, or 4338 * *(pchar / "/" / "?") if allow_qchars is true. 4339 */ 4340 static char * 4341 end_of_path(char *cp, enum uri_part part, unsigned flags) 4342 { 4343 if (flags & EVHTTP_URI_NONCONFORMANT) { 4344 /* If NONCONFORMANT: 4345 * Path is everything up to a # or ? or nul. 4346 * Query is everything up a # or nul 4347 * Fragment is everything up to a nul. 4348 */ 4349 switch (part) { 4350 case PART_PATH: 4351 while (*cp && *cp != '#' && *cp != '?') 4352 ++cp; 4353 break; 4354 case PART_QUERY: 4355 while (*cp && *cp != '#') 4356 ++cp; 4357 break; 4358 case PART_FRAGMENT: 4359 cp += strlen(cp); 4360 break; 4361 }; 4362 return cp; 4363 } 4364 4365 while (*cp) { 4366 if (CHAR_IS_UNRESERVED(*cp) || 4367 strchr(SUBDELIMS, *cp) || 4368 *cp == ':' || *cp == '@' || *cp == '/') 4369 ++cp; 4370 else if (*cp == '%' && EVUTIL_ISXDIGIT_(cp[1]) && 4371 EVUTIL_ISXDIGIT_(cp[2])) 4372 cp += 3; 4373 else if (*cp == '?' && part != PART_PATH) 4374 ++cp; 4375 else 4376 return cp; 4377 } 4378 return cp; 4379 } 4380 4381 static int 4382 path_matches_noscheme(const char *cp) 4383 { 4384 while (*cp) { 4385 if (*cp == ':') 4386 return 0; 4387 else if (*cp == '/') 4388 return 1; 4389 ++cp; 4390 } 4391 return 1; 4392 } 4393 4394 struct evhttp_uri * 4395 evhttp_uri_parse(const char *source_uri) 4396 { 4397 return evhttp_uri_parse_with_flags(source_uri, 0); 4398 } 4399 4400 struct evhttp_uri * 4401 evhttp_uri_parse_with_flags(const char *source_uri, unsigned flags) 4402 { 4403 char *readbuf = NULL, *readp = NULL, *token = NULL, *query = NULL; 4404 char *path = NULL, *fragment = NULL; 4405 int got_authority = 0; 4406 4407 struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri)); 4408 if (uri == NULL) { 4409 event_warn("%s: calloc", __func__); 4410 goto err; 4411 } 4412 uri->port = -1; 4413 uri->flags = flags; 4414 4415 readbuf = mm_strdup(source_uri); 4416 if (readbuf == NULL) { 4417 event_warn("%s: strdup", __func__); 4418 goto err; 4419 } 4420 4421 readp = readbuf; 4422 token = NULL; 4423 4424 /* We try to follow RFC3986 here as much as we can, and match 4425 the productions 4426 4427 URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 4428 4429 relative-ref = relative-part [ "?" query ] [ "#" fragment ] 4430 */ 4431 4432 /* 1. scheme: */ 4433 token = strchr(readp, ':'); 4434 if (token && scheme_ok(readp,token)) { 4435 *token = '\0'; 4436 uri->scheme = mm_strdup(readp); 4437 if (uri->scheme == NULL) { 4438 event_warn("%s: strdup", __func__); 4439 goto err; 4440 } 4441 readp = token+1; /* eat : */ 4442 } 4443 4444 /* 2. Optionally, "//" then an 'authority' part. */ 4445 if (readp[0]=='/' && readp[1] == '/') { 4446 char *authority; 4447 readp += 2; 4448 authority = readp; 4449 path = end_of_authority(readp); 4450 if (parse_authority(uri, authority, path) < 0) 4451 goto err; 4452 readp = path; 4453 got_authority = 1; 4454 } 4455 4456 /* 3. Query: path-abempty, path-absolute, path-rootless, or path-empty 4457 */ 4458 path = readp; 4459 readp = end_of_path(path, PART_PATH, flags); 4460 4461 /* Query */ 4462 if (*readp == '?') { 4463 *readp = '\0'; 4464 ++readp; 4465 query = readp; 4466 readp = end_of_path(readp, PART_QUERY, flags); 4467 } 4468 /* fragment */ 4469 if (*readp == '#') { 4470 *readp = '\0'; 4471 ++readp; 4472 fragment = readp; 4473 readp = end_of_path(readp, PART_FRAGMENT, flags); 4474 } 4475 if (*readp != '\0') { 4476 goto err; 4477 } 4478 4479 /* These next two cases may be unreachable; I'm leaving them 4480 * in to be defensive. */ 4481 /* If you didn't get an authority, the path can't begin with "//" */ 4482 if (!got_authority && path[0]=='/' && path[1]=='/') 4483 goto err; 4484 /* If you did get an authority, the path must begin with "/" or be 4485 * empty. */ 4486 if (got_authority && path[0] != '/' && path[0] != '\0') 4487 goto err; 4488 /* (End of maybe-unreachable cases) */ 4489 4490 /* If there was no scheme, the first part of the path (if any) must 4491 * have no colon in it. */ 4492 if (! uri->scheme && !path_matches_noscheme(path)) 4493 goto err; 4494 4495 EVUTIL_ASSERT(path); 4496 uri->path = mm_strdup(path); 4497 if (uri->path == NULL) { 4498 event_warn("%s: strdup", __func__); 4499 goto err; 4500 } 4501 4502 if (query) { 4503 uri->query = mm_strdup(query); 4504 if (uri->query == NULL) { 4505 event_warn("%s: strdup", __func__); 4506 goto err; 4507 } 4508 } 4509 if (fragment) { 4510 uri->fragment = mm_strdup(fragment); 4511 if (uri->fragment == NULL) { 4512 event_warn("%s: strdup", __func__); 4513 goto err; 4514 } 4515 } 4516 4517 mm_free(readbuf); 4518 4519 return uri; 4520 err: 4521 if (uri) 4522 evhttp_uri_free(uri); 4523 if (readbuf) 4524 mm_free(readbuf); 4525 return NULL; 4526 } 4527 4528 void 4529 evhttp_uri_free(struct evhttp_uri *uri) 4530 { 4531 #define URI_FREE_STR_(f) \ 4532 if (uri->f) { \ 4533 mm_free(uri->f); \ 4534 } 4535 4536 URI_FREE_STR_(scheme); 4537 URI_FREE_STR_(userinfo); 4538 URI_FREE_STR_(host); 4539 URI_FREE_STR_(path); 4540 URI_FREE_STR_(query); 4541 URI_FREE_STR_(fragment); 4542 4543 mm_free(uri); 4544 #undef URI_FREE_STR_ 4545 } 4546 4547 char * 4548 evhttp_uri_join(struct evhttp_uri *uri, char *buf, size_t limit) 4549 { 4550 struct evbuffer *tmp = 0; 4551 size_t joined_size = 0; 4552 char *output = NULL; 4553 4554 #define URI_ADD_(f) evbuffer_add(tmp, uri->f, strlen(uri->f)) 4555 4556 if (!uri || !buf || !limit) 4557 return NULL; 4558 4559 tmp = evbuffer_new(); 4560 if (!tmp) 4561 return NULL; 4562 4563 if (uri->scheme) { 4564 URI_ADD_(scheme); 4565 evbuffer_add(tmp, ":", 1); 4566 } 4567 if (uri->host) { 4568 evbuffer_add(tmp, "//", 2); 4569 if (uri->userinfo) 4570 evbuffer_add_printf(tmp,"%s@", uri->userinfo); 4571 URI_ADD_(host); 4572 if (uri->port >= 0) 4573 evbuffer_add_printf(tmp,":%d", uri->port); 4574 4575 if (uri->path && uri->path[0] != '/' && uri->path[0] != '\0') 4576 goto err; 4577 } 4578 4579 if (uri->path) 4580 URI_ADD_(path); 4581 4582 if (uri->query) { 4583 evbuffer_add(tmp, "?", 1); 4584 URI_ADD_(query); 4585 } 4586 4587 if (uri->fragment) { 4588 evbuffer_add(tmp, "#", 1); 4589 URI_ADD_(fragment); 4590 } 4591 4592 evbuffer_add(tmp, "\0", 1); /* NUL */ 4593 4594 joined_size = evbuffer_get_length(tmp); 4595 4596 if (joined_size > limit) { 4597 /* It doesn't fit. */ 4598 evbuffer_free(tmp); 4599 return NULL; 4600 } 4601 evbuffer_remove(tmp, buf, joined_size); 4602 4603 output = buf; 4604 err: 4605 evbuffer_free(tmp); 4606 4607 return output; 4608 #undef URI_ADD_ 4609 } 4610 4611 const char * 4612 evhttp_uri_get_scheme(const struct evhttp_uri *uri) 4613 { 4614 return uri->scheme; 4615 } 4616 const char * 4617 evhttp_uri_get_userinfo(const struct evhttp_uri *uri) 4618 { 4619 return uri->userinfo; 4620 } 4621 const char * 4622 evhttp_uri_get_host(const struct evhttp_uri *uri) 4623 { 4624 return uri->host; 4625 } 4626 int 4627 evhttp_uri_get_port(const struct evhttp_uri *uri) 4628 { 4629 return uri->port; 4630 } 4631 const char * 4632 evhttp_uri_get_path(const struct evhttp_uri *uri) 4633 { 4634 return uri->path; 4635 } 4636 const char * 4637 evhttp_uri_get_query(const struct evhttp_uri *uri) 4638 { 4639 return uri->query; 4640 } 4641 const char * 4642 evhttp_uri_get_fragment(const struct evhttp_uri *uri) 4643 { 4644 return uri->fragment; 4645 } 4646 4647 #define URI_SET_STR_(f) do { \ 4648 if (uri->f) \ 4649 mm_free(uri->f); \ 4650 if (f) { \ 4651 if ((uri->f = mm_strdup(f)) == NULL) { \ 4652 event_warn("%s: strdup()", __func__); \ 4653 return -1; \ 4654 } \ 4655 } else { \ 4656 uri->f = NULL; \ 4657 } \ 4658 } while(0) 4659 4660 int 4661 evhttp_uri_set_scheme(struct evhttp_uri *uri, const char *scheme) 4662 { 4663 if (scheme && !scheme_ok(scheme, scheme+strlen(scheme))) 4664 return -1; 4665 4666 URI_SET_STR_(scheme); 4667 return 0; 4668 } 4669 int 4670 evhttp_uri_set_userinfo(struct evhttp_uri *uri, const char *userinfo) 4671 { 4672 if (userinfo && !userinfo_ok(userinfo, userinfo+strlen(userinfo))) 4673 return -1; 4674 URI_SET_STR_(userinfo); 4675 return 0; 4676 } 4677 int 4678 evhttp_uri_set_host(struct evhttp_uri *uri, const char *host) 4679 { 4680 if (host) { 4681 if (host[0] == '[') { 4682 if (! bracket_addr_ok(host, host+strlen(host))) 4683 return -1; 4684 } else { 4685 if (! regname_ok(host, host+strlen(host))) 4686 return -1; 4687 } 4688 } 4689 4690 URI_SET_STR_(host); 4691 return 0; 4692 } 4693 int 4694 evhttp_uri_set_port(struct evhttp_uri *uri, int port) 4695 { 4696 if (port < -1) 4697 return -1; 4698 uri->port = port; 4699 return 0; 4700 } 4701 #define end_of_cpath(cp,p,f) \ 4702 ((const char*)(end_of_path(((char*)(cp)), (p), (f)))) 4703 4704 int 4705 evhttp_uri_set_path(struct evhttp_uri *uri, const char *path) 4706 { 4707 if (path && end_of_cpath(path, PART_PATH, uri->flags) != path+strlen(path)) 4708 return -1; 4709 4710 URI_SET_STR_(path); 4711 return 0; 4712 } 4713 int 4714 evhttp_uri_set_query(struct evhttp_uri *uri, const char *query) 4715 { 4716 if (query && end_of_cpath(query, PART_QUERY, uri->flags) != query+strlen(query)) 4717 return -1; 4718 URI_SET_STR_(query); 4719 return 0; 4720 } 4721 int 4722 evhttp_uri_set_fragment(struct evhttp_uri *uri, const char *fragment) 4723 { 4724 if (fragment && end_of_cpath(fragment, PART_FRAGMENT, uri->flags) != fragment+strlen(fragment)) 4725 return -1; 4726 URI_SET_STR_(fragment); 4727 return 0; 4728 } 4729