1
0
mirror of https://github.com/moparisthebest/curl synced 2025-01-11 05:58:01 -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_done(struct connectdata *, CURLcode, bool premature);
CURLcode Curl_http_connect(struct connectdata *conn, bool *done); 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 */ /* These functions are in http.c */
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
const char *auth); 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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * 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, CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
char *datap, char *datap,
ssize_t datalen, ssize_t datalen,
ssize_t *wrotep) ssize_t *wrotep,
CURLcode *extrap)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct Curl_easy *data = conn->data; 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*/ chunk read process, to properly calculate the content length*/
if(data->set.http_te_skip && !k->ignorebody) { if(data->set.http_te_skip && !k->ignorebody) {
result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, datalen); result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, datalen);
if(result) if(result) {
return CHUNKE_WRITE_ERROR; *extrap = result;
return CHUNKE_PASSTHRU_ERROR;
}
} }
while(length) { while(length) {
@ -197,8 +200,10 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
else else
result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, piece); result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, piece);
if(result) if(result) {
return CHUNKE_WRITE_ERROR; *extrap = result;
return CHUNKE_PASSTHRU_ERROR;
}
} }
*wrote += piece; *wrote += piece;
@ -244,8 +249,10 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
if(!data->set.http_te_skip) { if(!data->set.http_te_skip) {
result = Curl_client_write(conn, CLIENTWRITE_HEADER, result = Curl_client_write(conn, CLIENTWRITE_HEADER,
conn->trailer, conn->trlPos); conn->trailer, conn->trlPos);
if(result) if(result) {
return CHUNKE_WRITE_ERROR; *extrap = result;
return CHUNKE_PASSTHRU_ERROR;
}
} }
conn->trlPos = 0; conn->trlPos = 0;
ch->state = CHUNK_TRAILER_CR; ch->state = CHUNK_TRAILER_CR;
@ -339,8 +346,9 @@ const char *Curl_chunked_strerror(CHUNKcode code)
return "Illegal or missing hexadecimal sequence"; return "Illegal or missing hexadecimal sequence";
case CHUNKE_BAD_CHUNK: case CHUNKE_BAD_CHUNK:
return "Malformed encoding found"; return "Malformed encoding found";
case CHUNKE_WRITE_ERROR: case CHUNKE_PASSTHRU_ERROR:
return "Write error"; DEBUGASSERT(0); /* never used */
return "";
case CHUNKE_BAD_ENCODING: case CHUNKE_BAD_ENCODING:
return "Bad content-encoding found"; return "Bad content-encoding found";
case CHUNKE_OUT_OF_MEMORY: 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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -21,6 +21,9 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
struct connectdata;
/* /*
* The longest possible hexadecimal number we support in a chunked transfer. * The longest possible hexadecimal number we support in a chunked transfer.
* Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul() * 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_TOO_LONG_HEX = 1,
CHUNKE_ILLEGAL_HEX, CHUNKE_ILLEGAL_HEX,
CHUNKE_BAD_CHUNK, CHUNKE_BAD_CHUNK,
CHUNKE_WRITE_ERROR,
CHUNKE_BAD_ENCODING, CHUNKE_BAD_ENCODING,
CHUNKE_OUT_OF_MEMORY, CHUNKE_OUT_OF_MEMORY,
CHUNKE_PASSTHRU_ERROR, /* Curl_httpchunk_read() returns a CURLcode to use */
CHUNKE_LAST CHUNKE_LAST
} CHUNKcode; } CHUNKcode;
@ -87,4 +90,10 @@ struct Curl_chunker {
size_t dataleft; /* untouched data amount at the end of the last buffer */ 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 */ #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 /* chunked-encoded body, so we need to do the chunked dance
properly to know when the end of the body is reached */ properly to know when the end of the body is reached */
CHUNKcode r; CHUNKcode r;
CURLcode extra;
ssize_t tookcareof = 0; ssize_t tookcareof = 0;
/* now parse the chunked piece of data so that we can /* now parse the chunked piece of data so that we can
properly tell when the stream ends */ 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) { if(r == CHUNKE_STOP) {
/* we're done reading chunks! */ /* we're done reading chunks! */
infof(data, "chunk reading DONE\n"); infof(data, "chunk reading DONE\n");
@ -455,6 +456,7 @@ static CURLcode CONNECT(struct connectdata *conn,
} }
else if(s->chunked_encoding) { else if(s->chunked_encoding) {
CHUNKcode r; CHUNKcode r;
CURLcode extra;
infof(data, "Ignore chunked response-body\n"); 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 /* now parse the chunked piece of data so that we can
properly tell when the stream ends */ 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) { if(r == CHUNKE_STOP) {
/* we're done reading chunks! */ /* we're done reading chunks! */
infof(data, "chunk reading DONE\n"); 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 * and writes away the data. The returned 'nread' holds the number
* of actual data it wrote to the client. * of actual data it wrote to the client.
*/ */
CURLcode extra;
CHUNKcode res = 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_OK < res) {
if(CHUNKE_WRITE_ERROR == res) { if(CHUNKE_PASSTHRU_ERROR == res) {
failf(data, "Failed writing data"); failf(data, "Failed reading the chunked-encoded stream");
return CURLE_WRITE_ERROR; return extra;
} }
failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res)); failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res));
return CURLE_RECV_ERROR; return CURLE_RECV_ERROR;