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