mirror of
https://github.com/curl/curl.git
synced 2026-08-24 15:23:36 +03:00
lib: add CURLFOLLOW_OBEYCODE and CURLFOLLOW_FIRSTONLY
With this change, the argument passed to the CURLOPT_FOLLOWLOCATION option is now instead a "mode" instead of just a boolean. Documentation is extended to describe the two new modes. Test 1571 to 1581 verify. Closes #16473
This commit is contained in:
parent
294136b754
commit
fb13923dd6
23 changed files with 1328 additions and 34 deletions
48
lib/http.c
48
lib/http.c
|
|
@ -1154,6 +1154,21 @@ static bool http_should_fail(struct Curl_easy *data, int httpcode)
|
|||
return data->state.authproblem;
|
||||
}
|
||||
|
||||
static void http_switch_to_get(struct Curl_easy *data, int code)
|
||||
{
|
||||
const char *req = data->set.str[STRING_CUSTOMREQUEST];
|
||||
if((req || data->state.httpreq != HTTPREQ_GET) &&
|
||||
(data->set.http_follow_mode == CURLFOLLOW_OBEYCODE)) {
|
||||
infof(data, "Switch to GET because of %d response", code);
|
||||
data->state.http_ignorecustom = TRUE;
|
||||
}
|
||||
else if(req && (data->set.http_follow_mode != CURLFOLLOW_FIRSTONLY))
|
||||
infof(data, "Stick to %s instead of GET", req);
|
||||
|
||||
data->state.httpreq = HTTPREQ_GET;
|
||||
Curl_creader_set_rewind(data, FALSE);
|
||||
}
|
||||
|
||||
CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
||||
followtype type)
|
||||
{
|
||||
|
|
@ -1320,6 +1335,12 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
|||
data->state.url_alloc = TRUE;
|
||||
Curl_req_soft_reset(&data->req, data);
|
||||
infof(data, "Issue another request to this URL: '%s'", data->state.url);
|
||||
if((data->set.http_follow_mode == CURLFOLLOW_FIRSTONLY) &&
|
||||
data->set.str[STRING_CUSTOMREQUEST] &&
|
||||
!data->state.http_ignorecustom) {
|
||||
data->state.http_ignorecustom = TRUE;
|
||||
infof(data, "Drop custom request method for next request");
|
||||
}
|
||||
|
||||
/*
|
||||
* We get here when the HTTP code is 300-399 (and 401). We need to perform
|
||||
|
|
@ -1361,11 +1382,8 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
|||
if((data->state.httpreq == HTTPREQ_POST
|
||||
|| data->state.httpreq == HTTPREQ_POST_FORM
|
||||
|| data->state.httpreq == HTTPREQ_POST_MIME)
|
||||
&& !(data->set.keep_post & CURL_REDIR_POST_301)) {
|
||||
infof(data, "Switch from POST to GET");
|
||||
data->state.httpreq = HTTPREQ_GET;
|
||||
Curl_creader_set_rewind(data, FALSE);
|
||||
}
|
||||
&& !(data->set.keep_post & CURL_REDIR_POST_301))
|
||||
http_switch_to_get(data, 301);
|
||||
break;
|
||||
case 302: /* Found */
|
||||
/* (quote from RFC7231, section 6.4.3)
|
||||
|
|
@ -1387,11 +1405,8 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
|||
if((data->state.httpreq == HTTPREQ_POST
|
||||
|| data->state.httpreq == HTTPREQ_POST_FORM
|
||||
|| data->state.httpreq == HTTPREQ_POST_MIME)
|
||||
&& !(data->set.keep_post & CURL_REDIR_POST_302)) {
|
||||
infof(data, "Switch from POST to GET");
|
||||
data->state.httpreq = HTTPREQ_GET;
|
||||
Curl_creader_set_rewind(data, FALSE);
|
||||
}
|
||||
&& !(data->set.keep_post & CURL_REDIR_POST_302))
|
||||
http_switch_to_get(data, 302);
|
||||
break;
|
||||
|
||||
case 303: /* See Other */
|
||||
|
|
@ -1404,11 +1419,8 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
|
|||
((data->state.httpreq != HTTPREQ_POST &&
|
||||
data->state.httpreq != HTTPREQ_POST_FORM &&
|
||||
data->state.httpreq != HTTPREQ_POST_MIME) ||
|
||||
!(data->set.keep_post & CURL_REDIR_POST_303))) {
|
||||
data->state.httpreq = HTTPREQ_GET;
|
||||
infof(data, "Switch to %s",
|
||||
data->req.no_body ? "HEAD" : "GET");
|
||||
}
|
||||
!(data->set.keep_post & CURL_REDIR_POST_303)))
|
||||
http_switch_to_get(data, 303);
|
||||
break;
|
||||
case 304: /* Not Modified */
|
||||
/* 304 means we did a conditional request and it was "Not modified".
|
||||
|
|
@ -1802,8 +1814,10 @@ void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
|
|||
httpreq = HTTPREQ_PUT;
|
||||
|
||||
/* Now set the 'request' pointer to the proper request string */
|
||||
if(data->set.str[STRING_CUSTOMREQUEST])
|
||||
if(data->set.str[STRING_CUSTOMREQUEST] &&
|
||||
!data->state.http_ignorecustom) {
|
||||
request = data->set.str[STRING_CUSTOMREQUEST];
|
||||
}
|
||||
else {
|
||||
if(data->req.no_body)
|
||||
request = "HEAD";
|
||||
|
|
@ -3137,7 +3151,7 @@ static CURLcode http_header(struct Curl_easy *data,
|
|||
else {
|
||||
data->req.location = location;
|
||||
|
||||
if(data->set.http_follow_location) {
|
||||
if(data->set.http_follow_mode) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(data->req.location); /* clone */
|
||||
if(!data->req.newurl)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue