Skip to content

Commit

Permalink
Fix WASM compilation for resolvers that use HTTP
Browse files Browse the repository at this point in the history
- WASM compilation of reqwest
- Remove async Send for wasm32 target
- Install wasm target in CI
- Vendor openssl for Android
  • Loading branch information
sbihel authored and clehner committed Mar 16, 2021
1 parent c98fe67 commit 849934d
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 60 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,8 @@ jobs:
npm i
cp ../vc-test/config.json .
npm test
- name: Test WASM compilation
run: |
rustup target add wasm32-unknown-unknown
cargo check --workspace --target wasm32-unknown-unknown
4 changes: 3 additions & 1 deletion did-ethr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ edition = "2018"
[dependencies]
ssi = { path = "../", default-features = false, features = ["secp256k1", "keccak-hash"] }
chrono = { version = "0.4", features = ["serde"] }
tokio = { version = "1.0", features = ["macros", "rt"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
async-trait = "0.1"
libsecp256k1 = { version = "0.3" }
keccak-hash = "0.7"

[dev-dependencies]
tokio = { version = "1.0", features = ["macros"] }
3 changes: 2 additions & 1 deletion did-ethr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ fn parse_did(did: &str) -> Option<(i64, String)> {
Some((chain_id, address))
}

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl DIDResolver for DIDEthr {
async fn resolve(
&self,
Expand Down
3 changes: 2 additions & 1 deletion did-key/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ pub enum DIDKeyError {

pub struct DIDKey;

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl DIDResolver for DIDKey {
async fn resolve(
&self,
Expand Down
4 changes: 3 additions & 1 deletion did-sol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ edition = "2018"
[dependencies]
ssi = { path = "../", default-features = false, features = [] }
chrono = { version = "0.4", features = ["serde"] }
tokio = { version = "1.0", features = ["macros", "rt"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
async-trait = "0.1"
bs58 = { version = "0.4", features = ["check"] }

[dev-dependencies]
tokio = { version = "1.0", features = ["macros"] }
3 changes: 2 additions & 1 deletion did-sol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ fn parse_did(did: &str) -> Option<(String, Vec<u8>)> {
Some((address, bytes))
}

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl DIDResolver for DIDSol {
async fn resolve(
&self,
Expand Down
7 changes: 5 additions & 2 deletions did-tezos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ p256 = ["ssi/p256"]
[dependencies]
ssi = { path = "../", default-features = false }
chrono = { version = "0.4" }
tokio = { version = "1.0", features = ["macros", "rt"] }
reqwest = { version = "0.11", features = ["json", "default-tls"] }
reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
async-trait = "0.1"
Expand All @@ -23,5 +22,9 @@ anyhow = "1.0.33"
json-patch = "0.2.6"
bs58 = { version = "0.4", features = ["check"] }

[target.'cfg(target_os = "android")'.dependencies.reqwest]
features = ["native-tls-vendored"]

[dev-dependencies]
tokio = { version = "1.0", features = ["macros"] }
tezedge_client = { git = "https://github.com/binier/tezedge-client", rev = "672e61297f0ba7d1d94168a2588b9b27d76c1fc4", package = "lib" }
4 changes: 2 additions & 2 deletions did-tezos/src/explorer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct SearchResult {
}

pub async fn retrieve_did_manager(address: &str, network: &str) -> Result<Option<String>> {
let client = reqwest::Client::new();
let client = reqwest::Client::builder().build()?;
let mut search_result: SearchResult = client
.get(&format!("{}v1/search", BCD_URL))
.query(&[
Expand Down Expand Up @@ -73,7 +73,7 @@ struct ServiceResultItem {
}

pub async fn execute_service_view(did: &str, contract: &str, network: &str) -> Result<Service> {
let client = reqwest::Client::new();
let client = reqwest::Client::builder().build()?;
let service_result: ServiceResult = client
.post(&format!(
"{}v1/contract/{}/{}/views/execute",
Expand Down
3 changes: 2 additions & 1 deletion did-tezos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ use std::convert::TryInto;
/// [Specification](https://github.com/spruceid/did-tezos/)
pub struct DIDTz;

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl DIDResolver for DIDTz {
async fn resolve(
&self,
Expand Down
11 changes: 7 additions & 4 deletions did-web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ edition = "2018"
[dependencies]
ssi = { path = "../", default-features = false }
async-trait = "0.1"
hyper = { version = "0.14", features = ["server", "client", "http1", "stream"] }
hyper-tls = "0.5"
reqwest = { version = "0.11", features = ["json"] }
http = "0.2"
serde_json = "1.0"
tokio = { version = "1.0", features = ["macros"] }
futures = "0.3"

[target.'cfg(target_os = "android")'.dependencies.reqwest]
features = ["native-tls-vendored"]

[dev-dependencies]
tokio = { version = "1.0", features = ["macros"] }
serde = { version = "1.0", features = ["derive"] }
async-std = { version = "1.9", features = ["attributes"] }
futures = "0.3"
hyper = { version = "0.14", features = ["server", "client", "http1", "stream"] }
48 changes: 24 additions & 24 deletions did-web/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use async_trait::async_trait;
use hyper::{Client, Request, StatusCode};
use hyper_tls::HttpsConnector;

use ssi::did::{DIDMethod, Document};
use ssi::did_resolve::{
DIDResolver, DocumentMetadata, ResolutionInputMetadata, ResolutionMetadata, ERROR_INVALID_DID,
ERROR_NOT_FOUND, TYPE_DID_LD_JSON,
TYPE_DID_LD_JSON,
};

// For testing, enable handling requests at localhost.
Expand Down Expand Up @@ -50,7 +48,8 @@ fn did_web_url(did: &str) -> Result<String, ResolutionMetadata> {
}

/// <https://w3c-ccg.github.io/did-method-web/#read-resolve>
#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl DIDResolver for DIDWeb {
async fn resolve(
&self,
Expand Down Expand Up @@ -91,47 +90,48 @@ impl DIDResolver for DIDWeb {
Err(meta) => return (meta, Vec::new(), None),
Ok(url) => url,
};
let https = HttpsConnector::new();
// TODO: https://w3c-ccg.github.io/did-method-web/#in-transit-security
let client = Client::builder().build::<_, hyper::Body>(https);
let client = match reqwest::Client::builder().build() {
Ok(c) => c,
Err(err) => {
return (
ResolutionMetadata::from_error(&format!(
"Error building HTTP client: {}",
err.to_string()
)),
Vec::new(),
None,
)
}
};
let accept = input_metadata
.accept
.clone()
.unwrap_or_else(|| "application/json".to_string());
let request = match Request::get(url)
.header("Accept", accept)
.body(hyper::Body::default())
{
let resp = match client.get(&url).header("Accept", accept).send().await {
Ok(req) => req,
Err(err) => {
return (
ResolutionMetadata::from_error(&format!(
"Error building HTTP request: {}",
"Error sending HTTP request : {}",
err.to_string()
)),
Vec::new(),
None,
)
}
};
let mut resp = match client.request(request).await {
Ok(resp) => resp,
match resp.error_for_status_ref() {
Ok(_) => (),
Err(err) => {
return (
ResolutionMetadata::from_error(&format!("HTTP Error: {}", err.to_string())),
ResolutionMetadata::from_error(&err.to_string()),
Vec::new(),
None,
Some(DocumentMetadata::default()),
)
}
};
if resp.status() == StatusCode::NOT_FOUND {
return (
ResolutionMetadata::from_error(ERROR_NOT_FOUND),
Vec::new(),
Some(DocumentMetadata::default()),
);
}
let doc_representation = match hyper::body::to_bytes(resp.body_mut()).await {
let doc_representation = match resp.bytes().await {
Ok(bytes) => bytes.to_vec(),
Err(err) => {
return (
Expand Down Expand Up @@ -228,7 +228,7 @@ mod tests {
}

let (mut parts, body) = Response::<Body>::default().into_parts();
parts.status = StatusCode::NOT_FOUND;
parts.status = hyper::StatusCode::NOT_FOUND;
let response = Response::from_parts(parts, body);
return Ok::<_, hyper::Error>(response);
}))
Expand Down
12 changes: 8 additions & 4 deletions src/did.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ pub struct DIDParameters {
pub property_set: Option<Map<String, Value>>,
}

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait DIDMethod: DIDResolver {
/// Get the DID method name.
/// <https://w3c.github.io/did-core/#method-schemes>
Expand Down Expand Up @@ -261,7 +262,8 @@ impl<'a> DIDMethods<'a> {
}
}

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<'a> DIDResolver for DIDMethods<'a> {
async fn resolve(
&self,
Expand Down Expand Up @@ -545,7 +547,8 @@ pub mod example {

pub struct DIDExample;

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl DIDMethod for DIDExample {
fn name(&self) -> &'static str {
return "example";
Expand All @@ -556,7 +559,8 @@ pub mod example {
}
}

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl DIDResolver for DIDExample {
async fn resolve(
&self,
Expand Down
9 changes: 6 additions & 3 deletions src/did_resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ impl Default for ResolutionResult {
}
}

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait DIDResolver: Sync {
async fn resolve(
&self,
Expand Down Expand Up @@ -623,7 +624,8 @@ impl HTTPDIDResolver {
}

#[cfg(feature = "http")]
#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl DIDResolver for HTTPDIDResolver {
// https://w3c-ccg.github.io/did-resolution/#bindings-https
async fn resolve(
Expand Down Expand Up @@ -972,7 +974,8 @@ pub struct SeriesResolver<'a> {
pub resolvers: Vec<&'a (dyn DIDResolver)>,
}

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<'a> DIDResolver for SeriesResolver<'a> {
async fn resolve(
&self,
Expand Down
Loading

0 comments on commit 849934d

Please sign in to comment.