X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=cgi.c;h=d4a1f22fb45a36ebd14cee1abfca3483bec08144;hp=93af14b8dd1cffa39f5050d21805b6f1c97f23e4;hb=af5f45fc80e52bddde9d4e5e252f0767b740d3f6;hpb=43a77cc29aa0ed0564f3180bacfb024470d115fb
diff --git a/cgi.c b/cgi.c
index 93af14b8..d4a1f22f 100644
--- a/cgi.c
+++ b/cgi.c
@@ -1,4 +1,4 @@
-const char cgi_rcs[] = "$Id: cgi.c,v 1.125 2009/06/14 14:37:08 fabiankeil Exp $";
+const char cgi_rcs[] = "$Id: cgi.c,v 1.139 2011/07/08 13:27:56 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/cgi.c,v $
@@ -49,6 +49,10 @@ const char cgi_rcs[] = "$Id: cgi.c,v 1.125 2009/06/14 14:37:08 fabiankeil Exp $"
#include Privoxy ran out of memory while processing your request. Please contact your proxy administrator, or try again later Privoxy ran out of memory while processing your request. Please contact your proxy administrator, or try again later Privoxy encountered an error while processing your request: Privoxy encountered an error while processing your request: Could not load template file Please contact your proxy administrator.500 Internal Privoxy Error
\r\n"
- "500 Internal Privoxy Error
\n"
+ "500 Internal Privoxy Error
\r\n"
- "500 Internal Privoxy Error
\n"
+ "";
static const char body_suffix[] =
- "
or one of its included components.
Please contact your proxy administrator.
\n" "If you are the proxy administrator, please put the required file(s)"
"in the (confdir)/templates
directory. The "
"location of the (confdir)
directory "
@@ -1125,9 +1138,9 @@ jb_err cgi_error_no_template(const struct client_state *csp,
#ifndef _WIN32
", or /etc/privoxy/
"
#endif /* ndef _WIN32 */
- ").
Privoxy encountered an error while processing your request:
\r\n" + "\n" + "\n" + "Privoxy encountered an error while processing your request:
\n" "Unexpected internal error: "; static const char body_suffix[] = - "
\r\n" + "\n" "Please " "" - "file a bug report.
\r\n" - "\r\n" - "\r\n"; - char errnumbuf[30]; - /* - * Due to sizeof(errnumbuf), body_size will be slightly - * bigger than necessary but it doesn't really matter. - */ - const size_t body_size = strlen(body_prefix) + sizeof(errnumbuf) + strlen(body_suffix) + 1; + "file a bug report.\n" + "\n" + "\n"; + /* Includes room for larger error numbers in the future. */ + const size_t body_size = sizeof(body_prefix) + sizeof(body_suffix) + 5; assert(csp); assert(rsp); @@ -1224,18 +1233,15 @@ jb_err cgi_error_unknown(const struct client_state *csp, rsp->content_length = 0; rsp->head_length = 0; rsp->is_static = 0; - rsp->reason = RSP_REASON_INTERNAL_ERROR; - - snprintf(errnumbuf, sizeof(errnumbuf), "%d", error_to_report); + rsp->crunch_reason = INTERNAL_ERROR; rsp->body = malloc(body_size); if (rsp->body == NULL) { return JB_ERR_MEMORY; } - strlcpy(rsp->body, body_prefix, body_size); - strlcat(rsp->body, errnumbuf, body_size); - strlcat(rsp->body, body_suffix, body_size); + + snprintf(rsp->body, body_size, "%s%d%s", body_prefix, error_to_report, body_suffix); rsp->status = strdup(status); if (rsp->status == NULL) @@ -1479,6 +1485,71 @@ static void get_locale_time(char *buf, size_t buffer_size) } + +#ifdef FEATURE_COMPRESSION +/********************************************************************* + * + * Function : compress_buffer + * + * Description : Compresses the content of a buffer with zlib's deflate + * Allocates a new buffer for the result, free'ing it is + * up to the caller. + * + * 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, int compression_level) +{ + char *compressed_buffer; + 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) + { + log_error(LOG_LEVEL_FATAL, + "Out of memory allocation compression buffer."); + } + + if (Z_OK != compress2((Bytef *)compressed_buffer, &new_length, + (Bytef *)buffer, *buffer_length, compression_level)) + { + 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. Compression level: %d", + *buffer_length, new_length, compression_level); + + *buffer_length = new_length; + + return compressed_buffer; + +} +#endif + + /********************************************************************* * * Function : finish_http_response @@ -1524,6 +1595,24 @@ struct http_response *finish_http_response(const struct client_state *csp, struc { rsp->content_length = rsp->body ? strlen(rsp->body) : 0; } + +#ifdef FEATURE_COMPRESSION + if (!err && (csp->flags & CSP_FLAG_CLIENT_SUPPORTS_DEFLATE) + && (rsp->content_length > LOWER_LENGTH_LIMIT_FOR_COMPRESSION)) + { + char *compressed_content; + + compressed_content = compress_buffer(rsp->body, &rsp->content_length, + csp->config->compression_level); + if (NULL != compressed_content) + { + freez(rsp->body); + rsp->body = compressed_content; + err = enlist_unique_header(rsp->headers, "Content-Encoding", "deflate"); + } + } +#endif + if (!err) { snprintf(buf, sizeof(buf), "Content-Length: %d", (int)rsp->content_length); @@ -1636,13 +1725,10 @@ struct http_response *finish_http_response(const struct client_state *csp, struc if (!err) err = enlist_unique_header(rsp->headers, "Pragma", "no-cache"); } - /* - * Quoting RFC 2616: - * - * HTTP/1.1 applications that do not support persistent connections MUST - * include the "close" connection option in every message. - */ - if (!err) err = enlist_unique_header(rsp->headers, "Connection", "close"); + if (!err && !(csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)) + { + err = enlist_unique_header(rsp->headers, "Connection", "close"); + } /* * Write the head @@ -1865,7 +1951,7 @@ jb_err template_load(const struct client_state *csp, char **template_ptr, * HTML template by replacing @name@ with value using * pcrs, for each item in the output map. * - * Note that a leading '$' charachter in the export map's + * Note that a leading '$' character in the export map's * values will be stripped and toggle on backreference * interpretation. *