mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-12-23 11:02:43 +03:00
Use HTTP instead of HTTP/* for any HTTP version match
This commit is contained in:
parent
fef446a4e0
commit
4e41799623
@ -1,7 +1,7 @@
|
||||
error: Parsing version
|
||||
--> tests_error_parser/version.hurl:2:6
|
||||
--> tests_error_parser/version.hurl:2:1
|
||||
|
|
||||
2 | HTTP/11 200
|
||||
| ^ HTTP version must be 1.0, 1.1, 2 or *
|
||||
| ^ HTTP version must be HTTP, HTTP/1.0, HTTP/1.1 or HTTP/2
|
||||
|
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
error: Assert HTTP version
|
||||
--> tests_failed/assert_http_version.hurl:2:6
|
||||
--> tests_failed/assert_http_version.hurl:2:1
|
||||
|
|
||||
2 | HTTP/2 200
|
||||
| ^ actual value is <1.0>
|
||||
| ^^^^^^ actual value is <HTTP/1.0>
|
||||
|
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_failed/option_retry.hurl:6:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert status code
|
||||
* --> tests_failed/option_retry.hurl:6:8
|
||||
@ -72,6 +73,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_failed/option_retry.hurl:6:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert status code
|
||||
* --> tests_failed/option_retry.hurl:6:8
|
||||
@ -110,6 +112,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_failed/option_retry.hurl:6:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
*
|
||||
* Retry max count reached, no more retry
|
||||
|
@ -1,3 +1,4 @@
|
||||
warning: tests_failed/query_match_none.hurl:2:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
error: Assert failure
|
||||
--> tests_failed/query_match_none.hurl:4:0
|
||||
|
|
||||
|
@ -29,6 +29,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_failed/retry.hurl:2:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert status code
|
||||
* --> tests_failed/retry.hurl:2:8
|
||||
@ -62,6 +63,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_failed/retry.hurl:2:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert status code
|
||||
* --> tests_failed/retry.hurl:2:8
|
||||
@ -95,6 +97,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_failed/retry.hurl:2:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert status code
|
||||
* --> tests_failed/retry.hurl:2:8
|
||||
@ -128,6 +131,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_failed/retry.hurl:2:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert status code
|
||||
* --> tests_failed/retry.hurl:2:8
|
||||
@ -161,6 +165,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_failed/retry.hurl:2:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert status code
|
||||
* --> tests_failed/retry.hurl:2:8
|
||||
@ -194,6 +199,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_failed/retry.hurl:2:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
*
|
||||
* Retry max count reached, no more retry
|
||||
|
@ -1,16 +1,16 @@
|
||||
<pre><code class="language-hurl"><span class="hurl-entry"><span class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/hello</span></span>
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="number">200</span></span>
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
|
||||
<span class="raw"><span class="line">```Hello World!```</span></span>
|
||||
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
|
||||
<span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/hello</span></span>
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="number">200</span></span>
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
|
||||
<span class="line">file, <span class="filename">data.txt</span>;</span>
|
||||
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
|
||||
<span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/hello</span></span>
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="number">200</span></span>
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
|
||||
<span class="line">hex, <span class="hex">48656c6c6f20576f726c6421</span>;</span>
|
||||
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
|
||||
<span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/hello</span></span>
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="number">200</span></span>
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
|
||||
<span class="line">base64, <span class="base64">SGVsbG8gV29ybGQh</span>;</span>
|
||||
</span></span></code></pre>
|
||||
|
@ -1,15 +1,15 @@
|
||||
GET http://localhost:8000/hello
|
||||
HTTP/1.0 200
|
||||
HTTP 200
|
||||
```Hello World!```
|
||||
|
||||
GET http://localhost:8000/hello
|
||||
HTTP/1.0 200
|
||||
HTTP 200
|
||||
file, data.txt;
|
||||
|
||||
GET http://localhost:8000/hello
|
||||
HTTP/1.0 200
|
||||
HTTP 200
|
||||
hex, 48656c6c6f20576f726c6421;
|
||||
|
||||
GET http://localhost:8000/hello
|
||||
HTTP/1.0 200
|
||||
HTTP 200
|
||||
base64, SGVsbG8gV29ybGQh;
|
||||
|
@ -1 +1 @@
|
||||
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"type":"raw-string","value":"Hello World!"}}},{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"type":"file","filename":"data.txt"}}},{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"encoding":"base64","value":"SGVsbG8gV29ybGQh"}}},{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"encoding":"base64","value":"SGVsbG8gV29ybGQh"}}}]}
|
||||
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"status":200,"body":{"type":"raw-string","value":"Hello World!"}}},{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"status":200,"body":{"type":"file","filename":"data.txt"}}},{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"status":200,"body":{"encoding":"base64","value":"SGVsbG8gV29ybGQh"}}},{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"status":200,"body":{"encoding":"base64","value":"SGVsbG8gV29ybGQh"}}}]}
|
||||
|
@ -29,6 +29,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/option_retry.hurl:4:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
* Captures:
|
||||
* job_id: ~~~
|
||||
*
|
||||
@ -60,6 +61,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/option_retry.hurl:17:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert failure
|
||||
* --> tests_ok/option_retry.hurl:19:0
|
||||
@ -98,6 +100,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/option_retry.hurl:17:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert failure
|
||||
* --> tests_ok/option_retry.hurl:19:0
|
||||
@ -136,6 +139,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/option_retry.hurl:17:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert failure
|
||||
* --> tests_ok/option_retry.hurl:19:0
|
||||
@ -174,6 +178,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/option_retry.hurl:17:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert failure
|
||||
* --> tests_ok/option_retry.hurl:19:0
|
||||
@ -212,6 +217,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/option_retry.hurl:17:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* Executing entry 3
|
||||
@ -237,6 +243,7 @@
|
||||
< Content-Length: 0
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/option_retry.hurl:24:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* Executing entry 4
|
||||
@ -262,4 +269,5 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/option_retry.hurl:27:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
|
@ -25,6 +25,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/option_verbose.hurl:7:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* Executing entry 4
|
||||
|
@ -29,6 +29,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/retry.hurl:4:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
* Captures:
|
||||
* job_id: ~~~
|
||||
*
|
||||
@ -56,6 +57,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/retry.hurl:14:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert failure
|
||||
* --> tests_ok/retry.hurl:16:0
|
||||
@ -90,6 +92,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/retry.hurl:14:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert failure
|
||||
* --> tests_ok/retry.hurl:16:0
|
||||
@ -124,6 +127,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/retry.hurl:14:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert failure
|
||||
* --> tests_ok/retry.hurl:16:0
|
||||
@ -158,6 +162,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/retry.hurl:14:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* Assert failure
|
||||
* --> tests_ok/retry.hurl:16:0
|
||||
@ -192,6 +197,7 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/retry.hurl:14:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* Executing entry 3
|
||||
@ -217,6 +223,7 @@
|
||||
< Content-Length: 0
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/retry.hurl:21:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* Executing entry 4
|
||||
@ -242,4 +249,5 @@
|
||||
< Server: Flask Server
|
||||
< Date: ~~~
|
||||
<
|
||||
warning: tests_ok/retry.hurl:24:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
|
@ -75,6 +75,7 @@
|
||||
<
|
||||
* Response body:
|
||||
* Redirected.
|
||||
warning: tests_ok/very_verbose.hurl:2:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* Executing entry 2
|
||||
@ -110,6 +111,7 @@
|
||||
<
|
||||
* Response body:
|
||||
* café
|
||||
warning: tests_ok/very_verbose.hurl:5:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* Executing entry 3
|
||||
@ -156,6 +158,7 @@
|
||||
<
|
||||
* Response body:
|
||||
* Hello World!
|
||||
warning: tests_ok/very_verbose.hurl:13:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* Executing entry 4
|
||||
@ -191,6 +194,7 @@
|
||||
<
|
||||
* Response body:
|
||||
* Bytes <f198388ba26c2c53005f24643826384f15ba905b8ca070a470b61885c6639f8bbfe63fcee5fb498a630249e499e4eddcc9ca793406c14d02c97107e09c7af57a...>
|
||||
warning: tests_ok/very_verbose.hurl:16:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* Executing entry 5
|
||||
@ -233,6 +237,7 @@
|
||||
<
|
||||
* Response body:
|
||||
*
|
||||
warning: tests_ok/very_verbose.hurl:21:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
* ------------------------------------------------------------------------------
|
||||
* Executing entry 6
|
||||
@ -270,4 +275,5 @@
|
||||
<
|
||||
* Response body:
|
||||
* Done
|
||||
warning: tests_ok/very_verbose.hurl:25:1 'HTTP/*' keyword is deprecated, please use 'HTTP' instead
|
||||
*
|
||||
|
@ -40,9 +40,9 @@ pub enum Version {
|
||||
impl fmt::Display for Version {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let value = match self {
|
||||
Version::Http10 => "1.0",
|
||||
Version::Http11 => "1.1",
|
||||
Version::Http2 => "2",
|
||||
Version::Http10 => "HTTP/1.0",
|
||||
Version::Http11 => "HTTP/1.1",
|
||||
Version::Http2 => "HTTP/2",
|
||||
};
|
||||
write!(f, "{}", value)
|
||||
}
|
||||
|
@ -514,7 +514,7 @@ fn get_summary(duration: u128, hurl_results: &[HurlResult]) -> String {
|
||||
/// Returns status, version and HTTP headers from an HTTP `response`.
|
||||
fn get_status_line_headers(response: &Response, color: bool) -> String {
|
||||
let mut str = String::new();
|
||||
let status_line = format!("HTTP/{} {}\n", response.version, response.status);
|
||||
let status_line = format!("{} {}\n", response.version, response.status);
|
||||
let status_line = if color {
|
||||
format!("{}", status_line.green().bold())
|
||||
} else {
|
||||
|
@ -29,6 +29,7 @@ use super::query::eval_query;
|
||||
use super::value::Value;
|
||||
|
||||
impl AssertResult {
|
||||
/// Evaluates an assert and returns `None` if assert is succeeded or an `Error` if failed.
|
||||
pub fn error(&self) -> Option<Error> {
|
||||
match self {
|
||||
AssertResult::Version {
|
||||
@ -36,7 +37,10 @@ impl AssertResult {
|
||||
expected,
|
||||
source_info,
|
||||
} => {
|
||||
if expected.as_str() == "*" || actual == expected {
|
||||
if expected.as_str() == "HTTP"
|
||||
|| expected.as_str() == "HTTP/*"
|
||||
|| actual == expected
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(Error {
|
||||
|
@ -21,6 +21,7 @@ use std::time::Duration;
|
||||
use crate::cli::Logger;
|
||||
use crate::http;
|
||||
use crate::http::ClientOptions;
|
||||
use hurl_core::ast::VersionValue::VersionAnyLegacy;
|
||||
use hurl_core::ast::*;
|
||||
|
||||
use super::core::*;
|
||||
@ -61,8 +62,7 @@ pub fn run(
|
||||
};
|
||||
let client_options = http::ClientOptions::from(runner_options);
|
||||
|
||||
// Experimental features
|
||||
// with cookie storage
|
||||
// Experimental features with cookie storage
|
||||
use std::str::FromStr;
|
||||
if let Some(s) = cookie_storage_set(&entry.request) {
|
||||
if let Ok(cookie) = http::Cookie::from_str(s.as_str()) {
|
||||
@ -114,6 +114,23 @@ pub fn run(
|
||||
}
|
||||
};
|
||||
|
||||
// We display some warning if HTTP/* is used instead of HTTP.
|
||||
if let Some(response) = &entry.response {
|
||||
let version = &response.version;
|
||||
let source_info = &version.source_info;
|
||||
let line = &source_info.start.line;
|
||||
let column = &source_info.start.column;
|
||||
if version.value == VersionAnyLegacy {
|
||||
logger.warning(
|
||||
format!(
|
||||
"{}:{}:{} 'HTTP/*' keyword is deprecated, please use 'HTTP' instead",
|
||||
logger.filename, line, column
|
||||
)
|
||||
.as_str(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// We runs capture and asserts on the last HTTP request/response chains.
|
||||
let (_, http_response) = calls.last().unwrap();
|
||||
let calls: Vec<Call> = calls
|
||||
|
@ -30,12 +30,7 @@ use super::template::eval_template;
|
||||
use super::value::Value;
|
||||
use crate::runner::multipart::eval_multipart_param;
|
||||
|
||||
/// Transforms an AST request to a spec request given a set of variables.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `request` - An AST request
|
||||
/// * `variables` - A set of variables for templates/expressions.
|
||||
/// * `context_dir` - The context directory
|
||||
/// Transforms an AST `request` to a spec request given a set of `variables`.
|
||||
pub fn eval_request(
|
||||
request: &Request,
|
||||
variables: &HashMap<String, Value>,
|
||||
|
@ -29,14 +29,7 @@ use super::json::eval_json_value;
|
||||
use super::template::eval_template;
|
||||
use super::value::Value;
|
||||
|
||||
/// Returns a list of response assert results.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `response` - The spec HTTP response
|
||||
/// * `variables` - A map of input variables
|
||||
/// * `http_response` - The actual HTTP response
|
||||
/// * `context_dir` - The context directory for files
|
||||
/// Returns a list of assert results, given a set of `variables`, an actual `http_response` and a spec `response`.
|
||||
pub fn eval_asserts(
|
||||
response: &Response,
|
||||
variables: &HashMap<String, Value>,
|
||||
@ -45,23 +38,23 @@ pub fn eval_asserts(
|
||||
) -> Vec<AssertResult> {
|
||||
let mut asserts = vec![];
|
||||
|
||||
let version = response.clone().version;
|
||||
let version = &response.version;
|
||||
asserts.push(AssertResult::Version {
|
||||
actual: http_response.version.to_string(),
|
||||
expected: version.value.as_str().to_string(),
|
||||
source_info: version.source_info,
|
||||
expected: version.value.to_string(),
|
||||
source_info: version.source_info.clone(),
|
||||
});
|
||||
|
||||
let status = response.clone().status;
|
||||
let status = &response.status;
|
||||
if let StatusValue::Specific(v) = status.value {
|
||||
asserts.push(AssertResult::Status {
|
||||
actual: http_response.status as u64,
|
||||
expected: v as u64,
|
||||
source_info: status.source_info,
|
||||
source_info: status.source_info.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
for header in response.clone().headers {
|
||||
for header in response.headers.iter() {
|
||||
match eval_template(&header.value, variables) {
|
||||
Err(e) => {
|
||||
asserts.push(AssertResult::Header {
|
||||
@ -322,7 +315,7 @@ mod tests {
|
||||
line_terminators: vec![],
|
||||
version: Version {
|
||||
value: VersionValue::Version1,
|
||||
source_info: SourceInfo::new(2, 6, 2, 9),
|
||||
source_info: SourceInfo::new(2, 1, 2, 9),
|
||||
},
|
||||
space0: whitespace.clone(),
|
||||
status: Status {
|
||||
@ -366,9 +359,9 @@ mod tests {
|
||||
),
|
||||
vec![
|
||||
AssertResult::Version {
|
||||
actual: String::from("1.0"),
|
||||
expected: String::from("1.0"),
|
||||
source_info: SourceInfo::new(2, 6, 2, 9),
|
||||
actual: String::from("HTTP/1.0"),
|
||||
expected: String::from("HTTP/1.0"),
|
||||
source_info: SourceInfo::new(2, 1, 2, 9),
|
||||
},
|
||||
AssertResult::Status {
|
||||
actual: 200,
|
||||
|
@ -152,17 +152,7 @@ pub enum VersionValue {
|
||||
Version11,
|
||||
Version2,
|
||||
VersionAny,
|
||||
}
|
||||
|
||||
impl VersionValue {
|
||||
pub fn as_str<'a>(&self) -> &'a str {
|
||||
match self {
|
||||
VersionValue::Version1 => "1.0",
|
||||
VersionValue::Version11 => "1.1",
|
||||
VersionValue::Version2 => "2",
|
||||
VersionValue::VersionAny => "*",
|
||||
}
|
||||
}
|
||||
VersionAnyLegacy,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -44,10 +44,11 @@ impl fmt::Display for Version {
|
||||
impl fmt::Display for VersionValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let s = match self {
|
||||
VersionValue::Version1 => "1.0",
|
||||
VersionValue::Version11 => "1.1",
|
||||
VersionValue::Version2 => "2",
|
||||
VersionValue::VersionAny => "*",
|
||||
VersionValue::Version1 => "HTTP/1.0",
|
||||
VersionValue::Version11 => "HTTP/1.1",
|
||||
VersionValue::Version2 => "HTTP/2",
|
||||
VersionValue::VersionAny => "HTTP",
|
||||
VersionValue::VersionAnyLegacy => "HTTP/*",
|
||||
};
|
||||
write!(f, "{}", s)
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ impl Error for parser::Error {
|
||||
name.as_str(),
|
||||
"Available HTTP Methods are GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE or PATCH",
|
||||
)),
|
||||
ParseError::Version { .. } => "HTTP version must be 1.0, 1.1, 2 or *".to_string(),
|
||||
ParseError::Version { .. } => "HTTP version must be HTTP, HTTP/1.0, HTTP/1.1 or HTTP/2".to_string(),
|
||||
ParseError::Status { .. } => "HTTP status code is not valid".to_string(),
|
||||
ParseError::Filename { .. } => "expecting a filename".to_string(),
|
||||
ParseError::Expecting { value } => format!("expecting '{}'", value),
|
||||
|
@ -136,10 +136,7 @@ impl Htmlable for Method {
|
||||
|
||||
impl Htmlable for Version {
|
||||
fn to_html(&self) -> String {
|
||||
format!(
|
||||
"<span class=\"version\">HTTP/{}</span>",
|
||||
self.value.as_str()
|
||||
)
|
||||
format!("<span class=\"version\">{}</span>", self.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
use crate::ast::VersionValue::VersionAny;
|
||||
use crate::ast::*;
|
||||
|
||||
use super::bytes::*;
|
||||
@ -160,18 +161,22 @@ fn method(reader: &mut Reader) -> ParseResult<'static, Method> {
|
||||
}
|
||||
|
||||
fn version(reader: &mut Reader) -> ParseResult<'static, Version> {
|
||||
try_literal("HTTP/", reader)?;
|
||||
let available_version = vec![
|
||||
("1.0", VersionValue::Version1),
|
||||
("1.1", VersionValue::Version11),
|
||||
("2", VersionValue::Version2),
|
||||
("*", VersionValue::VersionAny),
|
||||
];
|
||||
let start = reader.state.clone();
|
||||
for (s, value) in available_version {
|
||||
try_literal("HTTP", reader)?;
|
||||
|
||||
let next_c = reader.peek();
|
||||
match next_c {
|
||||
Some('/') => {
|
||||
let available_version = vec![
|
||||
("/1.0", VersionValue::Version1),
|
||||
("/1.1", VersionValue::Version11),
|
||||
("/2", VersionValue::Version2),
|
||||
("/*", VersionValue::VersionAnyLegacy),
|
||||
];
|
||||
for (s, value) in available_version.iter() {
|
||||
if try_literal(s, reader).is_ok() {
|
||||
return Ok(Version {
|
||||
value,
|
||||
value: value.clone(),
|
||||
source_info: SourceInfo::new(
|
||||
start.pos.line,
|
||||
start.pos.column,
|
||||
@ -186,6 +191,22 @@ fn version(reader: &mut Reader) -> ParseResult<'static, Version> {
|
||||
recoverable: false,
|
||||
inner: ParseError::Version {},
|
||||
})
|
||||
}
|
||||
Some(' ') => Ok(Version {
|
||||
value: VersionAny,
|
||||
source_info: SourceInfo::new(
|
||||
start.pos.line,
|
||||
start.pos.column,
|
||||
reader.state.pos.line,
|
||||
reader.state.pos.column,
|
||||
),
|
||||
}),
|
||||
_ => Err(Error {
|
||||
pos: start.pos,
|
||||
recoverable: false,
|
||||
inner: ParseError::Version {},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn status(reader: &mut Reader) -> ParseResult<'static, Status> {
|
||||
@ -514,7 +535,7 @@ mod tests {
|
||||
|
||||
let mut reader = Reader::init("HTTP/1. 200");
|
||||
let error = version(&mut reader).err().unwrap();
|
||||
assert_eq!(error.pos, Pos { line: 1, column: 6 });
|
||||
assert_eq!(error.pos, Pos { line: 1, column: 1 });
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -530,7 +551,6 @@ mod tests {
|
||||
let mut reader = Reader::init("xxx");
|
||||
let result = status(&mut reader);
|
||||
assert!(result.is_err());
|
||||
// assert!(result.err().unwrap().pos, Pos { line: 1, column: 1 });
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -39,7 +39,7 @@ impl ToJson for HurlFile {
|
||||
impl ToJson for Entry {
|
||||
fn to_json(&self) -> JValue {
|
||||
let mut attributes = vec![("request".to_string(), self.request.to_json())];
|
||||
if let Some(response) = self.response.clone() {
|
||||
if let Some(response) = &self.response {
|
||||
attributes.push(("response".to_string(), response.to_json()));
|
||||
}
|
||||
JValue::Object(attributes)
|
||||
@ -55,40 +55,33 @@ impl ToJson for Request {
|
||||
),
|
||||
("url".to_string(), JValue::String(self.url.to_string())),
|
||||
];
|
||||
add_headers(&mut attributes, self.headers.clone());
|
||||
add_headers(&mut attributes, &self.headers);
|
||||
|
||||
if !self.clone().querystring_params().is_empty() {
|
||||
if !self.querystring_params().is_empty() {
|
||||
let params = self
|
||||
.clone()
|
||||
.querystring_params()
|
||||
.iter()
|
||||
.map(|p| p.to_json())
|
||||
.collect();
|
||||
attributes.push(("query_string_params".to_string(), JValue::List(params)));
|
||||
}
|
||||
if !self.clone().form_params().is_empty() {
|
||||
let params = self
|
||||
.clone()
|
||||
.form_params()
|
||||
.iter()
|
||||
.map(|p| p.to_json())
|
||||
.collect();
|
||||
if !self.form_params().is_empty() {
|
||||
let params = self.form_params().iter().map(|p| p.to_json()).collect();
|
||||
attributes.push(("form_params".to_string(), JValue::List(params)));
|
||||
}
|
||||
if !self.clone().multipart_form_data().is_empty() {
|
||||
if !self.multipart_form_data().is_empty() {
|
||||
let params = self
|
||||
.clone()
|
||||
.multipart_form_data()
|
||||
.iter()
|
||||
.map(|p| p.to_json())
|
||||
.collect();
|
||||
attributes.push(("multipart_form_data".to_string(), JValue::List(params)));
|
||||
}
|
||||
if !self.clone().cookies().is_empty() {
|
||||
let cookies = self.clone().cookies().iter().map(|c| c.to_json()).collect();
|
||||
if !self.cookies().is_empty() {
|
||||
let cookies = self.cookies().iter().map(|c| c.to_json()).collect();
|
||||
attributes.push(("cookies".to_string(), JValue::List(cookies)));
|
||||
}
|
||||
if let Some(body) = self.body.clone() {
|
||||
if let Some(body) = &self.body {
|
||||
attributes.push(("body".to_string(), body.to_json()));
|
||||
}
|
||||
JValue::Object(attributes)
|
||||
@ -99,13 +92,13 @@ impl ToJson for Response {
|
||||
/// Transforms this response to a JSON object.
|
||||
fn to_json(&self) -> JValue {
|
||||
let mut attributes = vec![];
|
||||
if let Some(v) = get_json_version(self.version.value.clone()) {
|
||||
if let Some(v) = get_json_version(&self.version.value) {
|
||||
attributes.push(("version".to_string(), JValue::String(v)))
|
||||
}
|
||||
if let StatusValue::Specific(n) = self.status.value {
|
||||
attributes.push(("status".to_string(), JValue::Number(n.to_string())));
|
||||
}
|
||||
add_headers(&mut attributes, self.headers.clone());
|
||||
add_headers(&mut attributes, &self.headers);
|
||||
if !self.captures().is_empty() {
|
||||
let captures = self.captures().iter().map(|c| c.to_json()).collect();
|
||||
attributes.push(("captures".to_string(), JValue::List(captures)));
|
||||
@ -121,7 +114,7 @@ impl ToJson for Response {
|
||||
}
|
||||
}
|
||||
|
||||
fn add_headers(attributes: &mut Vec<(String, JValue)>, headers: Vec<Header>) {
|
||||
fn add_headers(attributes: &mut Vec<(String, JValue)>, headers: &Vec<Header>) {
|
||||
if !headers.is_empty() {
|
||||
let headers = JValue::List(headers.iter().map(|h| h.to_json()).collect());
|
||||
attributes.push(("headers".to_string(), headers))
|
||||
@ -191,12 +184,13 @@ impl ToJson for File {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_json_version(version_value: VersionValue) -> Option<String> {
|
||||
fn get_json_version(version_value: &VersionValue) -> Option<String> {
|
||||
match version_value {
|
||||
VersionValue::Version1 => Some("HTTP/1.0".to_string()),
|
||||
VersionValue::Version11 => Some("HTTP/1.1".to_string()),
|
||||
VersionValue::Version2 => Some("HTTP/2".to_string()),
|
||||
VersionValue::VersionAny => None,
|
||||
VersionValue::VersionAnyLegacy => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,15 +134,7 @@ impl Tokenizable for Status {
|
||||
|
||||
impl Tokenizable for Version {
|
||||
fn tokenize(&self) -> Vec<Token> {
|
||||
vec![Token::Version(format!(
|
||||
"HTTP/{}",
|
||||
match self.value {
|
||||
VersionValue::Version1 => String::from("1.0"),
|
||||
VersionValue::Version11 => String::from("1.1"),
|
||||
VersionValue::Version2 => String::from("2"),
|
||||
VersionValue::VersionAny => String::from("*"),
|
||||
}
|
||||
))]
|
||||
vec![Token::Version(self.value.to_string())]
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user