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