From 49a7e1da06ba191de7bba6ff938ac57c84ea0765 Mon Sep 17 00:00:00 2001 From: Nils Ponsard Date: Mon, 29 Jan 2024 11:50:42 +0100 Subject: [PATCH] feat: ability to read spec file from an http server This commit add the detection of an url in the spec file path. If an url is passed as argument, the spec file will be downloaded and parsed. The tls verification is skipped if the --skip-tls-verification flag is passed. Signed-off-by: Nils Ponsard --- src/main.rs | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7c0c38f..e6aaa77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,13 +32,32 @@ enum Subcommands { Resend(ResendArgs), } +// Enum to allow passing URLs and local files as OpenApi spec file +#[derive(PartialEq, Debug)] +enum SpecFile { + Url(Url), + Path(PathBuf), +} + +impl FromStr for SpecFile { + type Err = ParseError; + + fn from_str(s: &str) -> Result { + if s.starts_with("http://") || s.starts_with("https://") { + Ok(SpecFile::Url(Url::from_str(s)?)) + } else { + Ok(SpecFile::Path(PathBuf::from(s))) + } + } +} + #[derive(FromArgs, Debug, PartialEq)] /// run openapi-fuzzer #[argh(subcommand, name = "run")] struct RunArgs { /// path to OpenAPI specification file #[argh(option, short = 's')] - spec: PathBuf, + spec: SpecFile, /// url of api to fuzz #[argh(option, short = 'u')] @@ -145,8 +164,23 @@ fn main() -> Result { let exit_code = match args.subcommands { Subcommands::Run(args) => { - let specfile = std::fs::read_to_string(&args.spec) - .context(format!("Unable to read {:?}", &args.spec))?; + // Read spec file from URL or local file + + let specfile = match args.spec { + SpecFile::Url(url) => { + // Skip TLS verification if requested + let spec_agent = create_agent(!args.skip_tls_verify); + spec_agent + .get(url.as_ref()) + .call() + .context(format!("Unable to fetch {:?}", url))? + .into_string()? + } + SpecFile::Path(path) => { + std::fs::read_to_string(&path).context(format!("Unable to read {:?}", path))? + } + }; + let openapi_schema: OpenAPI = serde_yaml::from_str(&specfile).context("Failed to parse schema")?; let openapi_schema = openapi_schema.deref_all();