mirror of
https://github.com/moparisthebest/curl
synced 2025-03-11 07:39:50 -04:00
redirect: store the "would redirect to" URL when max redirs is reached
Test 1261 added to verify. Reported-by: Lloyd Fournier Fixes #1489 Closes #1497
This commit is contained in:
parent
48f2a96a60
commit
bba59073c5
@ -65,9 +65,9 @@ The result of the HTTPS proxy's SSL peer certificate verification that was
|
|||||||
requested. 0 means the verification was successful. (Added in 7.52.0)
|
requested. 0 means the verification was successful. (Added in 7.52.0)
|
||||||
.TP
|
.TP
|
||||||
.B redirect_url
|
.B redirect_url
|
||||||
When an HTTP request was made without --location to follow redirects, this
|
When an HTTP request was made without --location to follow redirects (or when
|
||||||
variable will show the actual URL a redirect \fIwould\fP take you to. (Added
|
--max-redir is met), this variable will show the actual URL a redirect
|
||||||
in 7.18.2)
|
\fIwould\fP have gone to. (Added in 7.18.2)
|
||||||
.TP
|
.TP
|
||||||
.B remote_ip
|
.B remote_ip
|
||||||
The remote IP address of the most recently done connection - can be either
|
The remote IP address of the most recently done connection - can be either
|
||||||
|
11
lib/multi.c
11
lib/multi.c
@ -1715,20 +1715,18 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
else {
|
else {
|
||||||
/* Follow failed */
|
/* Follow failed */
|
||||||
result = drc;
|
result = drc;
|
||||||
free(newurl);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* done didn't return OK or SEND_ERROR */
|
/* done didn't return OK or SEND_ERROR */
|
||||||
result = drc;
|
result = drc;
|
||||||
free(newurl);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Have error handler disconnect conn if we can't retry */
|
/* Have error handler disconnect conn if we can't retry */
|
||||||
stream_error = TRUE;
|
stream_error = TRUE;
|
||||||
free(newurl);
|
|
||||||
}
|
}
|
||||||
|
free(newurl);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* failure detected */
|
/* failure detected */
|
||||||
@ -1963,9 +1961,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
if(!result) {
|
if(!result) {
|
||||||
multistate(data, CURLM_STATE_CONNECT);
|
multistate(data, CURLM_STATE_CONNECT);
|
||||||
rc = CURLM_CALL_MULTI_PERFORM;
|
rc = CURLM_CALL_MULTI_PERFORM;
|
||||||
newurl = NULL; /* handed over the memory ownership to
|
|
||||||
Curl_follow(), make sure we don't free() it
|
|
||||||
here */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1979,9 +1974,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
newurl = data->req.location;
|
newurl = data->req.location;
|
||||||
data->req.location = NULL;
|
data->req.location = NULL;
|
||||||
result = Curl_follow(data, newurl, FOLLOW_FAKE);
|
result = Curl_follow(data, newurl, FOLLOW_FAKE);
|
||||||
if(!result)
|
if(result)
|
||||||
newurl = NULL; /* allocation was handed over Curl_follow() */
|
|
||||||
else
|
|
||||||
stream_error = TRUE;
|
stream_error = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1624,9 +1624,7 @@ static char *concat_url(const char *base, const char *relurl)
|
|||||||
* as given by the remote server and set up the new URL to request.
|
* as given by the remote server and set up the new URL to request.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_follow(struct Curl_easy *data,
|
CURLcode Curl_follow(struct Curl_easy *data,
|
||||||
char *newurl, /* this 'newurl' is the Location: string,
|
char *newurl, /* the Location: string */
|
||||||
and it must be malloc()ed before passed
|
|
||||||
here */
|
|
||||||
followtype type) /* see transfer.h */
|
followtype type) /* see transfer.h */
|
||||||
{
|
{
|
||||||
#ifdef CURL_DISABLE_HTTP
|
#ifdef CURL_DISABLE_HTTP
|
||||||
@ -1639,33 +1637,36 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
|||||||
|
|
||||||
/* Location: redirect */
|
/* Location: redirect */
|
||||||
bool disallowport = FALSE;
|
bool disallowport = FALSE;
|
||||||
|
bool reachedmax = FALSE;
|
||||||
|
|
||||||
if(type == FOLLOW_REDIR) {
|
if(type == FOLLOW_REDIR) {
|
||||||
if((data->set.maxredirs != -1) &&
|
if((data->set.maxredirs != -1) &&
|
||||||
(data->set.followlocation >= data->set.maxredirs)) {
|
(data->set.followlocation >= data->set.maxredirs)) {
|
||||||
failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
|
reachedmax = TRUE;
|
||||||
return CURLE_TOO_MANY_REDIRECTS;
|
type = FOLLOW_FAKE; /* switch to fake to store the would-be-redirected
|
||||||
|
to URL */
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
/* mark the next request as a followed location: */
|
||||||
|
data->state.this_is_a_follow = TRUE;
|
||||||
|
|
||||||
/* mark the next request as a followed location: */
|
data->set.followlocation++; /* count location-followers */
|
||||||
data->state.this_is_a_follow = TRUE;
|
|
||||||
|
|
||||||
data->set.followlocation++; /* count location-followers */
|
if(data->set.http_auto_referer) {
|
||||||
|
/* We are asked to automatically set the previous URL as the referer
|
||||||
|
when we get the next URL. We pick the ->url field, which may or may
|
||||||
|
not be 100% correct */
|
||||||
|
|
||||||
if(data->set.http_auto_referer) {
|
if(data->change.referer_alloc) {
|
||||||
/* We are asked to automatically set the previous URL as the referer
|
Curl_safefree(data->change.referer);
|
||||||
when we get the next URL. We pick the ->url field, which may or may
|
data->change.referer_alloc = FALSE;
|
||||||
not be 100% correct */
|
}
|
||||||
|
|
||||||
if(data->change.referer_alloc) {
|
data->change.referer = strdup(data->change.url);
|
||||||
Curl_safefree(data->change.referer);
|
if(!data->change.referer)
|
||||||
data->change.referer_alloc = FALSE;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
data->change.referer_alloc = TRUE; /* yes, free this later */
|
||||||
}
|
}
|
||||||
|
|
||||||
data->change.referer = strdup(data->change.url);
|
|
||||||
if(!data->change.referer)
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
data->change.referer_alloc = TRUE; /* yes, free this later */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1677,7 +1678,6 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
|||||||
char *absolute = concat_url(data->change.url, newurl);
|
char *absolute = concat_url(data->change.url, newurl);
|
||||||
if(!absolute)
|
if(!absolute)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
free(newurl);
|
|
||||||
newurl = absolute;
|
newurl = absolute;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1693,8 +1693,6 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
|||||||
if(!newest)
|
if(!newest)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
strcpy_url(newest, newurl); /* create a space-free URL */
|
strcpy_url(newest, newurl); /* create a space-free URL */
|
||||||
|
|
||||||
free(newurl); /* that was no good */
|
|
||||||
newurl = newest; /* use this instead now */
|
newurl = newest; /* use this instead now */
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1703,6 +1701,11 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
|||||||
/* we're only figuring out the new url if we would've followed locations
|
/* we're only figuring out the new url if we would've followed locations
|
||||||
but now we're done so we can get out! */
|
but now we're done so we can get out! */
|
||||||
data->info.wouldredirect = newurl;
|
data->info.wouldredirect = newurl;
|
||||||
|
|
||||||
|
if(reachedmax) {
|
||||||
|
failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
|
||||||
|
return CURLE_TOO_MANY_REDIRECTS;
|
||||||
|
}
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1716,7 +1719,6 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
|||||||
|
|
||||||
data->change.url = newurl;
|
data->change.url = newurl;
|
||||||
data->change.url_alloc = TRUE;
|
data->change.url_alloc = TRUE;
|
||||||
newurl = NULL; /* don't free! */
|
|
||||||
|
|
||||||
infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
|
infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ test1228 test1229 test1230 test1231 test1232 test1233 test1234 test1235 \
|
|||||||
test1236 test1237 test1238 test1239 test1240 test1241 test1242 test1243 \
|
test1236 test1237 test1238 test1239 test1240 test1241 test1242 test1243 \
|
||||||
test1244 test1245 test1246 test1247 test1248 test1249 test1250 test1251 \
|
test1244 test1245 test1246 test1247 test1248 test1249 test1250 test1251 \
|
||||||
test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 \
|
test1252 test1253 test1254 test1255 test1256 test1257 test1258 test1259 \
|
||||||
test1260 \
|
test1260 test1261 \
|
||||||
\
|
\
|
||||||
test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 \
|
test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 \
|
||||||
test1288 \
|
test1288 \
|
||||||
|
61
tests/data/test1261
Normal file
61
tests/data/test1261
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP
|
||||||
|
HTTP GET
|
||||||
|
redirect_url
|
||||||
|
followlocation
|
||||||
|
--write-out
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data nocheck="yes">
|
||||||
|
HTTP/1.1 301 This is a weirdo text message swsclose
|
||||||
|
Location: data/10290002.txt?coolsite=yes
|
||||||
|
Content-Length: 62
|
||||||
|
Connection: close
|
||||||
|
|
||||||
|
This server reply is for testing a simple Location: following
|
||||||
|
</data>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
'redirect_url' with --location and --max-redir
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/we/want/our/1261 -w '%{redirect_url}\n' --location --max-redir 0
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET /we/want/our/1261 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
# CURLE_TOO_MANY_REDIRECTS
|
||||||
|
<errorcode>
|
||||||
|
47
|
||||||
|
</errorcode>
|
||||||
|
<stdout>
|
||||||
|
HTTP/1.1 301 This is a weirdo text message swsclose
|
||||||
|
Location: data/10290002.txt?coolsite=yes
|
||||||
|
Content-Length: 62
|
||||||
|
Connection: close
|
||||||
|
|
||||||
|
http://%HOSTIP:%HTTPPORT/we/want/our/data/10290002.txt?coolsite=yes
|
||||||
|
</stdout>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
Loading…
x
Reference in New Issue
Block a user