15ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/***************************************************************************
25ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                                  _   _ ____  _
35ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *  Project                     ___| | | |  _ \| |
45ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                             / __| | | | |_) | |
55ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                            | (__| |_| |  _ <| |___
65ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *                             \___|\___/|_| \_\_____|
75ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
8e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
95ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This software is licensed as described in the file COPYING, which
115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * you should have received as part of this distribution. The terms
125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * are also available at http://curl.haxx.se/docs/copyright.html.
135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * You may opt to use, copy, modify, merge, publish, distribute and/or sell
155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * copies of the Software, and permit persons to whom the Software is
165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * furnished to do so, under the terms of the COPYING file.
175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * KIND, either express or implied.
205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *
215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen ***************************************************************************/
225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
23e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_setup.h"
245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef HAVE_LIBZ
265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "urldata.h"
285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <curl/curl.h>
295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "sendf.h"
305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "content_encoding.h"
315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "curl_memory.h"
325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "memdebug.h"
345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* Comment this out if zlib is always going to be at least ver. 1.2.0.4
365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   (doing so will reduce code size slightly). */
375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define OLD_ZLIB_SUPPORT 1
385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define DSIZ CURL_MAX_WRITE_SIZE /* buffer size for decompressed data */
405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define GZIP_MAGIC_0 0x1f
425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define GZIP_MAGIC_1 0x8b
435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* gzip flag byte */
455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define COMMENT      0x10 /* bit 4 set: file comment present */
505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define RESERVED     0xE0 /* bits 5..7: reserved */
515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
52e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic voidpf
53e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETzalloc_cb(voidpf opaque, unsigned int items, unsigned int size)
54e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
55e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  (void) opaque;
56e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  /* not a typo, keep it calloc() */
57e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  return (voidpf) calloc(items, size);
58e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
59e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
60e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void
61e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETzfree_cb(voidpf opaque, voidpf ptr)
62e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{
63e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  (void) opaque;
64e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  free(ptr);
65e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}
66e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic CURLcode
685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenprocess_zlib_error(struct connectdata *conn, z_stream *z)
695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct SessionHandle *data = conn->data;
715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(z->msg)
725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    failf (data, "Error while processing content unencoding: %s",
735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen           z->msg);
745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  else
755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    failf (data, "Error while processing content unencoding: "
765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen           "Unknown failure within decompression software.");
775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return CURLE_BAD_CONTENT_ENCODING;
795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic CURLcode
825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenexit_zlib(z_stream *z, zlibInitState *zlib_init, CURLcode result)
835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  inflateEnd(z);
855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  *zlib_init = ZLIB_UNINIT;
865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return result;
875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic CURLcode
905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monseninflate_stream(struct connectdata *conn,
915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen               struct SingleRequest *k)
925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  int allow_restart = 1;
945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  z_stream *z = &k->z;          /* zlib state structure */
955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  uInt nread = z->avail_in;
965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  Bytef *orig_in = z->next_in;
975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  int status;                   /* zlib status */
985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  CURLcode result = CURLE_OK;   /* Curl_client_write status */
995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  char *decomp;                 /* Put the decompressed data here. */
1005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* Dynamically allocate a buffer for decompression because it's uncommonly
1025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     large to hold on the stack */
1035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  decomp = malloc(DSIZ);
1045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(decomp == NULL) {
1055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
1065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
1075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* because the buffer size is fixed, iteratively decompress and transfer to
1095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     the client via client_write. */
110e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET  for(;;) {
1115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* (re)set buffer for decompressed output for every iteration */
1125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    z->next_out = (Bytef *)decomp;
1135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    z->avail_out = DSIZ;
1145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    status = inflate(z, Z_SYNC_FLUSH);
1165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(status == Z_OK || status == Z_STREAM_END) {
1175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      allow_restart = 0;
1189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      if((DSIZ - z->avail_out) && (!k->ignorebody)) {
1195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp,
1205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                                   DSIZ - z->avail_out);
1215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        /* if !CURLE_OK, clean up, return */
1225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        if(result) {
1235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen          free(decomp);
1245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen          return exit_zlib(z, &k->zlib_init, result);
1255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        }
1265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      }
1275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* Done? clean up, return */
1295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      if(status == Z_STREAM_END) {
1305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        free(decomp);
1315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        if(inflateEnd(z) == Z_OK)
1325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen          return exit_zlib(z, &k->zlib_init, result);
1335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        else
1345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen          return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
1355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      }
1365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* Done with these bytes, exit */
1389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels
1399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      /* status is always Z_OK at this point! */
1409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels      if(z->avail_in == 0) {
1415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        free(decomp);
1425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        return result;
1435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      }
1445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
1455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    else if(allow_restart && status == Z_DATA_ERROR) {
1465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* some servers seem to not generate zlib headers, so this is an attempt
1475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen         to fix and continue anyway */
1485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      (void) inflateEnd(z);     /* don't care about the return code */
1505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
1515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        free(decomp);
1525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
1535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      }
1545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      z->next_in = orig_in;
1555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      z->avail_in = nread;
1565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      allow_restart = 0;
1575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      continue;
1585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
1595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    else {                      /* Error; exit loop, handle below */
1605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      free(decomp);
1615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
1625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
1635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
1645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* Will never get here */
1655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
1665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCURLcode
1685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCurl_unencode_deflate_write(struct connectdata *conn,
1695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                            struct SingleRequest *k,
1705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                            ssize_t nread)
1715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
1725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  z_stream *z = &k->z;          /* zlib state structure */
1735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* Initialize zlib? */
1755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(k->zlib_init == ZLIB_UNINIT) {
176e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    memset(z, 0, sizeof(z_stream));
177e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    z->zalloc = (alloc_func)zalloc_cb;
178e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    z->zfree = (free_func)zfree_cb;
179e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
1805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(inflateInit(z) != Z_OK)
1815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return process_zlib_error(conn, z);
1825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    k->zlib_init = ZLIB_INIT;
1835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
1845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* Set the compressed input when this function is called */
1865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  z->next_in = (Bytef *)k->str;
1875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  z->avail_in = (uInt)nread;
1885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* Now uncompress the data */
1905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return inflate_stream(conn, k);
1915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
1925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
1935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifdef OLD_ZLIB_SUPPORT
1945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* Skip over the gzip header */
1955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic enum {
1965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  GZIP_OK,
1975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  GZIP_BAD,
1985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  GZIP_UNDERFLOW
1995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen)
2005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
2015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  int method, flags;
2025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  const ssize_t totallen = len;
2035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* The shortest header is 10 bytes */
2055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(len < 10)
2065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return GZIP_UNDERFLOW;
2075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1))
2095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return GZIP_BAD;
2105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  method = data[2];
2125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  flags = data[3];
2135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(method != Z_DEFLATED || (flags & RESERVED) != 0) {
2155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Can't handle this compression method or unknown flag */
2165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return GZIP_BAD;
2175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
2185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* Skip over time, xflags, OS code and all previous bytes */
2205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  len -= 10;
2215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  data += 10;
2225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(flags & EXTRA_FIELD) {
2245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ssize_t extra_len;
2255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(len < 2)
2275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return GZIP_UNDERFLOW;
2285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    extra_len = (data[1] << 8) | data[0];
2305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(len < (extra_len+2))
2325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return GZIP_UNDERFLOW;
2335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    len -= (extra_len + 2);
2355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    data += (extra_len + 2);
2365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
2375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(flags & ORIG_NAME) {
2395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Skip over NUL-terminated file name */
2405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    while(len && *data) {
2415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      --len;
2425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      ++data;
2435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
2445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(!len || *data)
2455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return GZIP_UNDERFLOW;
2465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Skip over the NUL */
2485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    --len;
2495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ++data;
2505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
2515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(flags & COMMENT) {
2535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Skip over NUL-terminated comment */
2545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    while(len && *data) {
2555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      --len;
2565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      ++data;
2575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
2585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(!len || *data)
2595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return GZIP_UNDERFLOW;
2605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Skip over the NUL */
2625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    --len;
2635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
2645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(flags & HEAD_CRC) {
2665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(len < 2)
2675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return GZIP_UNDERFLOW;
2685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    len -= 2;
2705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
2715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  *headerlen = totallen - len;
2735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return GZIP_OK;
2745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
2755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
2765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCURLcode
2785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian MonsenCurl_unencode_gzip_write(struct connectdata *conn,
2795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                         struct SingleRequest *k,
2805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen                         ssize_t nread)
2815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
2825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  z_stream *z = &k->z;          /* zlib state structure */
2835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* Initialize zlib? */
2855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(k->zlib_init == ZLIB_UNINIT) {
286e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    memset(z, 0, sizeof(z_stream));
287e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    z->zalloc = (alloc_func)zalloc_cb;
288e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    z->zfree = (free_func)zfree_cb;
2895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
2905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(strcmp(zlibVersion(), "1.2.0.4") >= 0) {
2915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
2925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      if(inflateInit2(z, MAX_WBITS+32) != Z_OK) {
2935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        return process_zlib_error(conn, z);
2945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      }
2955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
2965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
2975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    else {
2985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* we must parse the gzip header ourselves */
2995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
3005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        return process_zlib_error(conn, z);
3015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      }
3025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      k->zlib_init = ZLIB_INIT;   /* Initial call state */
3035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
3045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
3055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(k->zlib_init == ZLIB_INIT_GZIP) {
3075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Let zlib handle the gzip decompression entirely */
3085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    z->next_in = (Bytef *)k->str;
3095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    z->avail_in = (uInt)nread;
3105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Now uncompress the data */
3115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return inflate_stream(conn, k);
3125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
3135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#ifndef OLD_ZLIB_SUPPORT
3155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* Support for old zlib versions is compiled away and we are running with
3165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen     an old version, so return an error. */
3175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return exit_zlib(z, &k->zlib_init, CURLE_FUNCTION_NOT_FOUND);
3185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#else
3205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* This next mess is to get around the potential case where there isn't
3215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   * enough data passed in to skip over the gzip header.  If that happens, we
3225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   * malloc a block and copy what we have then wait for the next call.  If
3235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   * there still isn't enough (this is definitely a worst-case scenario), we
3245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   * make the block bigger, copy the next part in and keep waiting.
3255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   *
3265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   * This is only required with zlib versions < 1.2.0.4 as newer versions
3275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   * can handle the gzip header themselves.
3285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen   */
3295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  switch (k->zlib_init) {
3315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* Skip over gzip header? */
3325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  case ZLIB_INIT:
3335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  {
3345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Initial call state */
3355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ssize_t hlen;
3365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    switch (check_gzip_header((unsigned char *)k->str, nread, &hlen)) {
3385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    case GZIP_OK:
3395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      z->next_in = (Bytef *)k->str + hlen;
3405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      z->avail_in = (uInt)(nread - hlen);
3415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
3425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      break;
3435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    case GZIP_UNDERFLOW:
3455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* We need more data so we can find the end of the gzip header.  It's
3465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * possible that the memory block we malloc here will never be freed if
3475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * the transfer abruptly aborts after this point.  Since it's unlikely
3485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * that circumstances will be right for this code path to be followed in
3495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * the first place, and it's even more unlikely for a transfer to fail
3505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       * immediately afterwards, it should seldom be a problem.
3515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen       */
3525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      z->avail_in = (uInt)nread;
3535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      z->next_in = malloc(z->avail_in);
3545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      if(z->next_in == NULL) {
3555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen        return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
3565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      }
3575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      memcpy(z->next_in, k->str, z->avail_in);
3585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      k->zlib_init = ZLIB_GZIP_HEADER;   /* Need more gzip header data state */
3595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* We don't have any data to inflate yet */
3605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return CURLE_OK;
3615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    case GZIP_BAD:
3635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    default:
3645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
3655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
3665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
3685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  break;
3695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  case ZLIB_GZIP_HEADER:
3715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  {
3725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Need more gzip header data state */
3735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    ssize_t hlen;
3745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    unsigned char *oldblock = z->next_in;
3755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    z->avail_in += (uInt)nread;
3775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    z->next_in = realloc(z->next_in, z->avail_in);
3785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    if(z->next_in == NULL) {
3795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      free(oldblock);
3805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY);
3815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
3825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Append the new block of data to the previous one */
3835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    memcpy(z->next_in + z->avail_in - nread, k->str, nread);
3845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    switch (check_gzip_header(z->next_in, z->avail_in, &hlen)) {
3865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    case GZIP_OK:
3875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* This is the zlib stream data */
3885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      free(z->next_in);
3895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* Don't point into the malloced block since we just freed it */
3905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in;
3915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      z->avail_in = (uInt)(z->avail_in - hlen);
3925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      k->zlib_init = ZLIB_GZIP_INFLATING;   /* Inflating stream state */
3935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      break;
3945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    case GZIP_UNDERFLOW:
3965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      /* We still don't have any data to inflate! */
3975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return CURLE_OK;
3985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
3995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    case GZIP_BAD:
4005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    default:
4015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      free(z->next_in);
4025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen      return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z));
4035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    }
4045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
4065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  break;
4075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  case ZLIB_GZIP_INFLATING:
4095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  default:
4105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* Inflating stream state */
4115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    z->next_in = (Bytef *)k->str;
4125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    z->avail_in = (uInt)nread;
4135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    break;
4145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
4155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(z->avail_in == 0) {
4175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    /* We don't have any data to inflate; wait until next time */
4185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    return CURLE_OK;
4195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  }
4205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  /* We've parsed the header, now uncompress the data */
4225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  return inflate_stream(conn, k);
4235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif
4245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
4255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenvoid Curl_unencode_cleanup(struct connectdata *conn)
4275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{
4285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct SessionHandle *data = conn->data;
4295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  struct SingleRequest *k = &data->req;
4305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  z_stream *z = &k->z;
4315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen  if(k->zlib_init != ZLIB_UNINIT)
4325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen    (void) exit_zlib(z, &k->zlib_init, CURLE_OK);
4335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}
4345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen
4355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif /* HAVE_LIBZ */
436