Introduced modular filters
[privoxy.git] / project.h
index 472222d..8625265 100644 (file)
--- a/project.h
+++ b/project.h
@@ -1,6 +1,6 @@
 #ifndef PROJECT_H_INCLUDED
 #define PROJECT_H_INCLUDED
-#define PROJECT_H_VERSION "$Id: project.h,v 1.38 2001/10/23 21:19:04 jongfoster Exp $"
+#define PROJECT_H_VERSION "$Id: project.h,v 1.54 2002/03/09 20:03:52 jongfoster Exp $"
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/project.h,v $
  *
  * Revisions   :
  *    $Log: project.h,v $
+ *    Revision 1.54  2002/03/09 20:03:52  jongfoster
+ *    - Making various functions return int rather than size_t.
+ *      (Undoing a recent change).  Since size_t is unsigned on
+ *      Windows, functions like read_socket that return -1 on
+ *      error cannot return a size_t.
+ *
+ *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
+ *      crashes, and also frequently caused JB to jump to 100%
+ *      CPU and stay there.  (Because it thought it had just
+ *      read ((unsigned)-1) == 4Gb of data...)
+ *
+ *    - The signature of write_socket has changed, it now simply
+ *      returns success=0/failure=nonzero.
+ *
+ *    - Trying to get rid of a few warnings --with-debug on
+ *      Windows, I've introduced a new type "jb_socket".  This is
+ *      used for the socket file descriptors.  On Windows, this
+ *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
+ *      an int.  The error value can't be -1 any more, so it's
+ *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
+ *      Windows it maps to the #define INVALID_SOCKET.)
+ *
+ *    - The signature of bind_port has changed.
+ *
+ *    Revision 1.53  2002/03/08 16:48:55  oes
+ *    Added FEATURE_NO_GIFS and BUILTIN_IMAGE_MIMETYPE
+ *
+ *    Revision 1.52  2002/03/07 03:46:17  oes
+ *    Fixed compiler warnings
+ *
+ *    Revision 1.51  2002/03/05 04:52:42  oes
+ *    Deleted non-errlog debugging code
+ *
+ *    Revision 1.50  2002/03/04 19:32:07  oes
+ *    Changed default port to 8118
+ *
+ *    Revision 1.49  2002/03/04 18:28:55  oes
+ *    Deleted PID_FILE_NAME
+ *
+ *    Revision 1.48  2002/03/03 14:50:40  oes
+ *    Fixed CLF logging: Added ocmd member for client's request to struct http_request
+ *
+ *    Revision 1.47  2002/02/20 23:15:13  jongfoster
+ *    Parsing functions now handle out-of-memory gracefully by returning
+ *    an error code.
+ *
+ *    Revision 1.46  2002/01/17 21:06:09  jongfoster
+ *    Now #defining the URLs of the config interface
+ *
+ *    Minor changes to struct http_request and struct url_spec due to
+ *    standardizing that struct http_request is used to represent a URL, and
+ *    struct url_spec is used to represent a URL pattern.  (Before, URLs were
+ *    represented as seperate variables and a partially-filled-in url_spec).
+ *
+ *    Revision 1.45  2002/01/09 14:33:27  oes
+ *    Added HOSTENT_BUFFER_SIZE
+ *
+ *    Revision 1.44  2001/12/30 14:07:32  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.43  2001/11/22 21:57:51  jongfoster
+ *    Making action_spec->flags into an unsigned long rather than just an
+ *    unsigned int.
+ *    Adding ACTION_NO_COOKIE_KEEP
+ *
+ *    Revision 1.42  2001/11/05 21:42:41  steudten
+ *    Include DBG() macro.
+ *
+ *    Revision 1.41  2001/10/28 19:12:06  jongfoster
+ *    Adding ijb_toupper()
+ *
+ *    Revision 1.40  2001/10/26 17:40:47  oes
+ *    Moved ijb_isspace and ijb_tolower to project.h
+ *    Removed http->user_agent, csp->referrer and csp->accept_types
+ *
+ *    Revision 1.39  2001/10/25 03:45:02  david__schmidt
+ *    Adding a (void*) cast to freez() because Visual Age C++ won't expand the
+ *    macro when called with a cast; so moving the cast to the macro def'n
+ *    seems to both eliminate compiler warnings (on darwin and OS/2, anyway) and
+ *    doesn't make macro expansion complain.  Hope this works for everyone else
+ *    too...
+ *
  *    Revision 1.38  2001/10/23 21:19:04  jongfoster
  *    New error-handling support: jb_err type and JB_ERR_xxx constants
  *    CGI functions now return a jb_err, and their parameters map is const.
 #include "amiga.h"
 #endif /* def AMIGA */
 
+#ifdef _WIN32
+/*
+ * I don't want to have to #include all this just for the declaration
+ * of SOCKET.  However, it looks like we have to...
+ */
+#include <windows.h>
+#endif
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/*
+ * The type used by sockets.  On UNIX it's an int.  Microsoft decided to
+ * make it an unsigned.
+ */
+#ifdef _WIN32
+typedef SOCKET jb_socket;
+#define JB_INVALID_SOCKET INVALID_SOCKET
+#else /* ndef _WIN32 */
+typedef int jb_socket;
+#define JB_INVALID_SOCKET (-1)
+#endif /* ndef _WIN32 */
+
 
 /*
  * Error codes.  Functions returning these should return a jb_err
@@ -364,6 +472,20 @@ typedef int jb_err;
  */
 #define freez(X)  { if(X) { free((void*)X); X = NULL ; } }
 
+
+/* Fix a problem with Solaris.  There should be no effect on other
+ * platforms.
+ * Solaris's isspace() is a macro which uses it's argument directly
+ * as an array index.  Therefore we need to make sure that high-bit
+ * characters generate +ve values, and ideally we also want to make
+ * the argument match the declared parameter type of "int".
+ *
+ * Note: Remember to #include <ctype.h> if you use these macros.
+ */
+#define ijb_toupper(__X) toupper((int)(unsigned char)(__X))
+#define ijb_tolower(__X) tolower((int)(unsigned char)(__X))
+#define ijb_isspace(__X) isspace((int)(unsigned char)(__X))  
+
 /*
  * Use for statically allocated buffers if you have no other choice.
  * Remember to check the length of what you write into the buffer
@@ -371,6 +493,16 @@ typedef int jb_err;
  */
 #define BUFFER_SIZE 5000
 
+/*
+ * Buffer size for capturing struct hostent data in the
+ * gethostby(name|addr)_r library calls. Since we don't
+ * loop over gethostbyname_r, the buffer must be sufficient
+ * to accomodate multiple IN A RRs, as used in DNS round robin
+ * load balancing. W3C's wwwlib uses 1K, so that should be
+ * good enough for us, too.
+ */
+#define HOSTENT_BUFFER_SIZE 1024
+
 /*
  * So you can say "while (FOREVER) { ...do something... }"
  */
@@ -378,8 +510,7 @@ typedef int jb_err;
 
 /* Default IP and port to listen on */
 #define HADDR_DEFAULT   "127.0.0.1"
-#define HADDR_PORT      8000
-
+#define HADDR_PORT      8118
 
 /* Forward defs for various structures */
 
@@ -421,6 +552,7 @@ struct map
 struct http_request
 {
    char *cmd;      /* Whole command line: method, URL, Version */
+   char *ocmd;     /* Backup of original cmd for CLF logging */
    char *gpc;      /* HTTP method: GET, POST, .. */
    char *url;      /* The URL */
    char *ver;      /* Protocol version */
@@ -434,20 +566,25 @@ struct http_request
 
    char *host_ip_addr_str; /* String with dotted decimal representation
                             * of host's IP. NULL before connect_to() */
-   char *user_agent;       /* Client's User-Agent: header value */
+
+   char  *dbuffer;     /* Buffer with '\0'-delimited domain name.           */
+   char **dvec;        /* List of pointers to the strings in dbuffer.       */
+   int    dcount;      /* How many parts to this domain? (length of dvec)   */
 };
 
-/* Response generated by CGI, blocker, or error handler */
+/* 
+ * Response generated by CGI, blocker, or error handler
+ */
 struct http_response
 {
-  char *status;           /* HTTP status (string)*/
+  char  *status;          /* HTTP status (string) */
   struct list headers[1]; /* List of header lines */
-  char *head;             /* Formatted http response head */
-  int   head_length;      /* Length of http response head */
-  char *body;             /* HTTP document body */
-  int   content_length;   /* Length of body, REQUIRED if binary body */
-  int   is_static;        /* Nonzero if the content will never change and
-                           * should be cached by the broser (e.g. images) */
+  char  *head;            /* Formatted http response head */
+  size_t head_length;     /* Length of http response head */
+  char  *body;            /* HTTP document body */
+  size_t content_length;  /* Length of body, REQUIRED if binary body */
+  int    is_static;       /* Nonzero if the content will never change and
+                           * should be cached by the brwoser (e.g. images) */
 };
 
 /* A URL pattern */
@@ -456,13 +593,11 @@ struct url_spec
    char  *spec;        /* The string which was parsed to produce this       */
                        /* url_spec.  Used for debugging or display only.    */
 
-   /* Hostname matching: */
-   char  *domain;      /* Fully qalified domain name (FQDN) pattern.        */
-                       /* May contain "*".                                  */
-   char  *dbuf;        /* Buffer with '\0'-delimited fqdn                   */
-   char **dvec;        /* Domain ptr vector into dbuf                       */
-   int    dcnt;        /* How many domains in fqdn?                         */
-   int    unanchored;  /* Bitmap - flags are ANCHOR_LEFT and ANCHOR_RIGHT   */
+   /* Hostname matching, or dbuffer == NULL to match all hosts */
+   char  *dbuffer;     /* Buffer with '\0'-delimited domain name.           */
+   char **dvec;        /* List of pointers to the strings in dbuffer.       */
+   int    dcount;      /* How many parts to this domain? (length of dvec)   */
+   int    unanchored;  /* Bitmap - flags are ANCHOR_LEFT and ANCHOR_RIGHT.  */
 
    /* Port matching: */
    int   port;         /* The port number, or 0 to match all ports.         */
@@ -476,9 +611,9 @@ struct url_spec
 #endif
 };
 #ifdef REGEX
-#define URL_SPEC_INITIALIZER { NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL }
+#define URL_SPEC_INITIALIZER { NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL }
 #else /* ifndef REGEX */
-#define URL_SPEC_INITIALIZER { NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0 }
+#define URL_SPEC_INITIALIZER { NULL, NULL, NULL, 0, 0, 0, NULL, 0 }
 #endif /* ndef REGEX */
 
 /* Constants for host part matching in URLs */
@@ -505,25 +640,25 @@ struct iob
 
 #define ACTION_MASK_ALL        (~0U)
 
-#define ACTION_MOST_COMPATIBLE 0x0000U
-
-#define ACTION_BLOCK           0x0001U
-#define ACTION_DEANIMATE       0x0002U
-#define ACTION_DOWNGRADE       0x0004U
-#define ACTION_FAST_REDIRECTS  0x0008U
-#define ACTION_FILTER          0x0010U
-#define ACTION_HIDE_FORWARDED  0x0020U
-#define ACTION_HIDE_FROM       0x0040U
-#define ACTION_HIDE_REFERER    0x0080U /* sic - follow HTTP, not English */
-#define ACTION_HIDE_USER_AGENT 0x0100U
-#define ACTION_IMAGE           0x0200U
-#define ACTION_IMAGE_BLOCKER   0x0400U
-#define ACTION_NO_COMPRESSION  0x0800U
-#define ACTION_NO_COOKIE_READ  0x1000U
-#define ACTION_NO_COOKIE_SET   0x2000U
-#define ACTION_NO_POPUPS       0x4000U
-#define ACTION_VANILLA_WAFER   0x8000U
-#define ACTION_LIMIT_CONNECT   0x010000U
+#define ACTION_MOST_COMPATIBLE 0x00000000UL
+
+#define ACTION_BLOCK           0x00000001UL
+#define ACTION_DEANIMATE       0x00000002UL
+#define ACTION_DOWNGRADE       0x00000004UL
+#define ACTION_FAST_REDIRECTS  0x00000008UL
+#define ACTION_HIDE_FORWARDED  0x00000010UL
+#define ACTION_HIDE_FROM       0x00000020UL
+#define ACTION_HIDE_REFERER    0x00000040UL /* sic - follow HTTP, not English */
+#define ACTION_HIDE_USER_AGENT 0x00000080UL
+#define ACTION_IMAGE           0x00000100UL
+#define ACTION_IMAGE_BLOCKER   0x00000200UL
+#define ACTION_NO_COMPRESSION  0x00000400UL
+#define ACTION_NO_COOKIE_KEEP  0x00000800UL
+#define ACTION_NO_COOKIE_READ  0x00001000UL
+#define ACTION_NO_COOKIE_SET   0x00002000UL
+#define ACTION_NO_POPUPS       0x00004000UL
+#define ACTION_VANILLA_WAFER   0x00008000UL
+#define ACTION_LIMIT_CONNECT   0x00010000UL
 
 #define ACTION_STRING_DEANIMATE     0
 #define ACTION_STRING_FROM          1
@@ -535,7 +670,9 @@ struct iob
 
 #define ACTION_MULTI_ADD_HEADER     0
 #define ACTION_MULTI_WAFER          1
-#define ACTION_MULTI_COUNT          2
+#define ACTION_MULTI_FILTER         2
+#define ACTION_MULTI_COUNT          3
+
 
 /*
  * This structure contains a list of actions to apply to a URL.
@@ -545,7 +682,7 @@ struct iob
  */
 struct current_action_spec
 {
-   unsigned flags;    /* a bit set to "1" = add action    */
+   unsigned long flags;    /* a bit set to "1" = add action    */
 
    /* For those actions that require parameters: */
 
@@ -564,8 +701,8 @@ struct current_action_spec
  */
 struct action_spec
 {
-   unsigned mask;   /* a bit set to "0" = remove action */
-   unsigned add;    /* a bit set to "1" = add action    */
+   unsigned long mask;   /* a bit set to "0" = remove action */
+   unsigned long add;    /* a bit set to "1" = add action    */
 
    /* For those actions that require parameters: */
 
@@ -598,28 +735,6 @@ struct url_actions
 };
 
 
-/* Constants defining bitmask for csp->accept_types */
-
-#ifdef FEATURE_IMAGE_DETECT_MSIE
-
-/* MSIE detected by user-agent string */
-#define ACCEPT_TYPE_IS_MSIE     0x0001
-
-/*
- * *If* this is MSIE, it wants an image.  (Or this is a shift-reload, or
- * it's got an image from this URL before...  yuck!)
- * Only meaningful if ACCEPT_TYPE_IS_MSIE set
- */
-#define ACCEPT_TYPE_MSIE_IMAGE  0x0002
-
-/*
- * *If* this is MSIE, it wants a HTML document.
- * Only meaningful if ACCEPT_TYPE_IS_MSIE set
- */
-#define ACCEPT_TYPE_MSIE_HTML   0x0004
-
-#endif /* def FEATURE_IMAGE_DETECT_MSIE */
-
 /*
  * Flags for use in csp->flags
  */
@@ -646,10 +761,10 @@ struct client_state
    struct current_action_spec  action[1];
 
    /* socket to talk to client (web browser) */
-   int  cfd;
+   jb_socket cfd;
 
    /* socket to talk to server (web server or proxy) */
-   int  sfd;
+   jb_socket sfd;
 
    /* Multi-purpose flag container, see CSP_FLAG_* above */
    unsigned short int flags;
@@ -669,18 +784,6 @@ struct client_state
    char *my_ip_addr_str;
    char *my_hostname;
 
-#ifdef FEATURE_TRUST
-   /* The referer in this request, if one was specified. */
-   char *referrer;
-#endif /* def FEATURE_TRUST */
-
-#if defined(FEATURE_IMAGE_DETECT_MSIE)
-   /* Types the client will accept.
-    * Bitmask - see ACCEPT_TYPE_XXX constants.
-    */
-   int accept_types;
-#endif /* defined(FEATURE_IMAGE_DETECT_MSIE) */
-
    /* The URL that was requested */
    struct http_request http[1];
 
@@ -713,14 +816,24 @@ struct client_state
 };
 
 
+/*
+ * A function to add a header
+ */
+typedef jb_err (*add_header_func_ptr)(struct client_state *);
+
+/*
+ * A function to process a header
+ */
+typedef jb_err (*parser_func_ptr    )(struct client_state *, char **);
+
 /*
  * List of functions to run on a list of headers
  */
 struct parsers
 {
-   char *str;
-   char  len;
-   char *(*parser)(const struct parsers *, const char *, struct client_state *);
+   char   *str;
+   size_t len;
+   parser_func_ptr parser;
 };
 
 
@@ -808,12 +921,18 @@ struct forward_spec
 #define FORWARD_SPEC_INITIALIZER { { URL_SPEC_INITIALIZER }, 0, NULL, 0, NULL, 0, NULL }
 
 
+/*
+ * This struct represents one filter (one block) from
+ * the re_filterfile. If there is more than one filter
+ * in the file, the file will be represented by a
+ * chained list of re_filterfile specs.
+ */
 struct re_filterfile_spec
 {
-   char *username;
-   char *filtername;
-   struct list patterns[1];
-   pcrs_job *joblist;
+   char *filtername;                /* Name from FILTER: statement in re_filterfile (or "default") */
+   struct list patterns[1];         /* The patterns from the re_filterfile */
+   pcrs_job *joblist;               /* The resulting compiled pcrs_jobs */
+   struct re_filterfile_spec *next; /* The pointer for chaining */
 };
 
 #ifdef FEATURE_ACL
@@ -880,7 +999,7 @@ struct configuration_spec
 
    /*
     * Port and IP to bind to.
-    * Defaults to HADDR_DEFAULT:HADDR_PORT == 127.0.0.1:8000
+    * Defaults to HADDR_DEFAULT:HADDR_PORT == 127.0.0.1:8118
     */
    const char *haddr;
    int         hport;
@@ -921,10 +1040,36 @@ struct configuration_spec
 #define FORCE_PREFIX "/IJB-FORCE-LOAD"
 #endif /* def FEATURE_FORCE_LOAD */
 
+#ifdef FEATURE_NO_GIFS
+#define BUILTIN_IMAGE_MIMETYPE "image/png"
+#else
+#define BUILTIN_IMAGE_MIMETYPE "image/gif"
+#endif /* def FEATURE_NO_GIFS */
+
+
 /* Hardwired URLs */
-#define HOME_PAGE_URL  "http://ijbswa.sourceforge.net"
-#define REDIRECT_URL HOME_PAGE_URL "/redirect.php?v=" VERSION "&to="
-#define CGI_PREFIX_HOST "i.j.b"
+#define HOME_PAGE_URL       "http://ijbswa.sourceforge.net"
+#define REDIRECT_URL        HOME_PAGE_URL "/redirect.php?v=" VERSION "&to="
+
+/*
+ * The "hosts" to intercept and display CGI pages.
+ * First one is a hostname only, second one can specify host and path.
+ *
+ * Notes:
+ * 1) Do not specify the http: prefix
+ * 2) CGI_SITE_2_PATH must not end with /, one will be added automatically.
+ * 3) CGI_SITE_2_PATH must start with /, unless it is the empty string.
+ */
+#define CGI_SITE_1_HOST "i.j.b"
+#define CGI_SITE_2_HOST "ijbswa.sourceforge.net"
+#define CGI_SITE_2_PATH "/config"
+
+/*
+ * The prefix for CGI pages.  Written out in generated HTML.
+ * INCLUDES the trailing slash.
+ */
+#define CGI_PREFIX  "http://" CGI_SITE_2_HOST CGI_SITE_2_PATH "/"
+
 
 /* HTTP snipplets */
 static const char CSUCCEED[] =