Add an enable-compression directive and disable compression by default
[privoxy.git] / loadcfg.c
index ff90b07..ac86848 100644 (file)
--- a/loadcfg.c
+++ b/loadcfg.c
@@ -1,4 +1,4 @@
-const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.110 2010/07/21 14:29:59 fabiankeil Exp $";
+const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.116 2011/07/08 13:29:39 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/loadcfg.c,v $
@@ -133,12 +133,14 @@ static struct file_list *current_configfile = NULL;
 #define hash_admin_address               4112573064ul /* "admin-address" */
 #define hash_allow_cgi_request_crunching  258915987ul /* "allow-cgi-request-crunching" */
 #define hash_buffer_limit                1881726070ul /* "buffer-limit */
+#define hash_compression_level           2464423563ul /* "compression-level" */
 #define hash_confdir                        1978389ul /* "confdir" */
 #define hash_connection_sharing          1348841265ul /* "connection-sharing" */
 #define hash_debug                            78263ul /* "debug" */
 #define hash_default_server_timeout      2530089913ul /* "default-server-timeout" */
 #define hash_deny_access                 1227333715ul /* "deny-access" */
 #define hash_enable_edit_actions         2517097536ul /* "enable-edit-actions" */
+#define hash_enable_compression          3943696946ul /* "enable-compression" */
 #define hash_enable_remote_toggle        2979744683ul /* "enable-remote-toggle" */
 #define hash_enable_remote_http_toggle    110543988ul /* "enable-remote-http-toggle" */
 #define hash_enforce_blocks              1862427469ul /* "enforce-blocks" */
@@ -276,6 +278,51 @@ void unload_current_config_file(void)
 #endif
 
 
+/*********************************************************************
+ *
+ * Function    :  parse_toggle_value
+ *
+ * Description :  Parse the value of a directive that can only be
+ *                enabled or disabled. Terminates with a fatal error
+ *                if the value is NULL or something other than 0 or 1.
+ *
+ * Parameters  :
+ *          1  :  name:  The name of the directive. Used for log messages.
+ *          2  :  value: The value to parse
+ *
+ *
+ * Returns     :  The numerical toggle state
+ *
+ *********************************************************************/
+static int parse_toggle_state(const char *name, const char *value)
+{
+   int toggle_state;
+   assert(name != NULL);
+   assert(value != NULL);
+
+   if ((value == NULL) || (*value == '\0'))
+   {
+      log_error(LOG_LEVEL_FATAL, "Directive %s used without argument", name);
+   }
+
+   toggle_state = atoi(value);
+
+   /*
+    * Also check the length as atoi() doesn't mind
+    * garbage after a valid integer, but we do.
+    */
+   if (((toggle_state != 0) && (toggle_state != 1)) || (strlen(value) != 1))
+   {
+      log_error(LOG_LEVEL_FATAL,
+         "Directive %s used with invalid argument '%s'. Use either '0' or '1'.",
+         name, value);
+   }
+
+   return toggle_state;
+
+}
+
+
 /*********************************************************************
  *
  * Function    :  load_config
@@ -292,7 +339,7 @@ void unload_current_config_file(void)
  *********************************************************************/
 struct configuration_spec * load_config(void)
 {
-   char buf[BUFFER_SIZE];
+   char *buf = NULL;
    char *p, *q;
    FILE *configfp = NULL;
    struct configuration_spec * config = NULL;
@@ -364,6 +411,13 @@ struct configuration_spec * load_config(void)
    config->feature_flags            &= ~RUNTIME_FEATURE_SPLIT_LARGE_FORMS;
    config->feature_flags            &= ~RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS;
    config->feature_flags            &= ~RUNTIME_FEATURE_EMPTY_DOC_RETURNS_OK;
+#ifdef FEATURE_COMPRESSION
+   config->feature_flags            &= ~RUNTIME_FEATURE_COMPRESSION;
+   /*
+    * XXX: Run some benchmarks to see if there are better default values.
+    */
+   config->compression_level         = 1;
+#endif
 
    configfp = fopen(configfile, "r");
    if (NULL == configfp)
@@ -373,7 +427,7 @@ struct configuration_spec * load_config(void)
       /* Never get here - LOG_LEVEL_FATAL causes program exit */
    }
 
-   while (read_config_line(buf, sizeof(buf), configfp, &linenum) != NULL)
+   while (read_config_line(configfp, &linenum, &buf) != NULL)
    {
       char cmd[BUFFER_SIZE];
       char arg[BUFFER_SIZE];
@@ -404,11 +458,15 @@ struct configuration_spec * load_config(void)
       }
 
       /* Copy the argument into arg */
-      strlcpy(arg, p, sizeof(arg));
+      if (strlcpy(arg, p, sizeof(arg)) >= sizeof(arg))
+      {
+         log_error(LOG_LEVEL_FATAL, "Config line too long: %s", buf);
+      }
 
       /* Should never happen, but check this anyway */
       if (*cmd == '\0')
       {
+         freez(buf);
          continue;
       }
 
@@ -449,7 +507,7 @@ struct configuration_spec * load_config(void)
  * accept-intercepted-requests
  * *************************************************************************/
          case hash_accept_intercepted_requests:
-            if ((*arg != '\0') && (0 != atoi(arg)))
+            if (parse_toggle_state(cmd, arg) == 1)
             {
                config->feature_flags |= RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS;
             }
@@ -471,7 +529,7 @@ struct configuration_spec * load_config(void)
  * allow-cgi-request-crunching
  * *************************************************************************/
          case hash_allow_cgi_request_crunching:
-            if ((*arg != '\0') && (0 != atoi(arg)))
+            if (parse_toggle_state(cmd, arg) == 1)
             {
                config->feature_flags |= RUNTIME_FEATURE_CGI_CRUNCHING;
             }
@@ -496,12 +554,38 @@ struct configuration_spec * load_config(void)
             config->confdir = make_path( NULL, arg);
             break;
 
+/* *************************************************************************
+ * compression-level 0-9
+ * *************************************************************************/
+#ifdef FEATURE_COMPRESSION
+         case hash_compression_level :
+            if (*arg != '\0')
+            {
+               int compression_level = atoi(arg);
+               if (-1 <= compression_level && compression_level <= 9)
+               {
+                  config->compression_level = compression_level;;
+               }
+               else
+               {
+                  log_error(LOG_LEVEL_FATAL,
+                     "Invalid compression-level value: %s", arg);
+               }
+            }
+            else
+            {
+               log_error(LOG_LEVEL_FATAL,
+                  "Invalid compression-level directive. Compression value missing");
+            }
+            break;
+#endif
+
 /* *************************************************************************
  * connection-sharing (0|1)
  * *************************************************************************/
 #ifdef FEATURE_CONNECTION_SHARING
          case hash_connection_sharing :
-            if ((*arg != '\0') && (0 != atoi(arg)))
+            if (parse_toggle_state(cmd, arg) == 1)
             {
                config->feature_flags |= RUNTIME_FEATURE_CONNECTION_SHARING;
             }
@@ -628,7 +712,7 @@ struct configuration_spec * load_config(void)
  * *************************************************************************/
 #ifdef FEATURE_CGI_EDIT_ACTIONS
          case hash_enable_edit_actions:
-            if ((*arg != '\0') && (0 != atoi(arg)))
+            if (parse_toggle_state(cmd, arg) == 1)
             {
                config->feature_flags |= RUNTIME_FEATURE_CGI_EDIT_ACTIONS;
             }
@@ -639,12 +723,29 @@ struct configuration_spec * load_config(void)
             break;
 #endif /* def FEATURE_CGI_EDIT_ACTIONS */
 
+/* *************************************************************************
+ * enable-compression 0|1
+ * *************************************************************************/
+#ifdef FEATURE_COMPRESSION
+         case hash_enable_compression:
+            if (parse_toggle_state(cmd, arg) == 1)
+            {
+               config->feature_flags |= RUNTIME_FEATURE_COMPRESSION;
+            }
+            else
+            {
+               config->feature_flags &= ~RUNTIME_FEATURE_COMPRESSION;
+            }
+            break;
+#endif /* def FEATURE_COMPRESSION */
+
+
 /* *************************************************************************
  * enable-remote-toggle 0|1
  * *************************************************************************/
 #ifdef FEATURE_TOGGLE
          case hash_enable_remote_toggle:
-            if ((*arg != '\0') && (0 != atoi(arg)))
+            if (parse_toggle_state(cmd, arg) == 1)
             {
                config->feature_flags |= RUNTIME_FEATURE_CGI_TOGGLE;
             }
@@ -659,7 +760,7 @@ struct configuration_spec * load_config(void)
  * enable-remote-http-toggle 0|1
  * *************************************************************************/
          case hash_enable_remote_http_toggle:
-            if ((*arg != '\0') && (0 != atoi(arg)))
+            if (parse_toggle_state(cmd, arg) == 1)
             {
                config->feature_flags |= RUNTIME_FEATURE_HTTP_TOGGLE;
             }
@@ -674,7 +775,7 @@ struct configuration_spec * load_config(void)
  * *************************************************************************/
          case hash_enforce_blocks:
 #ifdef FEATURE_FORCE_LOAD
-            if ((*arg != '\0') && (0 != atoi(arg)))
+            if (parse_toggle_state(cmd, arg) == 1)
             {
                config->feature_flags |= RUNTIME_FEATURE_ENFORCE_BLOCKS;
             }
@@ -918,7 +1019,7 @@ struct configuration_spec * load_config(void)
  *   to the browser for blocked pages.
  ***************************************************************************/
          case hash_handle_as_empty_returns_ok:
-            if ((*arg != '\0') && (0 != atoi(arg)))
+            if (parse_toggle_state(cmd, arg) == 1)
             {
                config->feature_flags |= RUNTIME_FEATURE_EMPTY_DOC_RETURNS_OK;
             }
@@ -1127,7 +1228,7 @@ struct configuration_spec * load_config(void)
  * split-large-cgi-forms
  * *************************************************************************/
          case hash_split_large_cgi_forms :
-            if ((*arg != '\0') && (0 != atoi(arg)))
+            if (parse_toggle_state(cmd, arg) == 1)
             {
                config->feature_flags |= RUNTIME_FEATURE_SPLIT_LARGE_FORMS;
             }
@@ -1339,7 +1440,7 @@ struct configuration_spec * load_config(void)
 
       /* Save the argument for the show-status page. */
       savearg(cmd, arg, config);
-
+      freez(buf);
    } /* end while ( read_config_line(...) ) */
 
    fclose(configfp);