]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
msh3: add support for request payload
authorNick Banks <nibanks@microsoft.com>
Tue, 27 Dec 2022 16:02:56 +0000 (16:02 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 28 Dec 2022 12:52:58 +0000 (13:52 +0100)
Closes #10136

lib/h2h3.c
lib/h2h3.h
lib/http2.c
lib/vquic/msh3.c
lib/vquic/ngtcp2.c
lib/vquic/quiche.c

index 3a9288df5c9e712ddee2fe2510d0d74982ee5eff..c8c096acb85d042117b4015d7ca781f128422ca0 100644 (file)
@@ -118,6 +118,7 @@ static header_instruction inspect_header(const char *name, size_t namelen,
 CURLcode Curl_pseudo_headers(struct Curl_easy *data,
                              const char *mem, /* the request */
                              const size_t len /* size of request */,
+                             size_t* hdrlen /* opt size of headers read */,
                              struct h2h3req **hp)
 {
   struct connectdata *conn = data->conn;
@@ -291,6 +292,12 @@ CURLcode Curl_pseudo_headers(struct Curl_easy *data,
     }
   }
 
+  if(hdrlen) {
+    /* Skip trailing CRLF */
+    end += 4;
+    *hdrlen = end - mem;
+  }
+
   hreq->entries = nheader;
   *hp = hreq;
 
index c35b7061fa531673c0e48cef28ddc98082b06487..eaaeaaaa0f0720a6b9446fb9ad90a9c9535200c2 100644 (file)
@@ -51,6 +51,7 @@ struct h2h3req {
 CURLcode Curl_pseudo_headers(struct Curl_easy *data,
                              const char *request,
                              const size_t len,
+                             size_t* hdrlen /* optional */,
                              struct h2h3req **hp);
 
 /*
index b9d3245cf89a15119fe7b355ea5c662ad0868659..6d060ae17f5a5b847b036dedb0865661abea4b7e 100644 (file)
@@ -1942,7 +1942,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
     return len;
   }
 
-  result = Curl_pseudo_headers(data, mem, len, &hreq);
+  result = Curl_pseudo_headers(data, mem, len, NULL, &hreq);
   if(result) {
     *err = result;
     return -1;
index d108d924a13f1f91df68ee1af2caf961f784fd63..caa16e5a7f9a453209bdf31e250298657184c177 100644 (file)
@@ -403,6 +403,8 @@ static ssize_t msh3_stream_send(struct Curl_easy *data,
   struct HTTP *stream = data->req.p.http;
   struct quicsocket *qs = conn->quic;
   struct h2h3req *hreq;
+  size_t hdrlen = 0;
+  size_t sentlen = 0;
 
   (void)sockindex;
   /* Sizes must match for cast below to work" */
@@ -411,15 +413,21 @@ static ssize_t msh3_stream_send(struct Curl_easy *data,
   H3BUGF(infof(data, "msh3_stream_send %zu", len));
 
   if(!stream->req) {
-    *curlcode = Curl_pseudo_headers(data, mem, len, &hreq);
+    /* The first send on the request contains the headers and possibly some
+       data. Parse out the headers and create the request, then if there is
+       any data left over go ahead and send it too. */
+    *curlcode = Curl_pseudo_headers(data, mem, len, &hdrlen, &hreq);
     if(*curlcode) {
       failf(data, "Curl_pseudo_headers failed");
       return -1;
     }
+
     H3BUGF(infof(data, "starting request with %zu headers", hreq->entries));
     stream->req = MsH3RequestOpen(qs->conn, &msh3_request_if, stream,
-                                 (MSH3_HEADER*)hreq->header, hreq->entries,
-                                 MSH3_REQUEST_FLAG_FIN);
+                                  (MSH3_HEADER*)hreq->header, hreq->entries,
+                                  hdrlen == len ? MSH3_REQUEST_FLAG_FIN :
+                                   MSH3_REQUEST_FLAG_NONE);
+
     Curl_pseudo_free(hreq);
     if(!stream->req) {
       failf(data, "request open failed");
@@ -431,8 +439,24 @@ static ssize_t msh3_stream_send(struct Curl_easy *data,
   }
   H3BUGF(infof(data, "send %zd body bytes on request %p", len,
                (void *)stream->req));
-  *curlcode = CURLE_SEND_ERROR;
-  return -1;
+  if(len > 0xFFFFFFFF) {
+    /* msh3 doesn't support size_t sends currently. */
+    *curlcode = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  /* TODO - Need an explicit signal to know when to FIN. */
+  if(!MsH3RequestSend(stream->req, MSH3_REQUEST_FLAG_FIN, mem, (uint32_t)len,
+                      stream)) {
+    *curlcode = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  /* TODO - msh3/msquic will hold onto this memory until the send complete
+     event. How do we make sure curl doesn't free it until then? */
+  sentlen += len;
+  *curlcode = CURLE_OK;
+  return sentlen;
 }
 
 static ssize_t msh3_stream_recv(struct Curl_easy *data,
index f16b469946247f9d401470cb205a29df1cf22156..535a36898a6541ea8f92bd0e3ae2d2bbe70a6eeb 100644 (file)
@@ -1526,7 +1526,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem,
   stream->h3req = TRUE; /* senf off! */
   Curl_dyn_init(&stream->overflow, CURL_MAX_READ_SIZE);
 
-  result = Curl_pseudo_headers(data, mem, len, &hreq);
+  result = Curl_pseudo_headers(data, mem, len, NULL, &hreq);
   if(result)
     goto fail;
   nheader = hreq->entries;
index 2b9a0410f14a85dae0257d5ede92e482cbb2c6b2..fd9d52a79c30c70e9e6c2c583ac8c26325001ca8 100644 (file)
@@ -765,7 +765,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem,
 
   stream->h3req = TRUE; /* senf off! */
 
-  result = Curl_pseudo_headers(data, mem, len, &hreq);
+  result = Curl_pseudo_headers(data, mem, len, NULL, &hreq);
   if(result)
     goto fail;
   nheader = hreq->entries;