diff options
author | George Hazan <ghazan@miranda.im> | 2017-12-06 21:44:09 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2017-12-06 21:44:17 +0300 |
commit | 4b6980f68d25901133519bc1ad1c5376819a3876 (patch) | |
tree | 0d919622bfc2659f34a7bed303fefb99ecab052a /libs/libcurl/src/http_chunks.c | |
parent | 0112d2767268037cf63e44c4464cf9eed237d06d (diff) |
libcurl: update to 7.57
Diffstat (limited to 'libs/libcurl/src/http_chunks.c')
-rw-r--r-- | libs/libcurl/src/http_chunks.c | 196 |
1 files changed, 73 insertions, 123 deletions
diff --git a/libs/libcurl/src/http_chunks.c b/libs/libcurl/src/http_chunks.c index e9fddf5889..1616429693 100644 --- a/libs/libcurl/src/http_chunks.c +++ b/libs/libcurl/src/http_chunks.c @@ -5,11 +5,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2017, 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 - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -29,13 +29,12 @@ #include "content_encoding.h" #include "http.h" -#include "curl_memory.h" #include "non-ascii.h" /* for Curl_convert_to_network prototype */ +#include "strtoofft.h" +#include "warnless.h" -#define _MPRINTF_REPLACE /* use our functions only */ -#include <curl/mprintf.h> - -/* The last #include file should be: */ +/* The last #include files should be: */ +#include "curl_memory.h" #include "memdebug.h" /* @@ -81,14 +80,14 @@ static bool Curl_isxdigit(char digit) { return ( (digit >= 0x30 && digit <= 0x39) /* 0-9 */ || (digit >= 0x41 && digit <= 0x46) /* A-F */ - || (digit >= 0x61 && digit <= 0x66) /* a-f */ ) ? TRUE : FALSE; + || (digit >= 0x61 && digit <= 0x66) /* a-f */) ? TRUE : FALSE; } void Curl_httpchunk_init(struct connectdata *conn) { struct Curl_chunker *chunk = &conn->chunk; - chunk->hexindex=0; /* start at 0 */ - chunk->dataleft=0; /* no data left yet! */ + chunk->hexindex = 0; /* start at 0 */ + chunk->dataleft = 0; /* no data left yet! */ chunk->state = CHUNK_HEX; /* we get hex first! */ } @@ -108,12 +107,12 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, ssize_t datalen, ssize_t *wrotep) { - CURLcode result=CURLE_OK; - struct SessionHandle *data = conn->data; + CURLcode result = CURLE_OK; + struct Curl_easy *data = conn->data; struct Curl_chunker *ch = &conn->chunk; struct SingleRequest *k = &data->req; size_t piece; - size_t length = (size_t)datalen; + curl_off_t length = (curl_off_t)datalen; size_t *wrote = (size_t *)wrotep; *wrote = 0; /* nothing's written yet */ @@ -141,13 +140,14 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, } } else { - if(0 == ch->hexindex) { + char *endptr; + if(0 == ch->hexindex) /* This is illegal data, we received junk where we expected a hexadecimal digit. */ return CHUNKE_ILLEGAL_HEX; - } + /* length and datap are unmodified */ - ch->hexbuffer[ch->hexindex]=0; + ch->hexbuffer[ch->hexindex] = 0; /* convert to host encoding before calling strtoul */ result = Curl_convert_from_network(conn->data, ch->hexbuffer, @@ -155,141 +155,79 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, if(result) { /* Curl_convert_from_network calls failf if unsuccessful */ /* Treat it as a bad hex character */ - return(CHUNKE_ILLEGAL_HEX); + return CHUNKE_ILLEGAL_HEX; } - ch->datasize=strtoul(ch->hexbuffer, NULL, 16); - ch->state = CHUNK_POSTHEX; + if(curlx_strtoofft(ch->hexbuffer, &endptr, 16, &ch->datasize)) + return CHUNKE_ILLEGAL_HEX; + ch->state = CHUNK_LF; /* now wait for the CRLF */ } break; - case CHUNK_POSTHEX: - /* In this state, we're waiting for CRLF to arrive. We support - this to allow so called chunk-extensions to show up here - before the CRLF comes. */ - if(*datap == 0x0d) - ch->state = CHUNK_CR; - length--; - datap++; - break; - - case CHUNK_CR: - /* waiting for the LF */ + case CHUNK_LF: + /* waiting for the LF after a chunk size */ if(*datap == 0x0a) { /* we're now expecting data to come, unless size was zero! */ if(0 == ch->datasize) { ch->state = CHUNK_TRAILER; /* now check for trailers */ - conn->trlPos=0; + conn->trlPos = 0; } - else { + else ch->state = CHUNK_DATA; - } } - else - /* previously we got a fake CR, go back to CR waiting! */ - ch->state = CHUNK_CR; + datap++; length--; break; case CHUNK_DATA: - /* we get pure and fine data - - We expect another 'datasize' of data. We have 'length' right now, - it can be more or less than 'datasize'. Get the smallest piece. + /* We expect 'datasize' of data. We have 'length' right now, it can be + more or less than 'datasize'. Get the smallest piece. */ - piece = (ch->datasize >= length)?length:ch->datasize; + piece = curlx_sotouz((ch->datasize >= length)?length:ch->datasize); /* Write the data portion available */ -#ifdef HAVE_LIBZ - switch (conn->data->set.http_ce_skip? - IDENTITY : data->req.auto_decoding) { - case IDENTITY: -#endif - if(!k->ignorebody) { - if(!data->set.http_te_skip) - result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, - piece); - else - result = CURLE_OK; - } -#ifdef HAVE_LIBZ - break; - - case DEFLATE: - /* update data->req.keep.str to point to the chunk data. */ - data->req.str = datap; - result = Curl_unencode_deflate_write(conn, &data->req, - (ssize_t)piece); - break; - - case GZIP: - /* update data->req.keep.str to point to the chunk data. */ - data->req.str = datap; - result = Curl_unencode_gzip_write(conn, &data->req, - (ssize_t)piece); - break; - - case COMPRESS: - default: - failf (conn->data, - "Unrecognized content encoding type. " - "libcurl understands `identity', `deflate' and `gzip' " - "content encodings."); - return CHUNKE_BAD_ENCODING; + if(conn->data->set.http_ce_skip || !k->writer_stack) { + if(!k->ignorebody) + result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, piece); } -#endif + else + result = Curl_unencode_write(conn, k->writer_stack, datap, piece); if(result) return CHUNKE_WRITE_ERROR; *wrote += piece; - ch->datasize -= piece; /* decrease amount left to expect */ datap += piece; /* move read pointer forward */ length -= piece; /* decrease space left in this round */ if(0 == ch->datasize) /* end of data this round, we now expect a trailing CRLF */ - ch->state = CHUNK_POSTCR; - break; - - case CHUNK_POSTCR: - if(*datap == 0x0d) { ch->state = CHUNK_POSTLF; - datap++; - length--; - } - else - return CHUNKE_BAD_CHUNK; - break; case CHUNK_POSTLF: if(*datap == 0x0a) { - /* - * The last one before we go back to hex state and start all - * over. - */ - Curl_httpchunk_init(conn); - datap++; - length--; + /* The last one before we go back to hex state and start all over. */ + Curl_httpchunk_init(conn); /* sets state back to CHUNK_HEX */ } - else + else if(*datap != 0x0d) return CHUNKE_BAD_CHUNK; - + datap++; + length--; break; case CHUNK_TRAILER: - if(*datap == 0x0d) { + if((*datap == 0x0d) || (*datap == 0x0a)) { /* this is the end of a trailer, but if the trailer was zero bytes there was no trailer and we move on */ if(conn->trlPos) { /* we allocate trailer with 3 bytes extra room to fit this */ - conn->trailer[conn->trlPos++]=0x0d; - conn->trailer[conn->trlPos++]=0x0a; - conn->trailer[conn->trlPos]=0; + conn->trailer[conn->trlPos++] = 0x0d; + conn->trailer[conn->trlPos++] = 0x0a; + conn->trailer[conn->trlPos] = 0; /* Convert to host encoding before calling Curl_client_write */ result = Curl_convert_from_network(conn->data, conn->trailer, @@ -305,8 +243,11 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, if(result) return CHUNKE_WRITE_ERROR; } - conn->trlPos=0; + conn->trlPos = 0; ch->state = CHUNK_TRAILER_CR; + if(*datap == 0x0a) + /* already on the LF */ + break; } else { /* no trailer, we're on the final CRLF pair */ @@ -326,7 +267,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, ptr = realloc(conn->trailer, conn->trlMax + 3); } else { - conn->trlMax=128; + conn->trlMax = 128; ptr = malloc(conn->trlMax + 3); } if(!ptr) @@ -352,27 +293,18 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, case CHUNK_TRAILER_POSTCR: /* We enter this state when a CR should arrive so we expect to have to first pass a CR before we wait for LF */ - if(*datap != 0x0d) { + if((*datap != 0x0d) && (*datap != 0x0a)) { /* not a CR then it must be another header in the trailer */ ch->state = CHUNK_TRAILER; break; } - datap++; - length--; - /* now wait for the final LF */ - ch->state = CHUNK_STOP; - break; - - case CHUNK_STOPCR: - /* Read the final CRLF that ends all chunk bodies */ - if(*datap == 0x0d) { - ch->state = CHUNK_STOP; + /* skip if CR */ datap++; length--; } - else - return CHUNKE_BAD_CHUNK; + /* now wait for the final LF */ + ch->state = CHUNK_STOP; break; case CHUNK_STOP: @@ -381,17 +313,35 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, /* Record the length of any data left in the end of the buffer even if there's no more chunks to read */ + ch->dataleft = curlx_sotouz(length); - ch->dataleft = length; return CHUNKE_STOP; /* return stop */ } else return CHUNKE_BAD_CHUNK; - - default: - return CHUNKE_STATE_ERROR; } } return CHUNKE_OK; } + +const char *Curl_chunked_strerror(CHUNKcode code) +{ + switch(code) { + default: + return "OK"; + case CHUNKE_TOO_LONG_HEX: + return "Too long hexadecimal number"; + case CHUNKE_ILLEGAL_HEX: + return "Illegal or missing hexadecimal sequence"; + case CHUNKE_BAD_CHUNK: + return "Malformed encoding found"; + case CHUNKE_WRITE_ERROR: + return "Write error"; + case CHUNKE_BAD_ENCODING: + return "Bad content-encoding found"; + case CHUNKE_OUT_OF_MEMORY: + return "Out of memory"; + } +} + #endif /* CURL_DISABLE_HTTP */ |