1
0
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:
Daniel Stenberg 2013-02-01 00:43:20 +01:00
parent e243d80dea
commit 32e8467a66
3 changed files with 5 additions and 377 deletions

View File

@ -1245,156 +1245,6 @@ long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps,
return (long)rv; 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. * Curl_pretransfer() is called immediately before a transfer starts.
*/ */
@ -1925,38 +1775,6 @@ CURLcode Curl_follow(struct SessionHandle *data,
#endif /* CURL_DISABLE_HTTP */ #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 CURLcode
Curl_reconnect_request(struct connectdata **connp) Curl_reconnect_request(struct connectdata **connp)
{ {
@ -2060,196 +1878,6 @@ CURLcode Curl_retry_request(struct connectdata *conn,
return CURLE_OK; 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 * Curl_setup_transfer() is called to setup some basic properties for the
* upcoming transfer. * upcoming transfer.

View File

@ -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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -21,7 +21,7 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
***************************************************************************/ ***************************************************************************/
CURLcode Curl_perform(struct SessionHandle *data);
CURLcode Curl_pretransfer(struct SessionHandle *data); CURLcode Curl_pretransfer(struct SessionHandle *data);
CURLcode Curl_second_connect(struct connectdata *conn); CURLcode Curl_second_connect(struct connectdata *conn);
CURLcode Curl_posttransfer(struct SessionHandle *data); CURLcode Curl_posttransfer(struct SessionHandle *data);

View File

@ -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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * 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_CLEAN, /* deallocate resources and reset settings */
CURLWC_SKIP, /* skip over concrete file */ CURLWC_SKIP, /* skip over concrete file */
CURLWC_ERROR, /* error cases */ CURLWC_ERROR, /* error cases */
CURLWC_DONE /* if is wildcard->state == CURLWC_DONE wildcard loop in CURLWC_DONE /* if is wildcard->state == CURLWC_DONE wildcard loop
Curl_perform() will end */ will end */
} curl_wildcard_states; } curl_wildcard_states;
typedef void (*curl_wildcard_tmp_dtor)(void *ptr); typedef void (*curl_wildcard_tmp_dtor)(void *ptr);