mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-09-21 18:57:33 +03:00
Add --http1.0 option
This commit is contained in:
parent
f444ebdb11
commit
2438905850
1
integration/tests_ok/http_version.curl
Normal file
1
integration/tests_ok/http_version.curl
Normal file
@ -0,0 +1 @@
|
||||
curl --http1.0 'http://localhost:8000/http_version/10'
|
3
integration/tests_ok/http_version.html
Normal file
3
integration/tests_ok/http_version.html
Normal file
@ -0,0 +1,3 @@
|
||||
<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/http_version/10</span></span>
|
||||
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
|
||||
</span></span></code></pre>
|
2
integration/tests_ok/http_version.hurl
Normal file
2
integration/tests_ok/http_version.hurl
Normal file
@ -0,0 +1,2 @@
|
||||
GET http://localhost:8000/http_version/10
|
||||
HTTP 200
|
1
integration/tests_ok/http_version.json
Normal file
1
integration/tests_ok/http_version.json
Normal file
@ -0,0 +1 @@
|
||||
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/http_version/10"},"response":{"status":200}}]}
|
1
integration/tests_ok/http_version.out
Normal file
1
integration/tests_ok/http_version.out
Normal file
@ -0,0 +1 @@
|
||||
HTTP/1.0
|
3
integration/tests_ok/http_version.ps1
Executable file
3
integration/tests_ok/http_version.ps1
Executable file
@ -0,0 +1,3 @@
|
||||
Set-StrictMode -Version latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
hurl --http1.0 tests_ok/http_version.hurl
|
9
integration/tests_ok/http_version.py
Normal file
9
integration/tests_ok/http_version.py
Normal file
@ -0,0 +1,9 @@
|
||||
from app import app
|
||||
from flask import request
|
||||
|
||||
|
||||
@app.route("/http_version/10")
|
||||
def http_10():
|
||||
version = request.environ["SERVER_PROTOCOL"]
|
||||
assert version == "HTTP/1.0"
|
||||
return "HTTP/1.0"
|
3
integration/tests_ok/http_version.sh
Executable file
3
integration/tests_ok/http_version.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
set -Eeuo pipefail
|
||||
hurl --http1.0 tests_ok/http_version.hurl
|
@ -161,6 +161,14 @@ pub fn glob() -> clap::Arg {
|
||||
.number_of_values(1)
|
||||
}
|
||||
|
||||
pub fn http10() -> clap::Arg {
|
||||
clap::Arg::new("http10")
|
||||
.short('0')
|
||||
.long("http1.0")
|
||||
.help("Tells Hurl to use HTTP version 1.0 instead of using its internally preferred HTTP version")
|
||||
.action(ArgAction::SetTrue)
|
||||
}
|
||||
|
||||
pub fn include() -> clap::Arg {
|
||||
clap::Arg::new("include")
|
||||
.short('i')
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
use super::variables::{parse as parse_variable, parse_value};
|
||||
use super::OptionsError;
|
||||
use crate::cli::options::ErrorFormat;
|
||||
use crate::cli::options::{ErrorFormat, HttpVersion};
|
||||
use crate::cli::OutputType;
|
||||
use clap::ArgMatches;
|
||||
use hurl::runner::Value;
|
||||
@ -169,6 +169,14 @@ pub fn html_dir(arg_matches: &ArgMatches) -> Result<Option<PathBuf>, OptionsErro
|
||||
}
|
||||
}
|
||||
|
||||
pub fn http_version(arg_matches: &ArgMatches) -> Option<HttpVersion> {
|
||||
if has_flag(arg_matches, "http10") {
|
||||
Some(HttpVersion::V10)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ignore_asserts(arg_matches: &ArgMatches) -> bool {
|
||||
has_flag(arg_matches, "ignore_asserts")
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ pub struct Options {
|
||||
pub file_root: Option<String>,
|
||||
pub follow_location: bool,
|
||||
pub html_dir: Option<PathBuf>,
|
||||
pub http_version: Option<HttpVersion>,
|
||||
pub ignore_asserts: bool,
|
||||
pub include: bool,
|
||||
pub input_files: Vec<String>,
|
||||
@ -102,6 +103,19 @@ pub enum ErrorFormat {
|
||||
Long,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum HttpVersion {
|
||||
V10,
|
||||
}
|
||||
|
||||
impl From<HttpVersion> for http::HttpVersion {
|
||||
fn from(value: HttpVersion) -> Self {
|
||||
match value {
|
||||
HttpVersion::V10 => http::HttpVersion::Http10,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ErrorFormat> for hurl::util::logger::ErrorFormat {
|
||||
fn from(value: ErrorFormat) -> Self {
|
||||
match value {
|
||||
@ -144,6 +158,7 @@ pub fn parse() -> Result<Options, OptionsError> {
|
||||
.arg(commands::file_root())
|
||||
.arg(commands::follow_location())
|
||||
.arg(commands::glob())
|
||||
.arg(commands::http10())
|
||||
.arg(commands::ignore_asserts())
|
||||
.arg(commands::include())
|
||||
.arg(commands::input_files())
|
||||
@ -209,6 +224,7 @@ fn parse_matches(arg_matches: &ArgMatches) -> Result<Options, OptionsError> {
|
||||
let file_root = matches::file_root(arg_matches);
|
||||
let follow_location = matches::follow_location(arg_matches);
|
||||
let html_dir = matches::html_dir(arg_matches)?;
|
||||
let http_version = matches::http_version(arg_matches);
|
||||
let ignore_asserts = matches::ignore_asserts(arg_matches);
|
||||
let include = matches::include(arg_matches);
|
||||
let input_files = matches::input_files(arg_matches)?;
|
||||
@ -252,6 +268,7 @@ fn parse_matches(arg_matches: &ArgMatches) -> Result<Options, OptionsError> {
|
||||
file_root,
|
||||
follow_location,
|
||||
html_dir,
|
||||
http_version,
|
||||
ignore_asserts,
|
||||
include,
|
||||
input_files,
|
||||
@ -297,6 +314,7 @@ impl Options {
|
||||
let connects_to = self.connects_to.clone();
|
||||
let follow_location = self.follow_location;
|
||||
let insecure = self.insecure;
|
||||
let http_version = self.http_version.map(|v| v.into());
|
||||
let max_redirect = self.max_redirect;
|
||||
let path_as_is = self.path_as_is;
|
||||
let proxy = self.proxy.clone();
|
||||
@ -351,6 +369,7 @@ impl Options {
|
||||
.context_dir(&context_dir)
|
||||
.cookie_input_file(cookie_input_file)
|
||||
.follow_location(follow_location)
|
||||
.http_version(http_version)
|
||||
.ignore_asserts(ignore_asserts)
|
||||
.insecure(insecure)
|
||||
.max_redirect(max_redirect)
|
||||
|
@ -160,6 +160,9 @@ impl Client {
|
||||
}
|
||||
self.handle.timeout(options.timeout)?;
|
||||
self.handle.connect_timeout(options.connect_timeout)?;
|
||||
if let Some(version) = options.http_version {
|
||||
self.handle.http_version(version.into())?;
|
||||
}
|
||||
|
||||
self.set_ssl_options(options.ssl_no_revoke)?;
|
||||
|
||||
@ -783,6 +786,17 @@ fn to_list(items: &[String]) -> List {
|
||||
list
|
||||
}
|
||||
|
||||
impl From<HttpVersion> for easy::HttpVersion {
|
||||
fn from(value: HttpVersion) -> Self {
|
||||
match value {
|
||||
HttpVersion::Http10 => easy::HttpVersion::V10,
|
||||
HttpVersion::Http11 => easy::HttpVersion::V11,
|
||||
HttpVersion::Http2 => easy::HttpVersion::V2,
|
||||
HttpVersion::Http3 => easy::HttpVersion::V3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -15,6 +15,7 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
use crate::http::HttpVersion;
|
||||
use hurl_core::ast::Retry;
|
||||
use std::time::Duration;
|
||||
|
||||
@ -29,6 +30,7 @@ pub struct ClientOptions {
|
||||
pub connects_to: Vec<String>,
|
||||
pub cookie_input_file: Option<String>,
|
||||
pub follow_location: bool,
|
||||
pub http_version: Option<HttpVersion>,
|
||||
pub insecure: bool,
|
||||
pub max_redirect: Option<usize>,
|
||||
pub no_proxy: Option<String>,
|
||||
@ -43,6 +45,7 @@ pub struct ClientOptions {
|
||||
pub verbosity: Option<Verbosity>,
|
||||
}
|
||||
|
||||
// FIXME/ we could implement copy here
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Verbosity {
|
||||
Verbose,
|
||||
@ -61,6 +64,7 @@ impl Default for ClientOptions {
|
||||
connects_to: vec![],
|
||||
cookie_input_file: None,
|
||||
follow_location: false,
|
||||
http_version: None,
|
||||
insecure: false,
|
||||
max_redirect: Some(50),
|
||||
no_proxy: None,
|
||||
@ -116,6 +120,9 @@ impl ClientOptions {
|
||||
if self.insecure {
|
||||
arguments.push("--insecure".to_string());
|
||||
}
|
||||
if self.http_version == Some(HttpVersion::Http10) {
|
||||
arguments.push("--http1.0".to_string());
|
||||
}
|
||||
if self.follow_location {
|
||||
arguments.push("--location".to_string());
|
||||
}
|
||||
@ -168,15 +175,17 @@ mod tests {
|
||||
cacert_file: None,
|
||||
client_cert_file: None,
|
||||
client_key_file: None,
|
||||
compressed: true,
|
||||
connect_timeout: Duration::from_secs(20),
|
||||
connects_to: vec!["example.com:443:host-47.example.com:443".to_string()],
|
||||
follow_location: true,
|
||||
max_redirect: Some(10),
|
||||
cookie_input_file: Some("cookie_file".to_string()),
|
||||
follow_location: true,
|
||||
http_version: Some(HttpVersion::Http10),
|
||||
insecure: true,
|
||||
max_redirect: Some(10),
|
||||
path_as_is: true,
|
||||
proxy: Some("localhost:3128".to_string()),
|
||||
no_proxy: None,
|
||||
verbosity: None,
|
||||
insecure: true,
|
||||
resolves: vec![
|
||||
"foo.com:80:192.168.0.1".to_string(),
|
||||
"bar.com:443:127.0.0.1".to_string()
|
||||
@ -184,10 +193,9 @@ mod tests {
|
||||
retry: Retry::None,
|
||||
ssl_no_revoke: false,
|
||||
timeout: Duration::from_secs(10),
|
||||
connect_timeout: Duration::from_secs(20),
|
||||
user: Some("user:password".to_string()),
|
||||
user_agent: Some("my-useragent".to_string()),
|
||||
compressed: true,
|
||||
verbosity: None,
|
||||
}
|
||||
.curl_args(),
|
||||
[
|
||||
@ -199,6 +207,7 @@ mod tests {
|
||||
"--cookie".to_string(),
|
||||
"cookie_file".to_string(),
|
||||
"--insecure".to_string(),
|
||||
"--http1.0".to_string(),
|
||||
"--location".to_string(),
|
||||
"--max-redirs".to_string(),
|
||||
"10".to_string(),
|
||||
|
@ -94,15 +94,16 @@ fn main() {
|
||||
.verbosity(verbosity)
|
||||
.build();
|
||||
let logger = Logger::from(&logger_options);
|
||||
|
||||
let total = opts.input_files.len();
|
||||
logger.test_running(current + 1, total);
|
||||
|
||||
// Run our Hurl file now
|
||||
let hurl_result = execute(&content, filename, current_dir, &opts);
|
||||
let hurl_result = match hurl_result {
|
||||
Ok(h) => h,
|
||||
Err(_) => process::exit(EXIT_ERROR_PARSING),
|
||||
};
|
||||
|
||||
logger.test_completed(&hurl_result);
|
||||
let success = hurl_result.success;
|
||||
|
||||
|
@ -223,27 +223,28 @@ impl ClientOptions {
|
||||
cacert_file: runner_options.cacert_file.clone(),
|
||||
client_cert_file: runner_options.client_cert_file.clone(),
|
||||
client_key_file: runner_options.client_key_file.clone(),
|
||||
compressed: runner_options.compressed,
|
||||
connect_timeout: runner_options.connect_timeout,
|
||||
connects_to: runner_options.connects_to.clone(),
|
||||
follow_location: runner_options.follow_location,
|
||||
max_redirect: runner_options.max_redirect,
|
||||
cookie_input_file: runner_options.cookie_input_file.clone(),
|
||||
follow_location: runner_options.follow_location,
|
||||
http_version: runner_options.http_version,
|
||||
max_redirect: runner_options.max_redirect,
|
||||
path_as_is: runner_options.path_as_is,
|
||||
proxy: runner_options.proxy.clone(),
|
||||
no_proxy: runner_options.no_proxy.clone(),
|
||||
verbosity: match verbosity {
|
||||
Some(Verbosity::Verbose) => Some(http::Verbosity::Verbose),
|
||||
Some(Verbosity::VeryVerbose) => Some(http::Verbosity::VeryVerbose),
|
||||
_ => None,
|
||||
},
|
||||
insecure: runner_options.insecure,
|
||||
resolves: runner_options.resolves.clone(),
|
||||
retry: runner_options.retry,
|
||||
ssl_no_revoke: runner_options.ssl_no_revoke,
|
||||
timeout: runner_options.timeout,
|
||||
connect_timeout: runner_options.connect_timeout,
|
||||
user: runner_options.user.clone(),
|
||||
user_agent: runner_options.user_agent.clone(),
|
||||
compressed: runner_options.compressed,
|
||||
verbosity: match verbosity {
|
||||
Some(Verbosity::Verbose) => Some(http::Verbosity::Verbose),
|
||||
Some(Verbosity::VeryVerbose) => Some(http::Verbosity::VeryVerbose),
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::http::HttpVersion;
|
||||
use hurl_core::ast::{Entry, Retry};
|
||||
|
||||
use crate::util::path::ContextDir;
|
||||
@ -34,6 +35,7 @@ pub struct RunnerOptionsBuilder {
|
||||
continue_on_error: bool,
|
||||
cookie_input_file: Option<String>,
|
||||
follow_location: bool,
|
||||
http_version: Option<HttpVersion>,
|
||||
ignore_asserts: bool,
|
||||
insecure: bool,
|
||||
max_redirect: Option<usize>,
|
||||
@ -67,6 +69,7 @@ impl Default for RunnerOptionsBuilder {
|
||||
continue_on_error: false,
|
||||
cookie_input_file: None,
|
||||
follow_location: false,
|
||||
http_version: None,
|
||||
ignore_asserts: false,
|
||||
insecure: false,
|
||||
max_redirect: Some(50),
|
||||
@ -190,6 +193,11 @@ impl RunnerOptionsBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn http_version(&mut self, version: Option<HttpVersion>) -> &mut Self {
|
||||
self.http_version = version;
|
||||
self
|
||||
}
|
||||
|
||||
/// Ignores all asserts defined in the Hurl file.
|
||||
pub fn ignore_asserts(&mut self, ignore_asserts: bool) -> &mut Self {
|
||||
self.ignore_asserts = ignore_asserts;
|
||||
@ -312,6 +320,7 @@ impl RunnerOptionsBuilder {
|
||||
continue_on_error: self.continue_on_error,
|
||||
cookie_input_file: self.cookie_input_file.clone(),
|
||||
follow_location: self.follow_location,
|
||||
http_version: self.http_version,
|
||||
ignore_asserts: self.ignore_asserts,
|
||||
insecure: self.insecure,
|
||||
max_redirect: self.max_redirect,
|
||||
@ -346,6 +355,7 @@ pub struct RunnerOptions {
|
||||
pub(crate) continue_on_error: bool,
|
||||
pub(crate) cookie_input_file: Option<String>,
|
||||
pub(crate) follow_location: bool,
|
||||
pub(crate) http_version: Option<HttpVersion>,
|
||||
pub(crate) ignore_asserts: bool,
|
||||
pub(crate) insecure: bool,
|
||||
pub(crate) max_redirect: Option<usize>,
|
||||
|
Loading…
Reference in New Issue
Block a user