mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-11-11 02:40:26 +03:00
Make minor codes modification for method computing and add unit tests.
This commit is contained in:
parent
cef2e80c1a
commit
45bb522794
@ -1,2 +1,3 @@
|
||||
curl --location 'http://localhost:8000/follow-redirect'
|
||||
curl --location --request POST 'http://localhost:8000/follow-redirect-308'
|
||||
curl --request POST --location 'http://localhost:8000/follow-redirect'
|
||||
curl --request POST --location 'http://localhost:8000/follow-redirect-308'
|
||||
|
@ -2,6 +2,12 @@
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
|
||||
<span class="line"><span class="string">`Followed redirect!`</span></span>
|
||||
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
|
||||
<span class="line"></span><span class="comment"># On 301, 302, 303, redirected request switch to GET.</span>
|
||||
<span class="line"></span><span class="comment"># Otherwise, method are untouched.</span>
|
||||
<span class="line"><span class="method">POST</span> <span class="url">http://localhost:8000/follow-redirect</span></span>
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
|
||||
<span class="line"><span class="string">`Followed redirect!`</span></span>
|
||||
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
|
||||
<span class="line"><span class="method">POST</span> <span class="url">http://localhost:8000/follow-redirect-308</span></span>
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
|
||||
<span class="line"><span class="string">`Followed redirect POST!`</span></span>
|
||||
|
@ -2,6 +2,12 @@ GET http://localhost:8000/follow-redirect
|
||||
HTTP 200
|
||||
`Followed redirect!`
|
||||
|
||||
# On 301, 302, 303, redirected request switch to GET.
|
||||
# Otherwise, method are untouched.
|
||||
POST http://localhost:8000/follow-redirect
|
||||
HTTP 200
|
||||
`Followed redirect!`
|
||||
|
||||
POST http://localhost:8000/follow-redirect-308
|
||||
HTTP 200
|
||||
`Followed redirect POST!`
|
||||
|
@ -1 +1 @@
|
||||
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect"},"response":{"status":200,"body":{"type":"text","value":"Followed redirect!"}}},{"request":{"method":"POST","url":"http://localhost:8000/follow-redirect-308"},"response":{"status":200,"body":{"type":"text","value":"Followed redirect POST!"}}}]}
|
||||
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect"},"response":{"status":200,"body":{"type":"text","value":"Followed redirect!"}}},{"request":{"method":"POST","url":"http://localhost:8000/follow-redirect"},"response":{"status":200,"body":{"type":"text","value":"Followed redirect!"}}},{"request":{"method":"POST","url":"http://localhost:8000/follow-redirect-308"},"response":{"status":200,"body":{"type":"text","value":"Followed redirect POST!"}}}]}
|
||||
|
@ -2,7 +2,7 @@ from app import app
|
||||
from flask import redirect, Response
|
||||
|
||||
|
||||
@app.route("/follow-redirect")
|
||||
@app.route("/follow-redirect", methods=["GET", "POST"])
|
||||
def follow_redirect():
|
||||
return redirect("http://localhost:8000/following-redirect")
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
curl 'http://localhost:8000/follow-redirect'
|
||||
curl 'http://localhost:8000/follow-redirect'
|
||||
curl --location 'http://localhost:8000/follow-redirect'
|
||||
curl --request POST --location 'http://localhost:8000/follow-redirect'
|
||||
curl --request POST --location 'http://localhost:8000/follow-redirect-308'
|
||||
|
@ -23,5 +23,26 @@
|
||||
<span class="line"><span class="section-header">[Asserts]</span></span>
|
||||
<span class="line"><span class="query-type">header</span> <span class="string">"Location"</span> <span class="not">not</span> <span class="predicate-type">exists</span></span>
|
||||
<span class="line"><span class="string">`Followed redirect!`</span></span>
|
||||
</span></span><span class="line"></span>
|
||||
</code></pre>
|
||||
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"></span><span class="comment"># On 301, 302, 303, redirected request switch to GET.</span>
|
||||
<span class="line"></span><span class="comment"># Otherwise, method are untouched.</span>
|
||||
<span class="line"><span class="method">POST</span> <span class="url">http://localhost:8000/follow-redirect</span></span>
|
||||
<span class="line"><span class="section-header">[Options]</span></span>
|
||||
<span class="line"><span class="string">location</span>: <span class="boolean">true</span></span>
|
||||
</span><span class="response"><span class="line"></span>
|
||||
<span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
|
||||
<span class="line"><span class="section-header">[Asserts]</span></span>
|
||||
<span class="line"><span class="query-type">header</span> <span class="string">"Location"</span> <span class="not">not</span> <span class="predicate-type">exists</span></span>
|
||||
<span class="line"><span class="string">`Followed redirect!`</span></span>
|
||||
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
|
||||
<span class="line"></span>
|
||||
<span class="line"><span class="method">POST</span> <span class="url">http://localhost:8000/follow-redirect-308</span></span>
|
||||
<span class="line"><span class="section-header">[Options]</span></span>
|
||||
<span class="line"><span class="string">location</span>: <span class="boolean">true</span></span>
|
||||
</span><span class="response"><span class="line"></span>
|
||||
<span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
|
||||
<span class="line"><span class="section-header">[Asserts]</span></span>
|
||||
<span class="line"><span class="query-type">header</span> <span class="string">"Location"</span> <span class="not">not</span> <span class="predicate-type">exists</span></span>
|
||||
<span class="line"><span class="string">`Followed redirect POST!`</span></span>
|
||||
</span></span></code></pre>
|
||||
|
@ -24,3 +24,24 @@ HTTP 200
|
||||
header "Location" not exists
|
||||
`Followed redirect!`
|
||||
|
||||
|
||||
# On 301, 302, 303, redirected request switch to GET.
|
||||
# Otherwise, method are untouched.
|
||||
POST http://localhost:8000/follow-redirect
|
||||
[Options]
|
||||
location: true
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect!`
|
||||
|
||||
|
||||
POST http://localhost:8000/follow-redirect-308
|
||||
[Options]
|
||||
location: true
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Location" not exists
|
||||
`Followed redirect POST!`
|
||||
|
@ -1 +1 @@
|
||||
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect"},"response":{"status":302,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"type":"equal","value":"http://localhost:8000/following-redirect"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect","options":[{"name":"location","value":false}]},"response":{"status":302,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"type":"equal","value":"http://localhost:8000/following-redirect"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect","options":[{"name":"location","value":true}]},"response":{"status":200,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"not":true,"type":"exist"}}],"body":{"type":"text","value":"Followed redirect!"}}}]}
|
||||
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect"},"response":{"status":302,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"type":"equal","value":"http://localhost:8000/following-redirect"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect","options":[{"name":"location","value":false}]},"response":{"status":302,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"type":"equal","value":"http://localhost:8000/following-redirect"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect","options":[{"name":"location","value":true}]},"response":{"status":200,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"not":true,"type":"exist"}}],"body":{"type":"text","value":"Followed redirect!"}}},{"request":{"method":"POST","url":"http://localhost:8000/follow-redirect","options":[{"name":"location","value":true}]},"response":{"status":200,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"not":true,"type":"exist"}}],"body":{"type":"text","value":"Followed redirect!"}}},{"request":{"method":"POST","url":"http://localhost:8000/follow-redirect-308","options":[{"name":"location","value":true}]},"response":{"status":200,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"not":true,"type":"exist"}}],"body":{"type":"text","value":"Followed redirect POST!"}}}]}
|
||||
|
@ -1 +1 @@
|
||||
Followed redirect!
|
||||
Followed redirect POST!
|
@ -86,7 +86,7 @@ impl Client {
|
||||
let call = self.execute(&request_spec, options, logger)?;
|
||||
let base_url = call.request.base_url()?;
|
||||
let redirect_url = self.get_follow_location(&call.response, &base_url);
|
||||
let call_response_status = call.response.status;
|
||||
let status = call.response.status;
|
||||
calls.push(call);
|
||||
if !options.follow_location || redirect_url.is_none() {
|
||||
break;
|
||||
@ -94,21 +94,16 @@ impl Client {
|
||||
let redirect_url = redirect_url.unwrap();
|
||||
logger.debug("");
|
||||
logger.debug(format!("=> Redirect to {redirect_url}").as_str());
|
||||
logger.debug("");
|
||||
redirect_count += 1;
|
||||
if let Some(max_redirect) = options.max_redirect {
|
||||
if redirect_count > max_redirect {
|
||||
return Err(HttpError::TooManyRedirect);
|
||||
}
|
||||
}
|
||||
let new_request_method = self.get_redirected_request_method(
|
||||
options,
|
||||
logger,
|
||||
call_response_status,
|
||||
request_spec.method,
|
||||
);
|
||||
logger.debug("");
|
||||
let redirect_method = get_redirect_method(status, request_spec.method);
|
||||
request_spec = RequestSpec {
|
||||
method: new_request_method,
|
||||
method: redirect_method,
|
||||
url: redirect_url,
|
||||
..Default::default()
|
||||
};
|
||||
@ -116,32 +111,6 @@ impl Client {
|
||||
Ok(calls)
|
||||
}
|
||||
|
||||
pub fn get_redirected_request_method(
|
||||
&self,
|
||||
options: &ClientOptions,
|
||||
logger: &Logger,
|
||||
response_status: u32,
|
||||
original_method: Method,
|
||||
) -> Method {
|
||||
// this replicates curls behavior
|
||||
return match response_status {
|
||||
301 | 302 | 303 => {
|
||||
// spaces at the start to align with the arrow used in a previous
|
||||
// debug line
|
||||
logger.debug(
|
||||
format!(
|
||||
" Resending with method GET because response code was {response_status}"
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
Method("GET".to_string())
|
||||
}
|
||||
// Could be only 307 and 308, but curl does this for all 3xx
|
||||
// codes not converted to GET above.
|
||||
_ => original_method,
|
||||
};
|
||||
}
|
||||
|
||||
/// Executes an HTTP request `request_spec`, without following redirection and returns a
|
||||
/// pair of [`Request`], [`Response`].
|
||||
pub fn execute(
|
||||
@ -685,6 +654,17 @@ fn get_redirect_url(location: &str, base_url: &str) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the method used for redirecting a request/response with `response_status`.
|
||||
fn get_redirect_method(response_status: u32, original_method: Method) -> Method {
|
||||
// This replicates curl's behavior
|
||||
match response_status {
|
||||
301 | 302 | 303 => Method("GET".to_string()),
|
||||
// Could be only 307 and 308, but curl does this for all 3xx
|
||||
// codes not converted to GET above.
|
||||
_ => original_method,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns cookies from both cookies from the cookie storage and the request.
|
||||
pub fn all_cookies(cookie_storage: &[Cookie], request_spec: &RequestSpec) -> Vec<RequestCookie> {
|
||||
let mut cookies = request_spec.cookies.clone();
|
||||
@ -844,4 +824,32 @@ mod tests {
|
||||
"http://localhost:8000/redirected".to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_redirect_method() {
|
||||
// Status of the response to be redirected | method of the original request | method of the new request
|
||||
let datas = [
|
||||
(301, "GET", "GET"),
|
||||
(301, "POST", "GET"),
|
||||
(301, "DELETE", "GET"),
|
||||
(302, "GET", "GET"),
|
||||
(302, "POST", "GET"),
|
||||
(302, "DELETE", "GET"),
|
||||
(303, "GET", "GET"),
|
||||
(303, "POST", "GET"),
|
||||
(303, "DELETE", "GET"),
|
||||
(304, "GET", "GET"),
|
||||
(304, "POST", "POST"),
|
||||
(304, "DELETE", "DELETE"),
|
||||
(308, "GET", "GET"),
|
||||
(308, "POST", "POST"),
|
||||
(308, "DELETE", "DELETE"),
|
||||
];
|
||||
for (status, original, redirected) in datas {
|
||||
assert_eq!(
|
||||
get_redirect_method(status, Method(original.to_string())),
|
||||
Method(redirected.to_string())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user