Skip to content

Commit

Permalink
fix: add missing http headers under wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
crwen authored and ethe committed Dec 9, 2024
1 parent 7721cfa commit 47fa1f5
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 17 deletions.
1 change: 1 addition & 0 deletions fusio/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ cfg-if = "1.0.0"
chrono = { version = "0.4", optional = true, default-features = false, features = [
"now",
"std",
"wasmbind"
] }
futures-core = { version = "0.3" }
futures-util = { version = "0.3" }
Expand Down
19 changes: 4 additions & 15 deletions fusio/src/impls/remotes/aws/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,7 @@
// specific language governing permissions and limitations
// under the License.

use std::{
collections::BTreeMap,
io,
sync::Arc,
time::{Duration, Instant},
};
use std::{collections::BTreeMap, io, sync::Arc};

use bytes::{Buf, Bytes};
use chrono::{DateTime, Utc};
Expand Down Expand Up @@ -228,7 +223,7 @@ impl<'a> AwsAuthorizer<'a> {
}

#[allow(unused)]
pub(crate) fn sign(&self, method: Method, url: &mut Url, expires_in: Duration) {
pub(crate) fn sign(&self, method: Method, url: &mut Url, expires_in: u32) {
let date = self.date.unwrap_or_else(Utc::now);
let scope = self.scope(date);

Expand All @@ -240,7 +235,7 @@ impl<'a> AwsAuthorizer<'a> {
&format!("{}/{}", self.credential.key_id, scope),
)
.append_pair("X-Amz-Date", &date.format("%Y%m%dT%H%M%SZ").to_string())
.append_pair("X-Amz-Expires", &expires_in.as_secs().to_string())
.append_pair("X-Amz-Expires", &expires_in.to_string())
.append_pair("X-Amz-SignedHeaders", "host");

// For S3, you must include the X-Amz-Security-Token query parameter in the URL if
Expand Down Expand Up @@ -521,7 +516,6 @@ async fn instance_creds<'c, C: HttpClient>(
let ttl = (creds.expiration - now).to_std().unwrap_or_default();
Ok(TemporaryToken {
token: Arc::new(creds.into()),
expiry: Some(Instant::now() + ttl),
})
}

Expand All @@ -548,15 +542,10 @@ impl From<InstanceCredentials> for AwsCredential {
pub(crate) struct TemporaryToken<T> {
/// The temporary credential
pub(crate) token: T,
/// The instant at which this credential is no longer valid
/// None means the credential does not expire
#[allow(unused)]
pub(crate) expiry: Option<Instant>,
}

#[cfg(test)]
mod tests {
use std::time::Duration;

#[allow(unused)]
use bytes::Bytes;
Expand Down Expand Up @@ -681,7 +670,7 @@ mod tests {
};

let mut url = Url::parse("https://examplebucket.s3.amazonaws.com/test.txt").unwrap();
authorizer.sign(Method::GET, &mut url, Duration::from_secs(86400));
authorizer.sign(Method::GET, &mut url, 86400);

assert_eq!(
url,
Expand Down
13 changes: 11 additions & 2 deletions fusio/src/impls/remotes/http/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,20 @@ impl HttpClient for WasmClient {
Ok(body) => {
let client = reqwest::Client::new();

let mut builder = client.request(parts.method, url);
let mut builder = client.request(parts.method, url).headers(parts.headers);
builder = builder.body(reqwest::Body::from(body.to_bytes()));
let response = builder.send().await?;

let mut resp_builder = Response::builder();
let mut headers = resp_builder.headers_mut();
for (name, value) in response.headers().iter() {
headers.as_mut().unwrap().append(name, value.clone());
}
let bytes = response.bytes().await?;

Ok(Response::new(http_body_util::Full::new(bytes)))
resp_builder
.body(http_body_util::Full::new(bytes))
.map_err(HttpError::Http)
}
Err(err) => Err(HttpError::Other(err.into())),
}
Expand Down Expand Up @@ -74,6 +82,7 @@ mod tests {
assert_eq!(response.status(), StatusCode::OK);
}

#[ignore]
#[cfg(all(feature = "wasm-http", feature = "aws"))]
#[wasm_bindgen_test]
async fn list_and_remove_wasm() {
Expand Down
53 changes: 53 additions & 0 deletions fusio/tests/wasm_http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#[cfg(all(feature = "wasm-http", target_arch = "wasm32", test))]
pub(crate) mod tests {

wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
use wasm_bindgen_test::wasm_bindgen_test;

#[ignore]
#[cfg(feature = "aws")]
#[wasm_bindgen_test]
async fn test_read_write_s3_wasm() {
use fusio::{
fs::Fs,
remotes::aws::{fs::AmazonS3Builder, AwsCredential},
Read, Write,
};

if option_env!("AWS_ACCESS_KEY_ID").is_none() {
return;
}
let key_id = option_env!("AWS_ACCESS_KEY_ID").unwrap().to_string();
let secret_key = option_env!("AWS_SECRET_ACCESS_KEY").unwrap().to_string();

let s3 = AmazonS3Builder::new("wasm-data".into())
.credential(AwsCredential {
key_id,
secret_key,
token: None,
})
.region("ap-southeast-2".into())
.sign_payload(true)
.build();

{
let mut s3_file = s3.open(&"read-write.txt".into()).await.unwrap();

let (result, _) = s3_file
.write_all(&b"The answer of life, universe and everthing"[..])
.await;

result.unwrap();

s3_file.close().await.unwrap();
}
let mut s3_file = s3.open(&"read-write.txt".into()).await.unwrap();

let size = s3_file.size().await.unwrap();
assert_eq!(size, 42);
let buf = Vec::new();
let (result, buf) = s3_file.read_to_end_at(buf, 0).await;
result.unwrap();
assert_eq!(buf, b"The answer of life, universe and everthing");
}
}

0 comments on commit 47fa1f5

Please sign in to comment.