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:
parent
daea056210
commit
5f649a1649
177
lib/transfer.c
177
lib/transfer.c
@ -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: */
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user