mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -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;
|
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;
|
/* Location: redirect */
|
||||||
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!
|
|
||||||
*/
|
|
||||||
char prot[16]; /* URL protocol string storage */
|
char prot[16]; /* URL protocol string storage */
|
||||||
char letter; /* used for a silly sscanf */
|
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);
|
failf(data,"Maximum (%d) redirects followed", data->set.maxredirs);
|
||||||
res=CURLE_TOO_MANY_REDIRECTS;
|
return CURLE_TOO_MANY_REDIRECTS;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mark the next request as a followed location: */
|
/* mark the next request as a followed location: */
|
||||||
@ -1349,10 +1280,8 @@ CURLcode Curl_perform(struct SessionHandle *data)
|
|||||||
point to read-only data */
|
point to read-only data */
|
||||||
char *url_clone=strdup(data->change.url);
|
char *url_clone=strdup(data->change.url);
|
||||||
|
|
||||||
if(!url_clone) {
|
if(!url_clone)
|
||||||
res = CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY; /* skip out of this NOW */
|
||||||
break; /* skip out of this loop NOW */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* protsep points to the start of the host name */
|
/* protsep points to the start of the host name */
|
||||||
protsep=strstr(url_clone, "//");
|
protsep=strstr(url_clone, "//");
|
||||||
@ -1422,10 +1351,9 @@ CURLcode Curl_perform(struct SessionHandle *data)
|
|||||||
1 + /* possible slash */
|
1 + /* possible slash */
|
||||||
strlen(useurl) + 1/* zero byte */);
|
strlen(useurl) + 1/* zero byte */);
|
||||||
|
|
||||||
if(!newest) {
|
if(!newest)
|
||||||
res = CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY; /* go out from this */
|
||||||
break; /* go go go out from this loop */
|
|
||||||
}
|
|
||||||
sprintf(newest, "%s%s%s", url_clone,
|
sprintf(newest, "%s%s%s", url_clone,
|
||||||
(('/' == useurl[0]) || !*protsep)?"":"/",
|
(('/' == useurl[0]) || !*protsep)?"":"/",
|
||||||
useurl);
|
useurl);
|
||||||
@ -1528,9 +1456,88 @@ CURLcode Curl_perform(struct SessionHandle *data)
|
|||||||
}
|
}
|
||||||
Curl_pgrsTime(data, TIMER_REDIRECT);
|
Curl_pgrsTime(data, TIMER_REDIRECT);
|
||||||
Curl_pgrsResetTimes(data);
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break; /* it only reaches here when this shouldn't loop */
|
break; /* it only reaches here when this shouldn't loop */
|
||||||
|
|
||||||
} while(1); /* loop if Location: */
|
} while(1); /* loop if Location: */
|
||||||
|
@ -23,10 +23,9 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
CURLcode Curl_perform(struct SessionHandle *data);
|
CURLcode Curl_perform(struct SessionHandle *data);
|
||||||
|
|
||||||
CURLcode Curl_pretransfer(struct SessionHandle *data);
|
CURLcode Curl_pretransfer(struct SessionHandle *data);
|
||||||
CURLcode Curl_posttransfer(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);
|
CURLcode Curl_readwrite(struct connectdata *conn, bool *done);
|
||||||
void Curl_single_fdset(struct connectdata *conn,
|
void Curl_single_fdset(struct connectdata *conn,
|
||||||
fd_set *read_fd_set,
|
fd_set *read_fd_set,
|
||||||
|
Loading…
Reference in New Issue
Block a user