diff --git a/Cargo.lock b/Cargo.lock index 9eaa1ea..86499c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -208,7 +208,7 @@ dependencies = [ "libc", "num-integer", "num-traits", - "time", + "time 0.1.44", "winapi", ] @@ -574,9 +574,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" +checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" dependencies = [ "bytes", "fnv", @@ -639,10 +639,26 @@ dependencies = [ "futures-util", "hyper", "log", - "rustls", + "rustls 0.19.1", "tokio", - "tokio-rustls", - "webpki", + "tokio-rustls 0.22.0", + "webpki 0.21.4", +] + +[[package]] +name = "hyper-rustls" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" +dependencies = [ + "http", + "hyper", + "log", + "rustls 0.20.2", + "rustls-native-certs", + "tokio", + "tokio-rustls 0.23.2", + "webpki-roots 0.22.1", ] [[package]] @@ -660,9 +676,9 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b855b45b2117a8834cd3d7088f1359ef3da0dd844893fba843097051c1bb49a" +checksum = "81e548dccc4db4fc5be468e7913f9c481866c7a987795c783c3b13a1dd4a4f91" dependencies = [ "async-trait", "base32", @@ -671,6 +687,7 @@ dependencies = [ "garcon", "hex", "http", + "hyper-rustls 0.23.0", "ic-types", "leb128", "mime", @@ -679,14 +696,13 @@ dependencies = [ "rand", "reqwest", "ring", - "rustls", + "rustls 0.20.2", "serde", "serde_bytes", "serde_cbor", "simple_asn1", "thiserror", "url", - "webpki-roots", ] [[package]] @@ -706,9 +722,9 @@ dependencies = [ [[package]] name = "ic-utils" -version = "0.7.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4128e89ed719c62ffeeaac90aedcf4d13d641c24ba4f4f5c83b022bbf9b8ca77" +checksum = "ff41e25a5a039b18609cb24f4e07e95d537e6db449765b6dd144177ba554e927" dependencies = [ "async-trait", "candid", @@ -843,9 +859,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "leb128" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" @@ -1044,9 +1060,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.36" +version = "0.10.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" dependencies = [ "bitflags", "cfg-if", @@ -1064,9 +1080,9 @@ checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" [[package]] name = "openssl-sys" -version = "0.9.66" +version = "0.9.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" dependencies = [ "autocfg", "cc", @@ -1114,9 +1130,9 @@ checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" [[package]] name = "pem" -version = "0.8.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" +checksum = "06673860db84d02a63942fa69cd9543f2624a5df3aea7f33173048fa7ad5cf1a" dependencies = [ "base64", "once_cell", @@ -1248,6 +1264,15 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "quickcheck" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" +dependencies = [ + "rand", +] + [[package]] name = "quote" version = "1.0.9" @@ -1356,7 +1381,7 @@ dependencies = [ "http", "http-body", "hyper", - "hyper-rustls", + "hyper-rustls 0.22.1", "hyper-tls", "ipnet", "js-sys", @@ -1366,18 +1391,18 @@ dependencies = [ "native-tls", "percent-encoding", "pin-project-lite", - "rustls", + "rustls 0.19.1", "serde", "serde_json", "serde_urlencoded", "tokio", "tokio-native-tls", - "tokio-rustls", + "tokio-rustls 0.22.0", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 0.21.1", "winreg", ] @@ -1405,8 +1430,41 @@ dependencies = [ "base64", "log", "ring", - "sct", - "webpki", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84" +dependencies = [ + "log", + "ring", + "sct 0.7.0", + "webpki 0.22.0", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca9ebdfa27d3fc180e42879037b5338ab1c040c06affd00d8338598e7800943" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" +dependencies = [ + "base64", ] [[package]] @@ -1447,6 +1505,16 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "security-framework" version = "2.3.1" @@ -1472,9 +1540,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.130" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" dependencies = [ "serde_derive", ] @@ -1500,9 +1568,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" dependencies = [ "proc-macro2", "quote", @@ -1556,14 +1624,14 @@ dependencies = [ [[package]] name = "simple_asn1" -version = "0.5.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb4ea60fb301dc81dfc113df680571045d375ab7345d171c5dc7d7e13107a80" +checksum = "4a762b1c38b9b990c694b9c2f8abe3372ce6a9ceaae6bca39cfc46e054f45745" dependencies = [ - "chrono", "num-bigint", "num-traits", "thiserror", + "time 0.3.5", ] [[package]] @@ -1651,19 +1719,20 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strum" -version = "0.21.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" +checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb" [[package]] name = "strum_macros" -version = "0.21.1" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec" +checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38" dependencies = [ "heck", "proc-macro2", "quote", + "rustversion", "syn", ] @@ -1729,18 +1798,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -1767,6 +1836,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "time" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad" +dependencies = [ + "itoa", + "libc", + "quickcheck", + "time-macros", +] + +[[package]] +name = "time-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6" + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -1838,9 +1925,20 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" dependencies = [ - "rustls", + "rustls 0.19.1", "tokio", - "webpki", + "webpki 0.21.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b" +dependencies = [ + "rustls 0.20.2", + "tokio", + "webpki 0.22.0", ] [[package]] @@ -2092,13 +2190,32 @@ dependencies = [ "untrusted", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "webpki-roots" version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" dependencies = [ - "webpki", + "webpki 0.21.4", +] + +[[package]] +name = "webpki-roots" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c475786c6f47219345717a043a37ec04cb4bc185e28853adcc4fa0a947eba630" +dependencies = [ + "webpki 0.22.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b8a0400..8ae3f9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,8 +24,8 @@ garcon = { version = "0.2.3", features = ["async"] } hex = "0.4.3" hyper = { version = "0.14.13", features = ["full"] } hyper-tls = "0.5.0" -ic-agent = "0.9" -ic-utils = "0.7" +ic-agent = "0.10.2" +ic-utils = "0.10.2" tokio = { version = "1.8.1", features = ["full"] } serde = "1.0.115" serde_json = "1.0.57" diff --git a/src/main.rs b/src/main.rs index 2f3cd8d..e8d033d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,9 +11,11 @@ use ic_agent::{ agent::http_transport::ReqwestHttpReplicaV2Transport, export::Principal, Agent, AgentError, }; use ic_utils::{ + call::AsyncCall, call::SyncCall, interfaces::http_request::{ - HeaderField, HttpRequestCanister, StreamingCallbackHttpResponse, StreamingStrategy, + HeaderField, HttpRequestCanister, HttpResponse, StreamingCallbackHttpResponse, + StreamingStrategy, }, }; use slog::Drain; @@ -201,7 +203,7 @@ async fn forward_request( .inspect(|HeaderField(name, value)| { slog::trace!(logger, "<< {}: {}", name, value); }) - .collect(); + .collect::>(); let entire_body = body::to_bytes(request.into_body()).await?.to_vec(); @@ -221,25 +223,55 @@ async fn forward_request( } let canister = HttpRequestCanister::create(agent.as_ref(), canister_id); - let result = canister - .http_request(method, uri.to_string(), headers, &entire_body) + let query_result = canister + .http_request( + method.clone(), + uri.to_string(), + headers.clone(), + &entire_body, + ) .call() .await; - // If the result is a Replica error, returns the 500 code and message. There is no information - // leak here because a user could use `dfx` to get the same reply. - let (http_response,) = match result { - Ok(response) => response, - Err(AgentError::ReplicaError { - reject_code, - reject_message, - }) => { - return Ok(Response::builder() + fn handle_result( + result: Result<(HttpResponse,), AgentError>, + ) -> Result, Box>> { + // If the result is a Replica error, returns the 500 code and message. There is no information + // leak here because a user could use `dfx` to get the same reply. + match result { + Ok((http_response,)) => Ok(http_response), + Err(AgentError::ReplicaError { + reject_code, + reject_message, + }) => Err(Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(format!(r#"Replica Error ({}): "{}""#, reject_code, reject_message).into()) - .unwrap()); + .unwrap())), + Err(e) => Err(Err(e.into())), } - Err(e) => return Err(e.into()), + } + + let http_response = match handle_result(query_result) { + Ok(http_response) => http_response, + Err(response_or_error) => return response_or_error, + }; + + let http_response = if http_response.upgrade { + let waiter = garcon::Delay::builder() + .throttle(std::time::Duration::from_millis(500)) + .timeout(std::time::Duration::from_secs(15)) + .build(); + let update_result = canister + .http_request_update(method, uri.to_string(), headers, &entire_body) + .call_and_wait(waiter) + .await; + let http_response = match handle_result(update_result) { + Ok(http_response) => http_response, + Err(response_or_error) => return response_or_error, + }; + http_response + } else { + http_response }; let mut builder = Response::builder().status(StatusCode::from_u16(http_response.status_code)?);