X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=parsers.c;h=c2020c75f25398420f2b9d41594210dcb3609403;hb=70b9ed04dec24ef32a00a14dbe2a1556275e9bd3;hp=6b2df76bf36a2889cbd2944f06bd86e327254620;hpb=e12300438d6e21f385f659792ac7ee60bf2e9b26;p=privoxy.git diff --git a/parsers.c b/parsers.c index 6b2df76b..c2020c75 100644 --- a/parsers.c +++ b/parsers.c @@ -1,4 +1,4 @@ -const char parsers_rcs[] = "$Id: parsers.c,v 1.199 2009/07/18 12:20:05 fabiankeil Exp $"; +const char parsers_rcs[] = "$Id: parsers.c,v 1.209 2009/09/06 14:11:06 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/parsers.c,v $ @@ -158,6 +158,7 @@ static jb_err server_save_content_length(struct client_state *csp, char **header static jb_err server_keep_alive(struct client_state *csp, char **header); static jb_err server_proxy_connection(struct client_state *csp, char **header); static jb_err client_keep_alive(struct client_state *csp, char **header); +static jb_err client_save_content_length(struct client_state *csp, char **header); #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ static jb_err client_host_adder (struct client_state *csp); @@ -204,6 +205,7 @@ static const struct parsers client_patterns[] = { { "if-modified-since:", 18, client_if_modified_since }, #ifdef FEATURE_CONNECTION_KEEP_ALIVE { "Keep-Alive:", 11, client_keep_alive }, + { "Content-Length:", 15, client_save_content_length }, #else { "Keep-Alive:", 11, crumble }, #endif @@ -586,7 +588,7 @@ jb_err decompress_iob(struct client_state *csp) assert(bufsize >= skip_size); memcpy(buf, csp->iob->buf, skip_size); - zstr.avail_out = bufsize - skip_size; + zstr.avail_out = (uInt)(bufsize - skip_size); zstr.next_out = (Bytef *)buf + skip_size; /* Try to decompress the whole stream in one shot. */ @@ -644,7 +646,7 @@ jb_err decompress_iob(struct client_state *csp) * buffer, which may be in a location different from * the old one. */ - zstr.avail_out += bufsize - oldbufsize; + zstr.avail_out += (uInt)(bufsize - oldbufsize); zstr.next_out = (Bytef *)tmpbuf + bufsize - zstr.avail_out; /* @@ -653,7 +655,6 @@ jb_err decompress_iob(struct client_state *csp) */ assert(zstr.avail_out == tmpbuf + bufsize - (char *)zstr.next_out); assert((char *)zstr.next_out == tmpbuf + ((char *)oldnext_out - buf)); - assert(zstr.avail_out > 0U); buf = tmpbuf; } @@ -1751,6 +1752,76 @@ static jb_err client_keep_alive(struct client_state *csp, char **header) return JB_ERR_OK; } + + +/********************************************************************* + * + * Function : get_content_length + * + * Description : Gets the content length specified in a + * Content-Length header. + * + * Parameters : + * 1 : header = The Content-Length header. + * 2 : length = Storage to return the value. + * + * Returns : JB_ERR_OK on success, or + * JB_ERR_PARSE if no value is recognized. + * + *********************************************************************/ +static jb_err get_content_length(const char *header, unsigned long long *length) +{ + assert(header[14] == ':'); + +#ifdef _WIN32 + assert(sizeof(unsigned long long) > 4); + if (1 != sscanf(header+14, ": %I64u", length)) +#else + if (1 != sscanf(header+14, ": %llu", length)) +#endif + { + return JB_ERR_PARSE; + } + + return JB_ERR_OK; +} + + +/********************************************************************* + * + * Function : client_save_content_length + * + * Description : Save the Content-Length sent by the client. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : header = On input, pointer to header to modify. + * On output, pointer to the modified header, or NULL + * to remove the header. This function frees the + * original string if necessary. + * + * Returns : JB_ERR_OK on success, or + * JB_ERR_MEMORY on out-of-memory error. + * + *********************************************************************/ +static jb_err client_save_content_length(struct client_state *csp, char **header) +{ + unsigned long long content_length = 0; + + assert(*(*header+14) == ':'); + + if (JB_ERR_OK != get_content_length(*header, &content_length)) + { + log_error(LOG_LEVEL_ERROR, "Crunching invalid header: %s", *header); + freez(*header); + } + else + { + csp->expected_client_content_length = content_length; + } + + return JB_ERR_OK; +} #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ @@ -1802,7 +1873,6 @@ static jb_err client_connection(struct client_state *csp, char **header) "Replaced: \'%s\' with \'%s\'", old_header, *header); freez(old_header); } - csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE; } else { @@ -1812,17 +1882,18 @@ static jb_err client_connection(struct client_state *csp, char **header) *header); csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE; } -#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ } - else + else if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)) { -#ifdef FEATURE_CONNECTION_KEEP_ALIVE log_error(LOG_LEVEL_HEADER, "Keeping the client header '%s' around. " "The server connection will be kept alive if possible.", *header); csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE; -#else +#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ + } + else + { char *old_header = *header; *header = strdup(connection_close); @@ -1833,7 +1904,6 @@ static jb_err client_connection(struct client_state *csp, char **header) log_error(LOG_LEVEL_HEADER, "Replaced: \'%s\' with \'%s\'", old_header, *header); freez(old_header); -#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ } /* Signal client_connection_adder() to return early. */ @@ -2219,11 +2289,7 @@ static jb_err server_save_content_length(struct client_state *csp, char **header assert(*(*header+14) == ':'); -#ifdef _WIN32 - if (1 != sscanf(*header+14, ": %I64u", &content_length)) -#else - if (1 != sscanf(*header+14, ": %llu", &content_length)) -#endif + if (JB_ERR_OK != get_content_length(*header, &content_length)) { log_error(LOG_LEVEL_ERROR, "Crunching invalid header: %s", *header); freez(*header); @@ -3667,8 +3733,7 @@ static jb_err server_http(struct client_state *csp, char **header) * Function : server_set_cookie * * Description : Handle the server "cookie" header properly. - * Log cookie to the jar file. Then "crunch", - * accept or rewrite it to a session cookie. + * Crunch, accept or rewrite it to a session cookie. * Called from `sed'. * * TODO: Allow the user to specify a new expiration @@ -3746,6 +3811,17 @@ static jb_err server_set_cookie(struct client_state *csp, char **header) { char *expiration_date = cur_tag + 8; /* Skip "[Ee]xpires=" */ + if ((expiration_date[0] == '"') + && (expiration_date[1] != '\0')) + { + /* + * Skip quotation mark. RFC 2109 10.1.2 seems to hint + * that the expiration date isn't supposed to be quoted, + * but some servers do it anyway. + */ + expiration_date++; + } + /* Did we detect the date properly? */ if (JB_ERR_OK != parse_header_time(expiration_date, &cookie_time)) {