mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
Curl_perfom: removed
Curl_perfom is no longer used anywhere since the always-multi commit
c43127414d
, and some related functions were used only from within
Curl_perfom.
This commit is contained in:
parent
e243d80dea
commit
32e8467a66
372
lib/transfer.c
372
lib/transfer.c
@ -1245,156 +1245,6 @@ long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
|
||||
return (long)rv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Transfer()
|
||||
*
|
||||
* This function is what performs the actual transfer. It is capable of doing
|
||||
* both ways simultaneously. The transfer must already have been setup by a
|
||||
* call to Curl_setup_transfer().
|
||||
*
|
||||
* Note that headers are created in a preallocated buffer of a default size.
|
||||
* That buffer can be enlarged on demand, but it is never shrunken again.
|
||||
*
|
||||
*/
|
||||
|
||||
static CURLcode
|
||||
Transfer(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct SingleRequest *k = &data->req;
|
||||
bool done=FALSE;
|
||||
bool first=TRUE;
|
||||
long timeout_ms;
|
||||
int buffersize;
|
||||
long totmp;
|
||||
|
||||
if((conn->sockfd == CURL_SOCKET_BAD) &&
|
||||
(conn->writesockfd == CURL_SOCKET_BAD))
|
||||
/* nothing to read, nothing to write, we're already OK! */
|
||||
return CURLE_OK;
|
||||
|
||||
/* we want header and/or body, if neither then don't do this! */
|
||||
if(!k->getheader && data->set.opt_no_body)
|
||||
return CURLE_OK;
|
||||
|
||||
while(!done) {
|
||||
curl_socket_t fd_read = conn->sockfd;
|
||||
curl_socket_t fd_write = conn->writesockfd;
|
||||
int keepon = k->keepon;
|
||||
timeout_ms = 1000;
|
||||
|
||||
if(conn->waitfor) {
|
||||
/* if waitfor is set, get the RECV and SEND bits from that but keep the
|
||||
other bits */
|
||||
keepon &= ~ (KEEP_RECV|KEEP_SEND);
|
||||
keepon |= conn->waitfor & (KEEP_RECV|KEEP_SEND);
|
||||
}
|
||||
|
||||
/* limit-rate logic: if speed exceeds threshold, then do not include fd in
|
||||
select set. The current speed is recalculated in each Curl_readwrite()
|
||||
call */
|
||||
if((keepon & KEEP_SEND) &&
|
||||
(!data->set.max_send_speed ||
|
||||
(data->progress.ulspeed < data->set.max_send_speed) )) {
|
||||
k->keepon &= ~KEEP_SEND_HOLD;
|
||||
}
|
||||
else {
|
||||
if(data->set.upload && data->set.max_send_speed &&
|
||||
(data->progress.ulspeed > data->set.max_send_speed) ) {
|
||||
/* calculate upload rate-limitation timeout. */
|
||||
buffersize = (int)(data->set.buffer_size ?
|
||||
data->set.buffer_size : BUFSIZE);
|
||||
totmp = Curl_sleep_time(data->set.max_send_speed,
|
||||
data->progress.ulspeed, buffersize);
|
||||
if(totmp < timeout_ms)
|
||||
timeout_ms = totmp;
|
||||
}
|
||||
fd_write = CURL_SOCKET_BAD;
|
||||
if(keepon & KEEP_SEND)
|
||||
k->keepon |= KEEP_SEND_HOLD; /* hold it */
|
||||
}
|
||||
|
||||
if((keepon & KEEP_RECV) &&
|
||||
(!data->set.max_recv_speed ||
|
||||
(data->progress.dlspeed < data->set.max_recv_speed)) ) {
|
||||
k->keepon &= ~KEEP_RECV_HOLD;
|
||||
}
|
||||
else {
|
||||
if((!data->set.upload) && data->set.max_recv_speed &&
|
||||
(data->progress.dlspeed > data->set.max_recv_speed)) {
|
||||
/* Calculate download rate-limitation timeout. */
|
||||
buffersize = (int)(data->set.buffer_size ?
|
||||
data->set.buffer_size : BUFSIZE);
|
||||
totmp = Curl_sleep_time(data->set.max_recv_speed,
|
||||
data->progress.dlspeed, buffersize);
|
||||
if(totmp < timeout_ms)
|
||||
timeout_ms = totmp;
|
||||
}
|
||||
fd_read = CURL_SOCKET_BAD;
|
||||
if(keepon & KEEP_RECV)
|
||||
k->keepon |= KEEP_RECV_HOLD; /* hold it */
|
||||
}
|
||||
|
||||
/* pause logic. Don't check descriptors for paused connections */
|
||||
if(k->keepon & KEEP_RECV_PAUSE)
|
||||
fd_read = CURL_SOCKET_BAD;
|
||||
if(k->keepon & KEEP_SEND_PAUSE)
|
||||
fd_write = CURL_SOCKET_BAD;
|
||||
|
||||
/* The *_HOLD and *_PAUSE logic is necessary since even though there might
|
||||
be no traffic during the select interval, we still call
|
||||
Curl_readwrite() for the timeout case and if we limit transfer speed we
|
||||
must make sure that this function doesn't transfer anything while in
|
||||
HOLD status.
|
||||
|
||||
The no timeout for the first round is for the protocols for which data
|
||||
has already been slurped off the socket and thus waiting for action
|
||||
won't work since it'll wait even though there is already data present
|
||||
to work with. */
|
||||
if(first &&
|
||||
((fd_read != CURL_SOCKET_BAD) || (fd_write != CURL_SOCKET_BAD)))
|
||||
/* if this is the first lap and one of the file descriptors is fine
|
||||
to work with, skip the timeout */
|
||||
timeout_ms = 0;
|
||||
else {
|
||||
totmp = Curl_timeleft(data, &k->now, FALSE);
|
||||
if(totmp < 0)
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
else if(!totmp)
|
||||
totmp = 1000;
|
||||
|
||||
if(totmp < timeout_ms)
|
||||
timeout_ms = totmp;
|
||||
}
|
||||
|
||||
switch (Curl_socket_ready(fd_read, fd_write, timeout_ms)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
#ifdef EINTR
|
||||
/* The EINTR is not serious, and it seems you might get this more
|
||||
often when using the lib in a multi-threaded environment! */
|
||||
if(SOCKERRNO == EINTR)
|
||||
continue;
|
||||
#endif
|
||||
return CURLE_RECV_ERROR; /* indicate a network problem */
|
||||
case 0: /* timeout */
|
||||
default: /* readable descriptors */
|
||||
|
||||
result = Curl_readwrite(conn, &done);
|
||||
/* "done" signals to us if the transfer(s) are ready */
|
||||
break;
|
||||
}
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
first = FALSE; /* not the first lap anymore */
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Curl_pretransfer() is called immediately before a transfer starts.
|
||||
*/
|
||||
@ -1925,38 +1775,6 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
||||
#endif /* CURL_DISABLE_HTTP */
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
connect_host(struct SessionHandle *data,
|
||||
struct connectdata **conn)
|
||||
{
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
bool async;
|
||||
bool protocol_done=TRUE; /* will be TRUE always since this is only used
|
||||
within the easy interface */
|
||||
Curl_pgrsTime(data, TIMER_STARTSINGLE);
|
||||
res = Curl_connect(data, conn, &async, &protocol_done);
|
||||
|
||||
if((CURLE_OK == res) && async) {
|
||||
/* Now, if async is TRUE here, we need to wait for the name
|
||||
to resolve */
|
||||
res = Curl_resolver_wait_resolv(*conn, NULL);
|
||||
if(CURLE_OK == res) {
|
||||
/* Resolved, continue with the connection */
|
||||
res = Curl_async_resolved(*conn, &protocol_done);
|
||||
if(res)
|
||||
*conn = NULL;
|
||||
}
|
||||
else {
|
||||
/* if we can't resolve, we kill this "connection" now */
|
||||
(void)Curl_disconnect(*conn, /* dead_connection */ FALSE);
|
||||
*conn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
CURLcode
|
||||
Curl_reconnect_request(struct connectdata **connp)
|
||||
{
|
||||
@ -2060,196 +1878,6 @@ CURLcode Curl_retry_request(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode Curl_do_perform(struct SessionHandle *data)
|
||||
{
|
||||
CURLcode res;
|
||||
CURLcode res2;
|
||||
struct connectdata *conn=NULL;
|
||||
char *newurl = NULL; /* possibly a new URL to follow to! */
|
||||
followtype follow = FOLLOW_NONE;
|
||||
|
||||
res = Curl_pretransfer(data);
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
/*
|
||||
* It is important that there is NO 'return' from this function at any other
|
||||
* place than falling down to the end of the function! This is because we
|
||||
* have cleanup stuff that must be done before we get back, and that is only
|
||||
* performed after this do-while loop.
|
||||
*/
|
||||
|
||||
for(;;) {
|
||||
res = connect_host(data, &conn); /* primary connection */
|
||||
|
||||
if(res == CURLE_OK) {
|
||||
bool do_done;
|
||||
if(data->set.connect_only) {
|
||||
/* keep connection open for application to use the socket */
|
||||
conn->bits.close = FALSE;
|
||||
res = Curl_done(&conn, CURLE_OK, FALSE);
|
||||
break;
|
||||
}
|
||||
res = Curl_do(&conn, &do_done);
|
||||
|
||||
if(res == CURLE_OK) {
|
||||
if(conn->data->set.wildcardmatch) {
|
||||
if(conn->data->wildcard.state == CURLWC_DONE ||
|
||||
conn->data->wildcard.state == CURLWC_SKIP) {
|
||||
/* keep connection open for application to use the socket */
|
||||
conn->bits.close = FALSE;
|
||||
res = Curl_done(&conn, CURLE_OK, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
res = Transfer(conn); /* now fetch that URL please */
|
||||
if((res == CURLE_OK) || (res == CURLE_RECV_ERROR)) {
|
||||
bool retry = FALSE;
|
||||
CURLcode rc = Curl_retry_request(conn, &newurl);
|
||||
if(rc)
|
||||
res = rc;
|
||||
else
|
||||
retry = (newurl?TRUE:FALSE);
|
||||
|
||||
if(retry) {
|
||||
/* we know (newurl != NULL) at this point */
|
||||
res = CURLE_OK;
|
||||
follow = FOLLOW_RETRY;
|
||||
}
|
||||
else if(res == CURLE_OK) {
|
||||
/*
|
||||
* We must duplicate the new URL here as the connection data may
|
||||
* be free()ed in the Curl_done() function. We prefer the newurl
|
||||
* one since that's used for redirects or just further requests
|
||||
* for retries or multi-stage HTTP auth methods etc.
|
||||
*/
|
||||
if(data->req.newurl) {
|
||||
follow = FOLLOW_REDIR;
|
||||
newurl = strdup(data->req.newurl);
|
||||
if(!newurl)
|
||||
res = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else if(data->req.location) {
|
||||
follow = FOLLOW_FAKE;
|
||||
newurl = strdup(data->req.location);
|
||||
if(!newurl)
|
||||
res = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/* in the above cases where 'newurl' gets assigned, we have a fresh
|
||||
* allocated memory pointed to */
|
||||
}
|
||||
if(res != CURLE_OK) {
|
||||
/* The transfer phase returned error, we mark the connection to get
|
||||
* closed to prevent being re-used. This is because we can't
|
||||
* possibly know if the connection is in a good shape or not now. */
|
||||
conn->bits.close = TRUE;
|
||||
|
||||
if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
|
||||
/* if we failed anywhere, we must clean up the secondary socket if
|
||||
it was used */
|
||||
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||
}
|
||||
}
|
||||
|
||||
/* Always run Curl_done(), even if some of the previous calls
|
||||
failed, but return the previous (original) error code */
|
||||
res2 = Curl_done(&conn, res, FALSE);
|
||||
|
||||
if(CURLE_OK == res)
|
||||
res = res2;
|
||||
}
|
||||
else if(conn)
|
||||
/* Curl_do() failed, clean up left-overs in the done-call, but note
|
||||
that at some cases the conn pointer is NULL when Curl_do() failed
|
||||
and the connection cache is very small so only call Curl_done() if
|
||||
conn is still "alive". */
|
||||
/* ignore return code since we already have an error to return */
|
||||
(void)Curl_done(&conn, res, FALSE);
|
||||
|
||||
/*
|
||||
* Important: 'conn' cannot be used here, since it may have been closed
|
||||
* in 'Curl_done' or other functions.
|
||||
*/
|
||||
|
||||
if((res == CURLE_OK) && follow) {
|
||||
res = Curl_follow(data, newurl, follow);
|
||||
if(CURLE_OK == res) {
|
||||
/* if things went fine, Curl_follow() freed or otherwise took
|
||||
responsibility for the newurl pointer */
|
||||
newurl = NULL;
|
||||
if(follow >= FOLLOW_RETRY) {
|
||||
follow = FOLLOW_NONE;
|
||||
continue;
|
||||
}
|
||||
/* else we break out of the loop below */
|
||||
}
|
||||
}
|
||||
}
|
||||
break; /* it only reaches here when this shouldn't loop */
|
||||
|
||||
} /* loop if Location: */
|
||||
|
||||
if(newurl)
|
||||
free(newurl);
|
||||
|
||||
if(res && !data->state.errorbuf) {
|
||||
/*
|
||||
* As an extra precaution: if no error string has been set and there was
|
||||
* an error, use the strerror() string or if things are so bad that not
|
||||
* even that is good, set a bad string that mentions the error code.
|
||||
*/
|
||||
const char *str = curl_easy_strerror(res);
|
||||
if(!str)
|
||||
failf(data, "unspecified error %d", (int)res);
|
||||
else
|
||||
failf(data, "%s", str);
|
||||
}
|
||||
|
||||
/* run post-transfer unconditionally, but don't clobber the return code if
|
||||
we already have an error code recorder */
|
||||
res2 = Curl_posttransfer(data);
|
||||
if(!res && res2)
|
||||
res = res2;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_perform() is the internal high-level function that gets called by the
|
||||
* external curl_easy_perform() function. It inits, performs and cleans up a
|
||||
* single file transfer.
|
||||
*/
|
||||
CURLcode Curl_perform(struct SessionHandle *data)
|
||||
{
|
||||
CURLcode res;
|
||||
if(!data->set.wildcardmatch)
|
||||
return Curl_do_perform(data);
|
||||
|
||||
/* init main wildcard structures */
|
||||
res = Curl_wildcard_init(&data->wildcard);
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
res = Curl_do_perform(data);
|
||||
if(res) {
|
||||
Curl_wildcard_dtor(&data->wildcard);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* wildcard loop */
|
||||
while(!res && data->wildcard.state != CURLWC_DONE)
|
||||
res = Curl_do_perform(data);
|
||||
|
||||
Curl_wildcard_dtor(&data->wildcard);
|
||||
|
||||
/* wildcard download finished or failed */
|
||||
data->wildcard.state = CURLWC_INIT;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_setup_transfer() is called to setup some basic properties for the
|
||||
* upcoming transfer.
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -21,7 +21,7 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
CURLcode Curl_perform(struct SessionHandle *data);
|
||||
|
||||
CURLcode Curl_pretransfer(struct SessionHandle *data);
|
||||
CURLcode Curl_second_connect(struct connectdata *conn);
|
||||
CURLcode Curl_posttransfer(struct SessionHandle *data);
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -33,8 +33,8 @@ typedef enum {
|
||||
CURLWC_CLEAN, /* deallocate resources and reset settings */
|
||||
CURLWC_SKIP, /* skip over concrete file */
|
||||
CURLWC_ERROR, /* error cases */
|
||||
CURLWC_DONE /* if is wildcard->state == CURLWC_DONE wildcard loop in
|
||||
Curl_perform() will end */
|
||||
CURLWC_DONE /* if is wildcard->state == CURLWC_DONE wildcard loop
|
||||
will end */
|
||||
} curl_wildcard_states;
|
||||
|
||||
typedef void (*curl_wildcard_tmp_dtor)(void *ptr);
|
||||
|
Loading…
Reference in New Issue
Block a user