mirror of
https://github.com/curl/curl.git
synced 2026-07-24 19:17:20 +03:00
http: decode transfer encoding first
The unencoding stack is added to as Transfer-Encoding and Content-Encoding fields are encountered with no distinction between the two, meaning the stack will be incorrect if, e.g., the message has both fields and a non-chunked Transfer-Encoding comes first. This commit fixes this by ordering the stack with transfer encodings first. Reviewed-by: Patrick Monnerat Closes #10187
This commit is contained in:
parent
fc9f22b46e
commit
aa6e7a1f45
4 changed files with 239 additions and 15 deletions
|
|
@ -5,7 +5,7 @@
|
|||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2023, 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,11 @@ 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 +1065,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 +1074,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;
|
||||
|
|
@ -1086,10 +1090,23 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
|
|||
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 +1116,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue