X-Git-Url: http://www.privoxy.org/gitweb/gpl.html?a=blobdiff_plain;f=parsers.c;h=f313f4f8158d12010c9f933ffd2d701687e5ea7b;hb=0a9a94e90b556e66c1e9ab23c419200977e09270;hp=745f7cbc1aa9ed5e4ead003cd45d5d330c7dc55c;hpb=dfe4228c4a76cbb35c6074819da67060cbcd4074;p=privoxy.git
diff --git a/parsers.c b/parsers.c
index 745f7cbc..f313f4f8 100644
--- a/parsers.c
+++ b/parsers.c
@@ -1,11 +1,10 @@
-const char parsers_rcs[] = "$Id: parsers.c,v 1.306 2016/01/16 12:33:36 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/parsers.c,v $
*
* Purpose : Declares functions to parse/crunch headers and pages.
*
- * Copyright : Written by and Copyright (C) 2001-2016 the
+ * Copyright : Written by and Copyright (C) 2001-2017 the
* Privoxy team. http://www.privoxy.org/
*
* Based on the Internet Junkbuster originally written
@@ -90,8 +89,6 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.306 2016/01/16 12:33:36 fabiankei
#include "strptime.h"
#endif
-const char parsers_h_rcs[] = PARSERS_H_VERSION;
-
static char *get_header_line(struct iob *iob);
static jb_err scan_headers(struct client_state *csp);
static jb_err header_tagger(struct client_state *csp, char *header);
@@ -259,6 +256,7 @@ static const add_header_func_ptr add_server_headers[] = {
* Parameters :
* 1 : fd = file descriptor of the socket to read
* 2 : iob = The I/O buffer to flush, usually csp->iob.
+ * 3 : delay = Number of milliseconds to delay the writes
*
* Returns : On success, the number of bytes written are returned (zero
* indicates nothing was written). On error, -1 is returned,
@@ -268,7 +266,7 @@ static const add_header_func_ptr add_server_headers[] = {
* file, the results are not portable.
*
*********************************************************************/
-long flush_socket(jb_socket fd, struct iob *iob)
+long flush_socket(jb_socket fd, struct iob *iob, unsigned int delay)
{
long len = iob->eod - iob->cur;
@@ -277,7 +275,7 @@ long flush_socket(jb_socket fd, struct iob *iob)
return(0);
}
- if (write_socket(fd, iob->cur, (size_t)len))
+ if (write_socket_delayed(fd, iob->cur, (size_t)len, delay))
{
return(-1);
}
@@ -387,7 +385,7 @@ jb_err add_to_iob(struct iob *iob, const size_t buffer_limit, char *src, long n)
void clear_iob(struct iob *iob)
{
free(iob->buf);
- memset(iob, '\0', sizeof(*iob));;
+ memset(iob, '\0', sizeof(*iob));
}
@@ -421,8 +419,13 @@ jb_err decompress_iob(struct client_state *csp)
int status; /* return status of the inflate() call */
z_stream zstr; /* used by calls to zlib */
+#ifdef FUZZ
+ assert(csp->iob->cur - csp->iob->buf >= 0);
+ assert(csp->iob->eod - csp->iob->cur >= 0);
+#else
assert(csp->iob->cur - csp->iob->buf > 0);
assert(csp->iob->eod - csp->iob->cur > 0);
+#endif
bufsize = csp->iob->size;
skip_size = (size_t)(csp->iob->cur - csp->iob->buf);
@@ -718,7 +721,7 @@ jb_err decompress_iob(struct client_state *csp)
* Make sure the new uncompressed iob obeys some minimal
* consistency conditions.
*/
- if ((csp->iob->buf < csp->iob->cur)
+ if ((csp->iob->buf <= csp->iob->cur)
&& (csp->iob->cur <= csp->iob->eod)
&& (csp->iob->eod <= csp->iob->buf + csp->iob->size))
{
@@ -1811,7 +1814,9 @@ static jb_err client_keep_alive(struct client_state *csp, char **header)
static jb_err get_content_length(const char *header_value, unsigned long long *length)
{
#ifdef _WIN32
- assert(sizeof(unsigned long long) > 4);
+#if SIZEOF_LONG_LONG < 8
+#error sizeof(unsigned long long) too small
+#endif
if (1 != sscanf(header_value, "%I64u", length))
#else
if (1 != sscanf(header_value, "%llu", length))
@@ -3800,7 +3805,8 @@ static jb_err server_proxy_connection_adder(struct client_state *csp)
* Function : client_connection_header_adder
*
* Description : Adds a proper "Connection:" header to csp->headers
- * unless the header was already present. Called from `sed'.
+ * unless the header was already present or it's a
+ * CONNECT request. Called from `sed'.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
@@ -3819,10 +3825,20 @@ static jb_err client_connection_header_adder(struct client_state *csp)
return JB_ERR_OK;
}
+ /*
+ * In case of CONNECT requests "Connection: close" is implied,
+ * but actually setting the header has been reported to cause
+ * problems with some forwarding proxies that close the
+ * connection prematurely.
+ */
+ if (csp->http->ssl != 0)
+ {
+ return JB_ERR_OK;
+ }
+
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
&& !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
- && (csp->http->ssl == 0)
&& !strcmpic(csp->http->ver, "HTTP/1.1"))
{
csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
@@ -4313,7 +4329,13 @@ static jb_err parse_header_time(const char *header_time, time_t *result)
time_t result2;
tm = gmtime(result);
- strftime(recreated_date, sizeof(recreated_date), time_formats[i], tm);
+ if (!strftime(recreated_date, sizeof(recreated_date),
+ time_formats[i], tm))
+ {
+ log_error(LOG_LEVEL_ERROR, "Failed to recreate date '%s' with '%s'.",
+ header_time, time_formats[i]);
+ continue;
+ }
memset(&gmt, 0, sizeof(gmt));
if (NULL == strptime(recreated_date, time_formats[i], &gmt))
{
@@ -4622,7 +4644,14 @@ static jb_err handle_conditional_hide_referrer_parameter(char **header,
static void create_content_length_header(unsigned long long content_length,
char *header, size_t buffer_length)
{
+#ifdef _WIN32
+#if SIZEOF_LONG_LONG < 8
+#error sizeof(unsigned long long) too small
+#endif
+ snprintf(header, buffer_length, "Content-Length: %I64u", content_length);
+#else
snprintf(header, buffer_length, "Content-Length: %llu", content_length);
+#endif
}