summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/content_encoding.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/content_encoding.c')
-rw-r--r--libs/libcurl/src/content_encoding.c54
1 files changed, 36 insertions, 18 deletions
diff --git a/libs/libcurl/src/content_encoding.c b/libs/libcurl/src/content_encoding.c
index 2ea5e140be..cccf027489 100644
--- a/libs/libcurl/src/content_encoding.c
+++ b/libs/libcurl/src/content_encoding.c
@@ -365,11 +365,14 @@ static CURLcode gzip_do_init(struct Curl_easy *data,
#ifdef OLD_ZLIB_SUPPORT
/* Skip over the gzip header */
-static enum {
+typedef enum {
GZIP_OK,
GZIP_BAD,
GZIP_UNDERFLOW
-} check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen)
+} gzip_status;
+
+static gzip_status check_gzip_header(unsigned char const *data, ssize_t len,
+ ssize_t *headerlen)
{
int method, flags;
const ssize_t totallen = len;
@@ -832,8 +835,8 @@ static const struct Curl_cwtype identity_encoding = {
};
-/* supported content encodings table. */
-static const struct Curl_cwtype * const encodings[] = {
+/* supported general content decoders. */
+static const struct Curl_cwtype * const general_unencoders[] = {
&identity_encoding,
#ifdef HAVE_LIBZ
&deflate_encoding,
@@ -848,6 +851,13 @@ static const struct Curl_cwtype * const encodings[] = {
NULL
};
+/* supported content decoders only for transfer encodings */
+static const struct Curl_cwtype * const transfer_unencoders[] = {
+#ifndef CURL_DISABLE_HTTP
+ &Curl_httpchunk_unencoder,
+#endif
+ NULL
+};
/* Provide a list of comma-separated names of supported encodings.
*/
@@ -861,7 +871,7 @@ void Curl_all_content_encodings(char *buf, size_t blen)
DEBUGASSERT(blen);
buf[0] = 0;
- for(cep = encodings; *cep; cep++) {
+ for(cep = general_unencoders; *cep; cep++) {
ce = *cep;
if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT))
len += strlen(ce->name) + 2;
@@ -873,7 +883,7 @@ void Curl_all_content_encodings(char *buf, size_t blen)
}
else if(blen > len) {
char *p = buf;
- for(cep = encodings; *cep; cep++) {
+ for(cep = general_unencoders; *cep; cep++) {
ce = *cep;
if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) {
strcpy(p, ce->name);
@@ -931,12 +941,23 @@ static const struct Curl_cwtype error_writer = {
};
/* Find the content encoding by name. */
-static const struct Curl_cwtype *find_encoding(const char *name,
- size_t len)
+static const struct Curl_cwtype *find_unencode_writer(const char *name,
+ size_t len,
+ Curl_cwriter_phase phase)
{
const struct Curl_cwtype * const *cep;
- for(cep = encodings; *cep; cep++) {
+ if(phase == CURL_CW_TRANSFER_DECODE) {
+ for(cep = transfer_unencoders; *cep; cep++) {
+ const struct Curl_cwtype *ce = *cep;
+ if((strncasecompare(name, ce->name, len) && !ce->name[len]) ||
+ (ce->alias && strncasecompare(name, ce->alias, len)
+ && !ce->alias[len]))
+ return ce;
+ }
+ }
+ /* look among the general decoders */
+ for(cep = general_unencoders; *cep; cep++) {
const struct Curl_cwtype *ce = *cep;
if((strncasecompare(name, ce->name, len) && !ce->name[len]) ||
(ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len]))
@@ -950,7 +971,6 @@ static const struct Curl_cwtype *find_encoding(const char *name,
CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
const char *enclist, int is_transfer)
{
- struct SingleRequest *k = &data->req;
Curl_cwriter_phase phase = is_transfer?
CURL_CW_TRANSFER_DECODE:CURL_CW_CONTENT_DECODE;
CURLcode result;
@@ -969,16 +989,14 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
if(!ISSPACE(*enclist))
namelen = enclist - name + 1;
- /* Special case: chunked encoding is handled at the reader level. */
- if(is_transfer && namelen == 7 && strncasecompare(name, "chunked", 7)) {
- k->chunk = TRUE; /* chunks coming our way. */
- Curl_httpchunk_init(data); /* init our chunky engine. */
- }
- else if(namelen) {
+ if(namelen) {
const struct Curl_cwtype *cwt;
struct Curl_cwriter *writer;
- if((is_transfer && !data->set.http_transfer_encoding) ||
+ /* if we skip the decoding in this phase, do not look further.
+ * Exception is "chunked" transfer-encoding which always must happen */
+ if((is_transfer && !data->set.http_transfer_encoding &&
+ (namelen != 7 || !strncasecompare(name, "chunked", 7))) ||
(!is_transfer && data->set.http_ce_skip)) {
/* not requested, ignore */
return CURLE_OK;
@@ -990,7 +1008,7 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
return CURLE_BAD_CONTENT_ENCODING;
}
- cwt = find_encoding(name, namelen);
+ cwt = find_unencode_writer(name, namelen, phase);
if(!cwt)
cwt = &error_writer; /* Defer error at use. */