-const char cgi_rcs[] = "$Id: cgi.c,v 1.129 2010/05/24 11:38:22 fabiankeil Exp $";
+const char cgi_rcs[] = "$Id: cgi.c,v 1.132 2011/06/25 12:39:41 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/cgi.c,v $
#include <limits.h>
#include <assert.h>
+#ifdef FEATURE_COMPRESSION
+#include <zlib.h>
+#endif
+
#include "project.h"
#include "cgi.h"
#include "list.h"
"Content-Type: text/html\r\n"
"\r\n";
cgi_error_memory_response->body =
- "<html>\r\n"
- "<head>\r\n"
- " <title>500 Internal Privoxy Error</title>\r\n"
+ "<html>\n"
+ "<head>\n"
+ " <title>500 Internal Privoxy Error</title>\n"
" <link rel=\"shortcut icon\" href=\"" CGI_PREFIX "error-favicon.ico\" type=\"image/x-icon\">"
- "</head>\r\n"
- "<body>\r\n"
- "<h1>500 Internal Privoxy Error</h1>\r\n"
- "<p>Privoxy <b>ran out of memory</b> while processing your request.</p>\r\n"
- "<p>Please contact your proxy administrator, or try again later</p>\r\n"
- "</body>\r\n"
- "</html>\r\n";
+ "</head>\n"
+ "<body>\n"
+ "<h1>500 Internal Privoxy Error</h1>\n"
+ "<p>Privoxy <b>ran out of memory</b> while processing your request.</p>\n"
+ "<p>Please contact your proxy administrator, or try again later</p>\n"
+ "</body>\n"
+ "</html>\n";
cgi_error_memory_response->head_length =
strlen(cgi_error_memory_response->head);
static const char status[] =
"500 Internal Privoxy Error";
static const char body_prefix[] =
- "<html>\r\n"
- "<head>\r\n"
- " <title>500 Internal Privoxy Error</title>\r\n"
+ "<html>\n"
+ "<head>\n"
+ " <title>500 Internal Privoxy Error</title>\n"
" <link rel=\"shortcut icon\" href=\"" CGI_PREFIX "error-favicon.ico\" type=\"image/x-icon\">"
- "</head>\r\n"
- "<body>\r\n"
- "<h1>500 Internal Privoxy Error</h1>\r\n"
- "<p>Privoxy encountered an error while processing your request:</p>\r\n"
+ "</head>\n"
+ "<body>\n"
+ "<h1>500 Internal Privoxy Error</h1>\n"
+ "<p>Privoxy encountered an error while processing your request:</p>\n"
"<p><b>Could not load template file <code>";
static const char body_suffix[] =
- "</code> or one of its included components.</b></p>\r\n"
- "<p>Please contact your proxy administrator.</p>\r\n"
+ "</code> or one of its included components.</b></p>\n"
+ "<p>Please contact your proxy administrator.</p>\n"
"<p>If you are the proxy administrator, please put the required file(s)"
"in the <code><i>(confdir)</i>/templates</code> directory. The "
"location of the <code><i>(confdir)</i></code> directory "
#ifndef _WIN32
", or <code>/etc/privoxy/</code>"
#endif /* ndef _WIN32 */
- ").</p>\r\n"
- "</body>\r\n"
- "</html>\r\n";
+ ").</p>\n"
+ "</body>\n"
+ "</html>\n";
const size_t body_size = strlen(body_prefix) + strlen(template_name) + strlen(body_suffix) + 1;
assert(csp);
static const char status[] =
"500 Internal Privoxy Error";
static const char body_prefix[] =
- "<html>\r\n"
- "<head>\r\n"
- " <title>500 Internal Privoxy Error</title>\r\n"
+ "<html>\n"
+ "<head>\n"
+ " <title>500 Internal Privoxy Error</title>\n"
" <link rel=\"shortcut icon\" href=\"" CGI_PREFIX "error-favicon.ico\" type=\"image/x-icon\">"
- "</head>\r\n"
- "<body>\r\n"
- "<h1>500 Internal Privoxy Error</h1>\r\n"
- "<p>Privoxy encountered an error while processing your request:</p>\r\n"
+ "</head>\n"
+ "<body>\n"
+ "<h1>500 Internal Privoxy Error</h1>\n"
+ "<p>Privoxy encountered an error while processing your request:</p>\n"
"<p><b>Unexpected internal error: ";
static const char body_suffix[] =
- "</b></p>\r\n"
+ "</b></p>\n"
"<p>Please "
"<a href=\"http://sourceforge.net/tracker/?group_id=11118&atid=111118\">"
- "file a bug report</a>.</p>\r\n"
- "</body>\r\n"
- "</html>\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</a>.</p>\n"
+ "</body>\n"
+ "</html>\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);
rsp->is_static = 0;
rsp->crunch_reason = INTERNAL_ERROR;
- snprintf(errnumbuf, sizeof(errnumbuf), "%d", error_to_report);
-
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)
}
+
+#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.
+ *
+ * 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
+ *
+ * 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 *compressed_buffer;
+ size_t new_length = *buffer_length;
+
+ 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, Z_DEFAULT_COMPRESSION))
+ {
+ log_error(LOG_LEVEL_ERROR, "Error in compress2()");
+ freez(compressed_buffer);
+ return NULL;
+ }
+
+ log_error(LOG_LEVEL_RE_FILTER,
+ "Compressed content from %d to %d bytes.", *buffer_length, new_length);
+
+ *buffer_length = new_length;
+
+ return compressed_buffer;
+
+}
+#endif
+
+
/*********************************************************************
*
* Function : finish_http_response
{
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_COMRPESSION))
+ {
+ char *compressed_content;
+
+ compressed_content = compress_buffer(rsp->body, &rsp->content_length);
+ 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);