summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/cw-out.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/cw-out.c')
-rw-r--r--libs/libcurl/src/cw-out.c106
1 files changed, 64 insertions, 42 deletions
diff --git a/libs/libcurl/src/cw-out.c b/libs/libcurl/src/cw-out.c
index 5e8895fae4..6f897ec376 100644
--- a/libs/libcurl/src/cw-out.c
+++ b/libs/libcurl/src/cw-out.c
@@ -32,6 +32,7 @@
#include "multiif.h"
#include "sendf.h"
#include "cw-out.h"
+#include "cw-pause.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
@@ -86,7 +87,7 @@ static struct cw_out_buf *cw_out_buf_create(cw_out_type otype)
struct cw_out_buf *cwbuf = calloc(1, sizeof(*cwbuf));
if(cwbuf) {
cwbuf->type = otype;
- Curl_dyn_init(&cwbuf->b, DYN_PAUSE_BUFFER);
+ curlx_dyn_init(&cwbuf->b, DYN_PAUSE_BUFFER);
}
return cwbuf;
}
@@ -94,7 +95,7 @@ static struct cw_out_buf *cw_out_buf_create(cw_out_type otype)
static void cw_out_buf_free(struct cw_out_buf *cwbuf)
{
if(cwbuf) {
- Curl_dyn_free(&cwbuf->b);
+ curlx_dyn_free(&cwbuf->b);
free(cwbuf);
}
}
@@ -113,7 +114,7 @@ static void cw_out_close(struct Curl_easy *data, struct Curl_cwriter *writer);
static CURLcode cw_out_init(struct Curl_easy *data,
struct Curl_cwriter *writer);
-struct Curl_cwtype Curl_cwt_out = {
+const struct Curl_cwtype Curl_cwt_out = {
"cw-out",
NULL,
cw_out_init,
@@ -145,7 +146,7 @@ static size_t cw_out_bufs_len(struct cw_out_ctx *ctx)
struct cw_out_buf *cwbuf = ctx->buf;
size_t len = 0;
while(cwbuf) {
- len += Curl_dyn_len(&cwbuf->b);
+ len += curlx_dyn_len(&cwbuf->b);
cwbuf = cwbuf->next;
}
return len;
@@ -198,7 +199,7 @@ static CURLcode cw_out_ptr_flush(struct cw_out_ctx *ctx,
const char *buf, size_t blen,
size_t *pconsumed)
{
- curl_write_callback wcb;
+ curl_write_callback wcb = NULL;
void *wcb_data;
size_t max_write, min_write;
size_t wlen, nwritten;
@@ -220,9 +221,9 @@ static CURLcode cw_out_ptr_flush(struct cw_out_ctx *ctx,
break;
wlen = max_write ? CURLMIN(blen, max_write) : blen;
Curl_set_in_callback(data, TRUE);
- nwritten = wcb((char *)buf, 1, wlen, wcb_data);
+ nwritten = wcb((char *)CURL_UNCONST(buf), 1, wlen, wcb_data);
Curl_set_in_callback(data, FALSE);
- CURL_TRC_WRITE(data, "cw_out, wrote %zu %s bytes -> %zu",
+ CURL_TRC_WRITE(data, "[OUT] wrote %zu %s bytes -> %zu",
wlen, (otype == CW_OUT_BODY) ? "body" : "header",
nwritten);
if(CURL_WRITEFUNC_PAUSE == nwritten) {
@@ -236,7 +237,7 @@ static CURLcode cw_out_ptr_flush(struct cw_out_ctx *ctx,
/* mark the connection as RECV paused */
data->req.keepon |= KEEP_RECV_PAUSE;
ctx->paused = TRUE;
- CURL_TRC_WRITE(data, "cw_out, PAUSE requested by client");
+ CURL_TRC_WRITE(data, "[OUT] PAUSE requested by client");
break;
}
else if(CURL_WRITEFUNC_ERROR == nwritten) {
@@ -262,23 +263,24 @@ static CURLcode cw_out_buf_flush(struct cw_out_ctx *ctx,
{
CURLcode result = CURLE_OK;
- if(Curl_dyn_len(&cwbuf->b)) {
+ if(curlx_dyn_len(&cwbuf->b)) {
size_t consumed;
result = cw_out_ptr_flush(ctx, data, cwbuf->type, flush_all,
- Curl_dyn_ptr(&cwbuf->b),
- Curl_dyn_len(&cwbuf->b),
+ curlx_dyn_ptr(&cwbuf->b),
+ curlx_dyn_len(&cwbuf->b),
&consumed);
if(result)
return result;
if(consumed) {
- if(consumed == Curl_dyn_len(&cwbuf->b)) {
- Curl_dyn_free(&cwbuf->b);
+ if(consumed == curlx_dyn_len(&cwbuf->b)) {
+ curlx_dyn_free(&cwbuf->b);
}
else {
- DEBUGASSERT(consumed < Curl_dyn_len(&cwbuf->b));
- result = Curl_dyn_tail(&cwbuf->b, Curl_dyn_len(&cwbuf->b) - consumed);
+ DEBUGASSERT(consumed < curlx_dyn_len(&cwbuf->b));
+ result = curlx_dyn_tail(&cwbuf->b,
+ curlx_dyn_len(&cwbuf->b) - consumed);
if(result)
return result;
}
@@ -318,7 +320,7 @@ static CURLcode cw_out_flush_chain(struct cw_out_ctx *ctx,
result = cw_out_buf_flush(ctx, data, cwbuf, flush_all);
if(result)
return result;
- if(!Curl_dyn_len(&cwbuf->b)) {
+ if(!curlx_dyn_len(&cwbuf->b)) {
cw_out_buf_free(cwbuf);
*pcwbuf = NULL;
}
@@ -326,11 +328,16 @@ static CURLcode cw_out_flush_chain(struct cw_out_ctx *ctx,
}
static CURLcode cw_out_append(struct cw_out_ctx *ctx,
+ struct Curl_easy *data,
cw_out_type otype,
const char *buf, size_t blen)
{
- if(cw_out_bufs_len(ctx) + blen > DYN_PAUSE_BUFFER)
+ CURL_TRC_WRITE(data, "[OUT] paused, buffering %zu more bytes (%zu/%d)",
+ blen, cw_out_bufs_len(ctx), DYN_PAUSE_BUFFER);
+ if(cw_out_bufs_len(ctx) + blen > DYN_PAUSE_BUFFER) {
+ failf(data, "pause buffer not large enough -> CURLE_TOO_LARGE");
return CURLE_TOO_LARGE;
+ }
/* if we do not have a buffer, or it is of another type, make a new one.
* And for CW_OUT_HDS always make a new one, so we "replay" headers
@@ -343,7 +350,7 @@ static CURLcode cw_out_append(struct cw_out_ctx *ctx,
ctx->buf = cwbuf;
}
DEBUGASSERT(ctx->buf && (ctx->buf->type == otype));
- return Curl_dyn_addn(&ctx->buf->b, buf, blen);
+ return curlx_dyn_addn(&ctx->buf->b, buf, blen);
}
static CURLcode cw_out_do_write(struct cw_out_ctx *ctx,
@@ -364,7 +371,7 @@ static CURLcode cw_out_do_write(struct cw_out_ctx *ctx,
if(ctx->buf) {
/* still have buffered data, append and flush */
- result = cw_out_append(ctx, otype, buf, blen);
+ result = cw_out_append(ctx, data, otype, buf, blen);
if(result)
return result;
result = cw_out_flush_chain(ctx, data, &ctx->buf, flush_all);
@@ -380,7 +387,8 @@ static CURLcode cw_out_do_write(struct cw_out_ctx *ctx,
return result;
if(consumed < blen) {
/* did not write all, append the rest */
- result = cw_out_append(ctx, otype, buf + consumed, blen - consumed);
+ result = cw_out_append(ctx, data, otype,
+ buf + consumed, blen - consumed);
if(result)
goto out;
}
@@ -430,44 +438,58 @@ bool Curl_cw_out_is_paused(struct Curl_easy *data)
return FALSE;
ctx = (struct cw_out_ctx *)cw_out;
- CURL_TRC_WRITE(data, "cw-out is%spaused", ctx->paused ? "" : " not");
return ctx->paused;
}
static CURLcode cw_out_flush(struct Curl_easy *data,
- bool unpause, bool flush_all)
+ struct Curl_cwriter *cw_out,
+ bool flush_all)
{
- struct Curl_cwriter *cw_out;
+ struct cw_out_ctx *ctx = (struct cw_out_ctx *)cw_out;
CURLcode result = CURLE_OK;
- cw_out = Curl_cwriter_get_by_type(data, &Curl_cwt_out);
- if(cw_out) {
- struct cw_out_ctx *ctx = (struct cw_out_ctx *)cw_out;
- if(ctx->errored)
- return CURLE_WRITE_ERROR;
- if(unpause && ctx->paused)
- ctx->paused = FALSE;
- if(ctx->paused)
- return CURLE_OK; /* not doing it */
+ if(ctx->errored)
+ return CURLE_WRITE_ERROR;
+ if(ctx->paused)
+ return CURLE_OK; /* not doing it */
- result = cw_out_flush_chain(ctx, data, &ctx->buf, flush_all);
- if(result) {
- ctx->errored = TRUE;
- cw_out_bufs_free(ctx);
- return result;
- }
+ result = cw_out_flush_chain(ctx, data, &ctx->buf, flush_all);
+ if(result) {
+ ctx->errored = TRUE;
+ cw_out_bufs_free(ctx);
+ return result;
}
return result;
}
CURLcode Curl_cw_out_unpause(struct Curl_easy *data)
{
- CURL_TRC_WRITE(data, "cw-out unpause");
- return cw_out_flush(data, TRUE, FALSE);
+ struct Curl_cwriter *cw_out;
+ CURLcode result = CURLE_OK;
+
+ cw_out = Curl_cwriter_get_by_type(data, &Curl_cwt_out);
+ if(cw_out) {
+ struct cw_out_ctx *ctx = (struct cw_out_ctx *)cw_out;
+ CURL_TRC_WRITE(data, "[OUT] unpause");
+ ctx->paused = FALSE;
+ result = Curl_cw_pause_flush(data);
+ if(!result)
+ result = cw_out_flush(data, cw_out, FALSE);
+ }
+ return result;
}
CURLcode Curl_cw_out_done(struct Curl_easy *data)
{
- CURL_TRC_WRITE(data, "cw-out done");
- return cw_out_flush(data, FALSE, TRUE);
+ struct Curl_cwriter *cw_out;
+ CURLcode result = CURLE_OK;
+
+ cw_out = Curl_cwriter_get_by_type(data, &Curl_cwt_out);
+ if(cw_out) {
+ CURL_TRC_WRITE(data, "[OUT] done");
+ result = Curl_cw_pause_flush(data);
+ if(!result)
+ result = cw_out_flush(data, cw_out, TRUE);
+ }
+ return result;
}