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