diff options
Diffstat (limited to 'Utilities/cmcurl/lib/transfer.c')
-rw-r--r-- | Utilities/cmcurl/lib/transfer.c | 103 |
1 files changed, 35 insertions, 68 deletions
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c index f5987fe..6245ee4 100644 --- a/Utilities/cmcurl/lib/transfer.c +++ b/Utilities/cmcurl/lib/transfer.c @@ -21,10 +21,7 @@ ***************************************************************************/ #include "curl_setup.h" - #include "strtoofft.h" -#include "strequal.h" -#include "rawstr.h" #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> @@ -75,6 +72,7 @@ #include "multiif.h" #include "connect.h" #include "non-ascii.h" +#include "http2.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -384,11 +382,15 @@ bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc) * Go ahead and do a read if we have a readable socket or if * the stream was rewound (in which case we have data in a * buffer) + * + * return '*comeback' TRUE if we didn't properly drain the socket so this + * function should get called again without select() or similar in between! */ static CURLcode readwrite_data(struct Curl_easy *data, struct connectdata *conn, struct SingleRequest *k, - int *didwhat, bool *done) + int *didwhat, bool *done, + bool *comeback) { CURLcode result = CURLE_OK; ssize_t nread; /* number of bytes read */ @@ -398,6 +400,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, int maxloops = 100; *done = FALSE; + *comeback = FALSE; /* This is where we loop until we have read everything there is to read or we get a CURLE_AGAIN */ @@ -529,6 +532,13 @@ static CURLcode readwrite_data(struct Curl_easy *data, is non-headers. */ if(k->str && !k->header && (nread > 0 || is_empty_data)) { + if(data->set.opt_no_body) { + /* data arrives although we want none, bail out */ + streamclose(conn, "ignoring body"); + *done = TRUE; + return CURLE_WEIRD_SERVER_REPLY; + } + #ifndef CURL_DISABLE_HTTP if(0 == k->bodywrites && !is_empty_data) { /* These checks are only made the first time we are about to @@ -804,6 +814,12 @@ static CURLcode readwrite_data(struct Curl_easy *data, } while(data_pending(conn) && maxloops--); + if(maxloops <= 0) { + /* we mark it as read-again-please */ + conn->cselect_bits = CURL_CSELECT_IN; + *comeback = TRUE; + } + if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) && conn->bits.close) { /* When we've read the entire thing and the close bit is set, the server @@ -821,6 +837,8 @@ static CURLcode done_sending(struct connectdata *conn, { k->keepon &= ~KEEP_SEND; /* we're done writing */ + Curl_http2_done_sending(conn); + if(conn->bits.rewindaftersend) { CURLcode result = Curl_readrewind(conn); if(result) @@ -1029,10 +1047,14 @@ static CURLcode readwrite_upload(struct Curl_easy *data, /* * Curl_readwrite() is the low-level function to be called when data is to * be read and written to/from the connection. + * + * return '*comeback' TRUE if we didn't properly drain the socket so this + * function should get called again without select() or similar in between! */ CURLcode Curl_readwrite(struct connectdata *conn, struct Curl_easy *data, - bool *done) + bool *done, + bool *comeback) { struct SingleRequest *k = &data->req; CURLcode result; @@ -1064,7 +1086,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(!select_res) /* Call for select()/poll() only, if read/write/error status is not known. */ - select_res = Curl_socket_ready(fd_read, fd_write, 0); + select_res = Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, 0); if(select_res == CURL_CSELECT_ERR) { failf(data, "select/poll returned error"); @@ -1077,7 +1099,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, if((k->keepon & KEEP_RECV) && ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) { - result = readwrite_data(data, conn, k, &didwhat, done); + result = readwrite_data(data, conn, k, &didwhat, done, comeback); if(result || *done) return result; } @@ -1249,60 +1271,6 @@ int Curl_single_getsock(const struct connectdata *conn, return bitmap; } -/* - * Determine optimum sleep time based on configured rate, current rate, - * and packet size. - * Returns value in milliseconds. - * - * The basic idea is to adjust the desired rate up/down in this method - * based on whether we are running too slow or too fast. Then, calculate - * how many milliseconds to wait for the next packet to achieve this new - * rate. - */ -long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps, - int pkt_size) -{ - curl_off_t min_sleep = 0; - curl_off_t rv = 0; - - if(rate_bps == 0) - return 0; - - /* If running faster than about .1% of the desired speed, slow - * us down a bit. Use shift instead of division as the 0.1% - * cutoff is arbitrary anyway. - */ - if(cur_rate_bps > (rate_bps + (rate_bps >> 10))) { - /* running too fast, decrease target rate by 1/64th of rate */ - rate_bps -= rate_bps >> 6; - min_sleep = 1; - } - else if(cur_rate_bps < (rate_bps - (rate_bps >> 10))) { - /* running too slow, increase target rate by 1/64th of rate */ - rate_bps += rate_bps >> 6; - } - - /* Determine number of milliseconds to wait until we do - * the next packet at the adjusted rate. We should wait - * longer when using larger packets, for instance. - */ - rv = ((curl_off_t)(pkt_size * 1000) / rate_bps); - - /* Catch rounding errors and always slow down at least 1ms if - * we are running too fast. - */ - if(rv < min_sleep) - rv = min_sleep; - - /* Bound value to fit in 'long' on 32-bit platform. That's - * plenty long enough anyway! - */ - if(rv > 0x7fffffff) - rv = 0x7fffffff; - - return (long)rv; -} - /* Curl_init_CONNECT() gets called each time the handle switches to CONNECT which means this gets called once for each subsequent redirect etc */ void Curl_init_CONNECT(struct Curl_easy *data) @@ -1875,13 +1843,12 @@ CURLcode Curl_retry_request(struct connectdata *conn, return CURLE_OK; if((data->req.bytecount + data->req.headerbytecount == 0) && - conn->bits.reuse && - !data->set.opt_no_body && - (data->set.rtspreq != RTSPREQ_RECEIVE)) { - /* We got no data, we attempted to re-use a connection and yet we want a - "body". This might happen if the connection was left alive when we were - done using it before, but that was closed when we wanted to read from - it again. Bad luck. Retry the same request on a fresh connect! */ + conn->bits.reuse && + (data->set.rtspreq != RTSPREQ_RECEIVE)) { + /* We didn't get a single byte when we attempted to re-use a + connection. This might happen if the connection was left alive when we + were done using it before, but that was closed when we wanted to use it + again. Bad luck. Retry the same request on a fresh connect! */ infof(conn->data, "Connection died, retrying a fresh connect\n"); *url = strdup(conn->data->change.url); if(!*url) |