summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcurl/lib/transfer.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/transfer.c')
-rw-r--r--Utilities/cmcurl/lib/transfer.c103
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)