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_CLIENT_HANDLER_H 26 #define SHRPX_CLIENT_HANDLER_H 27 28 #include "shrpx.h" 29 30 #include <memory> 31 32 #include <ev.h> 33 34 #include <openssl/ssl.h> 35 36 #include "shrpx_rate_limit.h" 37 #include "shrpx_connection.h" 38 #include "buffer.h" 39 #include "memchunk.h" 40 #include "allocator.h" 41 42 using namespace nghttp2; 43 44 namespace shrpx { 45 46 class Upstream; 47 class DownstreamConnection; 48 class HttpsUpstream; 49 class ConnectBlocker; 50 class DownstreamConnectionPool; 51 class Worker; 52 class Downstream; 53 struct WorkerStat; 54 struct DownstreamAddrGroup; 55 struct DownstreamAddr; 56 #ifdef ENABLE_HTTP3 57 class Http3Upstream; 58 #endif // ENABLE_HTTP3 59 60 class ClientHandler { 61 public: 62 ClientHandler(Worker *worker, int fd, SSL *ssl, const StringRef &ipaddr, 63 const StringRef &port, int family, const UpstreamAddr *faddr); 64 ~ClientHandler(); 65 66 int noop(); 67 // Performs clear text I/O 68 int read_clear(); 69 int write_clear(); 70 // Performs TLS handshake 71 int tls_handshake(); 72 // Performs TLS I/O 73 int read_tls(); 74 int write_tls(); 75 76 int upstream_noop(); 77 int upstream_read(); 78 int upstream_http2_connhd_read(); 79 int upstream_http1_connhd_read(); 80 int upstream_write(); 81 82 int proxy_protocol_read(); 83 int proxy_protocol_v2_read(); 84 int on_proxy_protocol_finish(); 85 86 // Performs I/O operation. Internally calls on_read()/on_write(). 87 int do_read(); 88 int do_write(); 89 90 // Processes buffers. No underlying I/O operation will be done. 91 int on_read(); 92 int on_write(); 93 94 struct ev_loop *get_loop() const; 95 void reset_upstream_read_timeout(ev_tstamp t); 96 void reset_upstream_write_timeout(ev_tstamp t); 97 98 int validate_next_proto(); 99 const StringRef &get_ipaddr() const; 100 bool get_should_close_after_write() const; 101 void set_should_close_after_write(bool f); 102 Upstream *get_upstream(); 103 104 void pool_downstream_connection(std::unique_ptr<DownstreamConnection> dconn); 105 void remove_downstream_connection(DownstreamConnection *dconn); 106 DownstreamAddr *get_downstream_addr(int &err, DownstreamAddrGroup *group, 107 Downstream *downstream); 108 // Returns DownstreamConnection object based on request path. This 109 // function returns non-null DownstreamConnection, and assigns 0 to 110 // |err| if it succeeds, or returns nullptr, and assigns negative 111 // error code to |err|. 112 std::unique_ptr<DownstreamConnection> 113 get_downstream_connection(int &err, Downstream *downstream); 114 MemchunkPool *get_mcpool(); 115 SSL *get_ssl() const; 116 // Call this function when HTTP/2 connection header is received at 117 // the start of the connection. 118 void direct_http2_upgrade(); 119 // Performs HTTP/2 Upgrade from the connection managed by 120 // |http|. If this function fails, the connection must be 121 // terminated. This function returns 0 if it succeeds, or -1. 122 int perform_http2_upgrade(HttpsUpstream *http); 123 bool get_http2_upgrade_allowed() const; 124 // Returns upstream scheme, either "http" or "https" 125 StringRef get_upstream_scheme() const; 126 void start_immediate_shutdown(); 127 128 // Writes upstream accesslog using |downstream|. The |downstream| 129 // must not be nullptr. 130 void write_accesslog(Downstream *downstream); 131 132 Worker *get_worker() const; 133 134 // Initializes forwarded_for_. 135 void init_forwarded_for(int family, const StringRef &ipaddr); 136 137 using ReadBuf = DefaultMemchunkBuffer; 138 139 ReadBuf *get_rb(); 140 141 RateLimit *get_rlimit(); 142 RateLimit *get_wlimit(); 143 144 void signal_write(); 145 ev_io *get_wev(); 146 147 void setup_upstream_io_callback(); 148 149 #ifdef ENABLE_HTTP3 150 void setup_http3_upstream(std::unique_ptr<Http3Upstream> &&upstream); 151 int read_quic(const UpstreamAddr *faddr, const Address &remote_addr, 152 const Address &local_addr, const uint8_t *data, size_t datalen); 153 int write_quic(); 154 #endif // ENABLE_HTTP3 155 156 // Returns string suitable for use in "by" parameter of Forwarded 157 // header field. 158 StringRef get_forwarded_by() const; 159 // Returns string suitable for use in "for" parameter of Forwarded 160 // header field. 161 StringRef get_forwarded_for() const; 162 163 Http2Session * 164 get_http2_session(const std::shared_ptr<DownstreamAddrGroup> &group, 165 DownstreamAddr *addr); 166 167 // Returns an affinity cookie value for |downstream|. |cookie_name| 168 // is used to inspect cookie header field in request header fields. 169 uint32_t get_affinity_cookie(Downstream *downstream, 170 const StringRef &cookie_name); 171 172 const UpstreamAddr *get_upstream_addr() const; 173 174 void repeat_read_timer(); 175 void stop_read_timer(); 176 177 Connection *get_connection(); 178 179 // Stores |sni| which is TLS SNI extension value client sent in this 180 // connection. 181 void set_tls_sni(const StringRef &sni); 182 // Returns TLS SNI extension value client sent in this connection. 183 StringRef get_tls_sni() const; 184 185 // Returns ALPN negotiated in this connection. 186 StringRef get_alpn() const; 187 188 BlockAllocator &get_block_allocator(); 189 190 private: 191 // Allocator to allocate memory for connection-wide objects. Make 192 // sure that the allocations must be bounded, and not proportional 193 // to the number of requests. 194 BlockAllocator balloc_; 195 DefaultMemchunkBuffer rb_; 196 Connection conn_; 197 ev_timer reneg_shutdown_timer_; 198 std::unique_ptr<Upstream> upstream_; 199 // IP address of client. If UNIX domain socket is used, this is 200 // "localhost". 201 StringRef ipaddr_; 202 StringRef port_; 203 // The ALPN identifier negotiated for this connection. 204 StringRef alpn_; 205 // The client address used in "for" parameter of Forwarded header 206 // field. 207 StringRef forwarded_for_; 208 // lowercased TLS SNI which client sent. 209 StringRef sni_; 210 std::function<int(ClientHandler &)> read_, write_; 211 std::function<int(ClientHandler &)> on_read_, on_write_; 212 // Address of frontend listening socket 213 const UpstreamAddr *faddr_; 214 Worker *worker_; 215 // The number of bytes of HTTP/2 client connection header to read 216 size_t left_connhd_len_; 217 // hash for session affinity using client IP 218 uint32_t affinity_hash_; 219 bool should_close_after_write_; 220 // true if affinity_hash_ is computed 221 bool affinity_hash_computed_; 222 }; 223 224 } // namespace shrpx 225 226 #endif // SHRPX_CLIENT_HANDLER_H 227