(void) size; /* Always 1. */
+ /* TODO: this loop is broken. If `nitems` is <= 4, some encoders will
+ * return STOP_FILLING without adding any data and this loops infinitely. */
do {
hasread = FALSE;
ret = readback_part(part, buffer, nitems, &hasread);
struct cr_mime_ctx *ctx = reader->ctx;
size_t nread;
+
/* Once we have errored, we will return the same error forever */
if(ctx->errored) {
+ CURL_TRC_READ(data, "cr_mime_read(len=%zu) is errored -> %d, eos=0",
+ blen, ctx->error_result);
*pnread = 0;
*peos = FALSE;
return ctx->error_result;
}
if(ctx->seen_eos) {
+ CURL_TRC_READ(data, "cr_mime_read(len=%zu) seen eos -> 0, eos=1", blen);
*pnread = 0;
*peos = TRUE;
return CURLE_OK;
else if(remain < (curl_off_t)blen)
blen = (size_t)remain;
}
- nread = 0;
- if(blen) {
- nread = Curl_mime_read(buf, 1, blen, ctx->part);
+
+ if(blen <= 4) {
+ /* TODO: Curl_mime_read() may go into an infinite loop when reading
+ * such small lengths. Returning 0 bytes read is a fix that only works
+ * as request upload buffers will get flushed eventually and larger
+ * reads will happen again. */
+ CURL_TRC_READ(data, "cr_mime_read(len=%zu), too small, return", blen);
+ *pnread = 0;
+ *peos = FALSE;
+ goto out;
}
+ nread = Curl_mime_read(buf, 1, blen, ctx->part);
+ CURL_TRC_READ(data, "cr_mime_read(len=%zu), mime_read() -> %zd",
+ blen, nread);
+
switch(nread) {
case 0:
if((ctx->total_len >= 0) && (ctx->read_len < ctx->total_len)) {
case CURL_READFUNC_PAUSE:
/* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
+ CURL_TRC_READ(data, "cr_mime_read(len=%zu), paused by callback", blen);
data->req.keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
*pnread = 0;
*peos = FALSE;
break; /* nothing was read */
+ case STOP_FILLING:
+ case READ_ERROR:
+ failf(data, "read error getting mime data");
+ *pnread = 0;
+ *peos = FALSE;
+ ctx->errored = TRUE;
+ ctx->error_result = CURLE_READ_ERROR;
+ return CURLE_READ_ERROR;
+
default:
if(nread > blen) {
/* the read function returned a too large value */
*peos = ctx->seen_eos;
break;
}
- DEBUGF(infof(data, "cr_mime_read(len=%zu, total=%"CURL_FORMAT_CURL_OFF_T
- ", read=%"CURL_FORMAT_CURL_OFF_T") -> %d, %zu, %d",
- blen, ctx->total_len, ctx->read_len, CURLE_OK, *pnread, *peos));
+
+out:
+ CURL_TRC_READ(data, "cr_mime_read(len=%zu, total=%" CURL_FORMAT_CURL_OFF_T
+ ", read=%"CURL_FORMAT_CURL_OFF_T") -> %d, %zu, %d",
+ blen, ctx->total_len, ctx->read_len, CURLE_OK, *pnread, *peos);
return CURLE_OK;
}