cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Support for GZIP Content-Encoding in HTTP responses

From: <niclists_at_nichines.com>
Date: Fri, 11 Apr 2003 16:20:11 +0100

On Fri, 11 Apr 2003 Daniel Stenberg <daniel_at_haxx.se> wrote:

Daniel,

>On Fri, 11 Apr 2003 niclists_at_nichines.com wrote:
>
>> Hi Nic!
>
>I have developed a patch for version 7.10.4 which adds support for the GZIP
>Content-Encoding method in HTTP responses.
>
>Whoa. This is next to unbelievable. Dan Fandrich posted a patch doing this,
>and he beat you with ~11 hours! ;-)

Damn! I searched around to see if it had been mentioned, I couldn't find
anything.

>
>> It also fixes a bug in the handling of Chunked+Encoded responses.
>
>What bug is that?

conn->keep.str needs to be updated to point to the chunk data. Is it safe
to just update it like this? It seems okay when I test it against
http://sourceforge.net/

--- http_chunks.c~1 2003-04-11 09:49:21.000000000 +0100
+++ http_chunks.c 2003-04-11 15:52:36.000000000 +0100
@@ -186,10 +186,16 @@
            break;

          case DEFLATE:
+ /* update conn->keep.str to point to the chunk data. */
+ conn->keep.str = datap;
+
            result = Curl_unencode_deflate_write(conn->data, &conn->keep,
piece);
            break;

          case GZIP:
+ /* update conn->keep.str to point to the chunk data. */
+ conn->keep.str = datap;
+
            result = Curl_unencode_gzip_write(conn->data, &conn->keep, piece);
            break;

>> It's a unified diff of 358 lines. Is anyone interested in this patch? If so
>> shall I post it to this list or something else?
>
>Sure, post it to the list!
>
>I am very interested in getting this into the sources, but since I just a few
>hours ago applied and commited Dan's version of the gzip Content-Encoding
>decoder, I would prefer if you two could compare each others' implementations
>and see if the currently committed one can be improved by yours, or if
>possibly it is easier to revert Dan's, apply yours and then get pieces of
>Dan's patch over ontop of yours... Whatever you think is best. You two are
>the ones with most clues in this area here.
>
>Getting a patch with this against 7.10.4 at this point would give me a head
>ache trying to apply...
>
>Thanks a lot for your efforts!

No problem.

At first glance I think it is one point each *8-) Dan's handles extended
headers but mine checks the CRC, which I don't think would be a big problem
to add to Dan's code. I'll look closer at Dan's stuff and see how it
compares. It's good to see that he had the same problem of having to cope
with fragmentation when dealing with the GZIP header.

To test the fragmentation handling I amended transfer.c and added a loop
around the call to Curl_unencode_deflate_write() to pass data in character
by character. By doing this I discovered that the inflate can return with
(DSIZ - z->avail_out) == 0 and Curl_client_write() didn't like a length of
0 so I would recommend the following...

--- content_encoding.c~1 2003-04-11 09:49:21.000000000 +0100
+++ content_encoding.c 2003-04-11 16:18:25.000000000 +0100
@@ -100,11 +100,13 @@

      status = inflate(z, Z_SYNC_FLUSH);
      if (status == Z_OK || status == Z_STREAM_END) {
- result = Curl_client_write(data, CLIENTWRITE_BODY, decomp,
+ if (DSIZ - z->avail_out) {
+ result = Curl_client_write(data, CLIENTWRITE_BODY, decomp,
                                   DSIZ - z->avail_out);
- /* if !CURLE_OK, clean up, return */
- if (result) {
- return exit_zlib(z, &k->zlib_init, result);
+ /* if !CURLE_OK, clean up, return */
+ if (result) {
+ return exit_zlib(z, &k->zlib_init, result);
+ }
        }

        /* Done?; clean up, return */
@@ -320,11 +322,13 @@

      status = inflate(z, Z_SYNC_FLUSH);
      if (status == Z_OK || status == Z_STREAM_END) {
- result = Curl_client_write(data, CLIENTWRITE_BODY, decomp,
+ if (DSIZ - z->avail_out) {
+ result = Curl_client_write(data, CLIENTWRITE_BODY, decomp,
                                   DSIZ - z->avail_out);
- /* if !CURLE_OK, clean up, return */
- if (result) {
- return exit_zlib(z, &k->zlib_init, result);
+ /* if !CURLE_OK, clean up, return */
+ if (result) {
+ return exit_zlib(z, &k->zlib_init, result);
+ }
        }

        /* Done?; clean up, return */

Regards,

Nic

-------------------------------------------------------
This SF.net email is sponsored by: Etnus, makers of TotalView, The debugger
for complex code. Debugging C/C++ programs can leave you feeling lost and
disoriented. TotalView can help you find your way. Available on major UNIX
and Linux platforms. Try it free. www.etnus.com
Received on 2003-04-11