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