1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-23 08:38:49 -05:00

chunked-encoding: stop hiding the CURLE_BAD_CONTENT_ENCODING error

Unknown content-encoding would get returned as CURLE_WRITE_ERROR if the
response is chunked-encoded.

Reported-by: Ilya Kosarev
Fixes #4310
Closes #4449
This commit is contained in:
Daniel Stenberg 2019-10-01 15:40:05 +02:00
parent ac830139da
commit f0f053fed0
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 39 additions and 24 deletions

View File

@ -83,11 +83,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done);
CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
/* The following functions are defined in http_chunks.c */
void Curl_httpchunk_init(struct connectdata *conn);
CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
ssize_t length, ssize_t *wrote);
/* These functions are in http.c */
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
const char *auth);

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2019, 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
@ -109,7 +109,8 @@ void Curl_httpchunk_init(struct connectdata *conn)
CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
char *datap,
ssize_t datalen,
ssize_t *wrotep)
ssize_t *wrotep,
CURLcode *extrap)
{
CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data;
@ -125,8 +126,10 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
chunk read process, to properly calculate the content length*/
if(data->set.http_te_skip && !k->ignorebody) {
result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, datalen);
if(result)
return CHUNKE_WRITE_ERROR;
if(result) {
*extrap = result;
return CHUNKE_PASSTHRU_ERROR;
}
}
while(length) {
@ -197,8 +200,10 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
else
result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, piece);
if(result)
return CHUNKE_WRITE_ERROR;
if(result) {
*extrap = result;
return CHUNKE_PASSTHRU_ERROR;
}
}
*wrote += piece;
@ -244,8 +249,10 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
if(!data->set.http_te_skip) {
result = Curl_client_write(conn, CLIENTWRITE_HEADER,
conn->trailer, conn->trlPos);
if(result)
return CHUNKE_WRITE_ERROR;
if(result) {
*extrap = result;
return CHUNKE_PASSTHRU_ERROR;
}
}
conn->trlPos = 0;
ch->state = CHUNK_TRAILER_CR;
@ -339,8 +346,9 @@ const char *Curl_chunked_strerror(CHUNKcode code)
return "Illegal or missing hexadecimal sequence";
case CHUNKE_BAD_CHUNK:
return "Malformed encoding found";
case CHUNKE_WRITE_ERROR:
return "Write error";
case CHUNKE_PASSTHRU_ERROR:
DEBUGASSERT(0); /* never used */
return "";
case CHUNKE_BAD_ENCODING:
return "Bad content-encoding found";
case CHUNKE_OUT_OF_MEMORY:

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2019, 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
@ -21,6 +21,9 @@
* KIND, either express or implied.
*
***************************************************************************/
struct connectdata;
/*
* The longest possible hexadecimal number we support in a chunked transfer.
* Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul()
@ -71,9 +74,9 @@ typedef enum {
CHUNKE_TOO_LONG_HEX = 1,
CHUNKE_ILLEGAL_HEX,
CHUNKE_BAD_CHUNK,
CHUNKE_WRITE_ERROR,
CHUNKE_BAD_ENCODING,
CHUNKE_OUT_OF_MEMORY,
CHUNKE_PASSTHRU_ERROR, /* Curl_httpchunk_read() returns a CURLcode to use */
CHUNKE_LAST
} CHUNKcode;
@ -87,4 +90,10 @@ struct Curl_chunker {
size_t dataleft; /* untouched data amount at the end of the last buffer */
};
/* The following functions are defined in http_chunks.c */
void Curl_httpchunk_init(struct connectdata *conn);
CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
ssize_t length, ssize_t *wrote,
CURLcode *passthru);
#endif /* HEADER_CURL_HTTP_CHUNKS_H */

View File

@ -384,11 +384,12 @@ static CURLcode CONNECT(struct connectdata *conn,
/* chunked-encoded body, so we need to do the chunked dance
properly to know when the end of the body is reached */
CHUNKcode r;
CURLcode extra;
ssize_t tookcareof = 0;
/* now parse the chunked piece of data so that we can
properly tell when the stream ends */
r = Curl_httpchunk_read(conn, s->ptr, 1, &tookcareof);
r = Curl_httpchunk_read(conn, s->ptr, 1, &tookcareof, &extra);
if(r == CHUNKE_STOP) {
/* we're done reading chunks! */
infof(data, "chunk reading DONE\n");
@ -455,6 +456,7 @@ static CURLcode CONNECT(struct connectdata *conn,
}
else if(s->chunked_encoding) {
CHUNKcode r;
CURLcode extra;
infof(data, "Ignore chunked response-body\n");
@ -472,7 +474,8 @@ static CURLcode CONNECT(struct connectdata *conn,
/* now parse the chunked piece of data so that we can
properly tell when the stream ends */
r = Curl_httpchunk_read(conn, s->line_start + 1, 1, &gotbytes);
r = Curl_httpchunk_read(conn, s->line_start + 1, 1, &gotbytes,
&extra);
if(r == CHUNKE_STOP) {
/* we're done reading chunks! */
infof(data, "chunk reading DONE\n");

View File

@ -776,14 +776,14 @@ static CURLcode readwrite_data(struct Curl_easy *data,
* and writes away the data. The returned 'nread' holds the number
* of actual data it wrote to the client.
*/
CURLcode extra;
CHUNKcode res =
Curl_httpchunk_read(conn, k->str, nread, &nread);
Curl_httpchunk_read(conn, k->str, nread, &nread, &extra);
if(CHUNKE_OK < res) {
if(CHUNKE_WRITE_ERROR == res) {
failf(data, "Failed writing data");
return CURLE_WRITE_ERROR;
if(CHUNKE_PASSTHRU_ERROR == res) {
failf(data, "Failed reading the chunked-encoded stream");
return extra;
}
failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res));
return CURLE_RECV_ERROR;