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