]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http: avoid Expect: 100-continue if Upgrade: is used
authorDaniel Stenberg <daniel@haxx.se>
Sun, 8 Oct 2023 10:04:59 +0000 (12:04 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 12 Oct 2023 14:31:41 +0000 (16:31 +0200)
Reported-by: Daniel Jelinski
Fixes #12022
Closes #12062

lib/http.c

index 40ef70df50c5c40fa077e9ae44a13456dbf141f5..d6b78cae792159f4de3e21ae9300d6af20ef5127 100644 (file)
@@ -1678,8 +1678,6 @@ static CURLcode expect100(struct Curl_easy *data,
                           struct dynbuf *req)
 {
   CURLcode result = CURLE_OK;
-  data->state.expect100header = FALSE; /* default to false unless it is set
-                                          to TRUE below */
   if(!data->state.disableexpect && Curl_use_http_1_1plus(data, conn) &&
      (conn->httpversion < 20)) {
     /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
@@ -2494,6 +2492,29 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
   return result;
 }
 
+static CURLcode addexpect(struct Curl_easy *data, struct connectdata *conn,
+                          struct dynbuf *r)
+{
+  data->state.expect100header = FALSE;
+  /* Avoid Expect: 100-continue if Upgrade: is used */
+  if(data->req.upgr101 == UPGR101_INIT) {
+    struct HTTP *http = data->req.p.http;
+    /* For really small puts we don't use Expect: headers at all, and for
+       the somewhat bigger ones we allow the app to disable it. Just make
+       sure that the expect100header is always set to the preferred value
+       here. */
+    char *ptr = Curl_checkheaders(data, STRCONST("Expect"));
+    if(ptr) {
+      data->state.expect100header =
+        Curl_compareheader(ptr, STRCONST("Expect:"),
+                           STRCONST("100-continue"));
+    }
+    else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0)
+      return expect100(data, conn, r);
+  }
+  return CURLE_OK;
+}
+
 CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
                             struct dynbuf *r, Curl_HttpReq httpreq)
 {
@@ -2506,14 +2527,8 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
 #endif
   CURLcode result = CURLE_OK;
   struct HTTP *http = data->req.p.http;
-  const char *ptr;
-
-  /* If 'authdone' is FALSE, we must not set the write socket index to the
-     Curl_transfer() call below, as we're not ready to actually upload any
-     data yet. */
 
   switch(httpreq) {
-
   case HTTPREQ_PUT: /* Let's PUT the data to the server! */
 
     if(conn->bits.authneg)
@@ -2531,20 +2546,9 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
         return result;
     }
 
-    /* For really small puts we don't use Expect: headers at all, and for
-       the somewhat bigger ones we allow the app to disable it. Just make
-       sure that the expect100header is always set to the preferred value
-       here. */
-    ptr = Curl_checkheaders(data, STRCONST("Expect"));
-    if(ptr) {
-      data->state.expect100header =
-        Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue"));
-    }
-    else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) {
-      result = expect100(data, conn, r);
-      if(result)
-        return result;
-    }
+    result = addexpect(data, conn, r);
+    if(result)
+      return result;
 
     /* end of headers */
     result = Curl_dyn_addn(r, STRCONST("\r\n"));
@@ -2617,22 +2621,9 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
     }
 #endif
 
-    /* For really small posts we don't use Expect: headers at all, and for
-       the somewhat bigger ones we allow the app to disable it. Just make
-       sure that the expect100header is always set to the preferred value
-       here. */
-    ptr = Curl_checkheaders(data, STRCONST("Expect"));
-    if(ptr) {
-      data->state.expect100header =
-        Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue"));
-    }
-    else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) {
-      result = expect100(data, conn, r);
-      if(result)
-        return result;
-    }
-    else
-      data->state.expect100header = FALSE;
+    result = addexpect(data, conn, r);
+    if(result)
+      return result;
 
     /* make the request end in a true CRLF */
     result = Curl_dyn_addn(r, STRCONST("\r\n"));
@@ -2692,22 +2683,9 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
         return result;
     }
 
-    /* For really small posts we don't use Expect: headers at all, and for
-       the somewhat bigger ones we allow the app to disable it. Just make
-       sure that the expect100header is always set to the preferred value
-       here. */
-    ptr = Curl_checkheaders(data, STRCONST("Expect"));
-    if(ptr) {
-      data->state.expect100header =
-        Curl_compareheader(ptr, STRCONST("Expect:"), STRCONST("100-continue"));
-    }
-    else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) {
-      result = expect100(data, conn, r);
-      if(result)
-        return result;
-    }
-    else
-      data->state.expect100header = FALSE;
+    result = addexpect(data, conn, r);
+    if(result)
+      return result;
 
 #ifndef USE_HYPER
     /* With Hyper the body is always passed on separately */