summaryrefslogtreecommitdiff
path: root/Utilities/cmcurl/lib/content_encoding.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/content_encoding.c')
-rw-r--r--Utilities/cmcurl/lib/content_encoding.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/Utilities/cmcurl/lib/content_encoding.c b/Utilities/cmcurl/lib/content_encoding.c
index 9e345b197e..a29d2041b6 100644
--- a/Utilities/cmcurl/lib/content_encoding.c
+++ b/Utilities/cmcurl/lib/content_encoding.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -977,7 +977,8 @@ static const struct content_encoding error_encoding = {
static struct contenc_writer *
new_unencoding_writer(struct Curl_easy *data,
const struct content_encoding *handler,
- struct contenc_writer *downstream)
+ struct contenc_writer *downstream,
+ int order)
{
struct contenc_writer *writer;
@@ -987,6 +988,7 @@ new_unencoding_writer(struct Curl_easy *data,
if(writer) {
writer->handler = handler;
writer->downstream = downstream;
+ writer->order = order;
if(handler->init_writer(data, writer)) {
free(writer);
writer = NULL;
@@ -1042,10 +1044,10 @@ static const struct content_encoding *find_encoding(const char *name,
/* Set-up the unencoding stack from the Content-Encoding header value.
* See RFC 7231 section 3.1.2.2. */
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
- const char *enclist, int maybechunked)
+ const char *enclist, int is_transfer)
{
struct SingleRequest *k = &data->req;
- int counter = 0;
+ unsigned int order = is_transfer? 2: 1;
do {
const char *name;
@@ -1062,7 +1064,7 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
namelen = enclist - name + 1;
/* Special case: chunked encoding is handled at the reader level. */
- if(maybechunked && namelen == 7 && strncasecompare(name, "chunked", 7)) {
+ if(is_transfer && namelen == 7 && strncasecompare(name, "chunked", 7)) {
k->chunk = TRUE; /* chunks coming our way. */
Curl_httpchunk_init(data); /* init our chunky engine. */
}
@@ -1071,7 +1073,8 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
struct contenc_writer *writer;
if(!k->writer_stack) {
- k->writer_stack = new_unencoding_writer(data, &client_encoding, NULL);
+ k->writer_stack = new_unencoding_writer(data, &client_encoding,
+ NULL, 0);
if(!k->writer_stack)
return CURLE_OUT_OF_MEMORY;
@@ -1080,16 +1083,29 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
if(!encoding)
encoding = &error_encoding; /* Defer error at stack use. */
- if(++counter >= MAX_ENCODE_STACK) {
- failf(data, "Reject response due to %u content encodings",
- counter);
+ if(k->writer_stack_depth++ >= MAX_ENCODE_STACK) {
+ failf(data, "Reject response due to more than %u content encodings",
+ MAX_ENCODE_STACK);
return CURLE_BAD_CONTENT_ENCODING;
}
/* Stack the unencoding stage. */
- writer = new_unencoding_writer(data, encoding, k->writer_stack);
- if(!writer)
- return CURLE_OUT_OF_MEMORY;
- k->writer_stack = writer;
+ if(order >= k->writer_stack->order) {
+ writer = new_unencoding_writer(data, encoding,
+ k->writer_stack, order);
+ if(!writer)
+ return CURLE_OUT_OF_MEMORY;
+ k->writer_stack = writer;
+ }
+ else {
+ struct contenc_writer *w = k->writer_stack;
+ while(w->downstream && order < w->downstream->order)
+ w = w->downstream;
+ writer = new_unencoding_writer(data, encoding,
+ w->downstream, order);
+ if(!writer)
+ return CURLE_OUT_OF_MEMORY;
+ w->downstream = writer;
+ }
}
} while(*enclist);
@@ -1099,11 +1115,11 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
#else
/* Stubs for builds without HTTP. */
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
- const char *enclist, int maybechunked)
+ const char *enclist, int is_transfer)
{
(void) data;
(void) enclist;
- (void) maybechunked;
+ (void) is_transfer;
return CURLE_NOT_BUILT_IN;
}