summaryrefslogtreecommitdiffstats
path: root/lib/c-hyper.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/c-hyper.c')
-rw-r--r--lib/c-hyper.c114
1 files changed, 69 insertions, 45 deletions
diff --git a/lib/c-hyper.c b/lib/c-hyper.c
index c29983c..61ca29a 100644
--- a/lib/c-hyper.c
+++ b/lib/c-hyper.c
@@ -61,6 +61,11 @@
#include "curl_memory.h"
#include "memdebug.h"
+typedef enum {
+ USERDATA_NOT_SET = 0, /* for tasks with no userdata set; must be zero */
+ USERDATA_RESP_BODY
+} userdata_t;
+
size_t Curl_hyper_recv(void *userp, hyper_context *ctx,
uint8_t *buf, size_t buflen)
{
@@ -182,8 +187,11 @@ static int hyper_each_header(void *userdata,
}
}
- data->info.header_size += (curl_off_t)len;
- data->req.headerbytecount += (curl_off_t)len;
+ result = Curl_bump_headersize(data, len, FALSE);
+ if(result) {
+ data->state.hresult = result;
+ return HYPER_ITER_BREAK;
+ }
return HYPER_ITER_CONTINUE;
}
@@ -313,9 +321,8 @@ static CURLcode status_line(struct Curl_easy *data,
if(result)
return result;
}
- data->info.header_size += (curl_off_t)len;
- data->req.headerbytecount += (curl_off_t)len;
- return CURLE_OK;
+ result = Curl_bump_headersize(data, len, FALSE);
+ return result;
}
/*
@@ -348,7 +355,6 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
struct hyptransfer *h = &data->hyp;
hyper_task *task;
hyper_task *foreach;
- hyper_error *hypererr = NULL;
const uint8_t *reasonp;
size_t reason_len;
CURLcode result = CURLE_OK;
@@ -391,19 +397,9 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
break;
}
t = hyper_task_type(task);
- switch(t) {
- case HYPER_TASK_ERROR:
- hypererr = hyper_task_value(task);
- break;
- case HYPER_TASK_RESPONSE:
- resp = hyper_task_value(task);
- break;
- default:
- break;
- }
- hyper_task_free(task);
-
if(t == HYPER_TASK_ERROR) {
+ hyper_error *hypererr = hyper_task_value(task);
+ hyper_task_free(task);
if(data->state.hresult) {
/* override Hyper's view, might not even be an error */
result = data->state.hresult;
@@ -414,36 +410,55 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
size_t errlen = hyper_error_print(hypererr, errbuf, sizeof(errbuf));
hyper_code code = hyper_error_code(hypererr);
failf(data, "Hyper: [%d] %.*s", (int)code, (int)errlen, errbuf);
- if(code == HYPERE_ABORTED_BY_CALLBACK)
+ switch(code) {
+ case HYPERE_ABORTED_BY_CALLBACK:
result = CURLE_OK;
- else if((code == HYPERE_UNEXPECTED_EOF) && !data->req.bytecount)
- result = CURLE_GOT_NOTHING;
- else if(code == HYPERE_INVALID_PEER_MESSAGE)
+ break;
+ case HYPERE_UNEXPECTED_EOF:
+ if(!data->req.bytecount)
+ result = CURLE_GOT_NOTHING;
+ else
+ result = CURLE_RECV_ERROR;
+ break;
+ case HYPERE_INVALID_PEER_MESSAGE:
+ /* bump headerbytecount to avoid the count remaining at zero and
+ appearing to not having read anything from the peer at all */
+ data->req.headerbytecount++;
result = CURLE_UNSUPPORTED_PROTOCOL; /* maybe */
- else
+ break;
+ default:
result = CURLE_RECV_ERROR;
+ break;
+ }
}
*done = TRUE;
hyper_error_free(hypererr);
break;
}
- else if(h->endtask == task) {
- /* end of transfer, forget the task handled, we might get a
- * new one with the same address in the future. */
- *done = TRUE;
- h->endtask = NULL;
- infof(data, "hyperstream is done");
- if(!k->bodywrites) {
- /* hyper doesn't always call the body write callback */
- bool stilldone;
- result = Curl_http_firstwrite(data, data->conn, &stilldone);
+ else if(t == HYPER_TASK_EMPTY) {
+ void *userdata = hyper_task_userdata(task);
+ hyper_task_free(task);
+ if((userdata_t)userdata == USERDATA_RESP_BODY) {
+ /* end of transfer */
+ *done = TRUE;
+ infof(data, "hyperstream is done");
+ if(!k->bodywrites) {
+ /* hyper doesn't always call the body write callback */
+ bool stilldone;
+ result = Curl_http_firstwrite(data, data->conn, &stilldone);
+ }
+ break;
+ }
+ else {
+ /* A background task for hyper; ignore */
+ continue;
}
- break;
- }
- else if(t != HYPER_TASK_RESPONSE) {
- continue;
}
- /* HYPER_TASK_RESPONSE */
+
+ DEBUGASSERT(HYPER_TASK_RESPONSE);
+
+ resp = hyper_task_value(task);
+ hyper_task_free(task);
*didwhat = KEEP_RECV;
if(!resp) {
@@ -523,13 +538,12 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
result = CURLE_OUT_OF_MEMORY;
break;
}
- DEBUGASSERT(hyper_task_type(foreach) == HYPER_TASK_EMPTY);
+ hyper_task_set_userdata(foreach, (void *)USERDATA_RESP_BODY);
if(HYPERE_OK != hyper_executor_push(h->exec, foreach)) {
failf(data, "Couldn't hyper_executor_push the body-foreach");
result = CURLE_OUT_OF_MEMORY;
break;
}
- h->endtask = foreach;
hyper_response_free(resp);
resp = NULL;
@@ -757,7 +771,7 @@ static int uploadstreamed(void *userdata, hyper_context *ctx,
/* increasing the writebytecount here is a little premature but we
don't know exactly when the body is sent */
data->req.writebytecount += fillcount;
- Curl_pgrsSetUploadCounter(data, fillcount);
+ Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
}
return HYPER_POLL_READY;
}
@@ -794,15 +808,16 @@ static CURLcode bodysend(struct Curl_easy *data,
hyper_body_set_data_func(body, uploadpostfields);
else {
result = Curl_get_upload_buffer(data);
- if(result)
+ if(result) {
+ hyper_body_free(body);
return result;
+ }
/* init the "upload from here" pointer */
data->req.upload_fromhere = data->state.ulbuf;
hyper_body_set_data_func(body, uploadstreamed);
}
if(HYPERE_OK != hyper_request_set_body(hyperreq, body)) {
/* fail */
- hyper_body_free(body);
result = CURLE_OUT_OF_MEMORY;
}
}
@@ -1194,14 +1209,17 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
result = CURLE_OUT_OF_MEMORY;
goto error;
}
+ req = NULL;
if(HYPERE_OK != hyper_executor_push(h->exec, sendtask)) {
failf(data, "Couldn't hyper_executor_push the send");
result = CURLE_OUT_OF_MEMORY;
goto error;
}
+ sendtask = NULL; /* ownership passed on */
hyper_clientconn_free(client);
+ client = NULL;
if((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) {
/* HTTP GET/HEAD download */
@@ -1214,8 +1232,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
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 */
+ /* clear userpwd and proxyuserpwd to avoid reusing old credentials
+ * from reused connections */
Curl_safefree(data->state.aptr.userpwd);
Curl_safefree(data->state.aptr.proxyuserpwd);
return CURLE_OK;
@@ -1230,6 +1248,12 @@ error:
if(handshake)
hyper_task_free(handshake);
+ if(client)
+ hyper_clientconn_free(client);
+
+ if(req)
+ hyper_request_free(req);
+
return result;
}