1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 23:58:49 -05:00

Move the URL concat code to Curl_follow(), and added a proto for that

function. For Location: following.
This commit is contained in:
Daniel Stenberg 2002-10-07 13:38:34 +00:00
parent daea056210
commit 5f649a1649
2 changed files with 237 additions and 231 deletions

View File

@ -1228,88 +1228,19 @@ CURLcode Curl_posttransfer(struct SessionHandle *data)
return CURLE_OK;
}
CURLcode Curl_perform(struct SessionHandle *data)
CURLcode Curl_follow(struct SessionHandle *data,
char *newurl) /* this 'newurl' is the Location: string,
and it must be malloc()ed before passed
here */
{
CURLcode res;
CURLcode res2;
struct connectdata *conn=NULL;
char *newurl = NULL; /* possibly a new URL to follow to! */
data->state.used_interface = Curl_if_easy;
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.
*/
do {
Curl_pgrsTime(data, TIMER_STARTSINGLE);
res = Curl_connect(data, &conn);
if(res == CURLE_OK) {
res = Curl_do(&conn);
if(res == CURLE_OK) {
CURLcode res2; /* just a local extra result container */
if(conn->protocol&PROT_FTPS)
/* FTPS, disable ssl while transfering data */
conn->ssl.use = FALSE;
res = Transfer(conn); /* now fetch that URL please */
if(conn->protocol&PROT_FTPS)
/* FTPS, enable ssl again after havving transferred data */
conn->ssl.use = TRUE;
if(res == CURLE_OK)
/*
* We must duplicate the new URL here as the connection data
* may be free()ed in the Curl_done() function.
*/
newurl = conn->newurl?strdup(conn->newurl):NULL;
else {
/* The transfer phase returned error, we mark the connection to get
* closed to prevent being re-used. This is becasue we can't
* possibly know if the connection is in a good shape or not now. */
conn->bits.close = TRUE;
if(-1 !=conn->secondarysocket) {
/* if we failed anywhere, we must clean up the secondary socket if
it was used */
sclose(conn->secondarysocket);
conn->secondarysocket=-1;
}
}
/* Always run Curl_done(), even if some of the previous calls
failed, but return the previous (original) error code */
res2 = Curl_done(conn);
if(CURLE_OK == res)
res = res2;
}
/*
* Important: 'conn' cannot be used here, since it may have been closed
* in 'Curl_done' or other functions.
*/
if((res == CURLE_OK) && newurl) {
/* Location: redirect
This is assumed to happen for HTTP(S) only!
*/
/* Location: redirect */
char prot[16]; /* URL protocol string storage */
char letter; /* used for a silly sscanf */
if (data->set.maxredirs && (data->set.followlocation >= data->set.maxredirs)) {
if (data->set.maxredirs &&
(data->set.followlocation >= data->set.maxredirs)) {
failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
res=CURLE_TOO_MANY_REDIRECTS;
break;
return CURLE_TOO_MANY_REDIRECTS;
}
/* mark the next request as a followed location: */
@ -1349,10 +1280,8 @@ CURLcode Curl_perform(struct SessionHandle *data)
point to read-only data */
char *url_clone=strdup(data->change.url);
if(!url_clone) {
res = CURLE_OUT_OF_MEMORY;
break; /* skip out of this loop NOW */
}
if(!url_clone)
return CURLE_OUT_OF_MEMORY; /* skip out of this NOW */
/* protsep points to the start of the host name */
protsep=strstr(url_clone, "//");
@ -1422,10 +1351,9 @@ CURLcode Curl_perform(struct SessionHandle *data)
1 + /* possible slash */
strlen(useurl) + 1/* zero byte */);
if(!newest) {
res = CURLE_OUT_OF_MEMORY;
break; /* go go go out from this loop */
}
if(!newest)
return CURLE_OUT_OF_MEMORY; /* go out from this */
sprintf(newest, "%s%s%s", url_clone,
(('/' == useurl[0]) || !*protsep)?"":"/",
useurl);
@ -1528,9 +1456,88 @@ CURLcode Curl_perform(struct SessionHandle *data)
}
Curl_pgrsTime(data, TIMER_REDIRECT);
Curl_pgrsResetTimes(data);
return CURLE_OK;
}
CURLcode Curl_perform(struct SessionHandle *data)
{
CURLcode res;
CURLcode res2;
struct connectdata *conn=NULL;
char *newurl = NULL; /* possibly a new URL to follow to! */
data->state.used_interface = Curl_if_easy;
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.
*/
do {
Curl_pgrsTime(data, TIMER_STARTSINGLE);
res = Curl_connect(data, &conn);
if(res == CURLE_OK) {
res = Curl_do(&conn);
if(res == CURLE_OK) {
CURLcode res2; /* just a local extra result container */
if(conn->protocol&PROT_FTPS)
/* FTPS, disable ssl while transfering data */
conn->ssl.use = FALSE;
res = Transfer(conn); /* now fetch that URL please */
if(conn->protocol&PROT_FTPS)
/* FTPS, enable ssl again after havving transferred data */
conn->ssl.use = TRUE;
if(res == CURLE_OK)
/*
* We must duplicate the new URL here as the connection data
* may be free()ed in the Curl_done() function.
*/
newurl = conn->newurl?strdup(conn->newurl):NULL;
else {
/* The transfer phase returned error, we mark the connection to get
* closed to prevent being re-used. This is becasue we can't
* possibly know if the connection is in a good shape or not now. */
conn->bits.close = TRUE;
if(-1 !=conn->secondarysocket) {
/* if we failed anywhere, we must clean up the secondary socket if
it was used */
sclose(conn->secondarysocket);
conn->secondarysocket=-1;
}
}
/* Always run Curl_done(), even if some of the previous calls
failed, but return the previous (original) error code */
res2 = Curl_done(conn);
if(CURLE_OK == res)
res = res2;
}
/*
* Important: 'conn' cannot be used here, since it may have been closed
* in 'Curl_done' or other functions.
*/
if((res == CURLE_OK) && newurl) {
res = Curl_follow(data, newurl);
if(CURLE_OK == res) {
newurl = NULL;
continue;
}
}
}
break; /* it only reaches here when this shouldn't loop */
} while(1); /* loop if Location: */

View File

@ -23,10 +23,9 @@
* $Id$
***************************************************************************/
CURLcode Curl_perform(struct SessionHandle *data);
CURLcode Curl_pretransfer(struct SessionHandle *data);
CURLcode Curl_posttransfer(struct SessionHandle *data);
CURLcode Curl_follow(struct SessionHandle *data, char *newurl);
CURLcode Curl_readwrite(struct connectdata *conn, bool *done);
void Curl_single_fdset(struct connectdata *conn,
fd_set *read_fd_set,