]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http: with chunked POST forced, disable length check on read callback
authorStefan Eissing <stefan@eissing.org>
Mon, 1 Apr 2024 13:41:18 +0000 (15:41 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 2 Apr 2024 06:41:44 +0000 (08:41 +0200)
- when an application forces HTTP/1.1 chunked transfer encoding
  by setting the corresponding header and instructs curl to use
  the CURLOPT_READFUNCTION, disregard any POST length information.
- this establishes backward compatibility with previous curl versions

Applications are encouraged to not force "chunked", but rather
set length information for a POST. By setting -1, curl will
auto-select chunked on HTTP/1.1 and work properly on other HTTP
versions.

Reported-by: Jeff King
Fixes #13229
Closes #13257

lib/http.c

index 92c04e69cd83734e643ba26a0e7762c2fb8ed727..a764d3c4403c395f5313d257a0da372439dd31c7 100644 (file)
@@ -2046,8 +2046,19 @@ static CURLcode set_reader(struct Curl_easy *data, Curl_HttpReq httpreq)
       else
         result = Curl_creader_set_null(data);
     }
-    else { /* we read the bytes from the callback */
-      result = Curl_creader_set_fread(data, postsize);
+    else {
+      /* we read the bytes from the callback. In case "chunked" encoding
+       * is forced by the application, we disregard `postsize`. This is
+       * a backward compatibility decision to earlier versions where
+       * chunking disregarded this. See issue #13229. */
+      bool chunked = FALSE;
+      char *ptr = Curl_checkheaders(data, STRCONST("Transfer-Encoding"));
+      if(ptr) {
+        /* Some kind of TE is requested, check if 'chunked' is chosen */
+        chunked = Curl_compareheader(ptr, STRCONST("Transfer-Encoding:"),
+                                     STRCONST("chunked"));
+      }
+      result = Curl_creader_set_fread(data, chunked? -1 : postsize);
     }
     return result;
 
@@ -2115,6 +2126,13 @@ CURLcode Curl_http_req_set_reader(struct Curl_easy *data,
     data->req.upload_chunky =
       Curl_compareheader(ptr,
                          STRCONST("Transfer-Encoding:"), STRCONST("chunked"));
+    if(data->req.upload_chunky &&
+       Curl_use_http_1_1plus(data, data->conn) &&
+       (data->conn->httpversion >= 20)) {
+       infof(data, "suppressing chunked transfer encoding on connection "
+             "using HTTP version 2 or higher");
+       data->req.upload_chunky = FALSE;
+    }
   }
   else {
     curl_off_t req_clen = Curl_creader_total_length(data);