Skip to content

Commit

Permalink
0.31.0 (#268)
Browse files Browse the repository at this point in the history
* Add custom_queries to command PresignGet (#262)

* fmt

* s3: Bump hmac to 0.12, sha2 to 0.10 and minidom to 0.14 (#265)

* cargo: Bump `hmac` to `0.12

* cargo: Update `sha2` to `0.10`

* cargo: bump `minidom` to `0.14`

* removed use of `NewMac` trait

Co-authored-by: Drazen Urch <[email protected]>

* Fix merge

* awscreds 0.29.0

* aws-region 0.24

* awsregion 0.24.1

* awscreds 0.29.1

* s3 0.31.0

Co-authored-by: Incomplete <[email protected]>
Co-authored-by: Luca Quartesan <[email protected]>
  • Loading branch information
3 people authored Apr 21, 2022
1 parent 1b37a48 commit 32a5a69
Show file tree
Hide file tree
Showing 21 changed files with 448 additions and 263 deletions.
6 changes: 3 additions & 3 deletions aws-creds/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aws-creds"
version = "0.28.0"
version = "0.29.1"
authors = ["Drazen Urch"]
description = "Tiny Rust library for working with Amazon IAM credential,s, supports `s3` crate"
repository = "https://github.com/durch/rust-s3"
Expand All @@ -15,10 +15,10 @@ name = "awscreds"
path = "src/lib.rs"

[dependencies]
anyhow = "1.0"
thiserror = "1"
dirs = "4"
rust-ini = "0.18"
attohttpc = { version = "0.18", default-features = false, features = ["json"], optional = true }
attohttpc = { version = "0.19", default-features = false, features = ["json"], optional = true }
url = "2"
serde-xml-rs = "0.5"
serde = "1"
Expand Down
42 changes: 19 additions & 23 deletions aws-creds/src/credentials.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(dead_code)]
use anyhow::{anyhow, bail, Result};
use crate::error::CredentialsError;
use ini::Ini;
use serde_xml_rs as serde_xml;
use std::collections::HashMap;
Expand Down Expand Up @@ -168,7 +168,7 @@ fn http_get(url: &str) -> attohttpc::Result<attohttpc::Response> {

impl Credentials {
#[cfg(feature = "http-credentials")]
pub fn from_sts_env(session_name: &str) -> Result<Credentials> {
pub fn from_sts_env(session_name: &str) -> Result<Credentials, CredentialsError> {
let role_arn = env::var("AWS_ROLE_ARN")?;
let web_identity_token_file = env::var("AWS_WEB_IDENTITY_TOKEN_FILE")?;
let web_identity_token = std::fs::read_to_string(web_identity_token_file)?;
Expand All @@ -180,7 +180,7 @@ impl Credentials {
role_arn: &str,
session_name: &str,
web_identity_token: &str,
) -> Result<Credentials> {
) -> Result<Credentials, CredentialsError> {
let url = Url::parse_with_params(
"https://sts.amazonaws.com/",
&[
Expand Down Expand Up @@ -220,11 +220,11 @@ impl Credentials {
}

#[cfg(feature = "http-credentials")]
pub fn default() -> Result<Credentials> {
pub fn default() -> Result<Credentials, CredentialsError> {
Credentials::new(None, None, None, None, None)
}

pub fn anonymous() -> Result<Credentials> {
pub fn anonymous() -> Result<Credentials, CredentialsError> {
Ok(Credentials {
access_key: None,
secret_key: None,
Expand All @@ -242,7 +242,7 @@ impl Credentials {
security_token: Option<&str>,
session_token: Option<&str>,
profile: Option<&str>,
) -> Result<Credentials> {
) -> Result<Credentials, CredentialsError> {
if access_key.is_some() {
return Ok(Credentials {
access_key: access_key.map(|s| s.to_string()),
Expand All @@ -263,7 +263,7 @@ impl Credentials {
secret_key_var: Option<&str>,
security_token_var: Option<&str>,
session_token_var: Option<&str>,
) -> Result<Credentials> {
) -> Result<Credentials, CredentialsError> {
let access_key = from_env_with_default(access_key_var, "AWS_ACCESS_KEY_ID")?;
let secret_key = from_env_with_default(secret_key_var, "AWS_SECRET_ACCESS_KEY")?;

Expand All @@ -277,12 +277,12 @@ impl Credentials {
})
}

pub fn from_env() -> Result<Credentials> {
pub fn from_env() -> Result<Credentials, CredentialsError> {
Credentials::from_env_specific(None, None, None, None)
}

#[cfg(feature = "http-credentials")]
pub fn from_instance_metadata() -> Result<Credentials> {
pub fn from_instance_metadata() -> Result<Credentials, CredentialsError> {
#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Response {
Expand All @@ -301,7 +301,7 @@ impl Credentials {
}
Err(_) => {
if !is_ec2() {
bail!("Not an AWS instance")
return Err(CredentialsError::NotEc2);
}

let role = attohttpc::get(
Expand All @@ -327,22 +327,22 @@ impl Credentials {
})
}

pub fn from_profile(section: Option<&str>) -> Result<Credentials> {
let home_dir = dirs::home_dir().ok_or_else(|| anyhow!("Invalid home dir"))?;
pub fn from_profile(section: Option<&str>) -> Result<Credentials, CredentialsError> {
let home_dir = dirs::home_dir().ok_or(CredentialsError::HomeDir)?;
let profile = format!("{}/.aws/credentials", home_dir.display());
let conf = Ini::load_from_file(&profile)?;
let section = section.unwrap_or("default");
let data = conf
.section(Some(section))
.ok_or_else(|| anyhow!("Config missing"))?;
.ok_or(CredentialsError::ConfigNotFound)?;
let access_key = data
.get("aws_access_key_id")
.map(|s| s.to_string())
.ok_or_else(|| anyhow!("Missing aws_access_key_id section"))?;
.ok_or(CredentialsError::ConfigMissingAccessKeyId)?;
let secret_key = data
.get("aws_secret_access_key")
.map(|s| s.to_string())
.ok_or_else(|| anyhow!("Missing aws_secret_access_key section"))?;
.ok_or(CredentialsError::ConfigMissingSecretKey)?;
let credentials = Credentials {
access_key: Some(access_key),
secret_key: Some(secret_key),
Expand All @@ -353,15 +353,11 @@ impl Credentials {
}
}

fn from_env_with_default(var: Option<&str>, default: &str) -> Result<String> {
fn from_env_with_default(var: Option<&str>, default: &str) -> Result<String, CredentialsError> {
let val = var.unwrap_or(default);
env::var(val).or_else(|_e| env::var(val)).map_err(|_| {
anyhow!(
"Neither {:?}, nor {} does not exist in the environment",
var,
default
)
})
env::var(val)
.or_else(|_e| env::var(val))
.map_err(|_| CredentialsError::MissingEnvVar(val.to_string(), default.to_string()))
}

fn is_ec2() -> bool {
Expand Down
30 changes: 30 additions & 0 deletions aws-creds/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use thiserror::Error;

#[derive(Error, Debug)]
pub enum CredentialsError {
#[error("Not an AWS instance")]
NotEc2,
#[error("Config not found")]
ConfigNotFound,
#[error("Missing aws_access_key_id section in config")]
ConfigMissingAccessKeyId,
#[error("Missing aws_access_key_id section in config")]
ConfigMissingSecretKey,
#[error("Neither {0}, nor {1} exists in the environment")]
MissingEnvVar(String, String),
#[cfg(feature = "http-credentials")]
#[error("attohttpc: {0}")]
Atto(#[from] attohttpc::Error),
#[error("ini: {0}")]
Ini(#[from] ini::Error),
#[error("serde_xml: {0}")]
SerdeXml(#[from] serde_xml_rs::Error),
#[error("url parse: {0}")]
UrlParse(#[from] url::ParseError),
#[error("io: {0}")]
Io(#[from] std::io::Error),
#[error("env var: {0}")]
Env(#[from] std::env::VarError),
#[error("Invalid home dir")]
HomeDir,
}
1 change: 1 addition & 0 deletions aws-creds/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ extern crate serde_derive;

mod credentials;
pub use credentials::*;
pub mod error;
4 changes: 2 additions & 2 deletions aws-region/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aws-region"
version = "0.23.5"
version = "0.24.1"
authors = ["Drazen Urch"]
description = "Tiny Rust library for working with Amazon AWS regions, supports `s3` crate"
repository = "https://github.com/durch/rust-s3"
Expand All @@ -15,4 +15,4 @@ name = "awsregion"
path = "src/lib.rs"

[dependencies]
anyhow = "1.0"
thiserror = "1"
4 changes: 4 additions & 0 deletions aws-region/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
use thiserror::Error;

#[derive(Error, Debug)]
pub enum RegionError {}
1 change: 1 addition & 0 deletions aws-region/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@

mod region;
pub use region::*;
pub mod error;
6 changes: 2 additions & 4 deletions aws-region/src/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
use std::fmt;
use std::str::{self, FromStr};

use anyhow::Result;

/// AWS S3 [region identifier](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region),
/// passing in custom values is also possible, in that case it is up to you to pass a valid endpoint,
/// otherwise boom will happen :)
Expand Down Expand Up @@ -135,9 +133,9 @@ impl fmt::Display for Region {
}

impl FromStr for Region {
type Err = anyhow::Error;
type Err = std::str::Utf8Error;

fn from_str(s: &str) -> Result<Self> {
fn from_str(s: &str) -> Result<Self, Self::Err> {
use self::Region::*;
match s {
"us-east-1" => Ok(UsEast1),
Expand Down
24 changes: 14 additions & 10 deletions s3/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rust-s3"
version = "0.31.0" # Not published
version = "0.31.0"
authors = ["Drazen Urch"]
description = "Rust library for working with Amazon S3 and compatible object storage APIs"
repository = "https://github.com/durch/rust-s3"
Expand All @@ -21,16 +21,18 @@ path = "src/lib.rs"
[dependencies]
async-std = { version = "1", optional = true }
async-trait = "0.1"
attohttpc = { version = "0.18", optional = true, default-features = false }
aws-creds = { version = "0.28", default-features = false }
aws-region = "0.23"
attohttpc = { version = "0.19", optional = true, default-features = false }
aws-creds = { version = "0.29", default-features = false }
# aws-creds = { path = "../aws-creds", default-features = false }
aws-region = "0.24"
# aws-region = {path = "../aws-region"}
base64 = "0.13"
cfg-if = "1"
time = { version = "0.3", features = ["formatting", "macros"] }
futures-io = { version = "0.3", optional = true }
futures-util = { version = "0.3", optional = true, features = ["io"] }
hex = "0.4"
hmac = "0.11"
hmac = "0.12"
http = "0.2"
log = "0.4"
maybe-async = { version = "0.2" }
Expand All @@ -40,13 +42,13 @@ reqwest = { version = "0.11", default-features = false, features = ["json", "str
serde = "1"
serde_derive = "1"
serde-xml-rs = "0.5"
sha2 = "0.9"
anyhow = "1"
sha2 = "0.10"
thiserror = "1"
surf = { version = "2", optional = true, default-features = false, features = ["h1-client-rustls"] }
tokio = { version = "1", features = ["io-util"], optional = true, default-features = false }
tokio-stream = { version = "0.1", optional = true }
url = "2"
minidom = { version = "0.13", optional = true }
minidom = { version = "0.14", optional = true }

block_on_proc = { version = "0.2", optional = true }

Expand All @@ -67,6 +69,8 @@ tags = ["minidom"]
[dev-dependencies]
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros", "fs"] }
async-std = { version = "1", features = ["attributes"] }
uuid = { version = "0.8", features = ["v4"] }
uuid = { version = "1", features = ["v4"] }
env_logger = "0.9"
aws-creds = { version = "0.28", features = ["http-credentials"] }
aws-creds = { version = "0.29", default-features = false }
# aws-creds = { path = "../aws-creds", features = ["http-credentials"] }
anyhow = "1"
2 changes: 1 addition & 1 deletion s3/bin/simple_crud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub fn main() -> Result<(), S3Error> {
// Put a "test_file" with the contents of MESSAGE at the root of the
// bucket.
let (_, code) = bucket.put_object_blocking("test_file", MESSAGE.as_bytes())?;
// println!("{}", bucket.presign_get("test_file", 604801)?);
// println!("{}", bucket.presign_get("test_file", 604801, None)?);
assert_eq!(200, code);

// Get the "test_file" contents and make sure that the returned message
Expand Down
19 changes: 8 additions & 11 deletions s3/src/blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ use attohttpc::header::HeaderName;

use super::bucket::Bucket;
use super::command::Command;
use crate::error::S3Error;
use time::OffsetDateTime;

use crate::command::HttpMethod;
use crate::request_trait::Request;
use anyhow::anyhow;
use anyhow::Result;
// static CLIENT: Lazy<Client> = Lazy::new(|| {
// if cfg!(feature = "no-verify-ssl") {
// Client::builder()
Expand Down Expand Up @@ -54,7 +53,7 @@ impl<'a> Request for AttoRequest<'a> {
self.path.to_string()
}

fn response(&self) -> Result<Self::Response> {
fn response(&self) -> Result<Self::Response, S3Error> {
// Build headers
let headers = match self.headers() {
Ok(headers) => headers,
Expand Down Expand Up @@ -82,17 +81,15 @@ impl<'a> Request for AttoRequest<'a> {
let response = request.bytes(&self.request_body()).send()?;

if cfg!(feature = "fail-on-err") && !response.status().is_success() {
return Err(anyhow!(
"Request failed with code {}\n{}",
response.status().as_u16(),
response.text()?
));
let status = response.status().as_u16();
let text = response.text()?;
return Err(S3Error::Http(status, text));
}

Ok(response)
}

fn response_data(&self, etag: bool) -> Result<(Vec<u8>, u16)> {
fn response_data(&self, etag: bool) -> Result<(Vec<u8>, u16), S3Error> {
let response = self.response()?;
let status_code = response.status().as_u16();
let headers = response.headers().clone();
Expand All @@ -108,7 +105,7 @@ impl<'a> Request for AttoRequest<'a> {
Ok((body_vec, status_code))
}

fn response_data_to_writer<T: Write>(&self, writer: &mut T) -> Result<u16> {
fn response_data_to_writer<T: Write>(&self, writer: &mut T) -> Result<u16, S3Error> {
let response = self.response()?;

let status_code = response.status();
Expand All @@ -119,7 +116,7 @@ impl<'a> Request for AttoRequest<'a> {
Ok(status_code.as_u16())
}

fn response_header(&self) -> Result<(Self::HeaderMap, u16)> {
fn response_header(&self) -> Result<(Self::HeaderMap, u16), S3Error> {
let response = self.response()?;
let status_code = response.status().as_u16();
let headers = response.headers().clone();
Expand Down
Loading

0 comments on commit 32a5a69

Please sign in to comment.