← Commit list

fa9151b41a

Stefan Eissing
Stefan Eissing
2025-08-29
FAILED Duration: 157s

Subject

cw-out: handle error codes for 0len writes

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/cw-out.c+55 -35
@@ -195,6 +195,50 @@ static void cw_get_writefunc(struct Curl_easy *data, cw_out_type otype,
}
}
+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,
@@ -206,6 +250,7 @@ static CURLcode cw_out_ptr_flush(struct cw_out_ctx *ctx,
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)
@@ -221,44 +266,18 @@ static CURLcode cw_out_ptr_flush(struct cw_out_ctx *ctx,
*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;
@@ -274,14 +293,14 @@ static CURLcode cw_out_buf_flush(struct cw_out_ctx *ctx,
{
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) {
@@ -394,8 +413,9 @@ static CURLcode cw_out_do_write(struct cw_out_ctx *ctx,
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,