* Rebuild the request line.
*/
freez(*request_line);
- *request_line = strdup(http->gpc);
- string_append(request_line, " ");
+#ifdef FEATURE_HTTPS_INSPECTION
+ if (fwd != NULL && fwd->forward_host &&
+ fwd->type != FORWARD_WEBSERVER && client_use_ssl(csp))
+ {
+ *request_line = strdup("CONNECT ");
+ }
+ else
+#endif
+ {
+ *request_line = strdup(http->gpc);
+ string_append(request_line, " ");
+ }
if (fwd != NULL && fwd->forward_host && fwd->type != FORWARD_WEBSERVER)
{
- string_append(request_line, http->url);
+#ifdef FEATURE_HTTPS_INSPECTION
+ if (client_use_ssl(csp))
+ {
+ char port_string[10];
+
+ string_append(request_line, http->host);
+ snprintf(port_string, sizeof(port_string), ":%d", http->port);
+ string_append(request_line, port_string);
+ }
+ else
+#endif
+ {
+ string_append(request_line, http->url);
+ }
}
else
{
}
log_error(LOG_LEVEL_HEADER, "Encrypted request processed");
- log_applied_actions(csp->action);
log_error(LOG_LEVEL_REQUEST, "https://%s%s", csp->http->hostport,
csp->http->path);
return;
}
+ log_applied_actions(csp->action);
+
log_error(LOG_LEVEL_CONNECT,
"Reusing server socket %d connected to %s. Requests already sent: %u.",
csp->server_connection.sfd, csp->server_connection.host,
* Function : handle_established_connection
*
* Description : Shuffle data between client and server once the
- * connection has been established.
+ * connection has been established and the request
+ * has been sent.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
for (;;)
{
+#ifdef FEATURE_HTTPS_INSPECTION
+ if (server_use_ssl(csp) && is_ssl_pending(&(csp->ssl_server_attr)))
+ {
+ /*
+ * It's possible that the TLS library already consumed all the
+ * data the server intends to send. If that happens poll() and
+ * select() will no longer see the data as available so we have
+ * to skip the calls.
+ */
+ goto server_wants_to_talk;
+ }
+#endif
#ifndef HAVE_POLL
FD_ZERO(&rfds);
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
n = select((int)maxfd + 1, &rfds, NULL, NULL, &timeout);
#endif /* def HAVE_POLL */
- /*server or client not responding in timeout */
+ /* Server or client not responding in timeout */
if (n == 0)
{
log_error(LOG_LEVEL_CONNECT, "Socket timeout %d reached: %s",
if (FD_ISSET(csp->server_connection.sfd, &rfds))
#endif /* HAVE_POLL */
{
+#ifdef FEATURE_HTTPS_INSPECTION
+ server_wants_to_talk:
+#endif
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
/*
* If we are buffering content, we don't want to eat up to
}
/*
- * This is NOT the body, so
- * Let's pretend the server just sent us a blank line.
+ * This is not the body, so let's pretend the server just sent
+ * us a blank line.
*/
snprintf(csp->receive_buffer, csp->receive_buffer_size, "\r\n");
len = (int)strlen(csp->receive_buffer);
return;
}
- /* decide how to route the HTTP request */
- fwd = forward_url(csp, http);
-
#ifdef FEATURE_HTTPS_INSPECTION
/*
* Setting flags to use old solution with SSL tunnel and to disable
#endif
}
-
- freez(csp->headers->first->str);
- build_request_line(csp, fwd, &csp->headers->first->str);
-
/*
* We have a request. Check if one of the crunchers wants it
* unless the client wants to use TLS/SSL in which case we
return;
}
+#ifdef FEATURE_HTTPS_INSPECTION
+ if (client_use_ssl(csp) && !use_ssl_tunnel)
+ {
+ int ret;
+ /*
+ * Creating a SSL proxy.
+ *
+ * By sending the CSUCCEED message we're lying to the client as
+ * the connection hasn't actually been established yet. We don't
+ * establish the connection until we have seen and parsed the
+ * encrypted client headers.
+ */
+ if (write_socket_delayed(csp->cfd, CSUCCEED,
+ strlen(CSUCCEED), get_write_delay(csp)) != 0)
+ {
+ log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
+ return;
+ }
+
+ ret = create_client_ssl_connection(csp);
+ if (ret != 0)
+ {
+ log_error(LOG_LEVEL_ERROR,
+ "Failed to open a secure connection with the client");
+ return;
+ }
+ if (JB_ERR_OK != process_encrypted_request(csp))
+ {
+ close_client_ssl_connection(csp);
+ return;
+ }
+ /*
+ * We have an encrypted request. Check if one of the crunchers now
+ * wants it (for example because the previously invisible path was
+ * required to match).
+ */
+ if (crunch_response_triggered(csp, crunchers_all))
+ {
+ /*
+ * Yes. The client got the crunch response and we're done here.
+ */
+ return;
+ }
+ }
+#endif
+
+ /* decide how to route the HTTP request */
+ fwd = forward_url(csp, http);
+
+ freez(csp->headers->first->str);
+ build_request_line(csp, fwd, &csp->headers->first->str);
+
log_applied_actions(csp->action);
if (fwd->forward_host)
{
mark_connection_closed(&csp->server_connection);
}
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
-#ifdef FEATURE_HTTPS_INSPECTION
- if (client_use_ssl(csp) && !use_ssl_tunnel)
- {
- int ret;
- /*
- * Creating a SSL proxy.
- *
- * By sending the CSUCCEED message we're lying to the client as
- * the connection hasn't actually been established yet. We don't
- * establish the connection until we have seen and parsed the
- * encrypted client headers.
- */
- if (write_socket_delayed(csp->cfd, CSUCCEED,
- strlen(CSUCCEED), get_write_delay(csp)) != 0)
- {
- log_error(LOG_LEVEL_ERROR, "Sending SUCCEED to client failed");
- return;
- }
- ret = create_client_ssl_connection(csp);
- if (ret != 0)
- {
- log_error(LOG_LEVEL_ERROR,
- "Failed to open a secure connection with the client");
- return;
- }
- if (JB_ERR_OK != process_encrypted_request(csp))
- {
- close_client_ssl_connection(csp);
- return;
- }
- /*
- * We have an encrypted request. Check if one of the crunchers now
- * wants it (for example because the previously invisible path was
- * required to match).
- */
- if (crunch_response_triggered(csp, crunchers_all))
- {
- /*
- * Yes. The client got the crunch response and we're done here.
- */
- return;
- }
- }
-#endif
/*
* Connecting to destination server
*/
if ((0 != config->max_client_connections)
&& (active_threads >= config->max_client_connections))
{
- log_error(LOG_LEVEL_CONNECT,
+ log_error(LOG_LEVEL_ERROR,
"Rejecting connection from %s. Maximum number of connections reached.",
csp->ip_addr_str);
write_socket_delayed(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE,
}
#endif
-#if defined(_WIN32) && !defined(_CYGWIN) && !defined(SELECTED_ONE_OPTION)
+#if defined(_WIN32) && !defined(SELECTED_ONE_OPTION)
#define SELECTED_ONE_OPTION
child_id = _beginthread(
(void (*)(void *))serve,