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