diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions index 2dc0af2c9602709e964dbb7e67e84b9cddf57e0a..abae02d5557f988d6b7f289e429c1baa8ecc4d12 100644 --- a/docs/libcurl/symbols-in-versions +++ b/docs/libcurl/symbols-in-versions @@ -943,6 +943,7 @@ CURL_LOCK_ACCESS_SINGLE 7.10.3 CURL_LOCK_DATA_CONNECT 7.10.3 CURL_LOCK_DATA_COOKIE 7.10.3 CURL_LOCK_DATA_DNS 7.10.3 +CURL_LOCK_DATA_HSTS 7.88.0 CURL_LOCK_DATA_NONE 7.10.3 CURL_LOCK_DATA_PSL 7.61.0 CURL_LOCK_DATA_SHARE 7.10.4 diff --git a/include/curl/curl.h b/include/curl/curl.h index 521c254e7700dc78c6ae7f544fadffcf27c7132c..f3bf8f41ca8f9e71d9165f96ce01e63bea53d2be 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -2824,6 +2824,7 @@ typedef enum { CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_DATA_CONNECT, CURL_LOCK_DATA_PSL, + CURL_LOCK_DATA_HSTS, CURL_LOCK_DATA_LAST } curl_lock_data; diff --git a/lib/content_encoding.c b/lib/content_encoding.c index e78cd1cab6a8b54c30193b37a320b10eca0df81d..cdc5baf21020d495f279f19cfb885154b10d214f 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2023, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -968,7 +968,8 @@ static const struct content_encoding error_encoding = { static struct contenc_writer * new_unencoding_writer(struct Curl_easy *data, const struct content_encoding *handler, - struct contenc_writer *downstream) + struct contenc_writer *downstream, + int order) { size_t sz = offsetof(struct contenc_writer, params) + handler->paramsize; struct contenc_writer *writer = (struct contenc_writer *)calloc(1, sz); @@ -976,6 +977,7 @@ new_unencoding_writer(struct Curl_easy *data, if(writer) { writer->handler = handler; writer->downstream = downstream; + writer->order = order; if(handler->init_writer(data, writer)) { free(writer); writer = NULL; @@ -1031,10 +1033,10 @@ static const struct content_encoding *find_encoding(const char *name, /* Set-up the unencoding stack from the Content-Encoding header value. * See RFC 7231 section 3.1.2.2. */ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, - const char *enclist, int maybechunked) + const char *enclist, int is_transfer) { struct SingleRequest *k = &data->req; - int counter = 0; + unsigned int order = is_transfer? 2: 1; do { const char *name; @@ -1051,7 +1053,7 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, namelen = enclist - name + 1; /* Special case: chunked encoding is handled at the reader level. */ - if(maybechunked && namelen == 7 && strncasecompare(name, "chunked", 7)) { + if(is_transfer && namelen == 7 && strncasecompare(name, "chunked", 7)) { k->chunk = TRUE; /* chunks coming our way. */ Curl_httpchunk_init(data); /* init our chunky engine. */ } @@ -1060,7 +1062,8 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, struct contenc_writer *writer; if(!k->writer_stack) { - k->writer_stack = new_unencoding_writer(data, &client_encoding, NULL); + k->writer_stack = new_unencoding_writer(data, &client_encoding, + NULL, 0); if(!k->writer_stack) return CURLE_OUT_OF_MEMORY; @@ -1069,16 +1072,29 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, if(!encoding) encoding = &error_encoding; /* Defer error at stack use. */ - if(++counter >= MAX_ENCODE_STACK) { - failf(data, "Reject response due to %u content encodings", - counter); + if(k->writer_stack_depth++ >= MAX_ENCODE_STACK) { + failf(data, "Reject response due to more than %u content encodings", + MAX_ENCODE_STACK); return CURLE_BAD_CONTENT_ENCODING; } /* Stack the unencoding stage. */ - writer = new_unencoding_writer(data, encoding, k->writer_stack); - if(!writer) - return CURLE_OUT_OF_MEMORY; - k->writer_stack = writer; + if(order >= k->writer_stack->order) { + writer = new_unencoding_writer(data, encoding, + k->writer_stack, order); + if(!writer) + return CURLE_OUT_OF_MEMORY; + k->writer_stack = writer; + } + else { + struct contenc_writer *w = k->writer_stack; + while(w->downstream && order < w->downstream->order) + w = w->downstream; + writer = new_unencoding_writer(data, encoding, + w->downstream, order); + if(!writer) + return CURLE_OUT_OF_MEMORY; + w->downstream = writer; + } } } while(*enclist); @@ -1088,11 +1104,11 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, #else /* Stubs for builds without HTTP. */ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, - const char *enclist, int maybechunked) + const char *enclist, int is_transfer) { (void) data; (void) enclist; - (void) maybechunked; + (void) is_transfer; return CURLE_NOT_BUILT_IN; } diff --git a/lib/content_encoding.h b/lib/content_encoding.h index acfd0c27b05e991eb62044b3f0d8f19f59380416..010297ca466edaa263f04411f1d30ae6b4d042de 100644 --- a/lib/content_encoding.h +++ b/lib/content_encoding.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2023, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -27,6 +27,7 @@ struct contenc_writer { const struct content_encoding *handler; /* Encoding handler. */ struct contenc_writer *downstream; /* Downstream writer. */ void *params; /* Encoding-specific storage (variable length). */ + unsigned int order; /* Ordering within writer stack. */ }; /* Content encoding writer. */ @@ -45,7 +46,7 @@ struct content_encoding { CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, - const char *enclist, int maybechunked); + const char *enclist, int is_transfer); CURLcode Curl_unencode_write(struct Curl_easy *data, struct contenc_writer *writer, const char *buf, size_t nbytes); diff --git a/lib/hsts.c b/lib/hsts.c index 1d0263cdfef496e6d053aa000de750c653ceafc3..4de55a91c8031e3bc8df89f0e502b520bed79393 100644 --- a/lib/hsts.c +++ b/lib/hsts.c @@ -38,6 +38,7 @@ #include "fopen.h" #include "rename.h" #include "strtoofft.h" +#include "share.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -394,14 +395,23 @@ static CURLcode hsts_add(struct hsts *h, char *line) host, date); if(2 == rc) { time_t expires = Curl_getdate_capped(date); - CURLcode result; + CURLcode result = CURLE_OK; char *p = host; bool subdomain = FALSE; + struct stsentry *e; if(p[0] == '.') { p++; subdomain = TRUE; } - result = hsts_create(h, p, subdomain, expires); + /* only add it if not already present */ + e = Curl_hsts(h, p, subdomain); + if(!e) + result = hsts_create(h, p, subdomain, expires); + else { + /* the same host name, use the largest expire time */ + if(expires > e->expires) + e->expires = expires; + } if(result) return result; } @@ -519,4 +529,18 @@ CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h) return hsts_pull(data, h); } +void Curl_hsts_loadfiles(struct Curl_easy *data) +{ + struct curl_slist *l = data->set.hstslist; + if(l) { + Curl_share_lock(data, CURL_LOCK_DATA_HSTS, CURL_LOCK_ACCESS_SINGLE); + + while(l) { + (void)Curl_hsts_loadfile(data, data->hsts, l->data); + l = l->next; + } + Curl_share_unlock(data, CURL_LOCK_DATA_HSTS); + } +} + #endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */ diff --git a/lib/hsts.h b/lib/hsts.h index baa582864a2599c14af2e78cb9dc420af0d21069..3c9d2dad133dec05b65bdfcefebdea7bc8e62703 100644 --- a/lib/hsts.h +++ b/lib/hsts.h @@ -57,9 +57,11 @@ CURLcode Curl_hsts_loadfile(struct Curl_easy *data, struct hsts *h, const char *file); CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h); +void Curl_hsts_loadfiles(struct Curl_easy *data); #else #define Curl_hsts_cleanup(x) #define Curl_hsts_loadcb(x,y) #define Curl_hsts_save(x,y,z) +#define Curl_hsts_loadfiles(x) #endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */ #endif /* HEADER_CURL_HSTS_H */ diff --git a/lib/setopt.c b/lib/setopt.c index 6edd187ac5b65ddc405449fb6516ee6364686065..c6bece9ab5833b44ec9ab67750e612eb2c26f1d4 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -2230,9 +2230,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->cookies = NULL; #endif +#ifndef CURL_DISABLE_HSTS + if(data->share->hsts == data->hsts) + data->hsts = NULL; +#endif +#ifdef USE_SSL if(data->share->sslsession == data->state.session) data->state.session = NULL; - +#endif #ifdef USE_LIBPSL if(data->psl == &data->share->psl) data->psl = data->multi? &data->multi->psl: NULL; @@ -2266,10 +2271,19 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->cookies = data->share->cookies; } #endif /* CURL_DISABLE_HTTP */ +#ifndef CURL_DISABLE_HSTS + if(data->share->hsts) { + /* first free the private one if any */ + Curl_hsts_cleanup(&data->hsts); + data->hsts = data->share->hsts; + } +#endif /* CURL_DISABLE_HTTP */ +#ifdef USE_SSL if(data->share->sslsession) { data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions; data->state.session = data->share->sslsession; } +#endif #ifdef USE_LIBPSL if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL)) data->psl = &data->share->psl; @@ -2961,19 +2975,39 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_HSTSWRITEDATA: data->set.hsts_write_userp = va_arg(param, void *); break; - case CURLOPT_HSTS: + case CURLOPT_HSTS: { + struct curl_slist *h; if(!data->hsts) { data->hsts = Curl_hsts_init(); if(!data->hsts) return CURLE_OUT_OF_MEMORY; } argptr = va_arg(param, char *); - result = Curl_setstropt(&data->set.str[STRING_HSTS], argptr); - if(result) - return result; - if(argptr) - (void)Curl_hsts_loadfile(data, data->hsts, argptr); + if(argptr) { + result = Curl_setstropt(&data->set.str[STRING_HSTS], argptr); + if(result) + return result; + /* this needs to build a list of file names to read from, so that it can + read them later, as we might get a shared HSTS handle to load them + into */ + h = curl_slist_append(data->set.hstslist, argptr); + if(!h) { + curl_slist_free_all(data->set.hstslist); + data->set.hstslist = NULL; + return CURLE_OUT_OF_MEMORY; + } + data->set.hstslist = h; /* store the list for later use */ + } + else { + /* clear the list of HSTS files */ + curl_slist_free_all(data->set.hstslist); + data->set.hstslist = NULL; + if(!data->share || !data->share->hsts) + /* throw away the HSTS cache unless shared */ + Curl_hsts_cleanup(&data->hsts); + } break; + } case CURLOPT_HSTS_CTRL: arg = va_arg(param, long); if(arg & CURLHSTS_ENABLE) { diff --git a/lib/share.c b/lib/share.c index 9c43c8f70534887236d85f20daa470913f7c9a1c..8681ac2c2e8d96b6a5f2d8f8f5bbb4610e5c1374 100644 --- a/lib/share.c +++ b/lib/share.c @@ -27,9 +27,11 @@ #include "share.h" #include "psl.h" #include "vtls/vtls.h" -#include "curl_memory.h" +#include "hsts.h" -/* The last #include file should be: */ +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" #include "memdebug.h" struct Curl_share * @@ -91,6 +93,18 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...) #endif break; + case CURL_LOCK_DATA_HSTS: +#ifndef CURL_DISABLE_HSTS + if(!share->hsts) { + share->hsts = Curl_hsts_init(); + if(!share->hsts) + res = CURLSHE_NOMEM; + } +#else /* CURL_DISABLE_HSTS */ + res = CURLSHE_NOT_BUILT_IN; +#endif + break; + case CURL_LOCK_DATA_SSL_SESSION: #ifdef USE_SSL if(!share->sslsession) { @@ -143,6 +157,16 @@ curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...) #endif break; + case CURL_LOCK_DATA_HSTS: +#ifndef CURL_DISABLE_HSTS + if(share->hsts) { + Curl_hsts_cleanup(&share->hsts); + } +#else /* CURL_DISABLE_HSTS */ + res = CURLSHE_NOT_BUILT_IN; +#endif + break; + case CURL_LOCK_DATA_SSL_SESSION: #ifdef USE_SSL Curl_safefree(share->sslsession); @@ -209,6 +233,10 @@ curl_share_cleanup(struct Curl_share *share) Curl_cookie_cleanup(share->cookies); #endif +#ifndef CURL_DISABLE_HSTS + Curl_hsts_cleanup(&share->hsts); +#endif + #ifdef USE_SSL if(share->sslsession) { size_t i; diff --git a/lib/share.h b/lib/share.h index 222e34ba6ea0abe5b169abeacdbbb63e9fc77041..97b820b0f9a2fc6dcdbf91bfe3c6132e0c1f9995 100644 --- a/lib/share.h +++ b/lib/share.h @@ -57,10 +57,14 @@ struct Curl_share { #ifdef USE_LIBPSL struct PslCache psl; #endif - +#ifndef CURL_DISABLE_HSTS + struct hsts *hsts; +#endif +#ifdef USE_SSL struct Curl_ssl_session *sslsession; size_t max_ssl_sessions; long sessionage; +#endif }; CURLSHcode Curl_share_lock(struct Curl_easy *, curl_lock_data, diff --git a/lib/transfer.c b/lib/transfer.c index 78bf349fc12c878e1531ed9697083e684a9ae0de..0d3736447dff41199d595f93ddc2d33f63cac492 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -1468,6 +1468,9 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) if(data->state.resolve) result = Curl_loadhostpairs(data); + /* If there is a list of hsts files to read */ + Curl_hsts_loadfiles(data); + if(!result) { /* Allow data->set.use_port to set which port to use. This needs to be * disabled for example when we follow Location: headers to URLs using diff --git a/lib/url.c b/lib/url.c index 10d6ade8c8d7075ad99d0e7cfa7424c8125bab6d..2569f6d111c8ba0ae4c684a20603f0f1bf54b51b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -427,7 +427,11 @@ CURLcode Curl_close(struct Curl_easy **datap) Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]); Curl_altsvc_cleanup(&data->asi); Curl_hsts_save(data, data->hsts, data->set.str[STRING_HSTS]); - Curl_hsts_cleanup(&data->hsts); +#ifndef CURL_DISABLE_HSTS + if(!data->share || !data->share->hsts) + Curl_hsts_cleanup(&data->hsts); + curl_slist_free_all(data->set.hstslist); /* clean up list */ +#endif #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) Curl_http_auth_cleanup_digest(data); #endif diff --git a/lib/urldata.h b/lib/urldata.h index 0430ac4e514300866846bf8d7d8cf95c28b7d041..ba76fc7946448b2d598a89b3177d4ea37c6f59b0 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -706,7 +706,8 @@ struct SingleRequest { struct dohdata *doh; /* DoH specific data for this request */ #endif unsigned char setcookies; - BIT(header); /* incoming data has HTTP header */ + unsigned char writer_stack_depth; /* Unencoding stack depth. */ + BIT(header); /* incoming data has HTTP header */ BIT(content_range); /* set TRUE if Content-Range: was found */ BIT(upload_done); /* set to TRUE when doing chunked transfer-encoding upload and we're uploading the last chunk */ @@ -1669,6 +1670,8 @@ struct UserDefined { /* function to convert from UTF-8 encoding: */ curl_conv_callback convfromutf8; #ifndef CURL_DISABLE_HSTS + struct curl_slist *hstslist; /* list of HSTS files set by + curl_easy_setopt(HSTS) calls */ curl_hstsread_callback hsts_read; void *hsts_read_userp; curl_hstswrite_callback hsts_write; diff --git a/src/tool_operate.c b/src/tool_operate.c index e6ca575bf4bda8b836b85cc5a68d86a428f300f9..c7025953351950125c19ce4d30eaf4d913c41821 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -2540,6 +2540,7 @@ CURLcode operate(struct GlobalConfig *global, int argc, argv_item_t argv[]) curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_PSL); + curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_HSTS); /* Get the required arguments for each operation */ do { diff --git a/tests/FILEFORMAT.md b/tests/FILEFORMAT.md index 7a9c4820428193f092564fb30fd58014f4905921..e17605beb4cd678fac21039736dc8a1563dfe19d 100644 --- a/tests/FILEFORMAT.md +++ b/tests/FILEFORMAT.md @@ -527,14 +527,14 @@ changing protocol data such as port numbers or user-agent strings. One perl op per line that operates on the protocol dump. This is pretty advanced. Example: `s/^EPRT .*/EPRT stripped/`. -### `` +### `` the protocol dump curl should transmit, if 'nonewline' is set, we will cut off the trailing newline of this given data before comparing with the one actually sent by the client The `` and `` rules are applied before comparisons are made. -### `` +### `` The protocol dump curl should transmit to a HTTP proxy (when the http-proxy server is used), if 'nonewline' is set, we will cut off the trailing newline diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 4368ddf3dcd98b1be32b63b2c2376604d5e9e004..7dc553696e174e36bf0c6da3a336dc0fae37192f 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -5,7 +5,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. +# Copyright (C) 1998 - 2023, Daniel Stenberg, , et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -65,11 +65,11 @@ test387 \ test393 test394 test395 test396 test397 \ \ test400 test401 test402 test403 test404 test405 test406 test407 test408 \ -test409 test410 \ +test409 test410 test418 \ \ test430 test431 test432 test433 test434 \ \ -test442 test443 test444 test445 \ +test442 test443 test444 test445 test446 \ \ test490 test491 test492 test493 test494 \ \ @@ -159,7 +159,7 @@ test1240 test1241 test1242 test1243 test1244 test1245 test1246 test1247 \ test1248 test1249 test1250 test1251 test1252 test1253 test1254 test1255 \ test1256 test1257 test1258 test1259 test1260 test1261 test1262 test1263 \ test1264 test1265 test1266 test1267 test1268 test1269 test1270 test1271 \ -test1272 test1273 \ +test1272 test1273 test1277 \ \ test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 \ test1288 test1289 test1290 test1291 test1292 test1293 test1294 test1295 \ diff --git a/tests/data/test1277 b/tests/data/test1277 new file mode 100644 index 0000000000000000000000000000000000000000..df740203841986db653e160d63bb3b9e4c2e8c60 --- /dev/null +++ b/tests/data/test1277 @@ -0,0 +1,206 @@ + + + +HTTP +HTTP GET +compressed +Transfer-Encoding +Content-Encoding + + +# +# Server-side + + +SFRUUC8xLjEgMjAwIE9LDQpEYXRlOiBNb24sIDI5IE5vdiAyMDA0IDIxOjU2OjUzIEdNVA0KU2Vy +dmVyOiBBcGFjaGUvMS4zLjMxIChEZWJpYW4gR05VL0xpbnV4KSBtb2RfZ3ppcC8xLjMuMjYuMWEg +UEhQLzQuMy45LTEgbW9kX3NzbC8yLjguMjAgT3BlblNTTC8wLjkuN2QgbW9kX3BlcmwvMS4yOQ0K +VmFyeTogQWNjZXB0LUVuY29kaW5nDQpDb250ZW50LVR5cGU6IHRleHQvaHRtbDsgY2hhcnNldD1J +U08tODg1OS0xDQpUcmFuc2Zlci1FbmNvZGluZzogZ3ppcCwgY2h1bmtlZA0KQ29udGVudC1FbmNv +ZGluZzogZGVmbGF0ZQ0KDQo1MjINCh+LCAAHgbBjAv8BCwX0+nja3VjbbuM2EH03kH9g/dQCtm62 +EzlwtChy2QTNNsHaBbpPBi3RNhtJFEjKuTz02zuUKImxHK93g74ESGJy5pzD4QxJk5l8ekpitCFc +UJaedV3L6SKShiyi6eqsezO96/v+aNx3u5+CzuSXi7vz2bf7S5Rx9g8JZT+mQgIQTb9NZ5dfUHct +ZXZq20tOxDohWFopkfYChw8kjexl0tc80XesoRXJqAuiW1pBB6HKptpNb06jwD12vYltGEpEhCWZ +4ygigBiP/b7j9z0XOcNTxz31xhPb8BuEPFMfUeA5zrDvOn3XR4536sHPQFMqxKs4UpyQuVgzLoMw +53EdjmFv45d5HBdwhNMIxXTRphYQHR4RoZY6Z0lSUlKCJGO1AMf8GS0ZR2FMSSr7gkYE/fX1FkmO +U7GEilowi0bIUN4ZDKIC4XIEpVqpcFXfJY2JOOrkQnXUGOI5lfjJQjcSiTzLQF+g69nsvlf8nfbQ +FbSPOldF++LmfNZDs8vbPy/h8/bid4Bd3dxe9orhP9/dX19+hTYM8EhiiKmU6mdMyJ5u5tAKGXug +RBTaKM9ihiMYApZanpComXUPZViIR8Yj1YTI0jxZFPbp9PaoExIu6ZKGUFcw/UE4+JgoQ4FqPMEI +xbQgGxl7JJxER53Fc5WkHpJr8mbGq7JYR53ZGqgIw++CpmozCUhtnWqVYAabDnnOUSfG6SrHKyKK +GEi6oZylCQwgQEeX0FgbGypxTOXzXISMk2B04g+t0cnE3rJvgTPCQ5AMBpZ7bGAr8xYa5vMAe21s +IAuTXtcsy2PMm7GOR2OIYQjLedvTIlQDugPLd18RXodiOMpgnNErtBEOx8W54VsjZ2LrjumZhywH +Xc+tvNrwClMO4g9qjDGAyBci5DSTcESKYKBOh9emEgalT8P1XO3l4IIscR7LiW0aSxjUf14dYBmU +Pdh5aFYnpa3Wiz2xW6xGbM0S8rYQLGDKSxV1eNomQ+vWAo2mXL0cLgdgraRojcjixTtcBMBaRNEa +kReaHS4CYC2iaI1IuIY9RmK2OlyqpmjBRqKR5VlyuCCAtZSiNSIRWRwuAmAtomiNCBNPh4sAWIso +mlEvEanz8gdqVhKqumm6scxzDmkTJNDrt+oahdmIHyjJRlTF2AhDRN0cDldRaC1TEBudhHLO+OFK +JV5rabJZ14QFVa2gWXpiCoccpODLzcz+G53D6QEpo3mCbkvHxK4QGq++p+Sck5jUmWuZ5/r+FpxY +rmfBBekN9xtsda86OXb8UYtYXbDaHHUv2n1x2gUs52LvmswEzlECE14zOZdr+KqGnLVMJRLnEm4y +og6p7Ffd2qBPYJxSEqOpJCl8w68mtulsUaBKu+v+7wKvIqKKbCBbdM5iEtw9poTXuMJURWqboVY9 +YVzJOE1oiqU5O8nhhlDUBgpad1pezzve5x7s5e5zur6/l+vuHReWxv6o97rd4+E+93gv2R/v9Tp7 +3e7oO3F/J7D9kQ1aY5f3u+3yw5rI4MkEDzG4jtY6tfEZyeeMnHU5CeF1oGzqJVUvygZnbmRHDbXL +sZOo7y3gPhmqYux07WQaj7MWdfvh9hZXUqk2FNjhzo5+1bep33Zqldh6pzWIt/PGinsbjv+/pDk/ +nbHh4J0ZU++rj58o1xuM3Hdk6gWeYh8/SwPPGZ68I0vXhCYRjj9+oobD0cB7R6LCPjz1xc/kybDo +s77+r1DQqZvNf8f+A904jtHT7+gYCwUAAA0KMA0KDQo= + + + + +HTTP/1.1 200 OK +Date: Mon, 29 Nov 2004 21:56:53 GMT +Server: Apache/1.3.31 (Debian GNU/Linux) mod_gzip/1.3.26.1a PHP/4.3.9-1 mod_ssl/2.8.20 OpenSSL/0.9.7d mod_perl/1.29 +Vary: Accept-Encoding +Content-Type: text/html; charset=ISO-8859-1 +Transfer-Encoding: gzip, chunked +Content-Encoding: deflate + + + + + + 1612 + 1998-08-21 04:01:29 + 2004-10-18 02:22:23 + curl + curl and libcurl + Command line tool and library for client-side URL transfers. + curl and libcurl is a tool for transferring files +using URL syntax. It supports HTTP, HTTPS, FTP, +FTPS, DICT, TELNET, LDAP, FILE, and GOPHER, as +well as HTTP-post, HTTP-put, cookies, FTP upload, +resumed transfers, passwords, portnumbers, SSL +certificates, Kerberos, and proxies. It is powered +by libcurl, the client-side URL transfer library. +There are bindings to libcurl for over 20 +languages and environments. + + 5784.57 + 3.16 + 169 + 6594.54 + 13.81 + 105 + 8.50 + 21 + 183 + 323 + Default + http://freshmeat.net/projects/curl/ + http://freshmeat.net/redir/curl/1612/url_homepage/ + http://freshmeat.net/redir/curl/1612/url_tgz/ + http://freshmeat.net/redir/curl/1612/url_bz2/ + http://freshmeat.net/redir/curl/1612/url_zip/ + http://freshmeat.net/redir/curl/1612/url_changelog/ + http://freshmeat.net/redir/curl/1612/url_rpm/ + http://freshmeat.net/redir/curl/1612/url_deb/ + http://freshmeat.net/redir/curl/1612/url_osx/ + http://freshmeat.net/redir/curl/1612/url_bsdport/ + + http://freshmeat.net/redir/curl/1612/url_cvs/ + http://freshmeat.net/redir/curl/1612/url_list/ + http://freshmeat.net/redir/curl/1612/url_mirror/ + + MIT/X Consortium License + + 7.12.2 + 176085 + 2004-10-18 02:22:23 + + + + + Daniel Stenberg + http://freshmeat.net/~bagder/ + Owner + + + + 12 + 226 + 3 + 2 + 188 + 216 + 200 + 220 + 164 + 90 + 89 + 809 + 150 + 224 + 900 + 839 + + + + 0 + 7464 + 7464 + OpenSSL (Default) + + + 0 + 0 + 7443 + OpenLDAP + + + 0 + 0 + 12351 + zlib + + + 0 + 0 + 32047 + Heimdal + + + 0 + 0 + 44532 + c-ares + + + + + + + + +# +# Client-side + + +libz + + +http + + +HTTP GET with both content and transfer encoding + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER --tr-encoding --compressed + + + +# +# Verify data after the test has been "shot" + + +s/^Accept-Encoding: [a-zA-Z, ]*/Accept-Encoding: xxx/ + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* +Connection: TE +TE: gzip +Accept-Encoding: xxx + + + + diff --git a/tests/data/test387 b/tests/data/test387 index 545c5752ef91c7bcb6d8c914fa392b020c44bccf..979ff733a958620466a78d80f04e08fa669ff726 100644 --- a/tests/data/test387 +++ b/tests/data/test387 @@ -47,7 +47,7 @@ Accept: */* 61 -curl: (61) Reject response due to 5 content encodings +curl: (61) Reject response due to more than 5 content encodings diff --git a/tests/data/test418 b/tests/data/test418 new file mode 100644 index 0000000000000000000000000000000000000000..50e974e60aa9ff5afdfbf0d35f7ac45f9858965d --- /dev/null +++ b/tests/data/test418 @@ -0,0 +1,152 @@ + + + +HTTP +gzip + + + +# +# Server-side + + +HTTP/1.1 200 OK +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip +Transfer-Encoding: gzip + +-foo- + + + +# +# Client-side + + +http + + +Response with multiple Transfer-Encoding headers + + +http://%HOSTIP:%HTTPPORT/%TESTNUMBER -sS + + + +# +# Verify data after the test has been "shot" + + +GET /%TESTNUMBER HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + +# CURLE_BAD_CONTENT_ENCODING is 61 + +61 + + +curl: (61) Reject response due to more than 5 content encodings + + + diff --git a/tests/data/test446 b/tests/data/test446 new file mode 100644 index 0000000000000000000000000000000000000000..eda302256db6126dd5616b60765ead9a2c64b9d5 --- /dev/null +++ b/tests/data/test446 @@ -0,0 +1,84 @@ + + + + +HTTP +HTTP proxy +HSTS +trailing-dot + + + + + +# we use this as response to a CONNECT + +HTTP/1.1 200 OK + + + +HTTP/1.1 200 OK +Content-Length: 6 +Strict-Transport-Security: max-age=604800 + +-foo- + + +HTTP/1.1 200 OK +Content-Length: 6 +Strict-Transport-Security: max-age=6048000 + +-baa- + + + + + +https +http-proxy + + +HSTS +proxy +https +debug + + +CURL_HSTS_HTTP=yes +CURL_TIME=2000000000 + + + +HSTS with two URLs + + +-x http://%HOSTIP:%PROXYPORT --hsts log/hsts%TESTNUMBER http://this.hsts.example./%TESTNUMBER http://another.example.com/%TESTNUMBER0002 + + + + +# we let it CONNECT to the server to confirm HSTS but deny from there + +GET http://this.hsts.example./%TESTNUMBER HTTP/1.1 +Host: this.hsts.example. +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive + +GET http://another.example.com/%TESTNUMBER0002 HTTP/1.1 +Host: another.example.com +User-Agent: curl/%VERSION +Accept: */* +Proxy-Connection: Keep-Alive + + + + +# Your HSTS cache. https://curl.se/docs/hsts.html +# This file was generated by libcurl! Edit at your own risk. +this.hsts.example "20330525 03:33:20" +another.example.com "20330727 03:33:20" + + + + diff --git a/tests/runtests.pl b/tests/runtests.pl index 9afc97df004939a8e591157402055fb8b1b111df..ecb5f93daa4a47e11d1ab5bdba02afeae7cbdf79 100755 --- a/tests/runtests.pl +++ b/tests/runtests.pl @@ -4470,6 +4470,11 @@ sub singletest { } } + if($hash{'crlf'} || + ($has_hyper && ($keywords{"HTTP"} || $keywords{"HTTPS"}))) { + map subNewlines(0, \$_), @protstrip; + } + $res = compare($testnum, $testname, "proxy", \@out, \@protstrip); if($res) { return $errorreturncode;