Add sha256 query

This commit is contained in:
Fabrice Reix 2021-06-17 20:28:13 +02:00
parent 73acfcb5bf
commit ead46740ab
12 changed files with 144 additions and 14 deletions

76
Cargo.lock generated
View File

@ -89,6 +89,15 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "brotli" name = "brotli"
version = "3.3.0" version = "3.3.0"
@ -182,6 +191,15 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "cpufeatures"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.2.1" version = "1.2.1"
@ -221,6 +239,15 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "encoding" name = "encoding"
version = "0.2.33" version = "0.2.33"
@ -306,6 +333,16 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
dependencies = [
"typenum",
"version_check",
]
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.1.14" version = "0.1.14"
@ -326,6 +363,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hex-literal"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8"
[[package]] [[package]]
name = "hurl" name = "hurl"
version = "1.3.0" version = "1.3.0"
@ -340,6 +383,7 @@ dependencies = [
"curl", "curl",
"encoding", "encoding",
"float-cmp", "float-cmp",
"hex-literal",
"hurl_core", "hurl_core",
"libflate", "libflate",
"libxml", "libxml",
@ -347,6 +391,7 @@ dependencies = [
"regex", "regex",
"serde", "serde",
"serde_json", "serde_json",
"sha2",
"termion", "termion",
"url", "url",
] ]
@ -480,6 +525,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]] [[package]]
name = "openssl-probe" name = "openssl-probe"
version = "0.1.2" version = "0.1.2"
@ -798,6 +849,19 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "sha2"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
dependencies = [
"block-buffer",
"cfg-if 1.0.0",
"cpufeatures",
"digest",
"opaque-debug",
]
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.3.15" version = "0.3.15"
@ -893,6 +957,12 @@ version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d" checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
[[package]]
name = "typenum"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.4" version = "0.3.4"
@ -940,6 +1010,12 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]] [[package]]
name = "wait-timeout" name = "wait-timeout"
version = "0.2.0" version = "0.2.0"

View File

@ -1 +1 @@
<div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/bytes</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line"><span class="string">Content-Type</span><span>:</span> <span class="string">application/octet-stream</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">bytes</span> <span class="predicate-type">equals</span> <span class="hex">hex,ff;</span></span><span class="line"><span class="query-type">bytes</span> <span class="predicate-type">equals</span> <span class="number">1</span></span></div></div><span class="line"></span></div> <div class="hurl-file"><div class="hurl-entry"><div class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/bytes</span></span></div><div class="response"><span class="line"><span class="version">HTTP/1.0</span> <span class="status">200</span></span><span class="line"><span class="string">Content-Type</span><span>:</span> <span class="string">application/octet-stream</span></span><span class="line section-header">[Asserts]</span></span><span class="line"><span class="query-type">bytes</span> <span class="predicate-type">equals</span> <span class="hex">hex,ff;</span></span><span class="line"><span class="query-type">bytes</span> <span class="predicate-type">equals</span> <span class="number">1</span></span><span class="line"><span class="query-type">sha256</span> <span class="predicate-type">equals</span> <span class="hex">hex,a8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89;</span></span></div></div></div>

View File

@ -4,4 +4,4 @@ Content-Type: application/octet-stream
[Asserts] [Asserts]
bytes equals hex,ff; bytes equals hex,ff;
bytes countEquals 1 bytes countEquals 1
sha256 equals hex,a8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89;

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/bytes"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Content-Type","value":"application/octet-stream"}],"asserts":[{"query":{"type":"bytes"},"predicate":{"type":"equal","value":{"value":"/w==","encoding":"base64"}}},{"query":{"type":"bytes"},"predicate":{"type":"count","value":1}}]}}]} {"entries":[{"request":{"method":"GET","url":"http://localhost:8000/bytes"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Content-Type","value":"application/octet-stream"}],"asserts":[{"query":{"type":"bytes"},"predicate":{"type":"equal","value":{"value":"/w==","encoding":"base64"}}},{"query":{"type":"bytes"},"predicate":{"type":"count","value":1}},{"query":{"type":"sha256"},"predicate":{"type":"equal","value":{"value":"qBAK5qoZQNC2Y7sxzUZhQuu9vVGHExuS2TgYmHgy64k=","encoding":"base64"}}}]}}]}

View File

@ -19,13 +19,14 @@ strict = []
[dependencies] [dependencies]
atty = "0.2.13" atty = "0.2.13"
base64 = "0.11.0" base64 = "0.11.0"
brotli="3.3.0" brotli = "3.3.0"
chrono = "0.4.11" chrono = "0.4.11"
clap = "2.33.0" clap = "2.33.0"
colored = "2" colored = "2"
curl = "0.4.33" curl = "0.4.33"
encoding = "0.2" encoding = "0.2"
float-cmp = "0.6.0" float-cmp = "0.6.0"
hex-literal = "0.3.1"
hurl_core = { version = "1.1.0", path = "../hurl_core" } hurl_core = { version = "1.1.0", path = "../hurl_core" }
libflate = "1.0.2" libflate = "1.0.2"
libxml = "0.2.17" libxml = "0.2.17"
@ -33,8 +34,10 @@ percent-encoding = "2.1.0"
regex = "1.1.0" regex = "1.1.0"
serde = "1.0.104" serde = "1.0.104"
serde_json = "1.0.40" serde_json = "1.0.40"
sha2 = "0.9.5"
url = "2.1.0" url = "2.1.0"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
termion = "1.5.5" termion = "1.5.5"
@ -44,3 +47,4 @@ cc = "1.0.52"

View File

@ -19,15 +19,15 @@
use regex::Regex; use regex::Regex;
use std::collections::HashMap; use std::collections::HashMap;
use crate::http;
use crate::jsonpath;
use hurl_core::ast::*;
use super::cookie; use super::cookie;
use super::core::{Error, RunnerError}; use super::core::{Error, RunnerError};
use super::template::eval_template; use super::template::eval_template;
use super::value::Value; use super::value::Value;
use super::xpath; use super::xpath;
use crate::http;
use crate::jsonpath;
use hurl_core::ast::*;
use sha2::Digest;
pub type QueryResult = Result<Option<Value>, Error>; pub type QueryResult = Result<Option<Value>, Error>;
@ -204,6 +204,13 @@ pub fn eval_query(
http_response.duration.as_millis() as i64 http_response.duration.as_millis() as i64
))), ))),
QueryValue::Bytes {} => Ok(Some(Value::Bytes(http_response.body))), QueryValue::Bytes {} => Ok(Some(Value::Bytes(http_response.body))),
QueryValue::Sha256 {} => {
let mut hasher = sha2::Sha256::new();
hasher.update(http_response.body);
let result = hasher.finalize();
let bytes = Value::Bytes(result[..].to_vec());
Ok(Some(bytes))
}
} }
} }
@ -267,6 +274,8 @@ impl Value {
pub mod tests { pub mod tests {
use super::*; use super::*;
use hurl_core::ast::{Pos, SourceInfo}; use hurl_core::ast::{Pos, SourceInfo};
#[macro_use]
use hex_literal::hex;
pub fn xpath_invalid_query() -> Query { pub fn xpath_invalid_query() -> Query {
// xpath ??? // xpath ???
@ -555,7 +564,7 @@ pub mod tests {
} }
], ],
body: vec![], body: vec![],
duration: Default::default() duration: Default::default(),
}; };
// cookie "LSID" // cookie "LSID"
@ -698,7 +707,7 @@ pub mod tests {
assert_eq!( assert_eq!(
eval_cookie_attribute_name( eval_cookie_attribute_name(
CookieAttributeName::Domain("_".to_string()), CookieAttributeName::Domain("_".to_string()),
cookie.clone() cookie.clone(),
), ),
None None
); );
@ -710,14 +719,14 @@ pub mod tests {
assert_eq!( assert_eq!(
eval_cookie_attribute_name( eval_cookie_attribute_name(
CookieAttributeName::MaxAge("_".to_string()), CookieAttributeName::MaxAge("_".to_string()),
cookie.clone() cookie.clone(),
), ),
None None
); );
assert_eq!( assert_eq!(
eval_cookie_attribute_name( eval_cookie_attribute_name(
CookieAttributeName::Expires("_".to_string()), CookieAttributeName::Expires("_".to_string()),
cookie.clone() cookie.clone(),
) )
.unwrap(), .unwrap(),
Value::String("Wed, 13 Jan 2021 22:23:01 GMT".to_string()) Value::String("Wed, 13 Jan 2021 22:23:01 GMT".to_string())
@ -725,7 +734,7 @@ pub mod tests {
assert_eq!( assert_eq!(
eval_cookie_attribute_name( eval_cookie_attribute_name(
CookieAttributeName::Secure("_".to_string()), CookieAttributeName::Secure("_".to_string()),
cookie.clone() cookie.clone(),
) )
.unwrap(), .unwrap(),
Value::Unit Value::Unit
@ -733,7 +742,7 @@ pub mod tests {
assert_eq!( assert_eq!(
eval_cookie_attribute_name( eval_cookie_attribute_name(
CookieAttributeName::HttpOnly("_".to_string()), CookieAttributeName::HttpOnly("_".to_string()),
cookie.clone() cookie.clone(),
) )
.unwrap(), .unwrap(),
Value::Unit Value::Unit
@ -1025,4 +1034,30 @@ pub mod tests {
Value::Bytes(String::into_bytes(String::from("Hello World!"))) Value::Bytes(String::into_bytes(String::from("Hello World!")))
); );
} }
#[test]
fn test_query_sha256() {
let variables = HashMap::new();
assert_eq!(
eval_query(
Query {
source_info: SourceInfo::init(0, 0, 0, 0),
value: QueryValue::Sha256 {},
},
&variables,
http::Response {
version: http::Version::Http10,
status: 200,
headers: vec![],
body: vec![0xff],
duration: Default::default(),
},
)
.unwrap()
.unwrap(),
Value::Bytes(
hex!("a8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89").to_vec()
)
);
}
} }

View File

@ -324,6 +324,7 @@ pub enum QueryValue {
}, },
Duration {}, Duration {},
Bytes {}, Bytes {},
Sha256 {},
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]

View File

@ -378,6 +378,9 @@ impl Htmlable for QueryValue {
QueryValue::Bytes {} => { QueryValue::Bytes {} => {
buffer.push_str("<span class=\"query-type\">bytes</span>"); buffer.push_str("<span class=\"query-type\">bytes</span>");
} }
QueryValue::Sha256 {} => {
buffer.push_str("<span class=\"query-type\">sha256</span>");
}
} }
buffer buffer
} }

View File

@ -57,6 +57,7 @@ fn query_value(reader: &mut Reader) -> ParseResult<'static, QueryValue> {
variable_query, variable_query,
duration_query, duration_query,
bytes_query, bytes_query,
sha256_query,
], ],
reader, reader,
) )
@ -160,6 +161,11 @@ fn bytes_query(reader: &mut Reader) -> ParseResult<'static, QueryValue> {
Ok(QueryValue::Bytes {}) Ok(QueryValue::Bytes {})
} }
fn sha256_query(reader: &mut Reader) -> ParseResult<'static, QueryValue> {
try_literal("sha256", reader)?;
Ok(QueryValue::Sha256 {})
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -296,6 +296,9 @@ impl ToJson for QueryValue {
QueryValue::Bytes {} => { QueryValue::Bytes {} => {
attributes.push(("type".to_string(), JValue::String("bytes".to_string()))); attributes.push(("type".to_string(), JValue::String("bytes".to_string())));
} }
QueryValue::Sha256 {} => {
attributes.push(("type".to_string(), JValue::String("sha256".to_string())));
}
}; };
JValue::Object(attributes) JValue::Object(attributes)
} }

View File

@ -464,6 +464,7 @@ impl Tokenizable for Query {
} }
QueryValue::Duration {} => tokens.push(Token::QueryType(String::from("duration"))), QueryValue::Duration {} => tokens.push(Token::QueryType(String::from("duration"))),
QueryValue::Bytes {} => tokens.push(Token::QueryType(String::from("bytes"))), QueryValue::Bytes {} => tokens.push(Token::QueryType(String::from("bytes"))),
QueryValue::Sha256 {} => tokens.push(Token::QueryType(String::from("sha256"))),
} }
tokens tokens
} }

View File

@ -297,6 +297,7 @@ impl Lintable<QueryValue> for QueryValue {
}, },
QueryValue::Duration {} => QueryValue::Duration {}, QueryValue::Duration {} => QueryValue::Duration {},
QueryValue::Bytes {} => QueryValue::Bytes {}, QueryValue::Bytes {} => QueryValue::Bytes {},
QueryValue::Sha256 {} => QueryValue::Sha256 {},
} }
} }
} }