]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
c-hyper: initial step for 100-continue support
authorDaniel Stenberg <daniel@haxx.se>
Fri, 13 Aug 2021 15:29:33 +0000 (17:29 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 13 Aug 2021 21:18:21 +0000 (23:18 +0200)
Enabled test 154

Closes #7568

lib/c-hyper.c
lib/c-hyper.h
tests/data/DISABLED

index 9ad76991c2821277296db22f7a297ffa2ce12844..57ac9af4be10cf30fc09b8431062d895f60a884a 100644 (file)
@@ -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) */
index d60ed78d1df82c2641f4db611646a5d8881255f9..d63defeffec9ffe2aeb99c0a9ceb06984ade81c4 100644 (file)
@@ -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,
index e04eaa8a66b47866f552373e38077664943e631d..69e03ea8fcef370616c7584e722f021db41ac55a 100644 (file)
@@ -36,7 +36,6 @@
 # hyper support remains EXPERIMENTAL as long as there's a test number
 # listed below
 %if hyper
-154
 155
 158
 206