New in-memory zlib patch.
Mark Atkinson <[email protected]> Tue, 3 May 2005 10:50:40 -0700 (PDT)
| Newsgroups | gmane.comp.web.wget.patches |
|---|---|
| Message-ID | <20050503103521.N34007@localhost> |
Here's a new version of my wget/zlib compression patch against the current cvs tree of wget. In this version: - in line/memory decompression - support for deflate and gzip compression methods Notes: - Probably only works up to 2G or 4G. Untested. - I don't like having to fudge sum_written in order to appease wget's error checking http_loop(). Probably needs a in-depth update of progress and error checking to get right. - -z or --compress is needed to turn it on. It needs thorough testing before making it a default behavior - Accept-Encoding header passes 'deflate,gzip' - seems to work here.
wget-zlib-05032005.patch
(text/plain, 9.3 KB)
Index: configure.in
===================================================================
RCS file: /pack/anoncvs/wget/configure.in,v
retrieving revision 1.83
diff -u -r1.83 configure.in
--- configure.in 2005/04/29 22:31:47 1.83
+++ configure.in 2005/05/03 15:48:07
@@ -245,6 +245,34 @@
dnl Checks for libraries.
dnl
+dnl $with_zlib
+AC_ARG_WITH(zlib,
+[ --with-zlib[[=DIR]] use libz in DIR],[
+ if test "$withval" != "no" -a "$withval" != "yes"; then
+ Z_DIR=$withval
+ CPPFLAGS="${CPPFLAGS} -I$withval/include"
+ LDFLAGS="${LDFLAGS} -L$withval/lib"
+ fi
+])
+if test "$with_zlib" = "no"; then
+ echo "Disabling compression support"
+else
+ AC_CHECK_HEADERS(zlib.h,
+ AC_CHECK_LIB(z, gzopen,[
+ AC_DEFINE([HAVE_ZLIB], [], [Have compression library])
+ if test "x${Z_DIR}" != "x"; then
+ CPPFLAGS="${CPPFLAGS} -I${Z_DIR}/include"
+ LIBS="${LIBS} -L${Z_DIR}/lib -lz"
+ [case ${host} in
+ *-*-solaris*)
+ LIBS="-L${Z_DIR}/lib -R${Z_DIR}/lib -lz"
+ ;;
+ esac]
+ else
+ LIBS="-lz"
+ fi]))
+fi
+
dnl $with_ssl can be one of:
dnl - empty string or "auto", meaning autodetect SSL and use it if found.
dnl - "yes", meaning link with SSL or bail out.
Index: src/http.c
===================================================================
RCS file: /pack/anoncvs/wget/src/http.c,v
retrieving revision 1.174
diff -u -r1.174 http.c
--- src/http.c 2005/05/03 15:24:29 1.174
+++ src/http.c 2005/05/03 15:48:08
@@ -1177,6 +1177,9 @@
int inhibit_keep_alive =
!opt.http_keep_alive || opt.ignore_length || proxy != NULL;
+ /* Content encoding */
+ char *encoding;
+
/* Headers sent when using POST. */
wgint post_data_size = 0;
@@ -1239,6 +1242,12 @@
SET_USER_AGENT (req);
request_set_header (req, "Accept", "*/*", rel_none);
+#ifdef HAVE_ZLIB
+ /* XXX order needs to be settable via the command-line */
+ if (opt.compress)
+ request_set_header (req, "Accept-Encoding", "deflate,gzip", rel_none);
+#endif
+
/* Find the username and password for authentication. */
user = u->user;
passwd = u->passwd;
@@ -1374,6 +1383,7 @@
for the Digest authorization scheme.) */
keep_alive = 0;
+ encoding = 0;
/* Establish the connection. */
@@ -1704,6 +1714,9 @@
*tmp = '\0';
}
}
+
+ encoding = resp_header_strdup (resp, "Content-Encoding");
+
hs->newloc = resp_header_strdup (resp, "Location");
hs->remote_time = resp_header_strdup (resp, "Last-Modified");
@@ -1935,6 +1948,11 @@
/* If the server ignored our range request, instruct fd_read_body
to skip the first RESTVAL bytes of body. */
flags |= rb_skip_startpos;
+ if (encoding && (strncasecmp(encoding, "deflate", 8) == 0))
+ flags |= rb_content_deflate;
+ if (encoding && (strncasecmp(encoding, "gzip", 4) == 0))
+ flags |= rb_content_gzip;
+
hs->len = hs->restval;
hs->rd_size = 0;
hs->res = fd_read_body (sock, fp, contlen != -1 ? contlen : 0,
Index: src/init.c
===================================================================
RCS file: /pack/anoncvs/wget/src/init.c,v
retrieving revision 1.110
diff -u -r1.110 init.c
--- src/init.c 2005/04/28 09:32:13 1.110
+++ src/init.c 2005/05/03 15:48:09
@@ -131,6 +131,9 @@
{ "certificatetype", &opt.cert_type, cmd_cert_type },
{ "checkcertificate", &opt.check_cert, cmd_boolean },
#endif
+#ifdef HAVE_ZLIB
+ { "compress", &opt.compress, cmd_boolean },
+#endif
{ "connecttimeout", &opt.connect_timeout, cmd_time },
{ "continue", &opt.always_rest, cmd_boolean },
{ "convertlinks", &opt.convert_links, cmd_boolean },
Index: src/main.c
===================================================================
RCS file: /pack/anoncvs/wget/src/main.c,v
retrieving revision 1.134
diff -u -r1.134 main.c
--- src/main.c 2005/04/27 22:08:28 1.134
+++ src/main.c 2005/05/03 15:48:09
@@ -165,6 +165,9 @@
{ IF_SSL ("check-certificate"), 0, OPT_BOOLEAN, "checkcertificate", -1 },
{ "clobber", 0, OPT__CLOBBER, NULL, optional_argument },
{ "connect-timeout", 0, OPT_VALUE, "connecttimeout", -1 },
+#ifdef HAVE_ZLIB
+ { "compress", 'z', OPT_BOOLEAN, "compress", -1 },
+#endif
{ "continue", 'c', OPT_BOOLEAN, "continue", -1 },
{ "convert-links", 'k', OPT_BOOLEAN, "convertlinks", -1 },
{ "cookies", 0, OPT_BOOLEAN, "cookies", -1 },
@@ -539,6 +542,10 @@
--post-data=STRING use the POST method; send STRING as the data.\n"),
N_("\
--post-file=FILE use the POST method; send contents of FILE.\n"),
+#ifdef HAVE_ZLIB
+ N_("\
+ -z --compress request gzip http compression\n"),
+#endif
"\n",
#ifdef HAVE_SSL
Index: src/options.h
===================================================================
RCS file: /pack/anoncvs/wget/src/options.h,v
retrieving revision 1.52
diff -u -r1.52 options.h
--- src/options.h 2005/04/27 21:30:22 1.52
+++ src/options.h 2005/05/03 15:48:09
@@ -213,6 +213,11 @@
int ipv4_only; /* IPv4 connections have been requested. */
int ipv6_only; /* IPv4 connections have been requested. */
#endif
+
+#ifdef HAVE_ZLIB
+ int compress; /* enable gzip compression requests */
+#endif
+
enum {
prefer_ipv4,
prefer_ipv6,
Index: src/retr.c
===================================================================
RCS file: /pack/anoncvs/wget/src/retr.c,v
retrieving revision 1.96
diff -u -r1.96 retr.c
--- src/retr.c 2005/05/03 15:24:30 1.96
+++ src/retr.c 2005/05/03 15:48:09
@@ -43,6 +43,8 @@
#endif /* HAVE_STRING_H */
#include <assert.h>
+#include <zlib.h>
+
#include "wget.h"
#include "utils.h"
#include "retr.h"
@@ -170,6 +172,12 @@
return !ferror (out);
}
+/* Buffer size for zlib decompression, of course, bigger is better
+ since it means less cycles per inflate call. */
+#ifdef HAVE_ZLIB
+#define ZLIB_INFLATE_BUFFER_SIZE 0x10000
+#endif
+
/* Read the contents of file descriptor FD until it the connection
terminates or a read error occurs. The data is read in portions of
up to 16K and written to OUT as it arrives. If opt.verbose is set,
@@ -217,6 +225,19 @@
wgint sum_read = 0;
wgint sum_written = 0;
+#ifdef HAVE_ZLIB
+ /* zlib specific variables defines */
+ int wbits = -MAX_WBITS;
+ int err;
+ unsigned char debuf[ZLIB_INFLATE_BUFFER_SIZE];
+ unsigned long last = 0;
+ z_stream z;
+
+ z.zalloc = (alloc_func)Z_NULL;
+ z.zfree = (free_func)Z_NULL;
+ z.opaque = (voidpf)0;
+#endif
+
if (flags & rb_skip_startpos)
skip = startpos;
@@ -296,11 +317,66 @@
if (ret > 0)
{
sum_read += ret;
- if (!write_data (out, dlbuf, ret, &skip, &sum_written))
- {
- ret = -2;
- goto out_;
- }
+ if ((flags & rb_content_deflate) || (flags & rb_content_gzip))
+ {
+#ifdef HAVE_ZLIB
+ z.next_in = (unsigned char *) dlbuf;
+ z.avail_in = (unsigned int) ret;
+
+ /* first time thru read the compressed header and init zlib */
+ if (last == 0) {
+ if (flags & rb_content_gzip)
+ wbits = MAX_WBITS + 32;
+
+ if ((err = inflateInit2(&z, wbits)) != Z_OK) {
+ logprintf (LOG_NOTQUIET, "inflateInit2() : %s\n", z.msg);
+ ret = -2;
+ goto out_;
+ }
+ }
+
+ for (;;) {
+ z.avail_out = (int)sizeof(debuf);
+ z.next_out = debuf;
+
+ if ((err = inflate(&z, Z_SYNC_FLUSH)) != Z_OK) {
+ if (err != Z_STREAM_END) {
+ logprintf (LOG_NOTQUIET, "inflate() : %s\n", z.msg);
+ ret = -2;
+ goto out_;
+ }
+
+ }
+
+ /* XXX don't think we can skip a compressed buf */
+ if (!write_data(out, debuf, (z.total_out - last),
+ &skip, &sum_written))
+ {
+ ret = -2;
+ goto out_;
+ }
+
+
+ last = z.total_out;
+
+ if (z.avail_in == 0) {
+ if (err == Z_STREAM_END)
+ /* XXX http.c checks for these to
+ match hstat.len/contlen */
+ sum_written = sum_read;
+
+ break;
+ }
+
+ }
+#endif
+ }
+ else if (!write_data (out, dlbuf, ret, &skip, &sum_written))
+ {
+ ret = -2;
+ goto out_;
+ }
+
}
if (opt.limit_rate)
@@ -318,6 +394,9 @@
ret = -1;
out_:
+#ifdef HAVE_ZLIB
+ inflateEnd(&z);
+#endif
if (progress)
progress_finish (progress, ptimer_read (timer));
Index: src/retr.h
===================================================================
RCS file: /pack/anoncvs/wget/src/retr.h,v
retrieving revision 1.22
diff -u -r1.22 retr.h
--- src/retr.h 2005/03/20 15:07:40 1.22
+++ src/retr.h 2005/05/03 15:48:09
@@ -33,7 +33,9 @@
/* Flags for fd_read_body. */
enum {
rb_read_exactly = 1,
- rb_skip_startpos = 2
+ rb_skip_startpos = 2,
+ rb_content_deflate = 4,
+ rb_content_gzip = 16
};
int fd_read_body PARAMS ((int, FILE *, wgint, wgint, wgint *, wgint *, double *,