|
|
|
@ -249,6 +249,7 @@ int http_response_handle_cachable(request_st * const r, const buffer * const mti
|
|
|
|
|
|
|
|
|
|
void http_response_body_clear (request_st * const r, int preserve_length) { |
|
|
|
|
r->resp_send_chunked = 0; |
|
|
|
|
r->resp_body_scratchpad = -1; |
|
|
|
|
if (light_btst(r->resp_htags, HTTP_HEADER_TRANSFER_ENCODING)) { |
|
|
|
|
http_header_response_unset(r, HTTP_HEADER_TRANSFER_ENCODING, |
|
|
|
|
CONST_STR_LEN("Transfer-Encoding")); |
|
|
|
@ -283,6 +284,7 @@ static void http_response_header_clear (request_st * const r) {
|
|
|
|
|
* Transfer-Encoding: chunked set, then other items need to be reset */ |
|
|
|
|
r->resp_send_chunked = 0; |
|
|
|
|
r->resp_decode_chunked = 0; |
|
|
|
|
r->resp_body_scratchpad = -1; |
|
|
|
|
if (r->gw_dechunk) { |
|
|
|
|
free(r->gw_dechunk->b.ptr); |
|
|
|
|
free(r->gw_dechunk); |
|
|
|
@ -1181,8 +1183,37 @@ static int http_response_process_headers(request_st * const r, http_response_opt
|
|
|
|
|
break; |
|
|
|
|
case HTTP_HEADER_CONTENT_LENGTH: |
|
|
|
|
if (*value == '+') ++value; |
|
|
|
|
if (!r->resp_decode_chunked |
|
|
|
|
&& !light_btst(r->resp_htags, HTTP_HEADER_CONTENT_LENGTH)) { |
|
|
|
|
const char *err = ns; |
|
|
|
|
if (err[-1] == '\0') --err; /*(skip one '\0', trailing whitespace)*/ |
|
|
|
|
while (err > value && (err[-1] == ' ' || err[-1] == '\t')) --err; |
|
|
|
|
if (err <= value) continue; /*(might error 502 Bad Gateway)*/ |
|
|
|
|
uint32_t vlen = (uint32_t)(err - value); |
|
|
|
|
r->resp_body_scratchpad = |
|
|
|
|
(off_t)li_restricted_strtoint64(value, vlen, &err); |
|
|
|
|
if (err != value + vlen) { |
|
|
|
|
/*(invalid Content-Length value from backend;
|
|
|
|
|
* read from backend until backend close, hope for the best) |
|
|
|
|
*(might choose to treat this as 502 Bad Gateway) */ |
|
|
|
|
r->resp_body_scratchpad = -1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
/* ignore Content-Length if Transfer-Encoding: chunked
|
|
|
|
|
* ignore subsequent (multiple) Content-Length |
|
|
|
|
* (might choose to treat this as 502 Bad Gateway) */ |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case HTTP_HEADER_TRANSFER_ENCODING: |
|
|
|
|
if (light_btst(r->resp_htags, HTTP_HEADER_CONTENT_LENGTH)) { |
|
|
|
|
/* ignore Content-Length if Transfer-Encoding: chunked
|
|
|
|
|
* (might choose to treat this as 502 Bad Gateway) */ |
|
|
|
|
r->resp_body_scratchpad = -1; |
|
|
|
|
http_header_response_unset(r, HTTP_HEADER_CONTENT_LENGTH, |
|
|
|
|
CONST_STR_LEN("Content-Length")); |
|
|
|
|
} |
|
|
|
|
/*(assumes "Transfer-Encoding: chunked"; does not verify)*/ |
|
|
|
|
r->resp_decode_chunked = 1; |
|
|
|
|
r->gw_dechunk = calloc(1, sizeof(response_dechunk)); |
|
|
|
|