Skip to content

Commit

Permalink
chunked-encoding: stop hiding the CURLE_BAD_CONTENT_ENCODING error
Browse files Browse the repository at this point in the history
Unknown content-encoding would get returned as CURLE_WRITE_ERROR if the
response is chunked-encoded.

Reported-by: Ilya Kosarev
Fixes #4310
  • Loading branch information
bagder committed Oct 1, 2019
1 parent ac83013 commit 766a63a
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 24 deletions.
5 changes: 0 additions & 5 deletions lib/http.h
Expand Up @@ -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);
Expand Down
28 changes: 18 additions & 10 deletions lib/http_chunks.c
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
break;
case CHUNKE_BAD_ENCODING:
return "Bad content-encoding found";
case CHUNKE_OUT_OF_MEMORY:
Expand Down
13 changes: 11 additions & 2 deletions lib/http_chunks.h
Expand Up @@ -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
Expand All @@ -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()
Expand Down Expand Up @@ -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;

Expand All @@ -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 */
7 changes: 5 additions & 2 deletions lib/http_proxy.c
Expand Up @@ -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");
Expand Down Expand Up @@ -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");

Expand All @@ -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");
Expand Down
10 changes: 5 additions & 5 deletions lib/transfer.c
Expand Up @@ -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;
Expand Down

0 comments on commit 766a63a

Please sign in to comment.