diff --git a/Cargo.lock b/Cargo.lock index 283eed0..b6450fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,6 +54,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + [[package]] name = "bitflags" version = "1.2.1" @@ -591,6 +597,8 @@ name = "workerns" version = "0.1.0" dependencies = [ "async_static", + "base64", + "bytes", "cfg-if 1.0.0", "console_error_panic_hook", "domain-core", diff --git a/Cargo.toml b/Cargo.toml index 956467e..52d67e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,8 @@ target = "wasm32-unknown-unknown" [dependencies] async_static = "0.1" +base64 = "0.13" +bytes = "0.4" cfg-if = "1.0" console_error_panic_hook = { version = "0.1.6", optional = true } domain-core = "0.4" @@ -30,5 +32,7 @@ web-sys = { version = "0.3", features = [ "Headers", "Request", "Response", - "ResponseInit" + "ResponseInit", + "Url", + "UrlSearchParams" ]} \ No newline at end of file diff --git a/src/server.rs b/src/server.rs index 6ce89b6..39fb62b 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,6 +1,7 @@ use std::borrow::Borrow; use async_static::async_static; +use bytes::Bytes; use domain_core::bits::message::Message; use serde::Deserialize; use wasm_bindgen::prelude::*; @@ -47,7 +48,7 @@ impl Server { .unwrap() } }; - return Response::new_with_opt_str_and_init(Some("hello"), ResponseInit::new().status(200)) + return Response::new_with_opt_str_and_init(Some(&format!("{:?}", body)), ResponseInit::new().status(200)) .unwrap(); } @@ -58,6 +59,36 @@ impl Server { // if we have URL param "name" in GET, then it's dns-json // Note that the return type can be different from the request type // e.g. a dns-message request can accept dns-json return - todo!() + let method = req.method(); + if method == "GET" { + // GET request -- DNS wireformat or JSON + // TODO: implement JSON + let url = Url::new(&req.url()).map_err(|_| "Invalid url")?; + let params = url.search_params(); + if params.has("dns") { + // base64-encoded DNS wireformat via GET + let decoded = base64::decode(params.get("dns").unwrap()) + .map_err(|_| "Failed to decode base64 DNS request")?; + return Self::parse_dns_wireformat(&decoded); + } else { + return Err("Missing supported GET parameters".to_string()); + } + } else if method == "POST" { + // POST request -- DNS wireformat + let headers = req.headers(); + if !headers.has("Content-Type").unwrap() { + return Err("Missing Content-Type header".to_string()); + } + + todo!() + } else { + return Err(format!("Unsupported method {}", method)) + } + } + + fn parse_dns_wireformat(msg: &[u8]) -> Result { + let bytes = Bytes::from(msg); + Message::from_bytes(bytes) + .map_err(|_| "Failed to parse DNS wireformat message".to_string()) } }