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