From 4f6a00170a07104d5682375bfe0a48e8051673f6 Mon Sep 17 00:00:00 2001 From: jcamiel Date: Thu, 6 Jul 2023 13:04:17 +0200 Subject: [PATCH] Fix URL runtime evaluation. --- integration/tests_failed/invalid_url_1.err | 7 ++++++ integration/tests_failed/invalid_url_1.exit | 2 ++ integration/tests_failed/invalid_url_1.html | 5 +++++ integration/tests_failed/invalid_url_1.hurl | 4 ++++ integration/tests_failed/invalid_url_1.json | 1 + integration/tests_failed/invalid_url_1.ps1 | 3 +++ integration/tests_failed/invalid_url_1.sh | 3 +++ packages/hurl/src/http/error.rs | 1 + packages/hurl/src/http/request.rs | 24 +++++++++++---------- packages/hurl/src/runner/core.rs | 1 + packages/hurl/src/runner/error.rs | 5 +++++ 11 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 integration/tests_failed/invalid_url_1.err create mode 100644 integration/tests_failed/invalid_url_1.exit create mode 100644 integration/tests_failed/invalid_url_1.html create mode 100644 integration/tests_failed/invalid_url_1.hurl create mode 100644 integration/tests_failed/invalid_url_1.json create mode 100644 integration/tests_failed/invalid_url_1.ps1 create mode 100755 integration/tests_failed/invalid_url_1.sh diff --git a/integration/tests_failed/invalid_url_1.err b/integration/tests_failed/invalid_url_1.err new file mode 100644 index 000000000..0165e1cf0 --- /dev/null +++ b/integration/tests_failed/invalid_url_1.err @@ -0,0 +1,7 @@ +error: Invalid URL + --> tests_failed/invalid_url_1.hurl:3:5 + | + 3 | GET {{host}} + | ^^^^^^^^ URL must start with http:// or https:// + | + diff --git a/integration/tests_failed/invalid_url_1.exit b/integration/tests_failed/invalid_url_1.exit new file mode 100644 index 000000000..8148ef7a0 --- /dev/null +++ b/integration/tests_failed/invalid_url_1.exit @@ -0,0 +1,2 @@ +3 + diff --git a/integration/tests_failed/invalid_url_1.html b/integration/tests_failed/invalid_url_1.html new file mode 100644 index 000000000..87f1d05ca --- /dev/null +++ b/integration/tests_failed/invalid_url_1.html @@ -0,0 +1,5 @@ +
# We test that an URL should be valid (starts with http:// or https://)
+# even if injected through variable.
+GET {{host}}
+
+
diff --git a/integration/tests_failed/invalid_url_1.hurl b/integration/tests_failed/invalid_url_1.hurl new file mode 100644 index 000000000..dd5d9bcac --- /dev/null +++ b/integration/tests_failed/invalid_url_1.hurl @@ -0,0 +1,4 @@ +# We test that an URL should be valid (starts with http:// or https://) +# even if injected through variable. +GET {{host}} + diff --git a/integration/tests_failed/invalid_url_1.json b/integration/tests_failed/invalid_url_1.json new file mode 100644 index 000000000..572ba03b0 --- /dev/null +++ b/integration/tests_failed/invalid_url_1.json @@ -0,0 +1 @@ +{"entries":[{"request":{"method":"GET","url":"{{host}}"}}]} diff --git a/integration/tests_failed/invalid_url_1.ps1 b/integration/tests_failed/invalid_url_1.ps1 new file mode 100644 index 000000000..5759eacc7 --- /dev/null +++ b/integration/tests_failed/invalid_url_1.ps1 @@ -0,0 +1,3 @@ +Set-StrictMode -Version latest +$ErrorActionPreference = 'Stop' +hurl --variable host=localhost:8000 tests_failed/invalid_url_1.hurl diff --git a/integration/tests_failed/invalid_url_1.sh b/integration/tests_failed/invalid_url_1.sh new file mode 100755 index 000000000..086ab98f6 --- /dev/null +++ b/integration/tests_failed/invalid_url_1.sh @@ -0,0 +1,3 @@ +#!/bin/bash +set -Eeuo pipefail +hurl --variable host=localhost:8000 tests_failed/invalid_url_1.hurl diff --git a/packages/hurl/src/http/error.rs b/packages/hurl/src/http/error.rs index 4f321dac0..2b687653b 100644 --- a/packages/hurl/src/http/error.rs +++ b/packages/hurl/src/http/error.rs @@ -41,6 +41,7 @@ pub enum HttpError { description: String, }, InvalidUrl(String), + InvalidUrlPrefix(String), } impl From for HttpError { diff --git a/packages/hurl/src/http/request.rs b/packages/hurl/src/http/request.rs index 7737fe8dc..a689d9121 100644 --- a/packages/hurl/src/http/request.rs +++ b/packages/hurl/src/http/request.rs @@ -68,17 +68,19 @@ impl Request { Ok(url) => url, Err(_) => return Err(HttpError::InvalidUrl(self.url.clone())), }; - let base_url = format!( - "{}://{}{}", - url.scheme(), - url.host().unwrap(), - if let Some(port) = url.port() { - format!(":{port}") - } else { - "".to_string() - } - ); - Ok(base_url) + let scheme = url.scheme(); + if scheme != "http" && scheme != "https" { + return Err(HttpError::InvalidUrlPrefix(self.url.clone())); + } + let host = match url.host() { + Some(host) => host, + None => return Err(HttpError::InvalidUrl(self.url.clone())), + }; + let port = match url.port() { + Some(port) => format!(":{port}"), + None => "".to_string(), + }; + Ok(format!("{scheme}://{host}{port}")) } } diff --git a/packages/hurl/src/runner/core.rs b/packages/hurl/src/runner/core.rs index 861cda710..035e7e527 100644 --- a/packages/hurl/src/runner/core.rs +++ b/packages/hurl/src/runner/core.rs @@ -119,6 +119,7 @@ pub enum RunnerError { value: String, }, InvalidUrl(String), + InvalidUrlPrefix(String), HttpConnection { url: String, diff --git a/packages/hurl/src/runner/error.rs b/packages/hurl/src/runner/error.rs index ed35e33c4..4cd3c0d6b 100644 --- a/packages/hurl/src/runner/error.rs +++ b/packages/hurl/src/runner/error.rs @@ -31,6 +31,7 @@ impl Error for runner::Error { fn description(&self) -> String { match &self.inner { RunnerError::InvalidUrl(..) => "Invalid URL".to_string(), + RunnerError::InvalidUrlPrefix(..) => "Invalid URL".to_string(), RunnerError::TemplateVariableNotDefined { .. } => "Undefined variable".to_string(), RunnerError::VariableNotDefined { .. } => "Undefined variable".to_string(), RunnerError::HttpConnection { .. } => "HTTP connection".to_string(), @@ -75,6 +76,9 @@ impl Error for runner::Error { fn fixme(&self) -> String { match &self.inner { RunnerError::InvalidUrl(url) => format!("invalid URL <{url}>"), + RunnerError::InvalidUrlPrefix(url) => { + format!("URL <{url}> must start with http:// or https://") + } RunnerError::TemplateVariableNotDefined { name } => { format!("you must set the variable {name}") } @@ -203,6 +207,7 @@ impl From for RunnerError { RunnerError::UnsupportedContentEncoding(description) } HttpError::InvalidUrl(url) => RunnerError::InvalidUrl(url), + HttpError::InvalidUrlPrefix(url) => RunnerError::InvalidUrlPrefix(url), } } }