]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http2: send HEADER & DATA together if possible
authorPontakorn Prasertsuk <ptk.prasertsuk@gmail.com>
Tue, 11 Jul 2023 08:00:29 +0000 (16:00 +0800)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 11 Jul 2023 18:09:55 +0000 (20:09 +0200)
Closes #11420

lib/http.c
lib/http2.c

index bc09f263129a02b6135590566237e485d03c3c20..f851bcd4a3443b03074861ad894e3a2ce7b8a18b 100644 (file)
@@ -2667,11 +2667,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
 #ifndef USE_HYPER
     /* With Hyper the body is always passed on separately */
     if(data->set.postfields) {
-
-      /* In HTTP2, we send request body in DATA frame regardless of
-         its size. */
-      if(conn->httpversion < 20 &&
-         !data->state.expect100header &&
+      if(!data->state.expect100header &&
          (http->postsize < MAX_INITIAL_POST_SIZE)) {
         /* if we don't use expect: 100  AND
            postsize is less than MAX_INITIAL_POST_SIZE
index c6275459a96c91dc63c14ce8c9203e122f0379bc..2d4bbce41c7b641c0ea465ac82ab39c43a547ed1 100644 (file)
@@ -1893,7 +1893,8 @@ static ssize_t h2_submit(struct stream_ctx **pstream,
   struct h1_req_parser h1;
   struct dynhds h2_headers;
   nghttp2_nv *nva = NULL;
-  size_t nheader, i;
+  const void *body = NULL;
+  size_t nheader, bodylen, i;
   nghttp2_data_provider data_prd;
   int32_t stream_id;
   nghttp2_priority_spec pri_spec;
@@ -2011,6 +2012,20 @@ static ssize_t h2_submit(struct stream_ctx **pstream,
     }
   }
 
+  body = (const char *)buf + nwritten;
+  bodylen = len - nwritten;
+
+  if(bodylen) {
+    /* We have request body to send in DATA frame */
+    ssize_t n = Curl_bufq_write(&stream->sendbuf, body, bodylen, err);
+    if(n < 0) {
+      *err = CURLE_SEND_ERROR;
+      nwritten = -1;
+      goto out;
+    }
+    nwritten += n;
+  }
+
 out:
   DEBUGF(LOG_CF(data, cf, "[h2sid=%d] submit -> %zd, %d",
          stream? stream->id : -1, nwritten, *err));
@@ -2060,8 +2075,9 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
       stream->upload_blocked_len = 0;
     }
     else {
-      /* If stream_id != -1, we have dispatched request HEADERS, and now
-         are going to send or sending request body in DATA frame */
+      /* If stream_id != -1, we have dispatched request HEADERS and
+       * optionally request body, and now are going to send or sending
+       * more request body in DATA frame */
       nwritten = Curl_bufq_write(&stream->sendbuf, buf, len, err);
       if(nwritten < 0) {
         if(*err != CURLE_AGAIN)