Deduplicate the INADDR_NONE definition for Solaris by moving it to jbsockets.h
[privoxy.git] / cgi.c
diff --git a/cgi.c b/cgi.c
index 02270ca..a55805b 100644 (file)
--- a/cgi.c
+++ b/cgi.c
@@ -1,4 +1,4 @@
-const char cgi_rcs[] = "$Id: cgi.c,v 1.134 2011/06/25 12:40:55 fabiankeil Exp $";
+const char cgi_rcs[] = "$Id: cgi.c,v 1.140 2011/07/08 13:28:11 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/cgi.c,v $
@@ -271,6 +271,13 @@ const char image_blank_data[] =
 const size_t image_pattern_length = sizeof(image_pattern_data) - 1;
 const size_t image_blank_length   = sizeof(image_blank_data) - 1;
 
+#ifdef FEATURE_COMPRESSION
+/*
+ * Minimum length which a buffer has to reach before
+ * we bother to (re-)compress it. Completely arbitrary.
+ */
+const size_t LOWER_LENGTH_LIMIT_FOR_COMPRESSION = 1024U;
+#endif
 
 static struct http_response cgi_error_memory_response[1];
 
@@ -1488,22 +1495,31 @@ static void get_locale_time(char *buf, size_t buffer_size)
  *                Allocates a new buffer for the result, free'ing it is
  *                up to the caller.
  *
- *                XXX: We should add a config option for the
- *                     compression level.
- *
- *
  * Parameters  :
  *          1  :  buffer = buffer whose content should be compressed
  *          2  :  buffer_length = length of the buffer
+ *          3  :  compression_level = compression level for compress2()
  *
  * Returns     :  NULL on error, otherwise a pointer to the compressed
  *                content of the input buffer.
  *
  *********************************************************************/
-char *compress_buffer(char *buffer, size_t *buffer_length)
+char *compress_buffer(char *buffer, size_t *buffer_length, int compression_level)
 {
    char *compressed_buffer;
-   size_t new_length = *buffer_length;
+   size_t new_length;
+   assert(-1 <= compression_level && compression_level <= 9);
+
+   /*
+    * If the compression level is 0 or if the entropy
+    * is high, the "compressing" data will take more
+    * room then the uncompressed data due to the zlib
+    * overhead.
+    *
+    * XXX: The overhead isn't constant and 30 bytes
+    *      may not be enough for everybody
+    */
+   new_length = *buffer_length + 30;
 
    compressed_buffer = malloc(new_length);
    if (NULL == compressed_buffer)
@@ -1513,15 +1529,18 @@ char *compress_buffer(char *buffer, size_t *buffer_length)
    }
 
    if (Z_OK != compress2((Bytef *)compressed_buffer, &new_length,
-         (Bytef *)buffer, *buffer_length, Z_DEFAULT_COMPRESSION))
+         (Bytef *)buffer, *buffer_length, compression_level))
    {
-      log_error(LOG_LEVEL_ERROR, "Error in compress2()");
+      log_error(LOG_LEVEL_ERROR,
+         "compress2() failed. Buffer size: %d, compression level: %d.",
+         new_length, compression_level);
       freez(compressed_buffer);
       return NULL;
    }
 
    log_error(LOG_LEVEL_RE_FILTER,
-      "Compressed content from %d to %d bytes.", *buffer_length, new_length);
+      "Compressed content from %d to %d bytes. Compression level: %d",
+      *buffer_length, new_length, compression_level);
 
    *buffer_length = new_length;
 
@@ -1579,11 +1598,12 @@ struct http_response *finish_http_response(const struct client_state *csp, struc
 
 #ifdef FEATURE_COMPRESSION
    if (!err && (csp->flags & CSP_FLAG_CLIENT_SUPPORTS_DEFLATE)
-      && (rsp->content_length > LOWER_LENGTH_LIMIT_FOR_COMRPESSION))
+      && (rsp->content_length > LOWER_LENGTH_LIMIT_FOR_COMPRESSION))
    {
       char *compressed_content;
 
-      compressed_content = compress_buffer(rsp->body, &rsp->content_length);
+      compressed_content = compress_buffer(rsp->body, &rsp->content_length,
+         csp->config->compression_level);
       if (NULL != compressed_content)
       {
          freez(rsp->body);
@@ -2123,6 +2143,7 @@ struct map *default_exports(const struct client_state *csp, const char *caller)
    struct map * exports;
    int local_help_exists = 0;
    char *ip_address = NULL;
+   char *port = NULL;
    char *hostname = NULL;
 
    assert(csp);
@@ -2135,12 +2156,12 @@ struct map *default_exports(const struct client_state *csp, const char *caller)
 
    if (csp->config->hostname)
    {
-      get_host_information(csp->cfd, &ip_address, NULL);
+      get_host_information(csp->cfd, &ip_address, &port, NULL);
       hostname = strdup(csp->config->hostname);
    }
    else
    {
-      get_host_information(csp->cfd, &ip_address, &hostname);
+      get_host_information(csp->cfd, &ip_address, &port, &hostname);
    }
 
    err = map(exports, "version", 1, html_encode(VERSION), 0);
@@ -2148,6 +2169,8 @@ struct map *default_exports(const struct client_state *csp, const char *caller)
    if (!err) err = map(exports, "time",          1, html_encode(buf), 0);
    if (!err) err = map(exports, "my-ip-address", 1, html_encode(ip_address ? ip_address : "unknown"), 0);
    freez(ip_address);
+   if (!err) err = map(exports, "my-port",       1, html_encode(port ? port : "unkown"), 0);
+   freez(port);
    if (!err) err = map(exports, "my-hostname",   1, html_encode(hostname ? hostname : "unknown"), 0);
    freez(hostname);
    if (!err) err = map(exports, "homepage",      1, html_encode(HOME_PAGE_URL), 0);
@@ -2172,9 +2195,6 @@ struct map *default_exports(const struct client_state *csp, const char *caller)
    if (!err) err = map_block_killer(exports, "can-toggle");
 #endif
 
-   snprintf(buf, sizeof(buf), "%d", csp->config->hport);
-   if (!err) err = map(exports, "my-port", 1, buf, 1);
-
    if(!strcmp(CODE_STATUS, "stable"))
    {
       if (!err) err = map_block_killer(exports, "unstable");