Hi all, I ran into an issue where SSL based uploads were failing sometimes. I eventually traced this to a problem with EAGAIN near the start of the transfer, before any data had been sent. This only happened to me with SSL, although it may be possible under other conditions.
Since this was network related, it is not easy to reproduce, but I had several hundred devices affected before applying the patch, and no complaints since (it's been a few months now, so I thought it was time to send it on). I have confirmed that the tests still pass, but I haven't found a way of automating the original failure. The attached patch is against the current git (at the time of writing). Regards, David Warman.
From 88fccd50a4e3f972200c81347bd28685ed2cdae1 Mon Sep 17 00:00:00 2001 From: David Warman <dwar...@manglebit.org> Date: Fri, 11 Apr 2014 15:19:34 +0100 Subject: [PATCH] Avoid early upload termination when first write accepts no bytes. If this module doesn't know the final upload size, data->set.infilesize may be zero. Then, if a socket write returns EAGAIN before any blocks are sent, the number of bytes written is zero, k->writebytecount will be equal to the expected file size (also zero) and k->upload_done is set. That caused the upload to stop. The fix is to check that any partial block from the source has been completed, as well the file size being as expected. --- lib/transfer.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/transfer.c b/lib/transfer.c index 3fcc600..ded08a3 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -967,12 +967,6 @@ static CURLcode readwrite_upload(struct SessionHandle *data, k->writebytecount += bytes_written; - if(k->writebytecount == data->set.infilesize) { - /* we have sent all data we were supposed to */ - k->upload_done = TRUE; - infof(data, "We are completely uploaded and fine\n"); - } - if(data->req.upload_present != bytes_written) { /* we only wrote a part of the buffer (if anything), deal with it! */ @@ -987,11 +981,18 @@ static CURLcode readwrite_upload(struct SessionHandle *data, /* we've uploaded that buffer now */ data->req.upload_fromhere = k->uploadbuf; data->req.upload_present = 0; /* no more bytes left */ + } - if(k->upload_done) { - /* switch off writing, we're done! */ - k->keepon &= ~KEEP_SEND; /* we're done writing */ - } + if(data->req.upload_present == 0 && + k->writebytecount == data->set.infilesize) { + /* we have sent all data we were supposed to */ + k->upload_done = TRUE; + infof(data, "We are completely uploaded and fine\n"); + } + + if(k->upload_done) { + /* switch off writing, we're done! */ + k->keepon &= ~KEEP_SEND; /* we're done writing */ } Curl_pgrsSetUploadCounter(data, k->writebytecount); -- 1.7.10.4
------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-library Etiquette: http://curl.haxx.se/mail/etiquette.html