For now it has to be explicitly enabled with the configure option --enable-compression.
-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.130 2011/04/19 13:00:47 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"
}
+
+#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);
#ifndef CGI_H_INCLUDED
#define CGI_H_INCLUDED
-#define CGI_H_VERSION "$Id: cgi.h,v 1.36 2009/05/16 13:27:20 fabiankeil Exp $"
+#define CGI_H_VERSION "$Id: cgi.h,v 1.37 2009/06/11 11:44:25 fabiankeil Exp $"
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/cgi.h,v $
const char **pparam);
extern char get_char_param(const struct map *parameters,
const char *param_name);
+#ifdef FEATURE_COMPRESSION
+extern char *compress_buffer(char *buffer, size_t *buffer_length);
+#endif
/*
* Text generators
dnl Process this file with autoconf to produce a configure script.
dnl
-dnl $Id: configure.in,v 1.156 2011/05/27 11:37:45 fabiankeil Exp $
+dnl $Id: configure.in,v 1.157 2011/05/27 11:37:57 fabiankeil Exp $
dnl
dnl Written by and Copyright (C) 2001-2010 the
dnl Privoxy team. http://www.privoxy.org/
dnl AutoConf Initialization
dnl =================================================================
-AC_REVISION($Revision: 1.156 $)
+AC_REVISION($Revision: 1.157 $)
AC_INIT(jcc.c)
if test ! -f config.h.in; then
fi
fi
+AC_ARG_ENABLE(compression,
+[ --enable-compression Allow Privoxy to compress buffered content if the client supports it. Requires zlib support.],
+[enableval2=$enableval],
+[enableval2=no])
+if test $enableval2 = yes; then
+ if test $have_zlib = "yes"; then
+ echo Enabling compression support.
+ AC_DEFINE(FEATURE_COMPRESSION,1,[Define to 1 to use compression through the zlib library.])
+ else
+ AC_MSG_WARN([No zlib found. Privoxy will not be able to (re-)compressed buffered content.])
+ fi
+fi
+
# If we have libpcre and either we also have pcreposix or
# we don't need pcreposix, then link pcre dynamically; else
-const char jcc_rcs[] = "$Id: jcc.c,v 1.351 2011/05/03 10:15:54 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.352 2011/05/27 11:34:39 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/jcc.c,v $
{
csp->content_length = (size_t)(csp->iob->eod - csp->iob->cur);
}
+#ifdef FEATURE_COMPRESSION
+ else if ((csp->flags & CSP_FLAG_CLIENT_SUPPORTS_DEFLATE)
+ && (csp->content_length > LOWER_LENGTH_LIMIT_FOR_COMRPESSION))
+ {
+ char *compressed_content = compress_buffer(p, (size_t *)&csp->content_length);
+ if (compressed_content != NULL)
+ {
+ freez(p);
+ p = compressed_content;
+ csp->flags |= CSP_FLAG_BUFFERED_CONTENT_DEFLATED;
+ }
+ }
+#endif
if (JB_ERR_OK != update_server_headers(csp))
{
-const char parsers_rcs[] = "$Id: parsers.c,v 1.222 2011/04/19 13:00:47 fabiankeil Exp $";
+const char parsers_rcs[] = "$Id: parsers.c,v 1.223 2011/06/23 13:57:47 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/parsers.c,v $
}
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+#ifdef FEATURE_COMPRESSION
+ if ((JB_ERR_OK == err)
+ && (csp->flags & CSP_FLAG_BUFFERED_CONTENT_DEFLATED))
+ {
+ err = enlist_unique_header(csp->headers, "Content-Encoding", "deflate");
+ if (JB_ERR_OK == err)
+ {
+ log_error(LOG_LEVEL_HEADER, "Added header: Content-Encoding: deflate");
+ }
+ }
+#endif
+
return err;
}
*********************************************************************/
static jb_err client_accept_encoding(struct client_state *csp, char **header)
{
+#ifdef FEATURE_COMPRESSION
+ if (strstr(*header, "deflate"))
+ {
+ csp->flags |= CSP_FLAG_CLIENT_SUPPORTS_DEFLATE;
+ }
+#endif
if ((csp->action->flags & ACTION_NO_COMPRESSION) != 0)
{
log_error(LOG_LEVEL_HEADER, "Suppressed offer to compress content");
#ifndef PROJECT_H_INCLUDED
#define PROJECT_H_INCLUDED
/** Version string. */
-#define PROJECT_H_VERSION "$Id: project.h,v 1.163 2011/02/19 13:58:48 fabiankeil Exp $"
+#define PROJECT_H_VERSION "$Id: project.h,v 1.164 2011/04/19 13:00:47 fabiankeil Exp $"
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/project.h,v $
*/
#define CGI_PARAM_LEN_MAX 500U
+/**
+ * Minimum length which a buffer has to reach before
+ * Privoxy bothers to (re-)compress it. Completely arbitrary.
+ */
+#define LOWER_LENGTH_LIMIT_FOR_COMRPESSION 1024U
+
/**
* Buffer size for capturing struct hostent data in the
* gethostby(name|addr)_r library calls. Since we don't
*/
#define CSP_FLAG_REUSED_CLIENT_CONNECTION 0x00100000U
+/**
+ * Flag for csp->flags: Set if the supports deflate compression.
+ */
+#define CSP_FLAG_CLIENT_SUPPORTS_DEFLATE 0x00200000U
+
+/**
+ * Flag for csp->flags: Set if the content has been deflated by Privoxy
+ */
+#define CSP_FLAG_BUFFERED_CONTENT_DEFLATED 0x00400000U
+
+
/*
* Flags for use in return codes of child processes
*/