From d50e6b6beceddfa20b0bb2fd67fa8ba975e55ec4 Mon Sep 17 00:00:00 2001 From: Toshit Chawda Date: Sat, 13 Jan 2024 03:57:53 -0800 Subject: [PATCH] allow disabling redirect --- client/src/lib.rs | 17 ++++++++++++----- client/src/web/index.js | 34 ++++++++++++++++++++++++---------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index b67ac4f..5d867f3 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -42,7 +42,7 @@ type WsTcpTlsStream = TlsStream>; type WsTcpUnencryptedStream = MuxStream; type WsTcpStream = Either; -async fn send_req(req: http::Request, io: WsTcpStream) -> Result { +async fn send_req(req: http::Request, should_redirect: bool, io: WsTcpStream) -> Result { let (mut req_sender, conn) = Builder::new() .title_case_headers(true) .preserve_header_case(true) @@ -56,7 +56,7 @@ async fn send_req(req: http::Request, io: WsTcpStream) -> Result, io: WsTcpStream) -> Result { if utils::is_redirect(res.status().as_u16()) + && let Some(mut new_req) = new_req && let Some(location) = res.headers().get("Location") && let Ok(redirect_url) = new_req.uri().get_redirect(location) && let Some(redirect_url_authority) = redirect_url @@ -181,16 +182,17 @@ impl WsTcp { async fn send_req( &self, req: http::Request, + should_redirect: bool ) -> Result<(hyper::Response, Uri, bool), JsError> { let mut redirected = false; let uri = req.uri().clone(); - let mut current_resp: WsTcpResponse = send_req(req, self.get_http_io(&uri).await?).await?; + let mut current_resp: WsTcpResponse = send_req(req, should_redirect, self.get_http_io(&uri).await?).await?; for _ in 0..self.redirect_limit - 1 { match current_resp { WsTcpResponse::Success(_) => break, WsTcpResponse::Redirect((_, req, new_url)) => { redirected = true; - current_resp = send_req(req, self.get_http_io(&new_url).await?).await? + current_resp = send_req(req, should_redirect, self.get_http_io(&new_url).await?).await? } } } @@ -217,6 +219,11 @@ impl WsTcp { http::Method::try_from(>::as_ref(&req_method_string)) .replace_err("Invalid http method")?; + let req_should_redirect = match Reflect::get(&options, &jval!("redirect")) { + Ok(val) => !matches!(val.as_string().unwrap_or_default().as_str(), "error" | "manual"), + Err(_) => true, + }; + let body_jsvalue: Option = Reflect::get(&options, &jval!("body")).ok(); let body = if let Some(val) = body_jsvalue { if val.is_string() { @@ -275,7 +282,7 @@ impl WsTcp { .body(HttpBody::new(body_bytes)) .replace_err("Failed to make request")?; - let (resp, last_url, req_redirected) = self.send_req(request).await?; + let (resp, last_url, req_redirected) = self.send_req(request, req_should_redirect).await?; let resp_headers_jsarray = resp .headers() diff --git a/client/src/web/index.js b/client/src/web/index.js index 0d383b5..22bd0f7 100644 --- a/client/src/web/index.js +++ b/client/src/web/index.js @@ -4,7 +4,8 @@ "color:red;font-size:2rem;font-weight:bold" ); - const should_test = (new URL(window.location.href)).searchParams.has("test"); + const should_feature_test = (new URL(window.location.href)).searchParams.has("feature_test"); + const should_perf_test = (new URL(window.location.href)).searchParams.has("perf_test"); await wasm_bindgen("./wstcp_client_bg.wasm"); @@ -14,14 +15,22 @@ const tconn1 = performance.now(); console.warn(`conn establish took ${tconn1 - tconn0} ms or ${(tconn1 - tconn0) / 1000} s`); - for (const url of ["https://httpbin.org/get", "https://httpbin.org/gzip", "https://httpbin.org/brotli"]) { - let resp = await wstcp.fetch(url); - console.warn(resp); - console.warn(Object.fromEntries(resp.headers)); - console.warn(await resp.text()); - } - if (should_test) { + if (should_feature_test) { + for (const url of [ + ["https://httpbin.org/get", {}], + ["https://httpbin.org/gzip", {}], + ["https://httpbin.org/brotli", {}], + ["https://httpbin.org/redirect/11", {}], + ["https://httpbin.org/redirect/1", { redirect: "manual" }] + ]) { + let resp = await wstcp.fetch(url[0], url[1]); + console.warn(url, resp, Object.fromEntries(resp.headers)); + console.warn(await resp.text()); + } + + alert("you can open console now"); + } else if (should_perf_test) { const test_mux = async (url) => { const t0 = performance.now(); await wstcp.fetch(url); @@ -40,19 +49,24 @@ let total_mux = 0; for (const _ of Array(num_tests).keys()) { - total_mux += await test_mux("https://httpbin.org/gzip"); + total_mux += await test_mux("https://httpbin.org/get"); } total_mux = total_mux / num_tests; let total_native = 0; for (const _ of Array(num_tests).keys()) { - total_native += await test_native("https://httpbin.org/gzip"); + total_native += await test_native("https://httpbin.org/get"); } total_native = total_native / num_tests; console.warn(`avg mux (10) took ${total_mux} ms or ${total_mux / 1000} s`); console.warn(`avg native (10) took ${total_native} ms or ${total_native / 1000} s`); console.warn(`mux - native: ${total_mux - total_native} ms or ${(total_mux - total_native) / 1000} s`); + alert("you can open console now"); + } else { + let resp = await wstcp.fetch("https://httpbin.org/get"); + console.warn(resp, Object.fromEntries(resp.headers)); + console.warn(await resp.text()); } })();