From 23bf37604201a339165f5938f75dc22edc178495 Mon Sep 17 00:00:00 2001 From: jcamiel Date: Tue, 14 Feb 2023 14:10:09 +0100 Subject: [PATCH] Add Certificate model for HTTP response. --- packages/hurl/src/http/certificate.rs | 28 +++++++++++++++++++++ packages/hurl/src/http/client.rs | 2 ++ packages/hurl/src/http/mod.rs | 1 + packages/hurl/src/http/response.rs | 12 +++++++++ packages/hurl/src/http/response_decoding.rs | 19 +++++++++++--- packages/hurl/src/runner/query.rs | 8 +++++- 6 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 packages/hurl/src/http/certificate.rs diff --git a/packages/hurl/src/http/certificate.rs b/packages/hurl/src/http/certificate.rs new file mode 100644 index 000000000..b091772a4 --- /dev/null +++ b/packages/hurl/src/http/certificate.rs @@ -0,0 +1,28 @@ +/* + * Hurl (https://hurl.dev) + * Copyright (C) 2023 Orange + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +use chrono::{DateTime, Utc}; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Certificate { + pub subject: String, + pub issuer: String, + pub start_date: DateTime, + pub expire_date: DateTime, + pub serial_number: String, +} diff --git a/packages/hurl/src/http/client.rs b/packages/hurl/src/http/client.rs index a98f13575..45b0f1b04 100644 --- a/packages/hurl/src/http/client.rs +++ b/packages/hurl/src/http/client.rs @@ -311,6 +311,7 @@ impl Client { let headers = self.parse_response_headers(&response_headers); let duration = start.elapsed(); let length = response_body.len(); + let certificate = None; self.handle.reset(); let request = Request { @@ -326,6 +327,7 @@ impl Client { body: response_body, duration, url, + certificate, }; if verbose { diff --git a/packages/hurl/src/http/mod.rs b/packages/hurl/src/http/mod.rs index df9fc1b44..6f06ce746 100644 --- a/packages/hurl/src/http/mod.rs +++ b/packages/hurl/src/http/mod.rs @@ -32,6 +32,7 @@ pub use self::response::tests::*; pub use self::response::{Response, Version}; pub use self::version::libcurl_version_info; +mod certificate; mod client; mod context_dir; mod cookie; diff --git a/packages/hurl/src/http/response.rs b/packages/hurl/src/http/response.rs index 5b217c925..7d9efe6b1 100644 --- a/packages/hurl/src/http/response.rs +++ b/packages/hurl/src/http/response.rs @@ -17,9 +17,11 @@ */ use super::{header, Header}; +use crate::http::certificate::Certificate; use core::fmt; use std::time::Duration; +/// Represents an HTTP response. #[derive(Clone, Debug, PartialEq, Eq)] pub struct Response { pub version: Version, @@ -28,6 +30,8 @@ pub struct Response { pub body: Vec, pub duration: Duration, pub url: String, + /// The end-user certificate, in the response certificate chain + pub certificate: Option, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -83,6 +87,7 @@ pub mod tests { body: String::into_bytes(String::from("Hello World!")), duration: Default::default(), url: "".to_string(), + certificate: None, } } @@ -99,6 +104,7 @@ pub mod tests { )), duration: Default::default(), url: "".to_string(), + certificate: None, } } @@ -124,6 +130,7 @@ xxx ), duration: Default::default(), url: "".to_string(), + certificate: None, } } @@ -153,6 +160,7 @@ xxx ), duration: Default::default(), url: "".to_string(), + certificate: None, } } @@ -183,6 +191,7 @@ xxx ), duration: Default::default(), url: "".to_string(), + certificate: None, } } @@ -206,6 +215,7 @@ xxx ), duration: Default::default(), url: "".to_string(), + certificate: None, } } @@ -226,6 +236,7 @@ xxx body: vec![255], duration: Default::default(), url: "".to_string(), + certificate: None, } } @@ -241,6 +252,7 @@ xxx body: vec![], duration: Default::default(), url: "".to_string(), + certificate: None, }; assert_eq!( response.get_header_values("Content-Length"), diff --git a/packages/hurl/src/http/response_decoding.rs b/packages/hurl/src/http/response_decoding.rs index d2c29ea18..b2ee89e89 100644 --- a/packages/hurl/src/http/response_decoding.rs +++ b/packages/hurl/src/http/response_decoding.rs @@ -223,6 +223,7 @@ pub mod tests { body: vec![], duration: Default::default(), url: "".to_string(), + certificate: None, }; assert_eq!(response.content_encoding().unwrap(), vec![]); @@ -236,6 +237,7 @@ pub mod tests { body: vec![], duration: Default::default(), url: "".to_string(), + certificate: None, }; assert_eq!( response.content_encoding().err().unwrap(), @@ -254,6 +256,7 @@ pub mod tests { body: vec![], duration: Default::default(), url: "".to_string(), + certificate: None, }; assert_eq!( response.content_encoding().unwrap(), @@ -273,6 +276,7 @@ pub mod tests { body: vec![], duration: Default::default(), url: "".to_string(), + certificate: None, }; assert_eq!( response.content_encoding().unwrap(), @@ -295,6 +299,7 @@ pub mod tests { ], duration: Default::default(), url: "".to_string(), + certificate: None, }; assert_eq!(response.uncompress_body().unwrap(), b"Hello World!"); @@ -311,6 +316,7 @@ pub mod tests { ], duration: Default::default(), url: "".to_string(), + certificate: None, }; assert_eq!(response.uncompress_body().unwrap(), b"Hello World!"); @@ -321,6 +327,7 @@ pub mod tests { body: b"Hello World!".to_vec(), duration: Default::default(), url: "".to_string(), + certificate: None, }; assert_eq!(response.uncompress_body().unwrap(), b"Hello World!"); } @@ -378,6 +385,7 @@ pub mod tests { body: b"Hello World!".to_vec(), duration: Default::default(), url: "".to_string(), + certificate: None, } } @@ -392,6 +400,7 @@ pub mod tests { body: vec![0x63, 0x61, 0x66, 0xc3, 0xa9], duration: Default::default(), url: "".to_string(), + certificate: None, } } @@ -406,6 +415,7 @@ pub mod tests { body: vec![0x63, 0x61, 0x66, 0xe9], duration: Default::default(), url: "".to_string(), + certificate: None, } } @@ -466,7 +476,8 @@ pub mod tests { }], body: b"Hello World!".to_vec(), duration: Default::default(), - url: "".to_string() + url: "".to_string(), + certificate: None, } .character_encoding() .err() @@ -486,7 +497,8 @@ pub mod tests { headers: vec![], body: vec![0x63, 0x61, 0x66, 0xe9], duration: Default::default(), - url: "".to_string() + url: "".to_string(), + certificate: None, } .text() .err() @@ -506,7 +518,8 @@ pub mod tests { }], body: vec![0x63, 0x61, 0x66, 0xc3, 0xa9], duration: Default::default(), - url: "".to_string() + url: "".to_string(), + certificate: None, } .text() .unwrap(), diff --git a/packages/hurl/src/runner/query.rs b/packages/hurl/src/runner/query.rs index 3b2c988c9..f7c2955ff 100644 --- a/packages/hurl/src/runner/query.rs +++ b/packages/hurl/src/runner/query.rs @@ -404,6 +404,7 @@ pub mod tests { ), duration: Default::default(), url: "".to_string(), + certificate: None, } } @@ -608,6 +609,7 @@ pub mod tests { body: vec![], duration: Default::default(), url: "".to_string(), + certificate: None, }; // cookie "LSID" @@ -839,6 +841,7 @@ pub mod tests { body: vec![200], duration: Default::default(), url: "".to_string(), + certificate: None, }; let error = eval_query(&xpath_users(), &variables, &http_response) .err() @@ -995,6 +998,7 @@ pub mod tests { body: String::into_bytes(String::from("xxx")), duration: Default::default(), url: "".to_string(), + certificate: None, }; let error = eval_query(&jsonpath_success(), &variables, &http_response) .err() @@ -1013,6 +1017,7 @@ pub mod tests { body: String::into_bytes(String::from("{}")), duration: Default::default(), url: "".to_string(), + certificate: None, }; //assert_eq!(jsonpath_success().eval(http_response).unwrap(), Value::List(vec![])); assert_eq!( @@ -1098,7 +1103,8 @@ pub mod tests { headers: vec![], body: vec![0xff], duration: Default::default(), - url: "".to_string() + url: "".to_string(), + certificate: None, } ) .unwrap()