| 166 | } |
| 167 | |
| 168 | static void |
| 169 | MakeHttpProxyAcceptor(HttpProxyAcceptor &acceptor, HttpProxyPort &port, unsigned nthreads) |
| 170 | { |
| 171 | NetProcessor::AcceptOptions &net_opt = acceptor._net_opt; |
| 172 | HttpSessionAccept::Options accept_opt; |
| 173 | |
| 174 | net_opt = make_net_accept_options(&port, nthreads); |
| 175 | |
| 176 | accept_opt.f_outbound_transparent = port.m_outbound_transparent_p; |
| 177 | accept_opt.transport_type = port.m_type; |
| 178 | accept_opt.setHostResPreference(port.m_host_res_preference); |
| 179 | accept_opt.setTransparentPassthrough(port.m_transparent_passthrough); |
| 180 | accept_opt.setSessionProtocolPreference(port.m_session_protocol_preference); |
| 181 | |
| 182 | accept_opt.outbound += HttpConfig::m_master.outbound; |
| 183 | accept_opt.outbound += port.m_outbound; // top priority, override master and base options. |
| 184 | |
| 185 | // OK the way this works is that the fallback for each port is a protocol |
| 186 | // probe acceptor. For SSL ports, we can stack a NPN+ALPN acceptor in front |
| 187 | // of that, and these ports will fall back to the probe if no NPN+ALPN endpoint |
| 188 | // was negotiated. |
| 189 | |
| 190 | // XXX the protocol probe should be a configuration option. |
| 191 | |
| 192 | ProtocolProbeSessionAccept *probe = new ProtocolProbeSessionAccept(); |
| 193 | HttpSessionAccept *http = nullptr; // don't allocate this unless it will be used. |
| 194 | probe->proxyPort = &port; |
| 195 | probe->proxy_protocol_ipmap = &HttpConfig::m_master.config_proxy_protocol_ip_addrs; |
| 196 | |
| 197 | if (port.m_session_protocol_preference.intersects(HTTP_PROTOCOL_SET)) { |
| 198 | http = new HttpSessionAccept(accept_opt); |
| 199 | probe->registerEndpoint(ProtocolProbeSessionAccept::PROTO_HTTP, http); |
| 200 | } |
| 201 | |
| 202 | if (port.m_session_protocol_preference.intersects(HTTP2_PROTOCOL_SET)) { |
| 203 | probe->registerEndpoint(ProtocolProbeSessionAccept::PROTO_HTTP2, new Http2SessionAccept(accept_opt)); |
| 204 | } |
| 205 | ProtocolSessionCreateMap.insert({TS_ALPN_PROTOCOL_INDEX_HTTP_1_0, create_h1_server_session}); |
| 206 | ProtocolSessionCreateMap.insert({TS_ALPN_PROTOCOL_INDEX_HTTP_1_1, create_h1_server_session}); |
| 207 | ProtocolSessionCreateMap.insert({TS_ALPN_PROTOCOL_INDEX_HTTP_2_0, create_h2_server_session}); |
| 208 | |
| 209 | if (port.isSSL()) { |
| 210 | SSLNextProtocolAccept *ssl = new SSLNextProtocolAccept(probe, port.m_transparent_passthrough, port.m_allow_plain); |
| 211 | |
| 212 | // ALPN selects the first server-offered protocol, |
| 213 | // so make sure that we offer the newest protocol first. |
| 214 | // But since registerEndpoint prepends you want to |
| 215 | // register them backwards, so you'd want to register |
| 216 | // the least important protocol first: |
| 217 | // http/1.0, http/1.1, h2 |
| 218 | |
| 219 | ssl->enableProtocols(port.m_session_protocol_preference); |
| 220 | ssl->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_1_0, http); |
| 221 | ssl->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_1_1, http); |
| 222 | ssl->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_2_0, new Http2SessionAccept(accept_opt)); |
| 223 | |
| 224 | SCOPED_MUTEX_LOCK(lock, ssl_plugin_mutex, this_ethread()); |
| 225 | ssl_plugin_acceptors.push(ssl); |
no test coverage detected