Home | History | Annotate | Download | only in lib
      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel (at) haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.haxx.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  ***************************************************************************/
     22 
     23 #include "curl_setup.h"
     24 
     25 #include "urldata.h"
     26 #include <curl/curl.h>
     27 #include <stddef.h>
     28 
     29 #ifdef HAVE_ZLIB_H
     30 #include <zlib.h>
     31 #ifdef __SYMBIAN32__
     32 /* zlib pollutes the namespace with this definition */
     33 #undef WIN32
     34 #endif
     35 #endif
     36 
     37 #ifdef HAVE_BROTLI
     38 #include <brotli/decode.h>
     39 #endif
     40 
     41 #include "sendf.h"
     42 #include "http.h"
     43 #include "content_encoding.h"
     44 #include "strdup.h"
     45 #include "strcase.h"
     46 #include "curl_memory.h"
     47 #include "memdebug.h"
     48 
     49 #define CONTENT_ENCODING_DEFAULT  "identity"
     50 
     51 #ifndef CURL_DISABLE_HTTP
     52 
     53 #define DSIZ CURL_MAX_WRITE_SIZE /* buffer size for decompressed data */
     54 
     55 
     56 #ifdef HAVE_LIBZ
     57 
     58 /* Comment this out if zlib is always going to be at least ver. 1.2.0.4
     59    (doing so will reduce code size slightly). */
     60 #define OLD_ZLIB_SUPPORT 1
     61 
     62 #define GZIP_MAGIC_0 0x1f
     63 #define GZIP_MAGIC_1 0x8b
     64 
     65 /* gzip flag byte */
     66 #define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
     67 #define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
     68 #define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
     69 #define ORIG_NAME    0x08 /* bit 3 set: original file name present */
     70 #define COMMENT      0x10 /* bit 4 set: file comment present */
     71 #define RESERVED     0xE0 /* bits 5..7: reserved */
     72 
     73 typedef enum {
     74   ZLIB_UNINIT,          /* uninitialized */
     75   ZLIB_INIT,            /* initialized */
     76   ZLIB_INFLATING,       /* Inflating started. */
     77   ZLIB_GZIP_HEADER,     /* reading gzip header */
     78   ZLIB_GZIP_TRAILER,    /* reading gzip trailer */
     79   ZLIB_GZIP_INFLATING,  /* inflating gzip stream */
     80   ZLIB_INIT_GZIP        /* initialized in transparent gzip mode */
     81 } zlibInitState;
     82 
     83 /* Writer parameters. */
     84 typedef struct {
     85   zlibInitState zlib_init;   /* zlib init state */
     86   uInt trailerlen;           /* Remaining trailer byte count. */
     87   z_stream z;                /* State structure for zlib. */
     88 }  zlib_params;
     89 
     90 
     91 static voidpf
     92 zalloc_cb(voidpf opaque, unsigned int items, unsigned int size)
     93 {
     94   (void) opaque;
     95   /* not a typo, keep it calloc() */
     96   return (voidpf) calloc(items, size);
     97 }
     98 
     99 static void
    100 zfree_cb(voidpf opaque, voidpf ptr)
    101 {
    102   (void) opaque;
    103   free(ptr);
    104 }
    105 
    106 static CURLcode
    107 process_zlib_error(struct connectdata *conn, z_stream *z)
    108 {
    109   struct Curl_easy *data = conn->data;
    110   if(z->msg)
    111     failf(data, "Error while processing content unencoding: %s",
    112           z->msg);
    113   else
    114     failf(data, "Error while processing content unencoding: "
    115           "Unknown failure within decompression software.");
    116 
    117   return CURLE_BAD_CONTENT_ENCODING;
    118 }
    119 
    120 static CURLcode
    121 exit_zlib(struct connectdata *conn,
    122           z_stream *z, zlibInitState *zlib_init, CURLcode result)
    123 {
    124   if(*zlib_init == ZLIB_GZIP_HEADER)
    125     Curl_safefree(z->next_in);
    126 
    127   if(*zlib_init != ZLIB_UNINIT) {
    128     if(inflateEnd(z) != Z_OK && result == CURLE_OK)
    129       result = process_zlib_error(conn, z);
    130     *zlib_init = ZLIB_UNINIT;
    131   }
    132 
    133   return result;
    134 }
    135 
    136 static CURLcode process_trailer(struct connectdata *conn, zlib_params *zp)
    137 {
    138   z_stream *z = &zp->z;
    139   CURLcode result = CURLE_OK;
    140   uInt len = z->avail_in < zp->trailerlen? z->avail_in: zp->trailerlen;
    141 
    142   /* Consume expected trailer bytes. Terminate stream if exhausted.
    143      Issue an error if unexpected bytes follow. */
    144 
    145   zp->trailerlen -= len;
    146   z->avail_in -= len;
    147   z->next_in += len;
    148   if(z->avail_in)
    149     result = CURLE_WRITE_ERROR;
    150   if(result || !zp->trailerlen)
    151     result = exit_zlib(conn, z, &zp->zlib_init, result);
    152   else {
    153     /* Only occurs for gzip with zlib < 1.2.0.4. */
    154     zp->zlib_init = ZLIB_GZIP_TRAILER;
    155   }
    156   return result;
    157 }
    158 
    159 static CURLcode inflate_stream(struct connectdata *conn,
    160                                contenc_writer *writer, zlibInitState started)
    161 {
    162   zlib_params *zp = (zlib_params *) &writer->params;
    163   z_stream *z = &zp->z;         /* zlib state structure */
    164   uInt nread = z->avail_in;
    165   Bytef *orig_in = z->next_in;
    166   int status;                   /* zlib status */
    167   bool done = FALSE;
    168   CURLcode result = CURLE_OK;   /* Curl_client_write status */
    169   char *decomp;                 /* Put the decompressed data here. */
    170 
    171   /* Check state. */
    172   if(zp->zlib_init != ZLIB_INIT &&
    173      zp->zlib_init != ZLIB_INFLATING &&
    174      zp->zlib_init != ZLIB_INIT_GZIP &&
    175      zp->zlib_init != ZLIB_GZIP_INFLATING)
    176     return exit_zlib(conn, z, &zp->zlib_init, CURLE_WRITE_ERROR);
    177 
    178   /* Dynamically allocate a buffer for decompression because it's uncommonly
    179      large to hold on the stack */
    180   decomp = malloc(DSIZ);
    181   if(decomp == NULL)
    182     return exit_zlib(conn, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
    183 
    184   /* because the buffer size is fixed, iteratively decompress and transfer to
    185      the client via downstream_write function. */
    186   while(!done) {
    187     done = TRUE;
    188 
    189     /* (re)set buffer for decompressed output for every iteration */
    190     z->next_out = (Bytef *) decomp;
    191     z->avail_out = DSIZ;
    192 
    193     status = inflate(z, Z_BLOCK);
    194 
    195     /* Flush output data if some. */
    196     if(z->avail_out != DSIZ) {
    197       if(status == Z_OK || status == Z_STREAM_END) {
    198         zp->zlib_init = started;      /* Data started. */
    199         result = Curl_unencode_write(conn, writer->downstream, decomp,
    200                                      DSIZ - z->avail_out);
    201         if(result) {
    202           exit_zlib(conn, z, &zp->zlib_init, result);
    203           break;
    204         }
    205       }
    206     }
    207 
    208     /* Dispatch by inflate() status. */
    209     switch(status) {
    210     case Z_OK:
    211       /* Always loop: there may be unflushed latched data in zlib state. */
    212       done = FALSE;
    213       break;
    214     case Z_BUF_ERROR:
    215       /* No more data to flush: just exit loop. */
    216       break;
    217     case Z_STREAM_END:
    218       result = process_trailer(conn, zp);
    219       break;
    220     case Z_DATA_ERROR:
    221       /* some servers seem to not generate zlib headers, so this is an attempt
    222          to fix and continue anyway */
    223       if(zp->zlib_init == ZLIB_INIT) {
    224         /* Do not use inflateReset2(): only available since zlib 1.2.3.4. */
    225         (void) inflateEnd(z);     /* don't care about the return code */
    226         if(inflateInit2(z, -MAX_WBITS) == Z_OK) {
    227           z->next_in = orig_in;
    228           z->avail_in = nread;
    229           zp->zlib_init = ZLIB_INFLATING;
    230           done = FALSE;
    231           break;
    232         }
    233         zp->zlib_init = ZLIB_UNINIT;    /* inflateEnd() already called. */
    234       }
    235       /* FALLTHROUGH */
    236     default:
    237       result = exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z));
    238       break;
    239     }
    240   }
    241   free(decomp);
    242 
    243   /* We're about to leave this call so the `nread' data bytes won't be seen
    244      again. If we are in a state that would wrongly allow restart in raw mode
    245      at the next call, assume output has already started. */
    246   if(nread && zp->zlib_init == ZLIB_INIT)
    247     zp->zlib_init = started;      /* Cannot restart anymore. */
    248 
    249   return result;
    250 }
    251 
    252 
    253 /* Deflate handler. */
    254 static CURLcode deflate_init_writer(struct connectdata *conn,
    255                                     contenc_writer *writer)
    256 {
    257   zlib_params *zp = (zlib_params *) &writer->params;
    258   z_stream *z = &zp->z;     /* zlib state structure */
    259 
    260   if(!writer->downstream)
    261     return CURLE_WRITE_ERROR;
    262 
    263   /* Initialize zlib */
    264   z->zalloc = (alloc_func) zalloc_cb;
    265   z->zfree = (free_func) zfree_cb;
    266 
    267   if(inflateInit(z) != Z_OK)
    268     return process_zlib_error(conn, z);
    269   zp->zlib_init = ZLIB_INIT;
    270   return CURLE_OK;
    271 }
    272 
    273 static CURLcode deflate_unencode_write(struct connectdata *conn,
    274                                        contenc_writer *writer,
    275                                        const char *buf, size_t nbytes)
    276 {
    277   zlib_params *zp = (zlib_params *) &writer->params;
    278   z_stream *z = &zp->z;     /* zlib state structure */
    279 
    280   /* Set the compressed input when this function is called */
    281   z->next_in = (Bytef *) buf;
    282   z->avail_in = (uInt) nbytes;
    283 
    284   /* Now uncompress the data */
    285   return inflate_stream(conn, writer, ZLIB_INFLATING);
    286 }
    287 
    288 static void deflate_close_writer(struct connectdata *conn,
    289                                  contenc_writer *writer)
    290 {
    291   zlib_params *zp = (zlib_params *) &writer->params;
    292   z_stream *z = &zp->z;     /* zlib state structure */
    293 
    294   exit_zlib(conn, z, &zp->zlib_init, CURLE_OK);
    295 }
    296 
    297 static const content_encoding deflate_encoding = {
    298   "deflate",
    299   NULL,
    300   deflate_init_writer,
    301   deflate_unencode_write,
    302   deflate_close_writer,
    303   sizeof(zlib_params)
    304 };
    305 
    306 
    307 /* Gzip handler. */
    308 static CURLcode gzip_init_writer(struct connectdata *conn,
    309                                  contenc_writer *writer)
    310 {
    311   zlib_params *zp = (zlib_params *) &writer->params;
    312   z_stream *z = &zp->z;     /* zlib state structure */
    313 
    314   if(!writer->downstream)
    315     return CURLE_WRITE_ERROR;
    316 
    317   /* Initialize zlib */
    318   z->zalloc = (alloc_func) zalloc_cb;
    319   z->zfree = (free_func) zfree_cb;
    320 
    321   if(strcmp(zlibVersion(), "1.2.0.4") >= 0) {
    322     /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
    323     if(inflateInit2(z, MAX_WBITS + 32) != Z_OK) {
    324       return process_zlib_error(conn, z);
    325     }
    326     zp->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
    327   }
    328   else {
    329     /* we must parse the gzip header and trailer ourselves */
    330     if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
    331       return process_zlib_error(conn, z);
    332     }
    333     zp->trailerlen = 8; /* A CRC-32 and a 32-bit input size (RFC 1952, 2.2) */
    334     zp->zlib_init = ZLIB_INIT; /* Initial call state */
    335   }
    336 
    337   return CURLE_OK;
    338 }
    339 
    340 #ifdef OLD_ZLIB_SUPPORT
    341 /* Skip over the gzip header */
    342 static enum {
    343   GZIP_OK,
    344   GZIP_BAD,
    345   GZIP_UNDERFLOW
    346 } check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen)
    347 {
    348   int method, flags;
    349   const ssize_t totallen = len;
    350 
    351   /* The shortest header is 10 bytes */
    352   if(len < 10)
    353     return GZIP_UNDERFLOW;
    354 
    355   if((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1))
    356     return GZIP_BAD;
    357 
    358   method = data[2];
    359   flags = data[3];
    360 
    361   if(method != Z_DEFLATED || (flags & RESERVED) != 0) {
    362     /* Can't handle this compression method or unknown flag */
    363     return GZIP_BAD;
    364   }
    365 
    366   /* Skip over time, xflags, OS code and all previous bytes */
    367   len -= 10;
    368   data += 10;
    369 
    370   if(flags & EXTRA_FIELD) {
    371     ssize_t extra_len;
    372 
    373     if(len < 2)
    374       return GZIP_UNDERFLOW;
    375 
    376     extra_len = (data[1] << 8) | data[0];
    377 
    378     if(len < (extra_len + 2))
    379       return GZIP_UNDERFLOW;
    380 
    381     len -= (extra_len + 2);
    382     data += (extra_len + 2);
    383   }
    384 
    385   if(flags & ORIG_NAME) {
    386     /* Skip over NUL-terminated file name */
    387     while(len && *data) {
    388       --len;
    389       ++data;
    390     }
    391     if(!len || *data)
    392       return GZIP_UNDERFLOW;
    393 
    394     /* Skip over the NUL */
    395     --len;
    396     ++data;
    397   }
    398 
    399   if(flags & COMMENT) {
    400     /* Skip over NUL-terminated comment */
    401     while(len && *data) {
    402       --len;
    403       ++data;
    404     }
    405     if(!len || *data)
    406       return GZIP_UNDERFLOW;
    407 
    408     /* Skip over the NUL */
    409     --len;
    410   }
    411 
    412   if(flags & HEAD_CRC) {
    413     if(len < 2)
    414       return GZIP_UNDERFLOW;
    415 
    416     len -= 2;
    417   }
    418 
    419   *headerlen = totallen - len;
    420   return GZIP_OK;
    421 }
    422 #endif
    423 
    424 static CURLcode gzip_unencode_write(struct connectdata *conn,
    425                                     contenc_writer *writer,
    426                                     const char *buf, size_t nbytes)
    427 {
    428   zlib_params *zp = (zlib_params *) &writer->params;
    429   z_stream *z = &zp->z;     /* zlib state structure */
    430 
    431   if(zp->zlib_init == ZLIB_INIT_GZIP) {
    432     /* Let zlib handle the gzip decompression entirely */
    433     z->next_in = (Bytef *) buf;
    434     z->avail_in = (uInt) nbytes;
    435     /* Now uncompress the data */
    436     return inflate_stream(conn, writer, ZLIB_INIT_GZIP);
    437   }
    438 
    439 #ifndef OLD_ZLIB_SUPPORT
    440   /* Support for old zlib versions is compiled away and we are running with
    441      an old version, so return an error. */
    442   return exit_zlib(conn, z, &zp->zlib_init, CURLE_WRITE_ERROR);
    443 
    444 #else
    445   /* This next mess is to get around the potential case where there isn't
    446    * enough data passed in to skip over the gzip header.  If that happens, we
    447    * malloc a block and copy what we have then wait for the next call.  If
    448    * there still isn't enough (this is definitely a worst-case scenario), we
    449    * make the block bigger, copy the next part in and keep waiting.
    450    *
    451    * This is only required with zlib versions < 1.2.0.4 as newer versions
    452    * can handle the gzip header themselves.
    453    */
    454 
    455   switch(zp->zlib_init) {
    456   /* Skip over gzip header? */
    457   case ZLIB_INIT:
    458   {
    459     /* Initial call state */
    460     ssize_t hlen;
    461 
    462     switch(check_gzip_header((unsigned char *) buf, nbytes, &hlen)) {
    463     case GZIP_OK:
    464       z->next_in = (Bytef *) buf + hlen;
    465       z->avail_in = (uInt) (nbytes - hlen);
    466       zp->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
    467       break;
    468 
    469     case GZIP_UNDERFLOW:
    470       /* We need more data so we can find the end of the gzip header.  It's
    471        * possible that the memory block we malloc here will never be freed if
    472        * the transfer abruptly aborts after this point.  Since it's unlikely
    473        * that circumstances will be right for this code path to be followed in
    474        * the first place, and it's even more unlikely for a transfer to fail
    475        * immediately afterwards, it should seldom be a problem.
    476        */
    477       z->avail_in = (uInt) nbytes;
    478       z->next_in = malloc(z->avail_in);
    479       if(z->next_in == NULL) {
    480         return exit_zlib(conn, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
    481       }
    482       memcpy(z->next_in, buf, z->avail_in);
    483       zp->zlib_init = ZLIB_GZIP_HEADER;  /* Need more gzip header data state */
    484       /* We don't have any data to inflate yet */
    485       return CURLE_OK;
    486 
    487     case GZIP_BAD:
    488     default:
    489       return exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z));
    490     }
    491 
    492   }
    493   break;
    494 
    495   case ZLIB_GZIP_HEADER:
    496   {
    497     /* Need more gzip header data state */
    498     ssize_t hlen;
    499     z->avail_in += (uInt) nbytes;
    500     z->next_in = Curl_saferealloc(z->next_in, z->avail_in);
    501     if(z->next_in == NULL) {
    502       return exit_zlib(conn, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
    503     }
    504     /* Append the new block of data to the previous one */
    505     memcpy(z->next_in + z->avail_in - nbytes, buf, nbytes);
    506 
    507     switch(check_gzip_header(z->next_in, z->avail_in, &hlen)) {
    508     case GZIP_OK:
    509       /* This is the zlib stream data */
    510       free(z->next_in);
    511       /* Don't point into the malloced block since we just freed it */
    512       z->next_in = (Bytef *) buf + hlen + nbytes - z->avail_in;
    513       z->avail_in = (uInt) (z->avail_in - hlen);
    514       zp->zlib_init = ZLIB_GZIP_INFLATING;   /* Inflating stream state */
    515       break;
    516 
    517     case GZIP_UNDERFLOW:
    518       /* We still don't have any data to inflate! */
    519       return CURLE_OK;
    520 
    521     case GZIP_BAD:
    522     default:
    523       return exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z));
    524     }
    525 
    526   }
    527   break;
    528 
    529   case ZLIB_GZIP_TRAILER:
    530     z->next_in = (Bytef *) buf;
    531     z->avail_in = (uInt) nbytes;
    532     return process_trailer(conn, zp);
    533 
    534   case ZLIB_GZIP_INFLATING:
    535   default:
    536     /* Inflating stream state */
    537     z->next_in = (Bytef *) buf;
    538     z->avail_in = (uInt) nbytes;
    539     break;
    540   }
    541 
    542   if(z->avail_in == 0) {
    543     /* We don't have any data to inflate; wait until next time */
    544     return CURLE_OK;
    545   }
    546 
    547   /* We've parsed the header, now uncompress the data */
    548   return inflate_stream(conn, writer, ZLIB_GZIP_INFLATING);
    549 #endif
    550 }
    551 
    552 static void gzip_close_writer(struct connectdata *conn,
    553                               contenc_writer *writer)
    554 {
    555   zlib_params *zp = (zlib_params *) &writer->params;
    556   z_stream *z = &zp->z;     /* zlib state structure */
    557 
    558   exit_zlib(conn, z, &zp->zlib_init, CURLE_OK);
    559 }
    560 
    561 static const content_encoding gzip_encoding = {
    562   "gzip",
    563   "x-gzip",
    564   gzip_init_writer,
    565   gzip_unencode_write,
    566   gzip_close_writer,
    567   sizeof(zlib_params)
    568 };
    569 
    570 #endif /* HAVE_LIBZ */
    571 
    572 
    573 #ifdef HAVE_BROTLI
    574 
    575 /* Writer parameters. */
    576 typedef struct {
    577   BrotliDecoderState *br;    /* State structure for brotli. */
    578 }  brotli_params;
    579 
    580 
    581 static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
    582 {
    583   switch(be) {
    584   case BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:
    585   case BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:
    586   case BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:
    587   case BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:
    588   case BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:
    589   case BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:
    590   case BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:
    591   case BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:
    592   case BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:
    593   case BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:
    594   case BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:
    595   case BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:
    596   case BROTLI_DECODER_ERROR_FORMAT_PADDING_1:
    597   case BROTLI_DECODER_ERROR_FORMAT_PADDING_2:
    598 #ifdef BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY
    599   case BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY:
    600 #endif
    601 #ifdef BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET
    602   case BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:
    603 #endif
    604   case BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:
    605     return CURLE_BAD_CONTENT_ENCODING;
    606   case BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:
    607   case BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:
    608   case BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:
    609   case BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:
    610   case BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:
    611   case BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:
    612     return CURLE_OUT_OF_MEMORY;
    613   default:
    614     break;
    615   }
    616   return CURLE_WRITE_ERROR;
    617 }
    618 
    619 static CURLcode brotli_init_writer(struct connectdata *conn,
    620                                    contenc_writer *writer)
    621 {
    622   brotli_params *bp = (brotli_params *) &writer->params;
    623 
    624   (void) conn;
    625 
    626   if(!writer->downstream)
    627     return CURLE_WRITE_ERROR;
    628 
    629   bp->br = BrotliDecoderCreateInstance(NULL, NULL, NULL);
    630   return bp->br? CURLE_OK: CURLE_OUT_OF_MEMORY;
    631 }
    632 
    633 static CURLcode brotli_unencode_write(struct connectdata *conn,
    634                                       contenc_writer *writer,
    635                                       const char *buf, size_t nbytes)
    636 {
    637   brotli_params *bp = (brotli_params *) &writer->params;
    638   const uint8_t *src = (const uint8_t *) buf;
    639   char *decomp;
    640   uint8_t *dst;
    641   size_t dstleft;
    642   CURLcode result = CURLE_OK;
    643   BrotliDecoderResult r = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT;
    644 
    645   if(!bp->br)
    646     return CURLE_WRITE_ERROR;  /* Stream already ended. */
    647 
    648   decomp = malloc(DSIZ);
    649   if(!decomp)
    650     return CURLE_OUT_OF_MEMORY;
    651 
    652   while((nbytes || r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) &&
    653         result == CURLE_OK) {
    654     dst = (uint8_t *) decomp;
    655     dstleft = DSIZ;
    656     r = BrotliDecoderDecompressStream(bp->br,
    657                                       &nbytes, &src, &dstleft, &dst, NULL);
    658     result = Curl_unencode_write(conn, writer->downstream,
    659                                  decomp, DSIZ - dstleft);
    660     if(result)
    661       break;
    662     switch(r) {
    663     case BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:
    664     case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:
    665       break;
    666     case BROTLI_DECODER_RESULT_SUCCESS:
    667       BrotliDecoderDestroyInstance(bp->br);
    668       bp->br = NULL;
    669       if(nbytes)
    670         result = CURLE_WRITE_ERROR;
    671       break;
    672     default:
    673       result = brotli_map_error(BrotliDecoderGetErrorCode(bp->br));
    674       break;
    675     }
    676   }
    677   free(decomp);
    678   return result;
    679 }
    680 
    681 static void brotli_close_writer(struct connectdata *conn,
    682                                 contenc_writer *writer)
    683 {
    684   brotli_params *bp = (brotli_params *) &writer->params;
    685 
    686   (void) conn;
    687 
    688   if(bp->br) {
    689     BrotliDecoderDestroyInstance(bp->br);
    690     bp->br = NULL;
    691   }
    692 }
    693 
    694 static const content_encoding brotli_encoding = {
    695   "br",
    696   NULL,
    697   brotli_init_writer,
    698   brotli_unencode_write,
    699   brotli_close_writer,
    700   sizeof(brotli_params)
    701 };
    702 #endif
    703 
    704 
    705 /* Identity handler. */
    706 static CURLcode identity_init_writer(struct connectdata *conn,
    707                                      contenc_writer *writer)
    708 {
    709   (void) conn;
    710   return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
    711 }
    712 
    713 static CURLcode identity_unencode_write(struct connectdata *conn,
    714                                         contenc_writer *writer,
    715                                         const char *buf, size_t nbytes)
    716 {
    717   return Curl_unencode_write(conn, writer->downstream, buf, nbytes);
    718 }
    719 
    720 static void identity_close_writer(struct connectdata *conn,
    721                                   contenc_writer *writer)
    722 {
    723   (void) conn;
    724   (void) writer;
    725 }
    726 
    727 static const content_encoding identity_encoding = {
    728   "identity",
    729   NULL,
    730   identity_init_writer,
    731   identity_unencode_write,
    732   identity_close_writer,
    733   0
    734 };
    735 
    736 
    737 /* supported content encodings table. */
    738 static const content_encoding * const encodings[] = {
    739   &identity_encoding,
    740 #ifdef HAVE_LIBZ
    741   &deflate_encoding,
    742   &gzip_encoding,
    743 #endif
    744 #ifdef HAVE_BROTLI
    745   &brotli_encoding,
    746 #endif
    747   NULL
    748 };
    749 
    750 
    751 /* Return a list of comma-separated names of supported encodings. */
    752 char *Curl_all_content_encodings(void)
    753 {
    754   size_t len = 0;
    755   const content_encoding * const *cep;
    756   const content_encoding *ce;
    757   char *ace;
    758   char *p;
    759 
    760   for(cep = encodings; *cep; cep++) {
    761     ce = *cep;
    762     if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT))
    763       len += strlen(ce->name) + 2;
    764   }
    765 
    766   if(!len)
    767     return strdup(CONTENT_ENCODING_DEFAULT);
    768 
    769   ace = malloc(len);
    770   if(ace) {
    771     p = ace;
    772     for(cep = encodings; *cep; cep++) {
    773       ce = *cep;
    774       if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) {
    775         strcpy(p, ce->name);
    776         p += strlen(p);
    777         *p++ = ',';
    778         *p++ = ' ';
    779       }
    780     }
    781     p[-2] = '\0';
    782   }
    783 
    784   return ace;
    785 }
    786 
    787 
    788 /* Real client writer: no downstream. */
    789 static CURLcode client_init_writer(struct connectdata *conn,
    790                                    contenc_writer *writer)
    791 {
    792   (void) conn;
    793   return writer->downstream? CURLE_WRITE_ERROR: CURLE_OK;
    794 }
    795 
    796 static CURLcode client_unencode_write(struct connectdata *conn,
    797                                       contenc_writer *writer,
    798                                       const char *buf, size_t nbytes)
    799 {
    800   struct Curl_easy *data = conn->data;
    801   struct SingleRequest *k = &data->req;
    802 
    803   (void) writer;
    804 
    805   if(!nbytes || k->ignorebody)
    806     return CURLE_OK;
    807 
    808   return Curl_client_write(conn, CLIENTWRITE_BODY, (char *) buf, nbytes);
    809 }
    810 
    811 static void client_close_writer(struct connectdata *conn,
    812                                 contenc_writer *writer)
    813 {
    814   (void) conn;
    815   (void) writer;
    816 }
    817 
    818 static const content_encoding client_encoding = {
    819   NULL,
    820   NULL,
    821   client_init_writer,
    822   client_unencode_write,
    823   client_close_writer,
    824   0
    825 };
    826 
    827 
    828 /* Deferred error dummy writer. */
    829 static CURLcode error_init_writer(struct connectdata *conn,
    830                                   contenc_writer *writer)
    831 {
    832   (void) conn;
    833   return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
    834 }
    835 
    836 static CURLcode error_unencode_write(struct connectdata *conn,
    837                                      contenc_writer *writer,
    838                                      const char *buf, size_t nbytes)
    839 {
    840   char *all = Curl_all_content_encodings();
    841 
    842   (void) writer;
    843   (void) buf;
    844   (void) nbytes;
    845 
    846   if(!all)
    847     return CURLE_OUT_OF_MEMORY;
    848   failf(conn->data, "Unrecognized content encoding type. "
    849                     "libcurl understands %s content encodings.", all);
    850   free(all);
    851   return CURLE_BAD_CONTENT_ENCODING;
    852 }
    853 
    854 static void error_close_writer(struct connectdata *conn,
    855                                contenc_writer *writer)
    856 {
    857   (void) conn;
    858   (void) writer;
    859 }
    860 
    861 static const content_encoding error_encoding = {
    862   NULL,
    863   NULL,
    864   error_init_writer,
    865   error_unencode_write,
    866   error_close_writer,
    867   0
    868 };
    869 
    870 /* Create an unencoding writer stage using the given handler. */
    871 static contenc_writer *new_unencoding_writer(struct connectdata *conn,
    872                                              const content_encoding *handler,
    873                                              contenc_writer *downstream)
    874 {
    875   size_t sz = offsetof(contenc_writer, params) + handler->paramsize;
    876   contenc_writer *writer = (contenc_writer *) malloc(sz);
    877 
    878   if(writer) {
    879     memset(writer, 0, sz);
    880     writer->handler = handler;
    881     writer->downstream = downstream;
    882     if(handler->init_writer(conn, writer)) {
    883       free(writer);
    884       writer = NULL;
    885     }
    886   }
    887 
    888   return writer;
    889 }
    890 
    891 /* Write data using an unencoding writer stack. */
    892 CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
    893                              const char *buf, size_t nbytes)
    894 {
    895   if(!nbytes)
    896     return CURLE_OK;
    897   return writer->handler->unencode_write(conn, writer, buf, nbytes);
    898 }
    899 
    900 /* Close and clean-up the connection's writer stack. */
    901 void Curl_unencode_cleanup(struct connectdata *conn)
    902 {
    903   struct Curl_easy *data = conn->data;
    904   struct SingleRequest *k = &data->req;
    905   contenc_writer *writer = k->writer_stack;
    906 
    907   while(writer) {
    908     k->writer_stack = writer->downstream;
    909     writer->handler->close_writer(conn, writer);
    910     free(writer);
    911     writer = k->writer_stack;
    912   }
    913 }
    914 
    915 /* Find the content encoding by name. */
    916 static const content_encoding *find_encoding(const char *name, size_t len)
    917 {
    918   const content_encoding * const *cep;
    919   const content_encoding *ce;
    920 
    921   for(cep = encodings; *cep; cep++) {
    922     ce = *cep;
    923     if((strncasecompare(name, ce->name, len) && !ce->name[len]) ||
    924        (ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len]))
    925       return ce;
    926   }
    927   return NULL;
    928 }
    929 
    930 /* Set-up the unencoding stack from the Content-Encoding header value.
    931  * See RFC 7231 section 3.1.2.2. */
    932 CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
    933                                      const char *enclist, int maybechunked)
    934 {
    935   struct Curl_easy *data = conn->data;
    936   struct SingleRequest *k = &data->req;
    937 
    938   do {
    939     const char *name;
    940     size_t namelen;
    941 
    942     /* Parse a single encoding name. */
    943     while(ISSPACE(*enclist) || *enclist == ',')
    944       enclist++;
    945 
    946     name = enclist;
    947 
    948     for(namelen = 0; *enclist && *enclist != ','; enclist++)
    949       if(!ISSPACE(*enclist))
    950         namelen = enclist - name + 1;
    951 
    952     /* Special case: chunked encoding is handled at the reader level. */
    953     if(maybechunked && namelen == 7 && strncasecompare(name, "chunked", 7)) {
    954       k->chunk = TRUE;             /* chunks coming our way. */
    955       Curl_httpchunk_init(conn);   /* init our chunky engine. */
    956     }
    957     else if(namelen) {
    958       const content_encoding *encoding = find_encoding(name, namelen);
    959       contenc_writer *writer;
    960 
    961       if(!k->writer_stack) {
    962         k->writer_stack = new_unencoding_writer(conn, &client_encoding, NULL);
    963 
    964         if(!k->writer_stack)
    965           return CURLE_OUT_OF_MEMORY;
    966       }
    967 
    968       if(!encoding)
    969         encoding = &error_encoding;  /* Defer error at stack use. */
    970 
    971       /* Stack the unencoding stage. */
    972       writer = new_unencoding_writer(conn, encoding, k->writer_stack);
    973       if(!writer)
    974         return CURLE_OUT_OF_MEMORY;
    975       k->writer_stack = writer;
    976     }
    977   } while(*enclist);
    978 
    979   return CURLE_OK;
    980 }
    981 
    982 #else
    983 /* Stubs for builds without HTTP. */
    984 CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
    985                                      const char *enclist, int maybechunked)
    986 {
    987   (void) conn;
    988   (void) enclist;
    989   (void) maybechunked;
    990   return CURLE_NOT_BUILT_IN;
    991 }
    992 
    993 CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
    994                              const char *buf, size_t nbytes)
    995 {
    996   (void) conn;
    997   (void) writer;
    998   (void) buf;
    999   (void) nbytes;
   1000   return CURLE_NOT_BUILT_IN;
   1001 }
   1002 
   1003 void Curl_unencode_cleanup(struct connectdata *conn)
   1004 {
   1005   (void) conn;
   1006 }
   1007 
   1008 char *Curl_all_content_encodings(void)
   1009 {
   1010   return strdup(CONTENT_ENCODING_DEFAULT);  /* Satisfy caller. */
   1011 }
   1012 
   1013 #endif /* CURL_DISABLE_HTTP */
   1014