diff options
Diffstat (limited to 'Utilities/cmcurl/lib/transfer.c')
-rw-r--r-- | Utilities/cmcurl/lib/transfer.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c index d0602b8..6886764 100644 --- a/Utilities/cmcurl/lib/transfer.c +++ b/Utilities/cmcurl/lib/transfer.c @@ -40,9 +40,7 @@ #ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> #endif -#ifdef HAVE_SIGNAL_H #include <signal.h> -#endif #ifdef HAVE_SYS_PARAM_H #include <sys/param.h> @@ -671,7 +669,9 @@ static CURLcode readwrite_data(struct Curl_easy *data, k->bytecount += nread; max_recv -= nread; - Curl_pgrsSetDownloadCounter(data, k->bytecount); + result = Curl_pgrsSetDownloadCounter(data, k->bytecount); + if(result) + goto out; if(!k->chunk && (nread || k->badheader || is_empty_data)) { /* If this is chunky transfer, it was already written */ @@ -700,19 +700,15 @@ static CURLcode readwrite_data(struct Curl_easy *data, in http_chunks.c. Make sure that ALL_CONTENT_ENCODINGS contains all the encodings handled here. */ - if(data->set.http_ce_skip || !k->writer_stack) { - if(!k->ignorebody && nread) { + if(!k->ignorebody && nread) { #ifndef CURL_DISABLE_POP3 - if(conn->handler->protocol & PROTO_FAMILY_POP3) - result = Curl_pop3_write(data, k->str, nread); - else + if(conn->handler->protocol & PROTO_FAMILY_POP3) + result = Curl_pop3_write(data, k->str, nread); + else #endif /* CURL_DISABLE_POP3 */ - result = Curl_client_write(data, CLIENTWRITE_BODY, k->str, - nread); - } + result = Curl_client_write(data, CLIENTWRITE_BODY, k->str, + nread); } - else if(!k->ignorebody && nread) - result = Curl_unencode_write(data, k->writer_stack, k->str, nread); } k->badheader = HEADER_NORMAL; /* taken care of now */ @@ -1050,6 +1046,19 @@ static CURLcode readwrite_upload(struct Curl_easy *data, return CURLE_OK; } +static int select_bits_paused(struct Curl_easy *data, int select_bits) +{ + /* See issue #11982: we really need to be careful not to progress + * a transfer direction when that direction is paused. Not all parts + * of our state machine are handling PAUSED transfers correctly. So, we + * do not want to go there. + * NOTE: we are only interested in PAUSE, not HOLD. */ + return (((select_bits & CURL_CSELECT_IN) && + (data->req.keepon & KEEP_RECV_PAUSE)) || + ((select_bits & CURL_CSELECT_OUT) && + (data->req.keepon & KEEP_SEND_PAUSE))); +} + /* * Curl_readwrite() is the low-level function to be called when data is to * be read and written to/from the connection. @@ -1068,12 +1077,20 @@ CURLcode Curl_readwrite(struct connectdata *conn, int didwhat = 0; int select_bits; - if(data->state.dselect_bits) { + if(select_bits_paused(data, data->state.dselect_bits)) { + /* leave the bits unchanged, so they'll tell us what to do when + * this transfer gets unpaused. */ + DEBUGF(infof(data, "readwrite, dselect_bits, early return on PAUSED")); + result = CURLE_OK; + goto out; + } select_bits = data->state.dselect_bits; data->state.dselect_bits = 0; } else if(conn->cselect_bits) { + /* CAVEAT: adding `select_bits_paused()` check here makes test640 hang + * (among others). Which hints at strange state handling in FTP land... */ select_bits = conn->cselect_bits; conn->cselect_bits = 0; } |