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