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