From: Nick Banks Date: Tue, 27 Dec 2022 16:02:56 +0000 (+0000) Subject: msh3: add support for request payload X-Git-Tag: curl-7_88_0~208 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ae98b85020094fb04eee7e7b4ec4eb1a38a98b98;p=thirdparty%2Fcurl.git msh3: add support for request payload Closes #10136 --- diff --git a/lib/h2h3.c b/lib/h2h3.c index 3a9288df5c..c8c096acb8 100644 --- a/lib/h2h3.c +++ b/lib/h2h3.c @@ -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; diff --git a/lib/h2h3.h b/lib/h2h3.h index c35b7061fa..eaaeaaaa0f 100644 --- a/lib/h2h3.h +++ b/lib/h2h3.h @@ -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); /* diff --git a/lib/http2.c b/lib/http2.c index b9d3245cf8..6d060ae17f 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -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; diff --git a/lib/vquic/msh3.c b/lib/vquic/msh3.c index d108d924a1..caa16e5a7f 100644 --- a/lib/vquic/msh3.c +++ b/lib/vquic/msh3.c @@ -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, diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c index f16b469946..535a36898a 100644 --- a/lib/vquic/ngtcp2.c +++ b/lib/vquic/ngtcp2.c @@ -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; diff --git a/lib/vquic/quiche.c b/lib/vquic/quiche.c index 2b9a0410f1..fd9d52a79c 100644 --- a/lib/vquic/quiche.c +++ b/lib/vquic/quiche.c @@ -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;