summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2021-08-13 17:29:33 +0200
committerDaniel Stenberg <daniel@haxx.se>2021-08-13 23:18:21 +0200
commit32f6812b5ac3649e21e28d46bfdbf96af2786347 (patch)
tree8820c051398e0927c1eef8700f33d19eea6ab69c
parentf67883e55a27f9ec4825a283c94c008bba644f06 (diff)
downloadcurl-32f6812b5ac3649e21e28d46bfdbf96af2786347.tar.gz
c-hyper: initial step for 100-continue support
Enabled test 154 Closes #7568
-rw-r--r--lib/c-hyper.c59
-rw-r--r--lib/c-hyper.h1
-rw-r--r--tests/data/DISABLED1
3 files changed, 57 insertions, 4 deletions
diff --git a/lib/c-hyper.c b/lib/c-hyper.c
index 9ad76991c..57ac9af4b 100644
--- a/lib/c-hyper.c
+++ b/lib/c-hyper.c
@@ -176,7 +176,7 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk)
size_t len = hyper_buf_len(chunk);
struct Curl_easy *data = (struct Curl_easy *)userdata;
struct SingleRequest *k = &data->req;
- CURLcode result;
+ CURLcode result = CURLE_OK;
if(0 == k->bodywrites++) {
bool done = FALSE;
@@ -192,6 +192,20 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk)
Curl_safefree(data->req.newurl);
}
#endif
+ if(data->state.expect100header) {
+ Curl_expire_done(data, EXPIRE_100_TIMEOUT);
+ if(data->req.httpcode < 400) {
+ k->exp100 = EXP100_SEND_DATA;
+ if(data->hyp.exp100_waker) {
+ hyper_waker_wake(data->hyp.exp100_waker);
+ data->hyp.exp100_waker = NULL;
+ }
+ }
+ else { /* >= 4xx */
+ k->exp100 = EXP100_FAILED;
+ done = TRUE;
+ }
+ }
if(data->state.hconnect &&
(data->req.httpcode/100 != 2)) {
done = TRUE;
@@ -306,8 +320,25 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
const uint8_t *reasonp;
size_t reason_len;
CURLcode result = CURLE_OK;
+ struct SingleRequest *k = &data->req;
(void)conn;
+ if(k->exp100 > EXP100_SEND_DATA) {
+ struct curltime now = Curl_now();
+ timediff_t ms = Curl_timediff(now, k->start100);
+ if(ms >= data->set.expect_100_timeout) {
+ /* we've waited long enough, continue anyway */
+ k->exp100 = EXP100_SEND_DATA;
+ k->keepon |= KEEP_SEND;
+ Curl_expire_done(data, EXPIRE_100_TIMEOUT);
+ infof(data, "Done waiting for 100-continue");
+ if(data->hyp.exp100_waker) {
+ hyper_waker_wake(data->hyp.exp100_waker);
+ data->hyp.exp100_waker = NULL;
+ }
+ }
+ }
+
if(select_res & CURL_CSELECT_IN) {
if(h->read_waker)
hyper_waker_wake(h->read_waker);
@@ -591,9 +622,21 @@ static int uploadstreamed(void *userdata, hyper_context *ctx,
{
size_t fillcount;
struct Curl_easy *data = (struct Curl_easy *)userdata;
- CURLcode result =
- Curl_fillreadbuffer(data, data->set.upload_buffer_size, &fillcount);
+ CURLcode result;
(void)ctx;
+
+ if(data->req.exp100 > EXP100_SEND_DATA) {
+ if(data->req.exp100 == EXP100_FAILED)
+ return HYPER_POLL_ERROR;
+
+ /* still waiting confirmation */
+ if(data->hyp.exp100_waker)
+ hyper_waker_free(data->hyp.exp100_waker);
+ data->hyp.exp100_waker = hyper_context_waker(ctx);
+ return HYPER_POLL_PENDING;
+ }
+
+ result = Curl_fillreadbuffer(data, data->set.upload_buffer_size, &fillcount);
if(result) {
data->state.hresult = result;
return HYPER_POLL_ERROR;
@@ -628,6 +671,7 @@ static CURLcode bodysend(struct Curl_easy *data,
hyper_request *hyperreq,
Curl_HttpReq httpreq)
{
+ struct HTTP *http = data->req.p.http;
CURLcode result = CURLE_OK;
struct dynbuf req;
if((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD))
@@ -660,6 +704,7 @@ static CURLcode bodysend(struct Curl_easy *data,
result = CURLE_OUT_OF_MEMORY;
}
}
+ http->sending = HTTPSEND_BODY;
return result;
}
@@ -938,6 +983,10 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
}
conn->datastream = Curl_hyper_stream;
+ if(data->state.expect100header)
+ /* Timeout count starts now since with Hyper we don't know exactly when
+ the full request has been sent. */
+ data->req.start100 = Curl_now();
/* clear userpwd and proxyuserpwd to avoid re-using old credentials
* from re-used connections */
@@ -973,6 +1022,10 @@ void Curl_hyper_done(struct Curl_easy *data)
hyper_waker_free(h->write_waker);
h->write_waker = NULL;
}
+ if(h->exp100_waker) {
+ hyper_waker_free(h->exp100_waker);
+ h->exp100_waker = NULL;
+ }
}
#endif /* !defined(CURL_DISABLE_HTTP) && defined(USE_HYPER) */
diff --git a/lib/c-hyper.h b/lib/c-hyper.h
index d60ed78d1..d63defeff 100644
--- a/lib/c-hyper.h
+++ b/lib/c-hyper.h
@@ -33,6 +33,7 @@ struct hyptransfer {
hyper_waker *read_waker;
const hyper_executor *exec;
hyper_task *endtask;
+ hyper_waker *exp100_waker;
};
size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
diff --git a/tests/data/DISABLED b/tests/data/DISABLED
index e04eaa8a6..69e03ea8f 100644
--- a/tests/data/DISABLED
+++ b/tests/data/DISABLED
@@ -36,7 +36,6 @@
# hyper support remains EXPERIMENTAL as long as there's a test number
# listed below
%if hyper
-154
155
158
206