#else
#include <poll.h>
#endif /* def __GLIBC__ */
-#else
-# ifndef FD_ZERO
-# include <select.h>
-# endif
-#warning poll() appears to be unavailable. Your platform will become unsupported in the future.
#endif /* HAVE_POLL */
#endif
*********************************************************************/
static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers)
{
- char *req;
-
if (!(csp->config->feature_flags & RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS))
{
log_error(LOG_LEVEL_ERROR, "%s's request: \'%s\' is invalid."
{
/* We can't work without destination. Go spread the news.*/
- req = list_to_text(headers);
- chomp(req);
/* XXX: Use correct size */
log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
csp->ip_addr_str, csp->http->cmd);
log_error(LOG_LEVEL_ERROR,
- "Privoxy was unable to get the destination for %s's request:\n%s\n%s",
- csp->ip_addr_str, csp->http->cmd, req);
- freez(req);
+ "Privoxy was unable to get the destination for %s's request: %s",
+ csp->ip_addr_str, csp->http->cmd);
write_socket_delayed(csp->cfd, MISSING_DESTINATION_RESPONSE,
strlen(MISSING_DESTINATION_RESPONSE), get_write_delay(csp));
{
log_error(LOG_LEVEL_CRUNCH, "%s: https://%s%s", crunch_reason(rsp),
http->hostport, http->path);
- log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s https://%s%s %s\" %s %llu",
+ log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s https://%s%s %s\" %s %lu",
csp->ip_addr_str, http->gpc, http->hostport, http->path,
http->version, status_code, rsp->content_length);
}
#endif
{
log_error(LOG_LEVEL_CRUNCH, "%s: %s", crunch_reason(rsp), http->url);
- log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %u",
+ log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %lu",
csp->ip_addr_str, http->ocmd, status_code, rsp->content_length);
}
/* Write the answer to the client */
server_connection->gateway_host = NULL;
}
server_connection->gateway_port = fwd->gateway_port;
+ if (NULL != fwd->auth_username)
+ {
+ server_connection->auth_username = strdup_or_die(fwd->auth_username);
+ }
+ else
+ {
+ server_connection->auth_username = NULL;
+ }
+ if (NULL != fwd->auth_password)
+ {
+ server_connection->auth_password = strdup_or_die(fwd->auth_password);
+ }
+ else
+ {
+ server_connection->auth_password = NULL;
+ }
if (NULL != fwd->forward_host)
{
return JB_ERR_PARSE;
}
log_error(LOG_LEVEL_CONNECT,
- "Chunked client body completely read. Length: %d", body_length);
+ "Chunked client body completely read. Length: %lu", body_length);
csp->expected_client_content_length = body_length;
return JB_ERR_OK;
csp->http->hostport);
return 1;
}
- if (flushed != 0)
+ if (flushed != 0 || csp->expected_client_content_length != 0)
{
if (csp->expected_client_content_length != 0)
{
if (csp->expected_client_content_length < flushed)
{
log_error(LOG_LEVEL_ERROR,
- "Flushed %d bytes of request body while only expecting %llu",
+ "Flushed %ld bytes of request body while only expecting %llu",
flushed, csp->expected_client_content_length);
csp->expected_client_content_length = 0;
}
else
{
log_error(LOG_LEVEL_CONNECT,
- "Flushed %d bytes of request body while expecting %llu",
+ "Flushed %ld bytes of request body while expecting %llu",
flushed, csp->expected_client_content_length);
csp->expected_client_content_length -= (unsigned)flushed;
if (receive_and_send_encrypted_post_data(csp))
else
{
log_error(LOG_LEVEL_CONNECT,
- "Flushed %d bytes of request body", flushed);
+ "Flushed %ld bytes of request body", flushed);
}
}
err = receive_encrypted_request(csp);
if (err != JB_ERR_OK)
{
- if (csp->client_iob->cur == NULL)
+ if (csp->client_iob->cur == NULL ||
+ csp->client_iob->cur == csp->client_iob->eod)
{
/*
* We did not receive any data, most likely because the
char *hdr;
char *p;
int n;
-#ifdef HAVE_POLL
struct pollfd poll_fds[2];
-#else
- fd_set rfds;
- jb_socket maxfd;
- struct timeval timeout;
-#endif
int server_body;
int ms_iis5_hack = 0;
unsigned long long byte_count = 0;
http = csp->http;
-#ifndef HAVE_POLL
- maxfd = (csp->cfd > csp->server_connection.sfd) ?
- csp->cfd : csp->server_connection.sfd;
-#endif
-
/* pass data between the client and server
* until one or the other shuts down the connection.
*/
for (;;)
{
-#ifndef HAVE_POLL
- FD_ZERO(&rfds);
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
- if (!watch_client_socket)
- {
- maxfd = csp->server_connection.sfd;
- }
- else
-#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
- {
- FD_SET(csp->cfd, &rfds);
- }
-
- FD_SET(csp->server_connection.sfd, &rfds);
-#endif /* ndef HAVE_POLL */
-
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
if ((csp->flags & CSP_FLAG_CHUNKED)
&& !(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET)
{
log_error(LOG_LEVEL_CONNECT,
"Done reading from server. Content length: %llu as expected. "
- "Bytes most recently read: %d.",
+ "Bytes most recently read: %ld.",
byte_count, len);
}
else
{
log_error(LOG_LEVEL_CONNECT,
"Done reading from server. Expected content length: %llu. "
- "Actual content length: %llu. Bytes most recently read: %d.",
+ "Actual content length: %llu. Bytes most recently read: %ld.",
csp->expected_content_length, byte_count, len);
}
len = 0;
}
#endif /* FEATURE_CONNECTION_KEEP_ALIVE */
-#ifdef HAVE_POLL
poll_fds[0].fd = csp->cfd;
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
if (!watch_client_socket)
poll_fds[1].fd = csp->server_connection.sfd;
poll_fds[1].events = POLLIN;
n = poll(poll_fds, 2, csp->config->socket_timeout * 1000);
-#else
- timeout.tv_sec = csp->config->socket_timeout;
- timeout.tv_usec = 0;
- n = select((int)maxfd + 1, &rfds, NULL, NULL, &timeout);
-#endif /* def HAVE_POLL */
/*server or client not responding in timeout */
if (n == 0)
}
else if (n < 0)
{
-#ifdef HAVE_POLL
log_error(LOG_LEVEL_ERROR, "poll() failed!: %E");
-#else
- log_error(LOG_LEVEL_ERROR, "select() failed!: %E");
-#endif
mark_server_socket_tainted(csp);
#ifdef FEATURE_HTTPS_INSPECTION
close_client_and_server_ssl_connections(csp);
* XXX: Make sure the client doesn't use pipelining
* behind Privoxy's back.
*/
-#ifdef HAVE_POLL
if ((poll_fds[0].revents & (POLLERR|POLLHUP|POLLNVAL)) != 0)
{
log_error(LOG_LEVEL_CONNECT,
}
if (poll_fds[0].revents != 0)
-#else
- if (FD_ISSET(csp->cfd, &rfds))
-#endif /* def HAVE_POLL*/
{
int max_bytes_to_read = (int)csp->receive_buffer_size;
{
/*
* If the next request is already waiting, we have
- * to stop select()ing the client socket. Otherwise
+ * to stop poll()ing the client socket. Otherwise
* we would always return right away and get nothing
* else done.
*/
#ifdef FEATURE_HTTPS_INSPECTION
if (client_use_ssl(csp))
{
+ if (csp->http->status == 101)
+ {
+ len = ssl_recv_data(&(csp->ssl_client_attr),
+ (unsigned char *)csp->receive_buffer,
+ (size_t)max_bytes_to_read);
+ if (len == -1)
+ {
+ log_error(LOG_LEVEL_ERROR, "Failed to receive data "
+ "on client socket %d for an upgraded connection",
+ csp->cfd);
+ break;
+ }
+ if (len == 0)
+ {
+ log_error(LOG_LEVEL_CONNECT, "Done receiving data "
+ "on client socket %d for an upgraded connection",
+ csp->cfd);
+ break;
+ }
+ byte_count += (unsigned long long)len;
+ len = ssl_send_data(&(csp->ssl_server_attr),
+ (unsigned char *)csp->receive_buffer, (size_t)len);
+ if (len == -1)
+ {
+ log_error(LOG_LEVEL_ERROR, "Failed to send data "
+ "on server socket %d for an upgraded connection",
+ csp->server_connection.sfd);
+ break;
+ }
+ continue;
+ }
log_error(LOG_LEVEL_CONNECT, "Breaking with TLS/SSL.");
break;
}
csp->expected_client_content_length -= (unsigned)len;
log_error(LOG_LEVEL_CONNECT,
"Expected client content length set to %llu "
- "after reading %d bytes.",
+ "after reading %ld bytes.",
csp->expected_client_content_length, len);
if (csp->expected_client_content_length == 0)
{
* If `hdr' is null, then it's the header otherwise it's the body.
* FIXME: Does `hdr' really mean `host'? No.
*/
-#ifdef HAVE_POLL
if (poll_fds[1].revents != 0)
-#else
- if (FD_ISSET(csp->server_connection.sfd, &rfds))
-#endif /* HAVE_POLL */
{
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
/*
*/
log_error(LOG_LEVEL_CONNECT,
"Continuing buffering server headers from socket %d. "
- "Bytes most recently read: %d.", csp->cfd, len);
+ "Bytes most recently read: %ld.", csp->cfd, len);
continue;
}
}
/* decide how to route the HTTP request */
fwd = forward_url(csp, http);
- if (NULL == fwd)
- {
- log_error(LOG_LEVEL_FATAL, "gateway spec is NULL!?!? This can't happen!");
- /* Never get here - LOG_LEVEL_FATAL causes program exit */
- return;
- }
#ifdef FEATURE_HTTPS_INSPECTION
/*
use_ssl_tunnel = 1;
}
- if (http->ssl && csp->action->flags & ACTION_IGNORE_CERTIFICATE_ERRORS)
+ if (http->ssl && (csp->action->flags & ACTION_IGNORE_CERTIFICATE_ERRORS))
{
csp->dont_verify_certificate = 1;
}
else
{
/*
- * If server certificate is invalid, we must inform client and then
- * close connection with client.
+ * If server certificate has been verified and is invalid,
+ * we must inform the client and then close the connection
+ * with client and server.
*/
- if (csp->server_cert_verification_result != SSL_CERT_VALID)
+ if (csp->server_cert_verification_result != SSL_CERT_VALID &&
+ csp->server_cert_verification_result != SSL_CERT_NOT_VERIFIED)
{
ssl_send_certificate_error(csp);
close_client_and_server_ssl_connections(csp);
assert(bytes_to_shift > 0);
assert(data_length > 0);
- log_error(LOG_LEVEL_CONNECT, "Shifting %d pipelined bytes by %d bytes",
+ log_error(LOG_LEVEL_CONNECT, "Shifting %lu pipelined bytes by %ld bytes",
data_length, bytes_to_shift);
memmove(csp->client_iob->buf, csp->client_iob->cur, data_length);
csp->client_iob->cur = csp->client_iob->buf;
chat(csp);
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+ if (csp->cfd != JB_INVALID_SOCKET)
+ {
+ log_error(LOG_LEVEL_CONNECT, "Closing client socket %d. "
+ "Keep-alive: %u. Socket alive: %u. Data available: %u. "
+ "Configuration file change detected: %u. Requests received: %u.",
+ csp->cfd, 0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE),
+ socket_is_still_alive(csp->cfd), data_is_available(csp->cfd, 0),
+ config_file_change_detected, csp->requests_received_total);
+#ifdef FEATURE_HTTPS_INSPECTION
+ close_client_ssl_connection(csp);
+#endif
+ drain_and_close_socket(csp->cfd);
+ }
+
if (csp->server_connection.sfd != JB_INVALID_SOCKET)
{
#ifdef FEATURE_CONNECTION_SHARING
mark_connection_closed(&csp->server_connection);
#endif
- if (csp->cfd != JB_INVALID_SOCKET)
- {
- log_error(LOG_LEVEL_CONNECT, "Closing client socket %d. "
- "Keep-alive: %u. Socket alive: %u. Data available: %u. "
- "Configuration file change detected: %u. Requests received: %u.",
- csp->cfd, 0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE),
- socket_is_still_alive(csp->cfd), data_is_available(csp->cfd, 0),
- config_file_change_detected, csp->requests_received_total);
-#ifdef FEATURE_HTTPS_INSPECTION
- close_client_ssl_connection(csp);
-#endif
- drain_and_close_socket(csp->cfd);
- }
-
free_csp_resources(csp);
csp->flags &= ~CSP_FLAG_ACTIVE;
return JB_INVALID_SOCKET;
}
-#ifndef HAVE_POLL
-#ifndef _WIN32
- if (bfd >= FD_SETSIZE)
- {
- log_error(LOG_LEVEL_FATAL,
- "Bind socket number too high to use select(): %d >= %d",
- bfd, FD_SETSIZE);
- }
-#endif
-#endif
-
if (haddr == NULL)
{
log_error(LOG_LEVEL_INFO, "Listening on port %d on all IP addresses",
csp = &csp_list->csp;
log_error(LOG_LEVEL_CONNECT,
- "Waiting for the next client connection. Currently active threads: %d",
+ "Waiting for the next client connection. Currently active threads: %u",
active_threads);
/*
* XXX: If you assume ...
*/
log_error(LOG_LEVEL_ERROR,
- "Unable to take any additional connections: %E. Active threads: %d",
+ "Unable to take any additional connections: %E. Active threads: %u",
active_threads);
write_socket_delayed(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE,
strlen(TOO_MANY_CONNECTIONS_RESPONSE), get_write_delay(csp));