From a5bc272223681e1473f260ab9580b50753f25b7b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 15 Dec 2020 16:53:04 +0100 Subject: [PATCH] http: show the request as headers even when split-sending When the initial request isn't possible to send in its entirety, the remainder of request would be delivered to the debug callback as data and would wrongly be counted internally as body-bytes sent. Extended test 1295 to verify. Closes #6328 --- lib/http.c | 5 +++++ lib/transfer.c | 26 +++++++++++++++++++++----- lib/urldata.h | 2 ++ tests/data/test1295 | 19 +++++++++++++++++-- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/lib/http.c b/lib/http.c index c232ed413..a2279eb0a 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1294,6 +1294,9 @@ CURLcode Curl_buffer_send(struct dynbuf *in, http->postdata = ptr; http->postsize = (curl_off_t)size; + /* this much data is remaining header: */ + data->req.pendingheader = headersize - headlen; + http->send_buffer = *in; /* copy the whole struct */ http->sending = HTTPSEND_REQUEST; @@ -1316,6 +1319,8 @@ CURLcode Curl_buffer_send(struct dynbuf *in, } Curl_dyn_free(in); + /* no remaining header data */ + data->req.pendingheader = 0; return result; } diff --git a/lib/transfer.c b/lib/transfer.c index bfd0218fe..8fcb71832 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -1016,6 +1016,8 @@ static CURLcode readwrite_upload(struct Curl_easy *data, *didwhat |= KEEP_SEND; do { + curl_off_t nbody; + /* only read more data if there's no upload data already present in the upload buffer */ if(0 == k->upload_present) { @@ -1153,12 +1155,26 @@ static CURLcode readwrite_upload(struct Curl_easy *data, win_update_buffer_size(conn->writesockfd); - /* show the data before we change the pointer upload_fromhere */ - Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere, - (size_t)bytes_written); + if(k->pendingheader) { + /* parts of what was sent was header */ + curl_off_t n = CURLMIN(k->pendingheader, bytes_written); + /* show the data before we change the pointer upload_fromhere */ + Curl_debug(data, CURLINFO_HEADER_OUT, k->upload_fromhere, (size_t)n); + k->pendingheader -= n; + nbody = bytes_written - n; /* size of the written body part */ + } + else + nbody = bytes_written; - k->writebytecount += bytes_written; - Curl_pgrsSetUploadCounter(data, k->writebytecount); + if(nbody) { + /* show the data before we change the pointer upload_fromhere */ + Curl_debug(data, CURLINFO_DATA_OUT, + &k->upload_fromhere[bytes_written - nbody], + (size_t)nbody); + + k->writebytecount += nbody; + Curl_pgrsSetUploadCounter(data, k->writebytecount); + } if((!k->upload_chunky || k->forbidchunk) && (k->writebytecount == data->state.infilesize)) { diff --git a/lib/urldata.h b/lib/urldata.h index 4679c9d46..296341ebd 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -604,6 +604,8 @@ struct SingleRequest { following second response code) result in a CURLE_GOT_NOTHING error code */ + curl_off_t pendingheader; /* this many bytes left to send is actually + header and not body */ struct curltime start; /* transfer started at this time */ struct curltime now; /* current time */ enum { diff --git a/tests/data/test1295 b/tests/data/test1295 index 50e5fa2e2..a543811de 100644 --- a/tests/data/test1295 +++ b/tests/data/test1295 @@ -9,7 +9,7 @@ HTTP POST # # Server-side - + HTTP/1.1 200 OK Date: Thu, 09 Nov 2010 14:49:00 GMT Server: test-server/fake @@ -44,7 +44,7 @@ HTTP POST with split initial request send CURL_SMALLREQSEND=100 -http://%HOSTIP:%HTTPPORT/012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679/1295 -H "012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679: 300" -d "Mr. Sherlock Holmes, who was usually very late in the mornings, save upon those not infrequent occasions when he was up all night, was seated at the breakfast table." +http://%HOSTIP:%HTTPPORT/012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679/1295 -H "012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679012345679: 300" -d "Mr. Sherlock Holmes, who was usually very late in the mornings, save upon those not infrequent occasions when he was up all night, was seated at the breakfast table." -w '%{size_upload}\n' @@ -62,5 +62,20 @@ Content-Type: application/x-www-form-urlencoded Mr. Sherlock Holmes, who was usually very late in the mornings, save upon those not infrequent occasions when he was up all night, was seated at the breakfast table. + +HTTP/1.1 200 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- +165 +