- Re-enabled Netscape 200/404 bug workaround in block_url():
[privoxy.git] / filters.c
index 57ad34c..309aca3 100644 (file)
--- a/filters.c
+++ b/filters.c
@@ -1,4 +1,4 @@
-const char filters_rcs[] = "$Id: filters.c,v 1.37 2001/10/22 15:33:56 david__schmidt Exp $";
+const char filters_rcs[] = "$Id: filters.c,v 1.40 2001/10/26 17:34:17 oes Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/filters.c,v $
@@ -15,10 +15,10 @@ const char filters_rcs[] = "$Id: filters.c,v 1.37 2001/10/22 15:33:56 david__sch
  *                IJBSWA team.  http://ijbswa.sourceforge.net
  *
  *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                by and Copyright (C) 1997 Anonymous Coders and
  *                Junkbusters Corporation.  http://www.junkbusters.com
  *
- *                This program is free software; you can redistribute it 
+ *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
  *                Public License as published by the Free Software
  *                Foundation; either version 2 of the License, or (at
@@ -38,6 +38,16 @@ const char filters_rcs[] = "$Id: filters.c,v 1.37 2001/10/22 15:33:56 david__sch
  *
  * Revisions   :
  *    $Log: filters.c,v $
+ *
+ *    Revision 1.39  2001/10/25 03:40:48  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.38  2001/10/23 21:32:33  jongfoster
+ *    Adding error-checking to selected functions
+ *
  *    Revision 1.37  2001/10/22 15:33:56  david__schmidt
  *    Special-cased OS/2 out of the Netscape-abort-on-404-in-js problem in
  *    filters.c.  Added a FIXME in front of the offending code.  I'll gladly
@@ -316,11 +326,17 @@ const char filters_rcs[] = "$Id: filters.c,v 1.37 2001/10/22 15:33:56 david__sch
 #include <assert.h>
 
 #ifndef _WIN32
+#ifndef __OS2__
 #include <unistd.h>
+#endif /* ndef __OS2__ */
 #include <netinet/in.h>
 #else
 #include <winsock2.h>
-#endif
+#endif /* ndef _WIN32 */
+
+#ifdef __OS2__
+#include <utils.h>
+#endif /* def __OS2__ */
 
 #include "project.h"
 #include "filters.h"
@@ -516,7 +532,7 @@ int match_portlist(const char *portlist, int port)
    {
       *next++ = '\0';
    }
-   
+
    /*
     * Loop through all items, checking for match
     */
@@ -545,8 +561,8 @@ int match_portlist(const char *portlist, int port)
             free(portlist_copy);
             return(1);
          }
-           
-      }      
+
+      }
 
       /*
        * Jump to next item
@@ -561,7 +577,7 @@ int match_portlist(const char *portlist, int port)
          *next++ = '\0';
       }
    }
-   
+
    free(portlist_copy);
    return 0;
 
@@ -587,7 +603,7 @@ struct http_response *block_url(struct client_state *csp)
 #endif /* def FEATURE_IMAGE_BLOCKING */
    struct http_response *rsp;
 
-   /* 
+   /*
     * If it's not blocked, don't block it ;-)
     */
    if ((csp->action->flags & ACTION_BLOCK) == 0)
@@ -595,7 +611,7 @@ struct http_response *block_url(struct client_state *csp)
       return NULL;
    }
 
-   /* 
+   /*
     * Else, prepare a response
     */
    if (NULL == (rsp = alloc_http_response()))
@@ -664,47 +680,36 @@ struct http_response *block_url(struct client_state *csp)
             return cgi_error_memory();
          }
       }
-   }  
+   }
    else
 #endif /* def FEATURE_IMAGE_BLOCKING */
 
-   /* 
+   /*
     * Else, generate an HTML "blocked" message:
     */
    {
       jb_err err;
       struct map * exports;
-      
-      /* FIXME */
-#ifdef __EMX__
-      /*
-       * The entire OS/2 community will hit the stupid Netscape bug
-       * (all three of us! :-) so we'll just keep ourselves out
-       * of this contentious debate and special-case ourselves.
-       * The problem is... a this point in parsing, we don't know
-       * what the csp->http->user_agent is (yet).  So we can't use
-       * it to decide if we should work around the NS bug or not.
-       */
-      rsp->status = strdup("200 Request for blocked URL"); 
-#else
+
       /*
        * Workaround for stupid Netscape bug which prevents
        * pages from being displayed if loading a referenced
        * JavaScript or style sheet fails. So make it appear
        * as if it succeeded.
        */
-      if (csp->http->user_agent
-          && !strncmpic(csp->http->user_agent, "mozilla", 7)
-          && !strstr(csp->http->user_agent, "compatible")
-          && !strstr(csp->http->user_agent, "Opera"))
+      if ( NULL != (p = get_header_value(csp->headers, "User-Agent:"))
+           && !strncmpic(p, "mozilla", 7) /* Catch Netscape but */
+           && !strstr(p, "Gecko")         /* save Mozilla, */
+           && !strstr(p, "compatible")    /* MSIE */
+           && !strstr(p, "Opera"))        /* and Opera. */
       {
-         rsp->status = strdup("200 Request for blocked URL"); 
+         rsp->status = strdup("200 Request for blocked URL");
       }
       else
       {
-         rsp->status = strdup("404 Request for blocked URL"); 
+         rsp->status = strdup("404 Request for blocked URL");
       }
-#endif /* __EMX__ */
+
       if (rsp->status == NULL)
       {
          free_http_response(rsp);
@@ -781,7 +786,7 @@ struct http_response *trust_url(struct client_state *csp)
       return NULL;
    }
 
-   /* 
+   /*
     * Else, prepare a response:
     */
    if (NULL == (rsp = alloc_http_response()))
@@ -796,7 +801,7 @@ struct http_response *trust_url(struct client_state *csp)
       return cgi_error_memory();
    }
 
-   /* 
+   /*
     * Export the host, port, and referrer information
     */
    err = map(exports, "hostport", 1, csp->http->hostport, 1)
@@ -804,10 +809,10 @@ struct http_response *trust_url(struct client_state *csp)
       || map(exports, "hostport-html", 1, html_encode(csp->http->hostport), 0)
       || map(exports, "path-html", 1, html_encode(csp->http->path), 0);
 
-   if (csp->referrer && strlen(csp->referrer) > 9)
+   if (NULL != (p = get_header_value(csp->headers, "Referer:")))
    {
-      err = err || map(exports, "referrer", 1, csp->referrer + 9, 1);
-      err = err || map(exports, "referrer-html", 1, html_encode(csp->referrer + 9), 0);
+      err = err || map(exports, "referrer", 1, p, 1);
+      err = err || map(exports, "referrer-html", 1, html_encode(p), 0);
    }
    else
    {
@@ -920,7 +925,7 @@ struct http_response *redirect_url(struct client_state *csp)
    p = q = csp->http->path;
    log_error(LOG_LEVEL_REDIRECTS, "checking path for redirects: %s", p);
 
-   /* 
+   /*
     * find the last URL encoded in the request
     */
    while ((p = strstr(p, "http://")))
@@ -928,7 +933,7 @@ struct http_response *redirect_url(struct client_state *csp)
       q = p++;
    }
 
-   /* 
+   /*
     * if there was any, generate and return a HTTP redirect
     */
    if (q != csp->http->path)
@@ -967,7 +972,7 @@ struct http_response *redirect_url(struct client_state *csp)
  *                using either the info from a previous +image action
  *                or, #ifdef FEATURE_IMAGE_DETECT_MSIE, the info from
  *                the browser's accept header.
- *                
+ *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
  *
@@ -978,17 +983,23 @@ struct http_response *redirect_url(struct client_state *csp)
 int is_imageurl(struct client_state *csp)
 {
 #ifdef FEATURE_IMAGE_DETECT_MSIE
-   if ((csp->accept_types 
-       & (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE|ACCEPT_TYPE_MSIE_HTML))
-       == (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE))
-   {
-      return 1;
-   }
-   else if ((csp->accept_types 
-       & (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_IMAGE|ACCEPT_TYPE_MSIE_HTML))
-       == (ACCEPT_TYPE_IS_MSIE|ACCEPT_TYPE_MSIE_HTML))
+   char *tmp;
+
+   tmp = get_header_value(csp->headers, "User-Agent:");
+   if (tmp && strstr(tmp, "MSIE"))
    {
-      return 0;
+      tmp = get_header_value(csp->headers, "Accept:");
+      if (tmp && strstr(tmp, "image/gif"))
+      {
+         /* Client will accept HTML.  If this seems counterintuitive,
+          * blame Microsoft.
+          */
+         return(0);
+      }
+      else
+      {
+         return(1);
+      }
    }
 #endif /* def FEATURE_IMAGE_DETECT_MSIE */
 
@@ -1071,7 +1082,7 @@ int is_untrusted_url(struct client_state *csp)
    freez(url->dbuf);
    freez(url->dvec);
 
-   if ((csp->referrer == NULL)|| (strlen(csp->referrer) <= 9))
+   if (NULL == (h = get_header_value(csp->headers, "Referer:")))
    {
       /* no referrer was supplied */
       return(1);
@@ -1083,7 +1094,7 @@ int is_untrusted_url(struct client_state *csp)
 
    p = NULL;
    p = strsav(p, "GET ");
-   p = strsav(p, csp->referrer + 9);   /* skip over "Referer: " */
+   p = strsav(p, h);
    p = strsav(p, " HTTP/1.0");
 
    parse_http_request(p, rhttp, csp);
@@ -1168,7 +1179,7 @@ int is_untrusted_url(struct client_state *csp)
  * Function    :  pcrs_filter_response
  *
  * Description :  Apply all the pcrs jobs from the joblist (re_filterfile)
- *                to the text buffer that's been accumulated in 
+ *                to the text buffer that's been accumulated in
  *                csp->iob->buf and set csp->content_length to the modified
  *                size and raise the CSP_FLAG_MODIFIED flag if appropriate.
  *
@@ -1177,7 +1188,7 @@ int is_untrusted_url(struct client_state *csp)
  *
  * Returns     :  a pointer to the (newly allocated) modified buffer.
  *                or NULL in case something went wrong
- *                
+ *
  *********************************************************************/
 char *pcrs_filter_response(struct client_state *csp)
 {
@@ -1237,7 +1248,7 @@ char *pcrs_filter_response(struct client_state *csp)
 
    log_error(LOG_LEVEL_RE_FILTER, " produced %d hits (new size %d).", hits, size);
 
-   /* 
+   /*
     * If there were no hits, destroy our copy and let
     * chat() use the original in csp->iob
     */
@@ -1260,7 +1271,7 @@ char *pcrs_filter_response(struct client_state *csp)
  *
  * Function    :  gif_deanimate_response
  *
- * Description :  Deanimate the GIF image that has been accumulated in 
+ * Description :  Deanimate the GIF image that has been accumulated in
  *                csp->iob->buf, set csp->content_length to the modified
  *                size and raise the CSP_FLAG_MODIFIED flag.
  *
@@ -1269,7 +1280,7 @@ char *pcrs_filter_response(struct client_state *csp)
  *
  * Returns     :  a pointer to the (newly allocated) modified buffer.
  *                or NULL in case something went wrong.
- *                
+ *
  *********************************************************************/
 char *gif_deanimate_response(struct client_state *csp)
 {
@@ -1318,7 +1329,7 @@ char *gif_deanimate_response(struct client_state *csp)
       free(in);
       free(out);
       return(p);
-   }  
+   }
 
 }
 
@@ -1337,7 +1348,7 @@ char *gif_deanimate_response(struct client_state *csp)
  * Returns     :  The new size, i.e. the number of bytes from buffer which
  *                are occupied by the stripped body, or 0 in case something
  *                went wrong
- *                
+ *
  *********************************************************************/
 int remove_chunked_transfer_coding(char *buffer, const size_t size)
 {
@@ -1363,7 +1374,7 @@ int remove_chunked_transfer_coding(char *buffer, const size_t size)
       }
       newsize += chunksize;
       from_p += 2;
-      
+
       memmove(to_p, from_p, (size_t) chunksize);
       to_p = buffer + newsize;
       from_p += chunksize + 2;
@@ -1395,7 +1406,7 @@ int remove_chunked_transfer_coding(char *buffer, const size_t size)
  * Returns     :  N/A
  *
  *********************************************************************/
-void url_actions(struct http_request *http, 
+void url_actions(struct http_request *http,
                  struct client_state *csp)
 {
    struct file_list *fl;
@@ -1427,8 +1438,8 @@ void url_actions(struct http_request *http,
  * Returns     :  N/A
  *
  *********************************************************************/
-void apply_url_actions(struct current_action_spec *action, 
-                       struct http_request *http, 
+void apply_url_actions(struct current_action_spec *action,
+                       struct http_request *http,
                        struct url_actions *b)
 {
    struct url_spec url[1];
@@ -1552,7 +1563,7 @@ const struct forward_spec * forward_url(struct http_request *http,
  *                them).
  *
  * FIXME: Returning a structure is horribly inefficient, please can
- *        this structure take a (struct url_spec * dest) 
+ *        this structure take a (struct url_spec * dest)
  *        pointer instead?
  *
  *********************************************************************/
@@ -1623,7 +1634,7 @@ struct url_spec dsplit(char *domain)
  *
  * Function    :  simple_domaincmp
  *
- * Description :  Domain-wise Compare fqdn's.  The comparison is 
+ * Description :  Domain-wise Compare fqdn's.  The comparison is
  *                both left- and right-anchored.  The individual
  *                domain names are compared with simplematch().
  *                This is only used by domaincmp.