You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by jm...@apache.org on 2006/12/03 21:45:54 UTC
svn commit: r481882 - in /spamassassin/branches/jm_spamc_hacks: ./
lib/Mail/SpamAssassin/Util/ spamc/ spamd/ t/
Author: jm
Date: Sun Dec 3 12:45:50 2006
New Revision: 481882
URL: http://svn.apache.org/viewvc?view=rev&rev=481882
Log:
add spamc -z switch: compression for spamc-spamd protocol, useful for cross-internet spamd protocol use
Added:
spamassassin/branches/jm_spamc_hacks/t/spamc_z.t
Modified:
spamassassin/branches/jm_spamc_hacks/INSTALL
spamassassin/branches/jm_spamc_hacks/MANIFEST
spamassassin/branches/jm_spamc_hacks/lib/Mail/SpamAssassin/Util/DependencyInfo.pm
spamassassin/branches/jm_spamc_hacks/spamc/config.h.in
spamassassin/branches/jm_spamc_hacks/spamc/configure
spamassassin/branches/jm_spamc_hacks/spamc/configure.in
spamassassin/branches/jm_spamc_hacks/spamc/libspamc.c
spamassassin/branches/jm_spamc_hacks/spamc/libspamc.h
spamassassin/branches/jm_spamc_hacks/spamc/spamc.c
spamassassin/branches/jm_spamc_hacks/spamc/spamc.pod
spamassassin/branches/jm_spamc_hacks/spamd/spamd.raw
Modified: spamassassin/branches/jm_spamc_hacks/INSTALL
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/INSTALL?view=diff&rev=481882&r1=481881&r2=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/INSTALL (original)
+++ spamassassin/branches/jm_spamc_hacks/INSTALL Sun Dec 3 12:45:50 2006
@@ -289,6 +289,13 @@
compatibile spamc.)
+ - Compress::Zlib (from CPAN)
+
+ If you wish to use the optional zlib compression for communication
+ between spamc and spamd (the -z option to spamc), you need to install
+ this module.
+
+
- Time::HiRes (from CPAN)
If this module is installed, the processing times are logged/reported
Modified: spamassassin/branches/jm_spamc_hacks/MANIFEST
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/MANIFEST?view=diff&rev=481882&r1=481881&r2=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/MANIFEST (original)
+++ spamassassin/branches/jm_spamc_hacks/MANIFEST Sun Dec 3 12:45:50 2006
@@ -345,6 +345,7 @@
t/spamc_l.t
t/spamc_optC.t
t/spamc_optL.t
+t/spamc_z.t
t/spamd.t
t/spamd_allow_user_rules.t
t/spamd_hup.t
Modified: spamassassin/branches/jm_spamc_hacks/lib/Mail/SpamAssassin/Util/DependencyInfo.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/lib/Mail/SpamAssassin/Util/DependencyInfo.pm?view=diff&rev=481882&r1=481881&r2=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/lib/Mail/SpamAssassin/Util/DependencyInfo.pm (original)
+++ spamassassin/branches/jm_spamc_hacks/lib/Mail/SpamAssassin/Util/DependencyInfo.pm Sun Dec 3 12:45:50 2006
@@ -122,6 +122,13 @@
compatibile spamc.)',
},
{
+ module => 'Compress::Zlib',
+ version => '0.00',
+ desc => 'If you wish to use the optional zlib compression for communication
+ between spamc and spamd (the -z option to spamc), you need to install
+ this module.',
+},
+{
module => 'Time::HiRes',
version => '0.00',
desc => 'If this module is installed, the processing times are logged/reported
Modified: spamassassin/branches/jm_spamc_hacks/spamc/config.h.in
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/spamc/config.h.in?view=diff&rev=481882&r1=481881&r2=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/spamc/config.h.in (original)
+++ spamassassin/branches/jm_spamc_hacks/spamc/config.h.in Sun Dec 3 12:45:50 2006
@@ -34,6 +34,9 @@
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
+/* Define to 1 if you have the `z' library (-lz). */
+#undef HAVE_LIBZ
+
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@@ -108,6 +111,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#undef HAVE_ZLIB_H
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
Modified: spamassassin/branches/jm_spamc_hacks/spamc/configure
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/spamc/configure?view=diff&rev=481882&r1=481881&r2=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/spamc/configure (original)
+++ spamassassin/branches/jm_spamc_hacks/spamc/configure Sun Dec 3 12:45:50 2006
@@ -3035,7 +3035,8 @@
-for ac_header in pwd.h signal.h openssl/crypto.h
+
+for ac_header in pwd.h signal.h openssl/crypto.h zlib.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -3957,6 +3958,79 @@
_ACEOF
LIBS="-lnsl $LIBS"
+
+fi
+
+
+echo "$as_me:$LINENO: checking for deflate in -lz" >&5
+echo $ECHO_N "checking for deflate in -lz... $ECHO_C" >&6
+if test "${ac_cv_lib_z_deflate+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char deflate ();
+int
+main ()
+{
+deflate ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_z_deflate=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_z_deflate=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_z_deflate" >&5
+echo "${ECHO_T}$ac_cv_lib_z_deflate" >&6
+if test $ac_cv_lib_z_deflate = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBZ 1
+_ACEOF
+
+ LIBS="-lz $LIBS"
fi
Modified: spamassassin/branches/jm_spamc_hacks/spamc/configure.in
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/spamc/configure.in?view=diff&rev=481882&r1=481881&r2=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/spamc/configure.in (original)
+++ spamassassin/branches/jm_spamc_hacks/spamc/configure.in Sun Dec 3 12:45:50 2006
@@ -29,7 +29,7 @@
AC_HEADER_STDC
AC_CHECK_HEADERS(sys/time.h syslog.h unistd.h errno.h sys/errno.h)
AC_CHECK_HEADERS(time.h sysexits.h sys/socket.h netdb.h netinet/in.h)
-AC_CHECK_HEADERS(pwd.h signal.h openssl/crypto.h)
+AC_CHECK_HEADERS(pwd.h signal.h openssl/crypto.h zlib.h)
dnl AC_CHECK_HEADERS(getopt.h)
AC_C_CONST
@@ -75,6 +75,7 @@
fi
AC_CHECK_LIB(inet, connect)
AC_CHECK_LIB(nsl, t_accept)
+AC_CHECK_LIB(z, deflate)
AC_CHECK_LIB(dl, dlopen)
AC_CHECK_FUNCS(socket strdup strtod strtol snprintf shutdown)
Modified: spamassassin/branches/jm_spamc_hacks/spamc/libspamc.c
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/spamc/libspamc.c?view=diff&rev=481882&r1=481881&r2=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/spamc/libspamc.c (original)
+++ spamassassin/branches/jm_spamc_hacks/spamc/libspamc.c Sun Dec 3 12:45:50 2006
@@ -57,6 +57,9 @@
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
/* FIXME: Make this configurable */
#define MAX_CONNECT_RETRIES 3
@@ -932,6 +935,61 @@
return EX_OK;
}
+static int
+_zlib_compress (char *m_msg, int m_msg_len,
+ unsigned char **zlib_buf, int *zlib_bufsiz)
+{
+ int rc;
+ int len, totallen;
+
+#ifndef HAVE_LIBZ
+
+ UNUSED_VARIABLE(rc);
+ UNUSED_VARIABLE(len);
+ UNUSED_VARIABLE(totallen);
+ libspamc_log(flags, LOG_ERR, "spamc not built with zlib support");
+ return EX_SOFTWARE;
+
+#else
+
+ /* worst-case, according to http://www.zlib.org/zlib_tech.html ;
+ * same as input, plus 5 bytes per 16k, plus 6 bytes. this should
+ * be plenty */
+ *zlib_bufsiz = (int) (m_msg_len * 1.0005) + 1024;
+ *zlib_buf = (unsigned char *) malloc (*zlib_bufsiz);
+ if (*zlib_buf == NULL) {
+ return EX_OSERR;
+ }
+
+ z_stream strm;
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ rc = deflateInit(&strm, 3);
+ if (rc != Z_OK) {
+ return EX_OSERR;
+ }
+
+ strm.avail_in = m_msg_len;
+ strm.next_in = (unsigned char *) m_msg;
+ strm.avail_out = *zlib_bufsiz;
+ strm.next_out = (unsigned char *) *zlib_buf;
+
+ totallen = 0;
+ do {
+ rc = deflate(&strm, Z_FINISH);
+ assert(rc != Z_STREAM_ERROR);
+ len = (size_t) (*zlib_bufsiz - strm.avail_out);
+ strm.next_out += len;
+ totallen += len;
+ } while (strm.avail_out == 0);
+
+ *zlib_bufsiz = totallen;
+ return EX_OK;
+
+#endif
+}
+
int message_filter(struct transport *tp, const char *username,
int flags, struct message *m)
{
@@ -948,10 +1006,19 @@
SSL_CTX *ctx = NULL;
SSL *ssl = NULL;
SSL_METHOD *meth;
+ char zlib_on = 0;
+ unsigned char *zlib_buf = NULL;
+ int zlib_bufsiz = 0;
+ unsigned char *towrite_buf;
+ int towrite_len;
assert(tp != NULL);
assert(m != NULL);
+ if ((flags & SPAMC_USE_ZLIB) != 0) {
+ zlib_on = 1;
+ }
+
if (flags & SPAMC_USE_SSL) {
#ifdef SPAMC_SSL
SSLeay_add_ssl_algorithms();
@@ -999,6 +1066,17 @@
strcat(buf, "\r\n");
len = strlen(buf);
+ towrite_buf = (unsigned char *) m->msg;
+ towrite_len = (int) m->msg_len;
+ if (zlib_on) {
+ if (_zlib_compress(m->msg, m->msg_len, &zlib_buf, &zlib_bufsiz) != EX_OK)
+ {
+ return EX_OSERR;
+ }
+ towrite_buf = zlib_buf;
+ towrite_len = zlib_bufsiz;
+ }
+
if (!(flags & SPAMC_PING)) {
if (username != NULL) {
if (strlen(username) + 8 >= (bufsiz - len)) {
@@ -1010,11 +1088,14 @@
strcat(buf + len, "\r\n");
len += strlen(buf + len);
}
+ if (zlib_on) {
+ len += snprintf(buf + len, 8192-len, "Compress: zlib\r\n");
+ }
if ((m->msg_len > SPAMC_MAX_MESSAGE_LEN) || ((len + 27) >= (bufsiz - len))) {
_use_msg_for_out(m);
return EX_DATAERR;
}
- len += sprintf(buf + len, "Content-length: %d\r\n\r\n", (int) m->msg_len);
+ len += snprintf(buf + len, 8192-len, "Content-length: %d\r\n\r\n", (int) towrite_len);
}
libspamc_timeout = m->timeout;
@@ -1041,12 +1122,12 @@
if (flags & SPAMC_USE_SSL) {
#ifdef SPAMC_SSL
SSL_write(ssl, buf, len);
- SSL_write(ssl, m->msg, m->msg_len);
+ SSL_write(ssl, towrite_buf, towrite_len);
#endif
}
else {
full_write(sock, 0, buf, len);
- full_write(sock, 0, m->msg, m->msg_len);
+ full_write(sock, 0, towrite_buf, towrite_len);
shutdown(sock, SHUT_WR);
}
Modified: spamassassin/branches/jm_spamc_hacks/spamc/libspamc.h
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/spamc/libspamc.h?view=diff&rev=481882&r1=481881&r2=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/spamc/libspamc.h (original)
+++ spamassassin/branches/jm_spamc_hacks/spamc/libspamc.h Sun Dec 3 12:45:50 2006
@@ -112,6 +112,9 @@
/* Oct 21, 2005 sidney: added ping test */
#define SPAMC_PING (1<<19)
+/* Nov 30, 2006 jm: add -z, zlib support */
+#define SPAMC_USE_ZLIB (1<<18)
+
#define SPAMC_MESSAGE_CLASS_SPAM 1
#define SPAMC_MESSAGE_CLASS_HAM 2
Modified: spamassassin/branches/jm_spamc_hacks/spamc/spamc.c
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/spamc/spamc.c?view=diff&rev=481882&r1=481881&r2=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/spamc/spamc.c (original)
+++ spamassassin/branches/jm_spamc_hacks/spamc/spamc.c Sun Dec 3 12:45:50 2006
@@ -190,6 +190,7 @@
usg(" -h, --help Print this help message and exit.\n");
usg(" -V, --version Print spamc version and exit.\n");
usg(" -K Keepalive check of spamd.\n");
+ usg(" -z Compress mail message sent to spamd.\n");
usg(" -f (Now default, ignored.)\n");
usg("\n");
@@ -208,9 +209,9 @@
struct transport *ptrn)
{
#ifndef _WIN32
- const char *opts = "-BcrRd:e:fyp:t:s:u:L:C:xSHU:ElhVKF:";
+ const char *opts = "-BcrRd:e:fyp:t:s:u:L:C:xzSHU:ElhVKF:";
#else
- const char *opts = "-BcrRd:fyp:t:s:u:L:C:xSHElhVKF:";
+ const char *opts = "-BcrRd:fyp:t:s:u:L:C:xzSHElhVKF:";
#endif
int opt;
int ret = EX_OK;
@@ -239,6 +240,7 @@
{ "pipe-to", required_argument, 0, 'e' },
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'V' },
+ { "compress", no_argument, 0, 'z' },
{ 0, 0, 0, 0} /* last element _must_ be all zeroes */
};
@@ -416,6 +418,11 @@
{
print_version();
return(EX_TEMPFAIL);
+ }
+ case 'z':
+ {
+ flags |= SPAMC_USE_ZLIB;
+ break;
}
}
}
Modified: spamassassin/branches/jm_spamc_hacks/spamc/spamc.pod
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/spamc/spamc.pod?view=diff&rev=481882&r1=481881&r2=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/spamc/spamc.pod (original)
+++ spamassassin/branches/jm_spamc_hacks/spamc/spamc.pod Sun Dec 3 12:45:50 2006
@@ -204,6 +204,13 @@
Perform a keep-alive check of spamd, instead of a full message check.
+=item B<-z>
+
+Use gzip compression to compress the mail message sent to C<spamd>. Note
+that this relies on C<zlib> being installed on the C<spamc> client side,
+and the C<Compress::Zlib> perl module on the server side; an error
+will be returned otherwise.
+
=back
=head1 CONFIGURATION FILE
Modified: spamassassin/branches/jm_spamc_hacks/spamd/spamd.raw
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/spamd/spamd.raw?view=diff&rev=481882&r1=481881&r2=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/spamd/spamd.raw (original)
+++ spamassassin/branches/jm_spamc_hacks/spamd/spamd.raw Sun Dec 3 12:45:50 2006
@@ -144,6 +144,8 @@
printf(" running on Perl %s\n", join(".", map { $_||=0; $_*1 } ($] =~ /(\d)\.(\d{3})(\d{3})?/)));
eval { require IO::Socket::SSL; };
printf(" with SSL support (%s %s)\n", "IO::Socket::SSL", $IO::Socket::SSL::VERSION) unless ($@);
+ eval { require Compress::Zlib; };
+ printf(" with zlib support (%s %s)\n", "Compress::Zlib", $Compress::Zlib::VERSION) unless ($@);
}
sub print_usage_and_exit {
@@ -1264,15 +1266,29 @@
}
sub parse_body {
- my ($client, $expected_length) = @_;
+ my ($client, $expected_length, $compress_zlib) = @_;
my @msglines;
- my $actual_length = 0;
+ my $actual_length;
- while (defined($_ = $client->getline())) {
- $actual_length += length($_);
- push(@msglines, $_);
- last if (defined $expected_length && $actual_length >= $expected_length);
+ if ($compress_zlib && !defined($expected_length)) {
+ service_unavailable_error("Compress requires Content-length header");
+ return;
+ }
+
+ if ($compress_zlib) {
+ $actual_length = zlib_inflate_read($client, $expected_length, \@msglines);
+ if ($actual_length < 0) { return; }
+ $expected_length = $actual_length;
+ }
+ else {
+ @msglines = ();
+ $actual_length = 0;
+ while (defined($_ = $client->getline())) {
+ $actual_length += length($_);
+ push(@msglines, $_);
+ last if (defined $expected_length && $actual_length >= $expected_length);
+ }
}
# Now parse *only* the message headers; the MIME tree won't be generated
@@ -1282,6 +1298,54 @@
return ($mail, $actual_length);
}
+sub zlib_inflate_read {
+ my ($client, $expected_length, $msglinesref) = @_;
+ my $out;
+ my $actual_length;
+
+ eval {
+ require Compress::Zlib;
+ my ($zlib, $status) = Compress::Zlib::inflateInit();
+ if (!$zlib) { die "inflateInit failed: $status"; }
+
+ my $red = 0;
+ my $buf;
+
+ # TODO: inflate in smaller buffers instead of at EOF
+ while (1) {
+ my $numbytes = $client->read($buf, (1024 * 64) + $red, $red);
+ if (!defined $numbytes) {
+ die "read of zlib data failed: $!";
+ return -1;
+ }
+ last if $numbytes == 0;
+ $red += $numbytes;
+ }
+
+ if ($red > $expected_length) {
+ warn "hmm, zlib read $red > expected_length $expected_length";
+ substr ($buf, $expected_length) = '';
+ }
+
+ ($out, $status) = $zlib->inflate($buf);
+ if ($status != Compress::Zlib::Z_STREAM_END()) {
+ die "failed to find end of zlib stream";
+ }
+ };
+
+ if ($@) {
+ service_unavailable_error("zlib: $@");
+ return -1;
+ }
+
+ $actual_length = length($out);
+
+ # TODO: split during inflate, too
+ # note that this preserves line endings
+ @{$msglinesref} = map { s/$/\n/gs; $_; } split(/\n/, $out);
+ return $actual_length;
+}
+
sub parse_msgids {
my ($mail) = @_;
@@ -1307,6 +1371,7 @@
my ( $method, $version, $start_time, $remote_hostname, $remote_hostaddr ) = @_;
local ($_);
my $expected_length;
+ my $compress_zlib;
# used to ensure we don't accidentally fork (bug 4370)
my $starting_self_pid = $$;
@@ -1320,6 +1385,7 @@
return 0 unless (parse_headers($hdrs, $client));
$expected_length = $hdrs->{expected_length};
+ $compress_zlib = $hdrs->{compress_zlib};
}
handle_setuid_to_user if ($setuid_to_user && $> == 0);
@@ -1338,7 +1404,13 @@
my $resp = "EX_OK";
# generate mail object from input
- my ($mail, $actual_length) = parse_body($client, $expected_length);
+ my ($mail, $actual_length) = parse_body($client, $expected_length,
+ $compress_zlib);
+ return 0 unless defined($mail); # error
+
+ if ($compress_zlib) {
+ $expected_length = $actual_length; # previously it was the gzipped length
+ }
# attempt to fetch the message ids
my ($msgid, $rmsgid) = parse_msgids($mail);
@@ -1491,13 +1563,13 @@
sub dotell {
my ($method, $version, $start_time, $remote_hostname, $remote_hostaddr) = @_;
local ($_);
- my $expected_length;
my $hdrs = {};
return 0 unless (parse_headers($hdrs, $client));
- $expected_length = $hdrs->{expected_length};
+ my $expected_length = $hdrs->{expected_length};
+ my $compress_zlib = $hdrs->{compress_zlib};
if (!$opt{tell}) {
service_unavailable_error("TELL commands have not been enabled.");
@@ -1530,7 +1602,13 @@
my $resp = "EX_OK";
# generate mail object from input
- my ($mail, $actual_length) = parse_body($client, $expected_length);
+ my ($mail, $actual_length) = parse_body($client, $expected_length,
+ $compress_zlib);
+ return 0 unless defined($mail); # error
+
+ if ($compress_zlib) {
+ $expected_length = $actual_length; # previously it was the gzipped length
+ }
if ( $mail->get_header("X-Spam-Checker-Version") ) {
my $new_mail = $spamtest->parse($spamtest->remove_spamassassin_markup($mail), 1);
@@ -1649,6 +1727,9 @@
elsif ($header eq 'Remove') {
return 0 unless &got_remove_header($hdrs, $header, $value);
}
+ elsif ($header eq 'Compress') {
+ return 0 unless &got_compress_header($hdrs, $header, $value);
+ }
}
# avoid too-many-headers DOS attack
@@ -1766,6 +1847,25 @@
if ($value =~ /remote/i) {
$hdrs->{remove_remote} = 1;
+ }
+
+ return 1;
+}
+
+sub got_compress_header {
+ my ($hdrs, $header, $value) = @_;
+
+ if ($value =~ /zlib/i) {
+ eval { require Compress::Zlib; };
+ if ($@) {
+ protocol_error("(compression not supported, Compress::Zlib not installed)");
+ return 0;
+ }
+ $hdrs->{compress_zlib} = 1;
+ }
+ else {
+ protocol_error("(compression type not supported)");
+ return 0;
}
return 1;
Added: spamassassin/branches/jm_spamc_hacks/t/spamc_z.t
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_spamc_hacks/t/spamc_z.t?view=auto&rev=481882
==============================================================================
--- spamassassin/branches/jm_spamc_hacks/t/spamc_z.t (added)
+++ spamassassin/branches/jm_spamc_hacks/t/spamc_z.t Sun Dec 3 12:45:50 2006
@@ -0,0 +1,31 @@
+#!/usr/bin/perl
+
+use constant HAVE_ZLIB => eval { require Compress::Zlib; };
+
+use lib '.'; use lib 't';
+use SATest; sa_t_init("spamc_z");
+use Test; plan tests => (($SKIP_SPAMD_TESTS || !HAVE_ZLIB) ? 0 : 9);
+
+exit if ($SKIP_SPAMD_TESTS || !HAVE_ZLIB);
+
+# ---------------------------------------------------------------------------
+
+%patterns = (
+
+q{ Return-Path: sb55sb55@yahoo.com}, 'firstline',
+q{ Subject: There yours for FREE!}, 'subj',
+q{ X-Spam-Status: Yes, score=}, 'status',
+q{ X-Spam-Flag: YES}, 'flag',
+q{ X-Spam-Level: **********}, 'stars',
+q{ TEST_ENDSNUMS}, 'endsinnums',
+q{ TEST_NOREALNAME}, 'noreal',
+q{ This must be the very last line}, 'lastline',
+
+
+);
+
+ok (sdrun ("-L",
+ "-z < data/spam/001",
+ \&patterns_run_cb));
+ok_all_patterns();
+