1 /* 2 * nghttp2 - HTTP/2 C Library 3 * 4 * Copyright (c) 2012 Tatsuhiro Tsujikawa 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 #ifndef SHRPX_DOWNSTREAM_H 26 #define SHRPX_DOWNSTREAM_H 27 28 #include "shrpx.h" 29 30 #include <cinttypes> 31 #include <vector> 32 #include <string> 33 #include <memory> 34 #include <chrono> 35 #include <algorithm> 36 37 #include <ev.h> 38 39 #include <nghttp2/nghttp2.h> 40 41 #ifdef ENABLE_HTTP3 42 # include <nghttp3/nghttp3.h> 43 #endif // ENABLE_HTTP3 44 45 #include "llhttp.h" 46 47 #include "shrpx_io_control.h" 48 #include "shrpx_log_config.h" 49 #include "http2.h" 50 #include "memchunk.h" 51 #include "allocator.h" 52 53 using namespace nghttp2; 54 55 namespace shrpx { 56 57 class Upstream; 58 class DownstreamConnection; 59 struct BlockedLink; 60 struct DownstreamAddrGroup; 61 struct DownstreamAddr; 62 63 class FieldStore { 64 public: FieldStore(BlockAllocator & balloc,size_t headers_initial_capacity)65 FieldStore(BlockAllocator &balloc, size_t headers_initial_capacity) 66 : content_length(-1), 67 balloc_(balloc), 68 buffer_size_(0), 69 header_key_prev_(false), 70 trailer_key_prev_(false) { 71 headers_.reserve(headers_initial_capacity); 72 } 73 headers()74 const HeaderRefs &headers() const { return headers_; } trailers()75 const HeaderRefs &trailers() const { return trailers_; } 76 headers()77 HeaderRefs &headers() { return headers_; } trailers()78 HeaderRefs &trailers() { return trailers_; } 79 add_extra_buffer_size(size_t n)80 const void add_extra_buffer_size(size_t n) { buffer_size_ += n; } buffer_size()81 size_t buffer_size() const { return buffer_size_; } 82 num_fields()83 size_t num_fields() const { return headers_.size() + trailers_.size(); } 84 85 // Returns pointer to the header field with the name |name|. If 86 // multiple header have |name| as name, return last occurrence from 87 // the beginning. If no such header is found, returns nullptr. 88 const HeaderRefs::value_type *header(int32_t token) const; 89 HeaderRefs::value_type *header(int32_t token); 90 // Returns pointer to the header field with the name |name|. If no 91 // such header is found, returns nullptr. 92 const HeaderRefs::value_type *header(const StringRef &name) const; 93 94 void add_header_token(const StringRef &name, const StringRef &value, 95 bool no_index, int32_t token); 96 97 // Adds header field name |name|. First, the copy of header field 98 // name pointed by name.c_str() of length name.size() is made, and 99 // stored. 100 void alloc_add_header_name(const StringRef &name); 101 102 void append_last_header_key(const char *data, size_t len); 103 void append_last_header_value(const char *data, size_t len); 104 header_key_prev()105 bool header_key_prev() const { return header_key_prev_; } 106 107 // Parses content-length, and records it in the field. If there are 108 // multiple Content-Length, returns -1. 109 int parse_content_length(); 110 111 // Empties headers. 112 void clear_headers(); 113 114 void add_trailer_token(const StringRef &name, const StringRef &value, 115 bool no_index, int32_t token); 116 117 // Adds trailer field name |name|. First, the copy of trailer field 118 // name pointed by name.c_str() of length name.size() is made, and 119 // stored. 120 void alloc_add_trailer_name(const StringRef &name); 121 122 void append_last_trailer_key(const char *data, size_t len); 123 void append_last_trailer_value(const char *data, size_t len); 124 trailer_key_prev()125 bool trailer_key_prev() const { return trailer_key_prev_; } 126 127 // erase_content_length_and_transfer_encoding erases content-length 128 // and transfer-encoding header fields. 129 void erase_content_length_and_transfer_encoding(); 130 131 // content-length, -1 if it is unknown. 132 int64_t content_length; 133 134 private: 135 BlockAllocator &balloc_; 136 HeaderRefs headers_; 137 // trailer fields. For HTTP/1.1, trailer fields are only included 138 // with chunked encoding. For HTTP/2, there is no such limit. 139 HeaderRefs trailers_; 140 // Sum of the length of name and value in headers_ and trailers_. 141 // This could also be increased by add_extra_buffer_size() to take 142 // into account for request URI in case of HTTP/1.x request. 143 size_t buffer_size_; 144 bool header_key_prev_; 145 bool trailer_key_prev_; 146 }; 147 148 // Protocols allowed in HTTP/2 :protocol header field. 149 enum class ConnectProto { 150 NONE, 151 WEBSOCKET, 152 }; 153 154 struct Request { RequestRequest155 Request(BlockAllocator &balloc) 156 : fs(balloc, 16), 157 recv_body_length(0), 158 unconsumed_body_length(0), 159 method(-1), 160 http_major(1), 161 http_minor(1), 162 connect_proto(ConnectProto::NONE), 163 upgrade_request(false), 164 http2_upgrade_seen(false), 165 connection_close(false), 166 http2_expect_body(false), 167 no_authority(false), 168 forwarded_once(false) {} 169 consumeRequest170 void consume(size_t len) { 171 assert(unconsumed_body_length >= len); 172 unconsumed_body_length -= len; 173 } 174 regular_connect_methodRequest175 bool regular_connect_method() const { 176 return method == HTTP_CONNECT && connect_proto == ConnectProto::NONE; 177 } 178 extended_connect_methodRequest179 bool extended_connect_method() const { 180 return connect_proto != ConnectProto::NONE; 181 } 182 183 FieldStore fs; 184 // Timestamp when all request header fields are received. 185 std::shared_ptr<Timestamp> tstamp; 186 // Request scheme. For HTTP/2, this is :scheme header field value. 187 // For HTTP/1.1, this is deduced from URI or connection. 188 StringRef scheme; 189 // Request authority. This is HTTP/2 :authority header field value 190 // or host header field value. We may deduce it from absolute-form 191 // HTTP/1 request. We also store authority-form HTTP/1 request. 192 // This could be empty if request comes from HTTP/1.0 without Host 193 // header field and origin-form. 194 StringRef authority; 195 // Request path, including query component. For HTTP/1.1, this is 196 // request-target. For HTTP/2, this is :path header field value. 197 // For CONNECT request, this is empty. 198 StringRef path; 199 // This is original authority which cannot be changed by per-pattern 200 // mruby script. 201 StringRef orig_authority; 202 // This is original path which cannot be changed by per-pattern 203 // mruby script. 204 StringRef orig_path; 205 // the length of request body received so far 206 int64_t recv_body_length; 207 // The number of bytes not consumed by the application yet. 208 size_t unconsumed_body_length; 209 int method; 210 // HTTP major and minor version 211 int http_major, http_minor; 212 // connect_proto specified in HTTP/2 :protocol pseudo header field 213 // which enables extended CONNECT method. This field is also set if 214 // WebSocket upgrade is requested in h1 frontend for convenience. 215 ConnectProto connect_proto; 216 // Returns true if the request is HTTP upgrade (HTTP Upgrade or 217 // CONNECT method). Upgrade to HTTP/2 is excluded. For HTTP/2 218 // Upgrade, check get_http2_upgrade_request(). 219 bool upgrade_request; 220 // true if h2c is seen in Upgrade header field. 221 bool http2_upgrade_seen; 222 bool connection_close; 223 // true if this is HTTP/2, and request body is expected. Note that 224 // we don't take into account HTTP method here. 225 bool http2_expect_body; 226 // true if request does not have any information about authority. 227 // This happens when: For HTTP/2 request, :authority is missing. 228 // For HTTP/1 request, origin or asterisk form is used. 229 bool no_authority; 230 // true if backend selection is done for request once. 231 // orig_authority and orig_path have the authority and path which 232 // are used for the first backend selection. 233 bool forwarded_once; 234 }; 235 236 struct Response { ResponseResponse237 Response(BlockAllocator &balloc) 238 : fs(balloc, 32), 239 recv_body_length(0), 240 unconsumed_body_length(0), 241 http_status(0), 242 http_major(1), 243 http_minor(1), 244 connection_close(false), 245 headers_only(false) {} 246 consumeResponse247 void consume(size_t len) { 248 assert(unconsumed_body_length >= len); 249 unconsumed_body_length -= len; 250 } 251 252 // returns true if a resource denoted by scheme, authority, and path 253 // has already been pushed. is_resource_pushedResponse254 bool is_resource_pushed(const StringRef &scheme, const StringRef &authority, 255 const StringRef &path) const { 256 if (!pushed_resources) { 257 return false; 258 } 259 return std::find(std::begin(*pushed_resources), std::end(*pushed_resources), 260 std::make_tuple(scheme, authority, path)) != 261 std::end(*pushed_resources); 262 } 263 264 // remember that a resource denoted by scheme, authority, and path 265 // is pushed. resource_pushedResponse266 void resource_pushed(const StringRef &scheme, const StringRef &authority, 267 const StringRef &path) { 268 if (!pushed_resources) { 269 pushed_resources = std::make_unique< 270 std::vector<std::tuple<StringRef, StringRef, StringRef>>>(); 271 } 272 pushed_resources->emplace_back(scheme, authority, path); 273 } 274 275 FieldStore fs; 276 // array of the tuple of scheme, authority, and path of pushed 277 // resource. This is required because RFC 8297 says that server 278 // typically includes header fields appeared in non-final response 279 // header fields in final response header fields. Without checking 280 // that a particular resource has already been pushed, or not, we 281 // end up pushing the same resource at least twice. It is unknown 282 // that we should use more complex data structure (e.g., std::set) 283 // to find the resources faster. 284 std::unique_ptr<std::vector<std::tuple<StringRef, StringRef, StringRef>>> 285 pushed_resources; 286 // the length of response body received so far 287 int64_t recv_body_length; 288 // The number of bytes not consumed by the application yet. This is 289 // mainly for HTTP/2 backend. 290 size_t unconsumed_body_length; 291 // HTTP status code 292 unsigned int http_status; 293 int http_major, http_minor; 294 bool connection_close; 295 // true if response only consists of HEADERS, and it bears 296 // END_STREAM. This is used to tell Http2Upstream that it can send 297 // response with single HEADERS with END_STREAM flag only. 298 bool headers_only; 299 }; 300 301 enum class DownstreamState { 302 INITIAL, 303 HEADER_COMPLETE, 304 MSG_COMPLETE, 305 STREAM_CLOSED, 306 CONNECT_FAIL, 307 MSG_RESET, 308 // header contains invalid header field. We can safely send error 309 // response (502) to a client. 310 MSG_BAD_HEADER, 311 // header fields in HTTP/1 request exceed the configuration limit. 312 // This state is only transitioned from INITIAL state, and solely 313 // used to signal 431 status code to the client. 314 HTTP1_REQUEST_HEADER_TOO_LARGE, 315 }; 316 317 enum class DispatchState { 318 NONE, 319 PENDING, 320 BLOCKED, 321 ACTIVE, 322 FAILURE, 323 }; 324 325 class Downstream { 326 public: 327 Downstream(Upstream *upstream, MemchunkPool *mcpool, int64_t stream_id); 328 ~Downstream(); 329 void reset_upstream(Upstream *upstream); 330 Upstream *get_upstream() const; 331 void set_stream_id(int64_t stream_id); 332 int64_t get_stream_id() const; 333 void set_assoc_stream_id(int64_t stream_id); 334 int64_t get_assoc_stream_id() const; 335 void pause_read(IOCtrlReason reason); 336 int resume_read(IOCtrlReason reason, size_t consumed); 337 void force_resume_read(); 338 // Set stream ID for downstream HTTP2 connection. 339 void set_downstream_stream_id(int64_t stream_id); 340 int64_t get_downstream_stream_id() const; 341 342 int attach_downstream_connection(std::unique_ptr<DownstreamConnection> dconn); 343 void detach_downstream_connection(); 344 DownstreamConnection *get_downstream_connection(); 345 // Returns dconn_ and nullifies dconn_. 346 std::unique_ptr<DownstreamConnection> pop_downstream_connection(); 347 348 // Returns true if output buffer is full. If underlying dconn_ is 349 // NULL, this function always returns false. 350 bool request_buf_full(); 351 // Returns true if upgrade (HTTP Upgrade or CONNECT) is succeeded in 352 // h1 backend. This should not depend on inspect_http1_response(). 353 void check_upgrade_fulfilled_http1(); 354 // Returns true if upgrade (HTTP Upgrade or CONNECT) is succeeded in 355 // h2 backend. 356 void check_upgrade_fulfilled_http2(); 357 // Returns true if the upgrade is succeeded as a result of the call 358 // check_upgrade_fulfilled_http*(). HTTP/2 Upgrade is excluded. 359 bool get_upgraded() const; 360 // Inspects HTTP/2 request. 361 void inspect_http2_request(); 362 // Inspects HTTP/1 request. This checks whether the request is 363 // upgrade request and tranfer-encoding etc. 364 void inspect_http1_request(); 365 // Returns true if the request is HTTP Upgrade for HTTP/2 366 bool get_http2_upgrade_request() const; 367 // Returns the value of HTTP2-Settings request header field. 368 StringRef get_http2_settings() const; 369 370 // downstream request API request()371 const Request &request() const { return req_; } request()372 Request &request() { return req_; } 373 374 // Count number of crumbled cookies 375 size_t count_crumble_request_cookie(); 376 // Crumbles (split cookie by ";") in request_headers_ and adds them 377 // in |nva|. Headers::no_index is inherited. 378 void crumble_request_cookie(std::vector<nghttp2_nv> &nva); 379 // Assembles request cookies. The opposite operation against 380 // crumble_request_cookie(). 381 StringRef assemble_request_cookie(); 382 383 void 384 set_request_start_time(std::chrono::high_resolution_clock::time_point time); 385 const std::chrono::high_resolution_clock::time_point & 386 get_request_start_time() const; 387 int push_request_headers(); 388 bool get_chunked_request() const; 389 void set_chunked_request(bool f); 390 int push_upload_data_chunk(const uint8_t *data, size_t datalen); 391 int end_upload_data(); 392 // Validates that received request body length and content-length 393 // matches. 394 bool validate_request_recv_body_length() const; 395 void set_request_downstream_host(const StringRef &host); 396 bool expect_response_body() const; 397 bool expect_response_trailer() const; 398 void set_request_state(DownstreamState state); 399 DownstreamState get_request_state() const; 400 DefaultMemchunks *get_request_buf(); 401 void set_request_pending(bool f); 402 bool get_request_pending() const; 403 void set_request_header_sent(bool f); 404 bool get_request_header_sent() const; 405 // Returns true if request is ready to be submitted to downstream. 406 // When sending pending request, get_request_pending() should be 407 // checked too because this function may return true when 408 // get_request_pending() returns false. 409 bool request_submission_ready() const; 410 411 DefaultMemchunks *get_blocked_request_buf(); 412 bool get_blocked_request_data_eof() const; 413 void set_blocked_request_data_eof(bool f); 414 415 // downstream response API response()416 const Response &response() const { return resp_; } response()417 Response &response() { return resp_; } 418 419 // Rewrites the location response header field. 420 void rewrite_location_response_header(const StringRef &upstream_scheme); 421 422 bool get_chunked_response() const; 423 void set_chunked_response(bool f); 424 425 void set_response_state(DownstreamState state); 426 DownstreamState get_response_state() const; 427 DefaultMemchunks *get_response_buf(); 428 bool response_buf_full(); 429 // Validates that received response body length and content-length 430 // matches. 431 bool validate_response_recv_body_length() const; 432 uint32_t get_response_rst_stream_error_code() const; 433 void set_response_rst_stream_error_code(uint32_t error_code); 434 // Inspects HTTP/1 response. This checks tranfer-encoding etc. 435 void inspect_http1_response(); 436 // Clears some of member variables for response. 437 void reset_response(); 438 // True if the response is non-final (1xx status code). Note that 439 // if connection was upgraded, 101 status code is treated as final. 440 bool get_non_final_response() const; 441 // True if protocol version used by client supports non final 442 // response. Only HTTP/1.1 and HTTP/2 clients support it. 443 bool supports_non_final_response() const; 444 void set_expect_final_response(bool f); 445 bool get_expect_final_response() const; 446 447 // Call this method when there is incoming data in downstream 448 // connection. 449 int on_read(); 450 451 // Resets upstream read timer. If it is active, timeout value is 452 // reset. If it is not active, timer will be started. 453 void reset_upstream_rtimer(); 454 // Resets upstream write timer. If it is active, timeout value is 455 // reset. If it is not active, timer will be started. This 456 // function also resets read timer if it has been started. 457 void reset_upstream_wtimer(); 458 // Makes sure that upstream write timer is started. If it has been 459 // started, do nothing. Otherwise, write timer will be started. 460 void ensure_upstream_wtimer(); 461 // Disables upstream read timer. 462 void disable_upstream_rtimer(); 463 // Disables upstream write timer. 464 void disable_upstream_wtimer(); 465 466 // Downstream timer functions. They works in a similar way just 467 // like the upstream timer function. 468 void reset_downstream_rtimer(); 469 void reset_downstream_wtimer(); 470 void ensure_downstream_wtimer(); 471 void disable_downstream_rtimer(); 472 void disable_downstream_wtimer(); 473 474 // Returns true if accesslog can be written for this downstream. 475 bool accesslog_ready() const; 476 477 // Increment retry count 478 void add_retry(); 479 // true if retry attempt should not be done. 480 bool no_more_retry() const; 481 482 DispatchState get_dispatch_state() const; 483 void set_dispatch_state(DispatchState s); 484 485 void attach_blocked_link(BlockedLink *l); 486 BlockedLink *detach_blocked_link(); 487 488 // Returns true if downstream_connection can be detached and reused. 489 bool can_detach_downstream_connection() const; 490 491 DefaultMemchunks pop_response_buf(); 492 493 BlockAllocator &get_block_allocator(); 494 495 void add_rcbuf(nghttp2_rcbuf *rcbuf); 496 #ifdef ENABLE_HTTP3 497 void add_rcbuf(nghttp3_rcbuf *rcbuf); 498 #endif // ENABLE_HTTP3 499 500 void 501 set_downstream_addr_group(const std::shared_ptr<DownstreamAddrGroup> &group); 502 void set_addr(const DownstreamAddr *addr); 503 504 const DownstreamAddr *get_addr() const; 505 506 void set_accesslog_written(bool f); 507 508 // Finds affinity cookie from request header fields. The name of 509 // cookie is given in |name|. If an affinity cookie is found, it is 510 // assigned to a member function, and is returned. If it is not 511 // found, or is malformed, returns 0. 512 uint32_t find_affinity_cookie(const StringRef &name); 513 // Set |h| as affinity cookie. 514 void renew_affinity_cookie(uint32_t h); 515 // Returns affinity cookie to send. If it does not need to be sent, 516 // for example, because the value is retrieved from a request header 517 // field, returns 0. 518 uint32_t get_affinity_cookie_to_send() const; 519 520 void set_ws_key(const StringRef &key); 521 522 bool get_expect_100_continue() const; 523 524 bool get_stop_reading() const; 525 void set_stop_reading(bool f); 526 527 enum { 528 EVENT_ERROR = 0x1, 529 EVENT_TIMEOUT = 0x2, 530 }; 531 532 Downstream *dlnext, *dlprev; 533 534 // the length of response body sent to upstream client 535 int64_t response_sent_body_length; 536 537 private: 538 BlockAllocator balloc_; 539 540 std::vector<nghttp2_rcbuf *> rcbufs_; 541 #ifdef ENABLE_HTTP3 542 std::vector<nghttp3_rcbuf *> rcbufs3_; 543 #endif // ENABLE_HTTP3 544 545 Request req_; 546 Response resp_; 547 548 std::chrono::high_resolution_clock::time_point request_start_time_; 549 550 // host we requested to downstream. This is used to rewrite 551 // location header field to decide the location should be rewritten 552 // or not. 553 StringRef request_downstream_host_; 554 555 // Data arrived in frontend before sending header fields to backend 556 // are stored in this buffer. 557 DefaultMemchunks blocked_request_buf_; 558 DefaultMemchunks request_buf_; 559 DefaultMemchunks response_buf_; 560 561 // The Sec-WebSocket-Key field sent to the peer. This field is used 562 // if frontend uses RFC 8441 WebSocket bootstrapping via HTTP/2. 563 StringRef ws_key_; 564 565 ev_timer upstream_rtimer_; 566 ev_timer upstream_wtimer_; 567 568 ev_timer downstream_rtimer_; 569 ev_timer downstream_wtimer_; 570 571 Upstream *upstream_; 572 std::unique_ptr<DownstreamConnection> dconn_; 573 574 // only used by HTTP/2 upstream 575 BlockedLink *blocked_link_; 576 // The backend address used to fulfill this request. These are for 577 // logging purpose. 578 std::shared_ptr<DownstreamAddrGroup> group_; 579 const DownstreamAddr *addr_; 580 // How many times we tried in backend connection 581 size_t num_retry_; 582 // The stream ID in frontend connection 583 int64_t stream_id_; 584 // The associated stream ID in frontend connection if this is pushed 585 // stream. 586 int64_t assoc_stream_id_; 587 // stream ID in backend connection 588 int64_t downstream_stream_id_; 589 // RST_STREAM error_code from downstream HTTP2 connection 590 uint32_t response_rst_stream_error_code_; 591 // An affinity cookie value. 592 uint32_t affinity_cookie_; 593 // request state 594 DownstreamState request_state_; 595 // response state 596 DownstreamState response_state_; 597 // only used by HTTP/2 upstream 598 DispatchState dispatch_state_; 599 // true if the connection is upgraded (HTTP Upgrade or CONNECT), 600 // excluding upgrade to HTTP/2. 601 bool upgraded_; 602 // true if backend request uses chunked transfer-encoding 603 bool chunked_request_; 604 // true if response to client uses chunked transfer-encoding 605 bool chunked_response_; 606 // true if we have not got final response code 607 bool expect_final_response_; 608 // true if downstream request is pending because backend connection 609 // has not been established or should be checked before use; 610 // currently used only with HTTP/2 connection. 611 bool request_pending_; 612 // true if downstream request header is considered to be sent. 613 bool request_header_sent_; 614 // true if access.log has been written. 615 bool accesslog_written_; 616 // true if affinity cookie is generated for this request. 617 bool new_affinity_cookie_; 618 // true if eof is received from client before sending header fields 619 // to backend. 620 bool blocked_request_data_eof_; 621 // true if request contains "expect: 100-continue" header field. 622 bool expect_100_continue_; 623 bool stop_reading_; 624 }; 625 626 } // namespace shrpx 627 628 #endif // SHRPX_DOWNSTREAM_H 629