http: stop dropping large custom headers
No binary (build failed)
—
(log yok)
| @@ -175,7 +175,7 @@ static bool header_has_value(const char **headerp, struct Curl_str *outp) | |
| (!curlx_str_single(headerp, ':') || !curlx_str_single(headerp, ';')); | |
| if(value) { | |
| - | curlx_str_untilnl(headerp, outp, MAX_HTTP_RESP_HEADER_SIZE); |
| + | curlx_str_cspn(headerp, outp, "\r\n"); |
| curlx_str_trimblanks(outp); | |
| } | |
| return value; | |
| @@ -1415,7 +1415,7 @@ bool Curl_compareheader(const char *headerline, /* line to check */ | |
| /* pass the header */ | |
| p = &headerline[hlen]; | |
| - | if(curlx_str_untilnl(&p, &val, MAX_HTTP_RESP_HEADER_SIZE)) |
| + | if(curlx_str_cspn(&p, &val, "\r\n")) |
| return FALSE; | |
| curlx_str_trimblanks(&val); | |
| @@ -1432,7 +1432,7 @@ bool Curl_compareheader(const char *headerline, /* line to check */ | |
| !p[clen])) | |
| return TRUE; /* match! */ | |
| /* advance to the next comma */ | |
| - | if(curlx_str_until(&p, &next, MAX_HTTP_RESP_HEADER_SIZE, ',') || |
| + | if(curlx_str_until(&p, &next, len, ',') || |
| curlx_str_single(&p, ',')) | |
| break; /* no comma, get out */ | |
| @@ -1784,21 +1784,22 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data, | |
| struct Curl_str name; | |
| const char *p = headers->data; | |
| const char *origp = p; | |
| + | size_t hlen = strlen(origp); |
| /* explicitly asked to send header without content is done by a header | |
| that ends with a semicolon, but there must be no colon present in the | |
| name */ | |
| - | if(!curlx_str_until(&p, &name, MAX_HTTP_RESP_HEADER_SIZE, ';') && |
| + | if(!curlx_str_until(&p, &name, hlen, ';') && |
| !curlx_str_single(&p, ';') && | |
| !curlx_str_single(&p, '\0') && | |
| !memchr(curlx_str(&name), ':', curlx_strlen(&name))) | |
| blankheader = TRUE; | |
| else { | |
| p = origp; | |
| - | if(!curlx_str_until(&p, &name, MAX_HTTP_RESP_HEADER_SIZE, ':') && |
| + | if(!curlx_str_until(&p, &name, hlen, ':') && |
| !curlx_str_single(&p, ':')) { | |
| struct Curl_str val; | |
| - | curlx_str_untilnl(&p, &val, MAX_HTTP_RESP_HEADER_SIZE); |
| + | curlx_str_untilnl(&p, &val, hlen); |
| curlx_str_trimblanks(&val); | |
| if(!curlx_strlen(&val)) | |
| /* no content, do not send this */ | |
| @@ -1849,9 +1850,11 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data, | |
| other hosts */ | |
| !Curl_auth_allowed_to_host(data)) | |
| ; | |
| - | else if(blankheader) |
| - | result = curlx_dyn_addf(req, "%.*s:\r\n", (int)curlx_strlen(&name), |
| - | curlx_str(&name)); |
| + | else if(blankheader) { |
| + | result = curlx_dyn_addn(req, curlx_str(&name), curlx_strlen(&name)); |
| + | if(!result) |
| + | result = curlx_dyn_addn(req, STRCONST(":\r\n")); |
| + | } |
| else | |
| result = curlx_dyn_addf(req, "%s\r\n", origp); | |
| @@ -284,7 +284,7 @@ test3100 test3101 test3102 test3103 test3104 test3105 test3106 \ | |
| test3200 test3201 test3202 test3203 test3204 test3205 test3206 test3207 \ | |
| test3208 test3209 test3210 test3211 test3212 test3213 test3214 test3215 \ | |
| test3216 test3217 test3218 test3219 test3220 test3221 test3222 \ | |
| - | test3223 test3224 test3225 test3226 test3227 \ |
| + | test3223 test3224 test3225 test3226 test3227 test3228 test3229 \ |
| \ | |
| test3300 test3301 test3302 test3303 test3304 test3305 \ | |
| \ | |
| @@ -0,0 +1,58 @@ | |
| + | <?xml version="1.0" encoding="US-ASCII"?> |
| + | <testcase> |
| + | <info> |
| + | <keywords> |
| + | HTTP |
| + | HTTP GET |
| + | HTTP added headers |
| + | </keywords> |
| + | </info> |
| + | |
| + | # Server-side |
| + | <reply> |
| + | <data> |
| + | HTTP/1.1 200 OK |
| + | Date: Tue, 09 Nov 2010 14:49:00 GMT |
| + | Server: test-server/fake |
| + | Content-Length: 6 |
| + | Connection: close |
| + | |
| + | -foo- |
| + | </data> |
| + | </reply> |
| + | |
| + | # Client-side |
| + | <client> |
| + | <server> |
| + | http |
| + | </server> |
| + | <name> |
| + | Send custom request headers larger than the response header limit |
| + | </name> |
| + | <stdin> |
| + | header "X-Large: %repeat[307200 x x]%" |
| + | header "Connection: %repeat[307200 x x]%" |
| + | header "%repeat[307201 x X]%;" |
| + | </stdin> |
| + | <command> |
| + | -K - http://%HOSTIP:%HTTPPORT/%TESTNUMBER |
| + | </command> |
| + | </client> |
| + | |
| + | # Verify data after the test has been "shot" |
| + | <verify> |
| + | <protocol crlf="yes"> |
| + | GET /%TESTNUMBER HTTP/1.1 |
| + | Host: %HOSTIP:%HTTPPORT |
| + | User-Agent: curl/%VERSION |
| + | Accept: */* |
| + | X-Large: %repeat[307200 x x]% |
| + | %repeat[307201 x X]%: |
| + | Connection: %repeat[307200 x x]% |
| + | |
| + | </protocol> |
| + | <limits> |
| + | Maximum allocated: 4000000 |
| + | </limits> |
| + | </verify> |
| + | </testcase> |
| @@ -0,0 +1,37 @@ | |
| + | <?xml version="1.0" encoding="US-ASCII"?> |
| + | <testcase> |
| + | <info> |
| + | <keywords> |
| + | HTTP |
| + | HTTP GET |
| + | HTTP added headers |
| + | </keywords> |
| + | </info> |
| + | |
| + | # Client-side |
| + | <client> |
| + | <server> |
| + | http |
| + | </server> |
| + | <name> |
| + | Reject a custom request header larger than the request buffer |
| + | </name> |
| + | <stdin> |
| + | header "X-Large: %repeat[1048576 x x]%" |
| + | </stdin> |
| + | <command> |
| + | -K - http://%HOSTIP:%HTTPPORT/%TESTNUMBER |
| + | </command> |
| + | </client> |
| + | |
| + | # Verify data after the test has been "shot" |
| + | <verify> |
| + | # 100 == CURLE_TOO_LARGE |
| + | <errorcode> |
| + | 100 |
| + | </errorcode> |
| + | <limits> |
| + | Maximum allocated: 6000000 |
| + | </limits> |
| + | </verify> |
| + | </testcase> |
| @@ -38,7 +38,11 @@ static CURLcode test_unit1625(const char *arg) | |
| { | |
| UNITTEST_BEGIN_SIMPLE | |
| + | char *large; |
| size_t i; | |
| + | const size_t large_value_len = MAX_HTTP_RESP_HEADER_SIZE; |
| + | const size_t large_prefix_len = strlen("Encoding: "); |
| + | const size_t large_suffix_len = strlen(", chunked"); |
| static const struct check1625 list[] = { | |
| /* basic case */ | |
| { "Encoding: gzip, chunked", "Encoding:", "chunked", TRUE }, | |
| @@ -129,6 +133,20 @@ static CURLcode test_unit1625(const char *arg) | |
| if(i != CURL_ARRAYSIZE(list)) | |
| return CURLE_FAILED_INIT; | |
| + | large = curlx_malloc(large_prefix_len + large_value_len + |
| + | large_suffix_len + 1); |
| + | if(!large) |
| + | return CURLE_OUT_OF_MEMORY; |
| + | |
| + | memcpy(large, "Encoding: ", large_prefix_len + 1); |
| + | memset(&large[large_prefix_len], 'a', large_value_len); |
| + | memcpy(&large[large_prefix_len + large_value_len], ", chunked", |
| + | large_suffix_len + 1); |
| + | fail_unless(Curl_compareheader(large, STRCONST("Encoding:"), |
| + | STRCONST("chunked")), |
| + | "token after 300 KiB was not found"); |
| + | curlx_free(large); |
| + | |
| UNITTEST_END_SIMPLE | |
| } | |
| #else /* CURL_DISABLE_HTTP */ | |