if (to_read != 0)
{
- log_error(LOG_LEVEL_CONNECT, "Not enough request body has been read: expected %llu more bytes",
- csp->expected_client_content_length);
+ log_error(LOG_LEVEL_CONNECT,
+ "Not enough request body has been read: expected %lu more bytes",
+ to_read);
return 1;
}
- log_error(LOG_LEVEL_CONNECT, "The last %llu bytes of the request body have been read",
- csp->expected_client_content_length);
+ log_error(LOG_LEVEL_CONNECT,
+ "The last %d bytes of the request body have been read", len);
return 0;
}
/*********************************************************************
*
- * Function : receive_encrypted_request
+ * Function : receive_encrypted_request_headers
*
- * Description : Receives an encrypted request.
+ * Description : Receives the encrypted request headers when
+ * https-inspecting.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
* JB_ERR_PARSE or JB_ERR_MEMORY otherwise
*
*********************************************************************/
-static jb_err receive_encrypted_request(struct client_state *csp)
+static jb_err receive_encrypted_request_headers(struct client_state *csp)
{
char buf[BUFFER_SIZE];
int len;
do
{
- log_error(LOG_LEVEL_HEADER, "Reading encrypted headers");
+ log_error(LOG_LEVEL_HEADER, "Waiting for encrypted client headers");
if (!is_ssl_pending(&(csp->ssl_client_attr)) &&
!data_is_available(csp->cfd, csp->config->socket_timeout))
{
/*********************************************************************
*
- * Function : process_encrypted_request
+ * Function : process_encrypted_request_headers
*
- * Description : Receives and parses an encrypted request.
+ * Description : Receives and parses the encrypted headers send
+ * by the client when https-inspecting.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
* JB_ERR_PARSE or JB_ERR_MEMORY otherwise
*
*********************************************************************/
-static jb_err process_encrypted_request(struct client_state *csp)
+static jb_err process_encrypted_request_headers(struct client_state *csp)
{
char *p;
char *request_line;
csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
}
#endif
- err = receive_encrypted_request(csp);
+ err = receive_encrypted_request_headers(csp);
if (err != JB_ERR_OK)
{
if (csp->client_iob->cur == NULL ||
return JB_ERR_PARSE;
}
- log_error(LOG_LEVEL_HEADER, "Encrypted request processed");
- log_applied_actions(csp->action);
+ log_error(LOG_LEVEL_HEADER, "Encrypted request headers processed");
log_error(LOG_LEVEL_REQUEST, "https://%s%s", csp->http->hostport,
csp->http->path);
{
const struct forward_spec *fwd;
- if (JB_ERR_OK != process_encrypted_request(csp))
+ if (JB_ERR_OK != process_encrypted_request_headers(csp))
{
csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
return;
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);
"Failed to open a secure connection with the client");
return;
}
- if (JB_ERR_OK != process_encrypted_request(csp))
+ if (JB_ERR_OK != process_encrypted_request_headers(csp))
{
close_client_ssl_connection(csp);
return;
}
#endif
+ log_applied_actions(csp->action);
+
/* 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)
{
log_error(LOG_LEVEL_CONNECT, "via [%s]:%d to: %s",
"can't bind to %s:%d: There may be another Privoxy "
"or some other proxy running on port %d",
bind_address, hport, hport);
+ exit(-1);
case -2:
log_error(LOG_LEVEL_FATAL,
"can't bind to %s:%d: The hostname is not resolvable",
bind_address, hport);
+ exit(-1);
default:
log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: %E",
bind_address, hport);
+ exit(-1);
}
/* shouldn't get here */
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,
log_error(LOG_LEVEL_INFO, "Graceful termination requested.");
+ close_ports_helper(bfds);
+
unload_current_config_file();
unload_current_actions_file();
unload_current_re_filterfile();