+
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+/*********************************************************************
+ *
+ * Function : continue_https_chat
+ *
+ * Description : Behaves similar to chat() but only deals with
+ * https-inspected requests that arrive on an already
+ * established connection. The first request is always
+ * served by chat() which is a lot more complex as it
+ * has to deal with forwarding settings and connection
+ * failures etc.
+ *
+ * If a connection to the server has already been
+ * opened it is reused unless the request is blocked
+ * or the forwarder changed.
+ *
+ * If a connection to the server has not yet been
+ * opened (because the previous request was crunched),
+ * or the forwarder changed, the connection is dropped
+ * so that the client retries on a fresh one.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns : Nothing.
+ *
+ *********************************************************************/
+static void continue_https_chat(struct client_state *csp)
+{
+ const struct forward_spec *fwd;
+
+ if (JB_ERR_OK != process_encrypted_request(csp))
+ {
+ return;
+ }
+
+ csp->requests_received_total++;
+
+ /*
+ * We have an encrypted request. Check if one of the crunchers wants it.
+ */
+ if (crunch_response_triggered(csp, crunchers_all))
+ {
+ /*
+ * Yes. The client got the crunch response and we're done here.
+ */
+ return;
+ }
+ if (csp->ssl_with_server_is_opened == 0)
+ {
+ log_error(LOG_LEVEL_CONNECT,
+ "Dropping the client connection on socket %d. "
+ "The server connection has not been established yet.",
+ csp->cfd);
+ csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
+ return;
+ }
+ assert(csp->server_connection.sfd != JB_INVALID_SOCKET);
+
+ fwd = forward_url(csp, csp->http);
+ if (!connection_destination_matches(&csp->server_connection, csp->http, fwd))
+ {
+ log_error(LOG_LEVEL_CONNECT,
+ "Dropping the client connection on socket %d with "
+ "server socket %d connected to %s. The forwarder has changed.",
+ csp->cfd, csp->server_connection.sfd, csp->server_connection.host);
+ csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
+ return;
+ }
+
+ log_error(LOG_LEVEL_CONNECT,
+ "Reusing server socket %d connected to %s. Requests already sent: %u.",
+ csp->server_connection.sfd, csp->server_connection.host,
+ csp->server_connection.requests_sent_total);
+
+ if (send_https_request(csp))
+ {
+ /*
+ * Most likely the server connection timed out. We can't easily
+ * create a new one so simply drop the client connection without a
+ * error response to let the client retry.
+ */
+ log_error(LOG_LEVEL_CONNECT,
+ "Dropping client connection on socket %d. "
+ "Forwarding the encrypted client request failed.",
+ csp->cfd);
+ return;
+ }
+ csp->server_connection.requests_sent_total++;
+ handle_established_connection(csp);
+ freez(csp->receive_buffer);
+}
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */