-const char parsers_rcs[] = "$Id: parsers.c,v 1.241 2012/03/04 11:47:54 fabiankeil Exp $";
+const char parsers_rcs[] = "$Id: parsers.c,v 1.244 2012/03/09 16:23:50 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/parsers.c,v $
for (job = joblist; NULL != job; job = job->next)
{
matches = pcrs_execute(job, *header, size, &newheader, &size);
- if ( 0 < matches )
+ if (0 < matches)
{
current_hits += matches;
log_error(LOG_LEVEL_HEADER, "Transforming \"%s\" to \"%s\"", *header, newheader);
freez(*header);
*header = newheader;
}
- else if ( 0 == matches )
+ else if (0 == matches)
{
/* Filter doesn't change header */
freez(newheader);
* 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.
+ * Returns : JB_ERR_OK on success.
*
*********************************************************************/
static jb_err server_connection(struct client_state *csp, char **header)
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
&& !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
#endif
- )
+ )
{
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE))
{
char *old_header = *header;
- *header = strdup("Connection: close");
- if (header == NULL)
- {
- return JB_ERR_MEMORY;
- }
+ *header = strdup_or_die("Connection: close");
log_error(LOG_LEVEL_HEADER, "Replaced: \'%s\' with \'%s\'", old_header, *header);
freez(old_header);
}
* 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.
+ * Returns : JB_ERR_OK on success.
*
*********************************************************************/
static jb_err client_connection(struct client_state *csp, char **header)
{
char *old_header = *header;
- *header = strdup("Connection: keep-alive");
- if (header == NULL)
- {
- return JB_ERR_MEMORY;
- }
+ *header = strdup_or_die("Connection: keep-alive");
log_error(LOG_LEVEL_HEADER,
"Replaced: \'%s\' with \'%s\'", old_header, *header);
freez(old_header);
{
char *old_header = *header;
- *header = strdup(connection_close);
- if (header == NULL)
- {
- return JB_ERR_MEMORY;
- }
+ *header = strdup_or_die(connection_close);
log_error(LOG_LEVEL_HEADER,
"Replaced: \'%s\' with \'%s\'", old_header, *header);
freez(old_header);
if ((csp->content_type & CT_TEXT) || (csp->action->flags & ACTION_FORCE_TEXT_MODE))
{
freez(*header);
- *header = strdup("Content-Type: ");
+ *header = strdup_or_die("Content-Type: ");
string_append(header, csp->action->string[ACTION_STRING_CONTENT_TYPE]);
if (header == NULL)
newval = csp->action->string[ACTION_STRING_LAST_MODIFIED];
- if (0 == strcmpic(newval, "block") )
+ if (0 == strcmpic(newval, "block"))
{
/*
* Blocking Last-Modified header. Useless but why not.
newval = csp->action->string[ACTION_STRING_LANGUAGE];
- if ((newval == NULL) || (0 == strcmpic(newval, "block")) )
+ if ((newval == NULL) || (0 == strcmpic(newval, "block")))
{
/*
* Blocking Accept-Language header
/*
* Are we blocking the e-mail address?
*/
- if ((newval == NULL) || (0 == strcmpic(newval, "block")) )
+ if ((newval == NULL) || (0 == strcmpic(newval, "block")))
{
log_error(LOG_LEVEL_HEADER, "crunched From!");
return JB_ERR_OK;
*csp->http->hostport == ' ' || *csp->http->hostport == '\0')
{
- if (NULL == (p = strdup((*header)+6)))
- {
- return JB_ERR_MEMORY;
- }
+ p = strdup_or_die((*header)+6);
chomp(p);
- if (NULL == (q = strdup(p)))
- {
- freez(p);
- return JB_ERR_MEMORY;
- }
+ q = strdup_or_die(p);
freez(csp->http->hostport);
csp->http->hostport = p;
const char *newval;
char * endptr;
- if ( 0 == strcmpic(*header, "If-Modified-Since: Wed, 08 Jun 1955 12:00:00 GMT"))
+ if (0 == strcmpic(*header, "If-Modified-Since: Wed, 08 Jun 1955 12:00:00 GMT"))
{
/*
* The client got an error message because of a temporary problem,
*********************************************************************/
jb_err client_x_filter(struct client_state *csp, char **header)
{
- if ( 0 == strcmpic(*header, "X-Filter: No"))
+ if (0 == strcmpic(*header, "X-Filter: No"))
{
if (!(csp->config->feature_flags & RUNTIME_FEATURE_HTTP_TOGGLE))
{
* Function : client_range
*
* Description : Removes Range, Request-Range and If-Range headers if
- * content filtering is enabled. If the client's version
- * of the document has been altered by Privoxy, the server
- * could interpret the range differently than the client
- * intended in which case the user could end up with
- * corrupted content.
+ * content filtering is enabled and the range doesn't
+ * start at byte 0.
+ *
+ * If the client's version of the document has been
+ * altered by Privoxy, the server could interpret the
+ * range differently than the client intended in which
+ * case the user could end up with corrupted content.
+ *
+ * If the range starts at byte 0 this isn't an issue
+ * so the header can pass. Partial requests like this
+ * are used to render preview images for videos without
+ * downloading the whole video.
+ *
+ * While HTTP doesn't require that range requests are
+ * honoured and the client could simply abort the download
+ * after receiving a sufficient amount of data, various
+ * clients don't handle complete responses to range
+ * requests gracefully and emit misleading error messages
+ * instead.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
*********************************************************************/
static jb_err client_range(struct client_state *csp, char **header)
{
- if (content_filters_enabled(csp->action))
+ if (content_filters_enabled(csp->action)
+ && (0 != strncmpic(strstr(*header, ":"), ": bytes=0-", 10)))
{
log_error(LOG_LEVEL_HEADER, "Content filtering is enabled."
" Crunching: \'%s\' to prevent range-mismatch problems.", *header);
return JB_ERR_OK;
}
- if ( !csp->http->hostport || !*(csp->http->hostport))
+ if (!csp->http->hostport || !*(csp->http->hostport))
{
/* XXX: When does this happen and why is it OK? */
log_error(LOG_LEVEL_INFO, "Weirdness in client_host_adder detected and ignored.");
/*
* remove 'user:pass@' from 'proto://user:pass@host'
*/
- if ( (p = strchr( csp->http->hostport, '@')) != NULL )
+ if ((p = strchr( csp->http->hostport, '@')) != NULL)
{
p++;
}
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
&& !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
#endif
- )
+ )
{
log_error(LOG_LEVEL_HEADER, "A HTTP/1.1 response "
"without Connection header implies keep-alive.");
* the "Host:" header)
* 2 : http = storage for the result (host, port and hostport).
*
- * Returns : JB_ERR_MEMORY in case of memory problems,
+ * Returns : JB_ERR_MEMORY (or terminates) in case of memory problems,
* JB_ERR_PARSE if the host header couldn't be found,
* JB_ERR_OK otherwise.
*
return JB_ERR_PARSE;
}
- p = strdup(host);
- if (NULL == p)
- {
- log_error(LOG_LEVEL_ERROR, "Out of memory while parsing \"Host:\" header");
- return JB_ERR_MEMORY;
- }
+ p = strdup_or_die(host);
chomp(p);
- if (NULL == (q = strdup(p)))
- {
- freez(p);
- log_error(LOG_LEVEL_ERROR, "Out of memory while parsing \"Host:\" header");
- return JB_ERR_MEMORY;
- }
+ q = strdup_or_die(p);
freez(http->hostport);
http->hostport = p;
static jb_err handle_conditional_hide_referrer_parameter(char **header,
const char *host, const int parameter_conditional_block)
{
- char *referer = strdup(*header);
+ char *referer = strdup_or_die(*header);
const size_t hostlength = strlen(host);
const char *referer_url = NULL;
- if (NULL == referer)
- {
- freez(*header);
- return JB_ERR_MEMORY;
- }
-
/* referer begins with 'Referer: http[s]://' */
if ((hostlength+17) < strlen(referer))
{