From d4c5a917226ad6d5bee1b1d6deb099e1d9a895e6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 15 Sep 2016 14:01:06 +0200 Subject: [PATCH] http: accept "Transfer-Encoding: chunked" for HTTP/2 as well ... but don't send the actual header over the wire as it isn't accepted. Chunked uploading is still triggered using this method. Fixes #1013 Fixes #662 --- lib/http.c | 64 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/lib/http.c b/lib/http.c index e4b9d8b..07ad463 100644 --- a/lib/http.c +++ b/lib/http.c @@ -3,11 +3,11 @@ * Project ___| | | | _ \| | * / __| | | | |_) | | * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2016, 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 * are also available at https://curl.haxx.se/docs/copyright.html. * @@ -1646,10 +1646,14 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, else if(conn->allocptr.te && /* when asking for Transfer-Encoding, don't pass on a custom Connection: */ checkprefix("Connection", headers->data)) ; + else if((conn->httpversion == 20) && + checkprefix("Transfer-Encoding:", headers->data)) + /* HTTP/2 doesn't support chunked requests */ + ; else { CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n", headers->data); if(result) return result; @@ -1932,44 +1936,39 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) if(!conn->allocptr.te) return CURLE_OUT_OF_MEMORY; } #endif - if(conn->httpversion == 20) - /* In HTTP2 forbids Transfer-Encoding: chunked */ - ptr = NULL; + ptr = Curl_checkheaders(conn, "Transfer-Encoding:"); + if(ptr) { + /* Some kind of TE is requested, check if 'chunked' is chosen */ + data->req.upload_chunky = + Curl_compareheader(ptr, "Transfer-Encoding:", "chunked"); + } else { - ptr = Curl_checkheaders(conn, "Transfer-Encoding:"); - if(ptr) { - /* Some kind of TE is requested, check if 'chunked' is chosen */ - data->req.upload_chunky = - Curl_compareheader(ptr, "Transfer-Encoding:", "chunked"); - } - else { - if((conn->handler->protocol&PROTO_FAMILY_HTTP) && - data->set.upload && - (data->state.infilesize == -1)) { - if(conn->bits.authneg) - /* don't enable chunked during auth neg */ - ; - else if(use_http_1_1plus(data, conn)) { - /* HTTP, upload, unknown file size and not HTTP 1.0 */ - data->req.upload_chunky = TRUE; - } - else { - failf(data, "Chunky upload is not supported by HTTP 1.0"); - return CURLE_UPLOAD_FAILED; - } + if((conn->handler->protocol&PROTO_FAMILY_HTTP) && + data->set.upload && + (data->state.infilesize == -1)) { + if(conn->bits.authneg) + /* don't enable chunked during auth neg */ + ; + else if(use_http_1_1plus(data, conn)) { + /* HTTP, upload, unknown file size and not HTTP 1.0 */ + data->req.upload_chunky = TRUE; } else { - /* else, no chunky upload */ - data->req.upload_chunky = FALSE; + failf(data, "Chunky upload is not supported by HTTP 1.0"); + return CURLE_UPLOAD_FAILED; } - - if(data->req.upload_chunky) - te = "Transfer-Encoding: chunked\r\n"; } + else { + /* else, no chunky upload */ + data->req.upload_chunky = FALSE; + } + + if(data->req.upload_chunky) + te = "Transfer-Encoding: chunked\r\n"; } Curl_safefree(conn->allocptr.host); ptr = Curl_checkheaders(conn, "Host:"); @@ -2759,10 +2758,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) data->req.keepon &= ~KEEP_SEND; /* we're done writing */ data->req.exp100 = EXP100_SEND_DATA; /* already sent */ } } + if((conn->httpversion == 20) && data->req.upload_chunky) + /* upload_chunky was set above to set up the request in a chunky fashion, + but is disabled here again to avoid that the chunked encoded version is + actually used when sending the request body over h2 */ + data->req.upload_chunky = FALSE; return result; } /* * checkhttpprefix() -- 2.9.3