}
}
+static CURLcode cw_out_cb_write(struct cw_out_ctx *ctx,
+ struct Curl_easy *data,
+ curl_write_callback wcb,
+ void *wcb_data,
+ cw_out_type otype,
+ const char *buf, size_t blen,
+ size_t *pnwritten)
+{
+ size_t nwritten;
+ CURLcode result;
+
+ *pnwritten = 0;
+ Curl_set_in_callback(data, TRUE);
+ nwritten = wcb((char *)CURL_UNCONST(buf), 1, blen, wcb_data);
+ Curl_set_in_callback(data, FALSE);
+ CURL_TRC_WRITE(data, "[OUT] wrote %zu %s bytes -> %zu",
+ blen, (otype == CW_OUT_HDS) ? "header" : "body",
+ nwritten);
+ if(CURL_WRITEFUNC_PAUSE == nwritten) {
+ if(data->conn && data->conn->handler->flags & PROTOPT_NONETWORK) {
+ /* Protocols that work without network cannot be paused. This is
+ actually only FILE:// just now, and it cannot pause since the
+ transfer is not done using the "normal" procedure. */
+ failf(data, "Write callback asked for PAUSE when not supported");
+ return CURLE_WRITE_ERROR;
+ }
+ ctx->paused = TRUE;
+ CURL_TRC_WRITE(data, "[OUT] PAUSE requested by client");
+ result = Curl_xfer_pause_recv(data, TRUE);
+ return result ? result : CURLE_AGAIN;
+ }
+ else if(CURL_WRITEFUNC_ERROR == nwritten) {
+ failf(data, "client returned ERROR on write of %zu bytes", blen);
+ return CURLE_WRITE_ERROR;
+ }
+ else if(nwritten != blen) {
+ failf(data, "Failure writing output to destination, "
+ "passed %zu returned %zd", blen, nwritten);
+ return CURLE_WRITE_ERROR;
+ }
+ *pnwritten = nwritten;
+ return CURLE_OK;
+}
+
static CURLcode cw_out_ptr_flush(struct cw_out_ctx *ctx,
struct Curl_easy *data,
cw_out_type otype,
void *wcb_data;
size_t max_write, min_write;
size_t wlen, nwritten;
+ CURLcode result;
/* If we errored once, we do not invoke the client callback again */
if(ctx->errored)
*pconsumed = 0;
if(otype == CW_OUT_BODY_0LEN) {
DEBUGASSERT(!blen);
- Curl_set_in_callback(data, TRUE);
- nwritten = wcb((char *)CURL_UNCONST(buf), 1, blen, wcb_data);
- Curl_set_in_callback(data, FALSE);
- CURL_TRC_WRITE(data, "[OUT] wrote %zu BODY bytes -> %zu",
- blen, nwritten);
+ return cw_out_cb_write(ctx, data, wcb, wcb_data, otype,
+ buf, blen, &nwritten);
}
else {
while(blen && !ctx->paused) {
if(!flush_all && blen < min_write)
break;
wlen = max_write ? CURLMIN(blen, max_write) : blen;
- Curl_set_in_callback(data, TRUE);
- nwritten = wcb((char *)CURL_UNCONST(buf), 1, wlen, wcb_data);
- Curl_set_in_callback(data, FALSE);
- CURL_TRC_WRITE(data, "[OUT] wrote %zu %s bytes -> %zu",
- wlen, (otype == CW_OUT_BODY) ? "body" : "header",
- nwritten);
- if(CURL_WRITEFUNC_PAUSE == nwritten) {
- if(data->conn && data->conn->handler->flags & PROTOPT_NONETWORK) {
- /* Protocols that work without network cannot be paused. This is
- actually only FILE:// just now, and it cannot pause since the
- transfer is not done using the "normal" procedure. */
- failf(data, "Write callback asked for PAUSE when not supported");
- return CURLE_WRITE_ERROR;
- }
- ctx->paused = TRUE;
- CURL_TRC_WRITE(data, "[OUT] PAUSE requested by client");
- return Curl_xfer_pause_recv(data, TRUE);
- }
- else if(CURL_WRITEFUNC_ERROR == nwritten) {
- failf(data, "client returned ERROR on write of %zu bytes", wlen);
- return CURLE_WRITE_ERROR;
- }
- else if(nwritten != wlen) {
- failf(data, "Failure writing output to destination, "
- "passed %zu returned %zd", wlen, nwritten);
- return CURLE_WRITE_ERROR;
- }
+ result = cw_out_cb_write(ctx, data, wcb, wcb_data, otype,
+ buf, wlen, &nwritten);
+ if(result)
+ return result;
*pconsumed += nwritten;
blen -= nwritten;
buf += nwritten;
{
CURLcode result = CURLE_OK;
- if(curlx_dyn_len(&cwbuf->b)) {
+ if(curlx_dyn_len(&cwbuf->b) || (cwbuf->type == CW_OUT_BODY_0LEN)) {
size_t consumed;
result = cw_out_ptr_flush(ctx, data, cwbuf->type, flush_all,
curlx_dyn_ptr(&cwbuf->b),
curlx_dyn_len(&cwbuf->b),
&consumed);
- if(result)
+ if(result && (result != CURLE_AGAIN))
return result;
if(consumed) {
size_t consumed;
result = cw_out_ptr_flush(ctx, data, otype, flush_all,
buf, blen, &consumed);
- if(result)
+ if(result && (result != CURLE_AGAIN))
return result;
+ result = CURLE_OK;
if(consumed < blen) {
/* did not write all, append the rest */
result = cw_out_append(ctx, data, otype,