diff --git a/README.md b/README.md
index ad786849e..a2b8b811e 100644
--- a/README.md
+++ b/README.md
@@ -976,6 +976,7 @@ will follow a redirection only for the second entry.
| --key <KEY>
| Private key file name.
|
| -L, --location
| Follow redirect. To limit the amount of redirects to follow use the [`--max-redirs`](#max-redirs) option
|
| --location-trusted
| Like [`-L, --location`](#location), but allows sending the name + password to all hosts that the site may redirect to.
This may or may not introduce a security breach if the site redirects you to a site to which you send your authentication info (which is plaintext in the case of HTTP Basic authentication).
|
+| --max-filesize <BYTES>
| Specify the maximum size (in bytes) of a file to download. If the file requested is larger than this value, the transfer does not start.
|
| --max-redirs <NUM>
| Set maximum number of redirection-followings allowed
By default, the limit is set to 50 redirections. Set this option to -1 to make it unlimited.
|
| -m, --max-time <SECONDS>
| Maximum time in seconds that you allow a request/response to take. This is the standard timeout.
See also [`--connect-timeout`](#connect-timeout).
This is a cli-only option.
|
| -n, --netrc
| Scan the .netrc file in the user's home directory for the username and password.
See also [`--netrc-file`](#netrc-file) and [`--netrc-optional`](#netrc-optional).
|
diff --git a/completions/_hurl b/completions/_hurl
index e8b9d7d7b..acc088743 100644
--- a/completions/_hurl
+++ b/completions/_hurl
@@ -46,6 +46,7 @@ _hurl() {
'(-6 --ipv6)'{-6,--ipv6}'[Tell Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4]' \
'--jobs[(Experimental) Maximum number of parallel jobs]: :' \
'--json[Output each Hurl file result to JSON]' \
+ '--max-filesize[Specify the maximum size (in bytes) of a file to download]: :' \
'--max-redirs[Maximum number of redirects allowed, -1 for unlimited redirects]: :' \
'(-m --max-time)'{-m,--max-time}'[Maximum time allowed for the transfer]: :' \
'(-n --netrc)'{-n,--netrc}'[Must read .netrc for username and password]' \
diff --git a/completions/_hurl.ps1 b/completions/_hurl.ps1
index a24d2cca9..c85617be9 100644
--- a/completions/_hurl.ps1
+++ b/completions/_hurl.ps1
@@ -51,6 +51,7 @@ Register-ArgumentCompleter -Native -CommandName 'hurl' -ScriptBlock {
[CompletionResult]::new('--ipv6', 'ipv6', [CompletionResultType]::ParameterName, 'Tell Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4')
[CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, '(Experimental) Maximum number of parallel jobs')
[CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'Output each Hurl file result to JSON')
+ [CompletionResult]::new('--max-filesize', 'max-filesize', [CompletionResultType]::ParameterName, 'Specify the maximum size (in bytes) of a file to download')
[CompletionResult]::new('--max-redirs', 'max-redirs', [CompletionResultType]::ParameterName, 'Maximum number of redirects allowed, -1 for unlimited redirects')
[CompletionResult]::new('--max-time', 'max-time', [CompletionResultType]::ParameterName, 'Maximum time allowed for the transfer')
[CompletionResult]::new('--netrc', 'netrc', [CompletionResultType]::ParameterName, 'Must read .netrc for username and password')
diff --git a/completions/hurl.bash b/completions/hurl.bash
index 7fb1dd12d..36f705302 100644
--- a/completions/hurl.bash
+++ b/completions/hurl.bash
@@ -5,7 +5,7 @@ _hurl()
_init_completion || return
if [[ $cur == -* ]]; then
- COMPREPLY=($(compgen -W '--aws-sigv4 --cacert --cert --key --color --compressed --connect-timeout --connect-to --continue-on-error --cookie --cookie-jar --delay --error-format --fail-at-end --file-root --location --location-trusted --from-entry --glob --http1.0 --http1.1 --http2 --http3 --ignore-asserts --include --insecure --interactive --ipv4 --ipv6 --jobs --json --max-redirs --max-time --netrc --netrc-file --netrc-optional --no-color --no-output --noproxy --output --parallel --path-as-is --proxy --report-html --report-junit --report-tap --resolve --retry --retry-interval --ssl-no-revoke --test --to-entry --unix-socket --user --user-agent --variable --variables-file --verbose --very-verbose --help --version' -- "$cur"))
+ COMPREPLY=($(compgen -W '--aws-sigv4 --cacert --cert --key --color --compressed --connect-timeout --connect-to --continue-on-error --cookie --cookie-jar --delay --error-format --fail-at-end --file-root --location --location-trusted --from-entry --glob --http1.0 --http1.1 --http2 --http3 --ignore-asserts --include --insecure --interactive --ipv4 --ipv6 --jobs --json --max-filesize --max-redirs --max-time --netrc --netrc-file --netrc-optional --no-color --no-output --noproxy --output --parallel --path-as-is --proxy --report-html --report-junit --report-tap --resolve --retry --retry-interval --ssl-no-revoke --test --to-entry --unix-socket --user --user-agent --variable --variables-file --verbose --very-verbose --help --version' -- "$cur"))
return
fi
diff --git a/completions/hurl.fish b/completions/hurl.fish
index 0111fe5ec..2657e3e61 100644
--- a/completions/hurl.fish
+++ b/completions/hurl.fish
@@ -29,6 +29,7 @@ complete -c hurl -l ipv4 -d 'Tell Hurl to use IPv4 addresses only when resolving
complete -c hurl -l ipv6 -d 'Tell Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4'
complete -c hurl -l jobs -d '(Experimental) Maximum number of parallel jobs'
complete -c hurl -l json -d 'Output each Hurl file result to JSON'
+complete -c hurl -l max-filesize -d 'Specify the maximum size (in bytes) of a file to download'
complete -c hurl -l max-redirs -d 'Maximum number of redirects allowed, -1 for unlimited redirects'
complete -c hurl -l max-time -d 'Maximum time allowed for the transfer'
complete -c hurl -l netrc -d 'Must read .netrc for username and password'
diff --git a/docs/manual.md b/docs/manual.md
index def49f0d2..fbbbdfb24 100644
--- a/docs/manual.md
+++ b/docs/manual.md
@@ -177,6 +177,7 @@ will follow a redirection only for the second entry.
| --key <KEY>
| Private key file name.
|
| -L, --location
| Follow redirect. To limit the amount of redirects to follow use the [`--max-redirs`](#max-redirs) option
|
| --location-trusted
| Like [`-L, --location`](#location), but allows sending the name + password to all hosts that the site may redirect to.
This may or may not introduce a security breach if the site redirects you to a site to which you send your authentication info (which is plaintext in the case of HTTP Basic authentication).
|
+| --max-filesize <BYTES>
| Specify the maximum size (in bytes) of a file to download. If the file requested is larger than this value, the transfer does not start.
|
| --max-redirs <NUM>
| Set maximum number of redirection-followings allowed
By default, the limit is set to 50 redirections. Set this option to -1 to make it unlimited.
|
| -m, --max-time <SECONDS>
| Maximum time in seconds that you allow a request/response to take. This is the standard timeout.
See also [`--connect-timeout`](#connect-timeout).
This is a cli-only option.
|
| -n, --netrc
| Scan the .netrc file in the user's home directory for the username and password.
See also [`--netrc-file`](#netrc-file) and [`--netrc-optional`](#netrc-optional).
|
diff --git a/docs/manual/hurl.1 b/docs/manual/hurl.1
index 199e1d7a8..99a6a3815 100644
--- a/docs/manual/hurl.1
+++ b/docs/manual/hurl.1
@@ -1,4 +1,4 @@
-.TH hurl 1 "26 Mar 2024" "hurl 4.3.0-SNAPSHOT" " Hurl Manual"
+.TH hurl 1 "01 Apr 2024" "hurl 4.3.0-SNAPSHOT" " Hurl Manual"
.SH NAME
hurl - run and test HTTP requests.
@@ -295,6 +295,10 @@ Follow redirect. To limit the amount of redirects to follow use the \fI--max-red
Like \fI-L, --location\fP, but allows sending the name + password to all hosts that the site may redirect to.
This may or may not introduce a security breach if the site redirects you to a site to which you send your authentication info (which is plaintext in the case of HTTP Basic authentication).
+.IP "--max-filesize "
+
+Specify the maximum size (in bytes) of a file to download. If the file requested is larger than this value, the transfer does not start.
+
.IP "--max-redirs "
Set maximum number of redirection-followings allowed
diff --git a/docs/manual/hurl.md b/docs/manual/hurl.md
index 590b6ac9d..8d7b924f2 100644
--- a/docs/manual/hurl.md
+++ b/docs/manual/hurl.md
@@ -314,6 +314,10 @@ Follow redirect. To limit the amount of redirects to follow use the [`--max-redi
Like [`-L, --location`](#location), but allows sending the name + password to all hosts that the site may redirect to.
This may or may not introduce a security breach if the site redirects you to a site to which you send your authentication info (which is plaintext in the case of HTTP Basic authentication).
+### --max-filesize {#max-filesize}
+
+Specify the maximum size (in bytes) of a file to download. If the file requested is larger than this value, the transfer does not start.
+
### --max-redirs {#max-redirs}
Set maximum number of redirection-followings allowed
diff --git a/docs/manual/hurlfmt.1 b/docs/manual/hurlfmt.1
index 3c2f664ed..e9f528efb 100644
--- a/docs/manual/hurlfmt.1
+++ b/docs/manual/hurlfmt.1
@@ -1,4 +1,4 @@
-.TH hurl 1 "26 Mar 2024" "hurl 4.3.0-SNAPSHOT" " Hurl Manual"
+.TH hurl 1 "01 Apr 2024" "hurl 4.3.0-SNAPSHOT" " Hurl Manual"
.SH NAME
hurlfmt - format Hurl files
diff --git a/docs/spec/options/hurl/max_filesize.option b/docs/spec/options/hurl/max_filesize.option
new file mode 100644
index 000000000..52ddf7da3
--- /dev/null
+++ b/docs/spec/options/hurl/max_filesize.option
@@ -0,0 +1,7 @@
+name: max_filesize
+long: max-filesize
+value: BYTES
+value_parser: clap::value_parser!(u64)
+help: Specify the maximum size (in bytes) of a file to download
+---
+Specify the maximum size (in bytes) of a file to download. If the file requested is larger than this value, the transfer does not start.
diff --git a/integration/hurl/tests_ok/help.out.pattern b/integration/hurl/tests_ok/help.out.pattern
index 2beaa4842..d6f102886 100644
--- a/integration/hurl/tests_ok/help.out.pattern
+++ b/integration/hurl/tests_ok/help.out.pattern
@@ -67,6 +67,8 @@ Options:
IPv4
--json
Output each Hurl file result to JSON
+ --max-filesize
+ Specify the maximum size (in bytes) of a file to download
--max-redirs
Maximum number of redirects allowed, -1 for unlimited redirects [default: 50]
-m, --max-time
diff --git a/packages/hurl/README.md b/packages/hurl/README.md
index e8f9eb9ca..4b9d5d892 100644
--- a/packages/hurl/README.md
+++ b/packages/hurl/README.md
@@ -968,6 +968,7 @@ will follow a redirection only for the second entry.
| --key <KEY>
| Private key file name.
|
| -L, --location
| Follow redirect. To limit the amount of redirects to follow use the [`--max-redirs`](#max-redirs) option
|
| --location-trusted
| Like [`-L, --location`](#location), but allows sending the name + password to all hosts that the site may redirect to.
This may or may not introduce a security breach if the site redirects you to a site to which you send your authentication info (which is plaintext in the case of HTTP Basic authentication).
|
+| --max-filesize <BYTES>
| Specify the maximum size (in bytes) of a file to download. If the file requested is larger than this value, the transfer does not start.
|
| --max-redirs <NUM>
| Set maximum number of redirection-followings allowed
By default, the limit is set to 50 redirections. Set this option to -1 to make it unlimited.
|
| -m, --max-time <SECONDS>
| Maximum time in seconds that you allow a request/response to take. This is the standard timeout.
See also [`--connect-timeout`](#connect-timeout).
This is a cli-only option.
|
| -n, --netrc
| Scan the .netrc file in the user's home directory for the username and password.
See also [`--netrc-file`](#netrc-file) and [`--netrc-optional`](#netrc-optional).
|
diff --git a/packages/hurl/src/cli/options/commands.rs b/packages/hurl/src/cli/options/commands.rs
index b2cc0700d..fcc6c0df8 100644
--- a/packages/hurl/src/cli/options/commands.rs
+++ b/packages/hurl/src/cli/options/commands.rs
@@ -282,6 +282,15 @@ pub fn json() -> clap::Arg {
.action(clap::ArgAction::SetTrue)
}
+pub fn max_filesize() -> clap::Arg {
+ clap::Arg::new("max_filesize")
+ .long("max-filesize")
+ .value_name("BYTES")
+ .value_parser(clap::value_parser!(u64))
+ .help("Specify the maximum size (in bytes) of a file to download")
+ .num_args(1)
+}
+
pub fn max_redirects() -> clap::Arg {
clap::Arg::new("max_redirects")
.long("max-redirs")
diff --git a/packages/hurl/src/cli/options/matches.rs b/packages/hurl/src/cli/options/matches.rs
index e2855cce9..e45a2d5ef 100644
--- a/packages/hurl/src/cli/options/matches.rs
+++ b/packages/hurl/src/cli/options/matches.rs
@@ -423,6 +423,10 @@ pub fn very_verbose(arg_matches: &ArgMatches) -> bool {
has_flag(arg_matches, "very_verbose")
}
+pub fn max_filesize(arg_matches: &ArgMatches) -> Option {
+ get::(arg_matches, "max_filesize")
+}
+
/// Returns a list of path names from the command line options `matches`.
fn glob_files(matches: &ArgMatches) -> Result, CliOptionsError> {
let mut all_files = vec![];
diff --git a/packages/hurl/src/cli/options/mod.rs b/packages/hurl/src/cli/options/mod.rs
index 1e46a7b19..f966c6de4 100644
--- a/packages/hurl/src/cli/options/mod.rs
+++ b/packages/hurl/src/cli/options/mod.rs
@@ -67,6 +67,7 @@ pub struct CliOptions {
pub ip_resolve: Option,
pub jobs: Option,
pub junit_file: Option,
+ pub max_filesize: Option,
pub max_redirect: Option,
pub netrc: bool,
pub netrc_file: Option,
@@ -191,6 +192,7 @@ pub fn parse() -> Result {
.arg(commands::ipv6())
.arg(commands::jobs())
.arg(commands::json())
+ .arg(commands::max_filesize())
.arg(commands::max_redirects())
.arg(commands::max_time())
.arg(commands::netrc())
@@ -264,6 +266,7 @@ fn parse_matches(arg_matches: &ArgMatches) -> Result Result Result Result ip.into(),
None => http::IpResolve::default(),
};
+ let max_filesize = self.max_filesize;
let max_redirect = self.max_redirect;
let netrc = self.netrc;
let netrc_file = self.netrc_file.clone();
@@ -466,6 +471,7 @@ impl CliOptions {
.ignore_asserts(ignore_asserts)
.insecure(insecure)
.ip_resolve(ip_resolve)
+ .max_filesize(max_filesize)
.max_redirect(max_redirect)
.netrc(netrc)
.netrc_file(netrc_file)
diff --git a/packages/hurl/src/http/client.rs b/packages/hurl/src/http/client.rs
index 93887083c..4c685f784 100644
--- a/packages/hurl/src/http/client.rs
+++ b/packages/hurl/src/http/client.rs
@@ -439,6 +439,9 @@ impl Client {
}
self.handle.timeout(options.timeout)?;
self.handle.connect_timeout(options.connect_timeout)?;
+ if let Some(max_filesize) = options.max_filesize {
+ self.handle.max_filesize(max_filesize)?;
+ }
self.set_ssl_options(options.ssl_no_revoke)?;
diff --git a/packages/hurl/src/http/options.rs b/packages/hurl/src/http/options.rs
index f57567a49..acb6b9f65 100644
--- a/packages/hurl/src/http/options.rs
+++ b/packages/hurl/src/http/options.rs
@@ -37,6 +37,7 @@ pub struct ClientOptions {
pub http_version: RequestedHttpVersion,
pub insecure: bool,
pub ip_resolve: IpResolve,
+ pub max_filesize: Option,
pub max_redirect: Option,
pub netrc: bool,
pub netrc_file: Option,
@@ -77,6 +78,7 @@ impl Default for ClientOptions {
http_version: RequestedHttpVersion::default(),
insecure: false,
ip_resolve: IpResolve::default(),
+ max_filesize: None,
max_redirect: Some(50),
netrc: false,
netrc_file: None,
@@ -152,6 +154,10 @@ impl ClientOptions {
} else if self.follow_location {
arguments.push("--location".to_string());
}
+ if let Some(max_filesize) = self.max_filesize {
+ arguments.push("--max-filesize".to_string());
+ arguments.push(max_filesize.to_string());
+ }
if self.max_redirect != ClientOptions::default().max_redirect {
let max_redirect = match self.max_redirect {
None => -1,
@@ -224,6 +230,7 @@ mod tests {
http_version: RequestedHttpVersion::Http10,
insecure: true,
ip_resolve: IpResolve::IpV6,
+ max_filesize: None,
max_redirect: Some(10),
netrc: false,
netrc_file: Some("/var/run/netrc".to_string()),
@@ -233,7 +240,7 @@ mod tests {
no_proxy: None,
resolves: vec![
"foo.com:80:192.168.0.1".to_string(),
- "bar.com:443:127.0.0.1".to_string()
+ "bar.com:443:127.0.0.1".to_string(),
],
retry: Retry::None,
ssl_no_revoke: false,
diff --git a/packages/hurl/src/runner/entry.rs b/packages/hurl/src/runner/entry.rs
index 97e77dfd8..2f656e72e 100644
--- a/packages/hurl/src/runner/entry.rs
+++ b/packages/hurl/src/runner/entry.rs
@@ -211,6 +211,7 @@ impl ClientOptions {
follow_location_trusted: runner_options.follow_location_trusted,
http_version: runner_options.http_version,
ip_resolve: runner_options.ip_resolve,
+ max_filesize: runner_options.max_filesize,
max_redirect: runner_options.max_redirect,
netrc: runner_options.netrc,
netrc_file: runner_options.netrc_file.clone(),
diff --git a/packages/hurl/src/runner/runner_options.rs b/packages/hurl/src/runner/runner_options.rs
index 25ef50fbc..2ff78cdc8 100644
--- a/packages/hurl/src/runner/runner_options.rs
+++ b/packages/hurl/src/runner/runner_options.rs
@@ -42,6 +42,7 @@ pub struct RunnerOptionsBuilder {
ignore_asserts: bool,
insecure: bool,
ip_resolve: IpResolve,
+ max_filesize: Option,
max_redirect: Option,
netrc: bool,
netrc_file: Option,
@@ -85,6 +86,7 @@ impl Default for RunnerOptionsBuilder {
ignore_asserts: false,
insecure: false,
ip_resolve: IpResolve::default(),
+ max_filesize: None,
max_redirect: Some(50),
netrc: false,
netrc_file: None,
@@ -375,6 +377,12 @@ impl RunnerOptionsBuilder {
self
}
+ /// Set the file size limit
+ pub fn max_filesize(&mut self, max_filesize: Option) -> &mut Self {
+ self.max_filesize = max_filesize;
+ self
+ }
+
/// Create an instance of [`RunnerOptions`].
pub fn build(&self) -> RunnerOptions {
RunnerOptions {
@@ -396,6 +404,7 @@ impl RunnerOptionsBuilder {
ignore_asserts: self.ignore_asserts,
insecure: self.insecure,
ip_resolve: self.ip_resolve,
+ max_filesize: self.max_filesize,
max_redirect: self.max_redirect,
netrc: self.netrc,
netrc_file: self.netrc_file.clone(),
@@ -440,6 +449,7 @@ pub struct RunnerOptions {
pub(crate) ignore_asserts: bool,
pub(crate) ip_resolve: IpResolve,
pub(crate) insecure: bool,
+ pub(crate) max_filesize: Option,
pub(crate) max_redirect: Option,
pub(crate) netrc: bool,
pub(crate) netrc_file: Option,