Skip to content

Commit

Permalink
Merge pull request #488 from amazonlinux/tough-generic-transport
Browse files Browse the repository at this point in the history
tough: Genericize file transport
  • Loading branch information
iliana authored Nov 8, 2019
2 parents 3e37000 + 558487e commit cb17aef
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 147 deletions.
14 changes: 2 additions & 12 deletions workspaces/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion workspaces/tuftool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ tough_schema = { path = "../updater/tough_schema" }
url = "2.1.0"
walkdir = "2.2.9"
tempdir = "0.3.7"
tough = { path = "../updater/tough" }
tough = { path = "../updater/tough", features = ["http"] }
22 changes: 13 additions & 9 deletions workspaces/tuftool/src/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::num::NonZeroU64;
use std::path::{Path, PathBuf};
use structopt::StructOpt;
use tempdir::TempDir;
use tough::{Limits, Repository, Settings};
use tough::{HttpTransport, Limits, Repository, Settings};
use url::Url;

#[derive(Debug, StructOpt)]
Expand Down Expand Up @@ -86,16 +86,20 @@ impl DownloadArgs {
};

// load repository
let transport = HttpTransport::new();
let repo_dir = TempDir::new("tuf").context(error::TempDir)?;
let repository = Repository::load(Settings {
root: File::open(&root_path).context(error::OpenRoot { path: &root_path })?,
datastore: repo_dir.path(),
metadata_base_url: &self.metadata_base_url,
target_base_url: &self.target_base_url,
limits: Limits {
..tough::Limits::default()
let repository = Repository::load(
&transport,
Settings {
root: File::open(&root_path).context(error::OpenRoot { path: &root_path })?,
datastore: repo_dir.path(),
metadata_base_url: &self.metadata_base_url,
target_base_url: &self.target_base_url,
limits: Limits {
..tough::Limits::default()
},
},
})
)
.context(error::Metadata)?;

// copy all available targets
Expand Down
8 changes: 3 additions & 5 deletions workspaces/updater/tough/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,17 @@ publish = false
[dependencies]
chrono = { version = "0.4.6", features = ["serde"] }
hex = "0.4.0"
reqwest = { version = "0.9.17", default-features = false }
reqwest = { version = "0.9.17", optional = true, default-features = false }
serde = "1.0.92"
serde_json = "1.0.39"
sha2 = "0.8.0"
snafu = "0.5.0"
tough_schema = { path = "../tough_schema" }
url = "2.1.0"

[dev-dependencies]
hex-literal = "0.2.0"
tempfile = "3.1.0"

[features]
default = ["rustls-tls"]
default-tls = ["reqwest/default-tls"]
default-tls-vendored = ["reqwest/default-tls-vendored"]
rustls-tls = ["reqwest/rustls-tls"]
http = ["reqwest"]
38 changes: 11 additions & 27 deletions workspaces/updater/tough/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,6 @@ pub enum Error {
backtrace: Backtrace,
},

/// A file from a `file:///` URL could not be opened.
#[snafu(display("Failed to read {}: {}", path.display(), source))]
FileRead {
path: PathBuf,
source: std::io::Error,
backtrace: Backtrace,
},

/// A downloaded target's checksum does not match the checksum listed in the repository
/// metadata.
#[snafu(display(
Expand All @@ -72,8 +64,8 @@ pub enum Error {
#[snafu(display("Failed to join \"{}\" to URL \"{}\": {}", path, url, source))]
JoinUrl {
path: String,
url: reqwest::Url,
source: reqwest::UrlError,
url: url::Url,
source: url::ParseError,
backtrace: Backtrace,
},

Expand Down Expand Up @@ -152,23 +144,7 @@ pub enum Error {
#[snafu(display("Failed to parse URL {:?}: {}", url, source))]
ParseUrl {
url: String,
source: reqwest::UrlError,
backtrace: Backtrace,
},

/// An HTTP request failed.
#[snafu(display("Failed to request \"{}\": {}", url, source))]
Request {
url: reqwest::Url,
source: reqwest::Error,
backtrace: Backtrace,
},

/// A response to an HTTP request was in the 4xx or 5xx range.
#[snafu(display("Status {} {} in response for \"{}\"", code.as_u16(), code.as_str(), url))]
ResponseStatus {
code: reqwest::StatusCode,
url: reqwest::Url,
source: url::ParseError,
backtrace: Backtrace,
},

Expand All @@ -183,6 +159,14 @@ pub enum Error {
latest_known_time: DateTime<Utc>,
},

/// A transport error occurred while fetching a URL.
#[snafu(display("Failed to fetch {}: {}", url, source))]
Transport {
url: url::Url,
source: Box<dyn std::error::Error + Send + Sync>,
backtrace: Backtrace,
},

/// A metadata file could not be verified.
#[snafu(display("Failed to verify {} metadata: {}", role, source))]
VerifyMetadata {
Expand Down
55 changes: 20 additions & 35 deletions workspaces/updater/tough/src/fetch.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,42 @@
use crate::error::Result;
use crate::error::{self, Result};
use crate::io::{DigestAdapter, MaxSizeAdapter};
use reqwest::{Client, Url};
use snafu::ensure;
use std::fs::File;
use crate::transport::Transport;
use snafu::ResultExt;
use std::io::Read;
use std::path::PathBuf;
use url::Url;

fn fetch(client: &Client, url: Url) -> Result<Box<dyn Read>> {
use crate::error;
use snafu::ResultExt;

if url.scheme() == "file" {
let path = PathBuf::from(url.path());
let file = File::open(&path).context(error::FileRead { path })?;
Ok(Box::new(file) as Box<dyn Read>)
} else {
let response = client
.get(url.clone())
.send()
.context(error::Request { url: url.clone() })?;
ensure!(
!response.status().is_client_error() && !response.status().is_server_error(),
error::ResponseStatus {
code: response.status(),
url
}
);
Ok(Box::new(response))
}
}

pub(crate) fn fetch_max_size(
client: &Client,
pub(crate) fn fetch_max_size<T: Transport>(
transport: &T,
url: Url,
max_size: u64,
specifier: &'static str,
) -> Result<impl Read> {
Ok(MaxSizeAdapter::new(
fetch(client, url)?,
transport
.fetch(url.clone())
.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
.context(error::Transport { url })?,
specifier,
max_size,
))
}

pub(crate) fn fetch_sha256(
client: &Client,
pub(crate) fn fetch_sha256<T: Transport>(
transport: &T,
url: Url,
size: u64,
specifier: &'static str,
sha256: &[u8],
) -> Result<impl Read> {
Ok(DigestAdapter::sha256(
MaxSizeAdapter::new(fetch(client, url.clone())?, specifier, size),
MaxSizeAdapter::new(
transport
.fetch(url.clone())
.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
.context(error::Transport { url: url.clone() })?,
specifier,
size,
),
sha256,
url,
))
Expand Down
4 changes: 2 additions & 2 deletions workspaces/updater/tough/src/io.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::error;
use reqwest::Url;
use sha2::{Digest, Sha256};
use std::io::{self, Read};
use url::Url;

pub(crate) struct DigestAdapter<T, D> {
url: Url,
Expand Down Expand Up @@ -86,8 +86,8 @@ impl<T: Read> Read for MaxSizeAdapter<T> {
mod tests {
use crate::io::{DigestAdapter, MaxSizeAdapter};
use hex_literal::hex;
use reqwest::Url;
use std::io::{Cursor, Read};
use url::Url;

#[test]
fn test_max_size_adapter() {
Expand Down
Loading

0 comments on commit cb17aef

Please sign in to comment.