From f14ae3768662a97942a3a8fc8c8c3a7107cc0820 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Tue, 6 Aug 2024 13:55:59 -0700 Subject: [PATCH] fix(ext/http): preserve authority and scheme from absolute URLs (#4) --- ext/http/00_serve.ts | 39 ++++++++++++---------------------- ext/http/http_next.rs | 29 +++++++++++++++++++++---- ext/http/request_properties.rs | 6 ------ 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/ext/http/00_serve.ts b/ext/http/00_serve.ts index b1816c2b9d..23a97cb604 100644 --- a/ext/http/00_serve.ts +++ b/ext/http/00_serve.ts @@ -264,32 +264,19 @@ class InnerRequest { this.#methodAndUri = op_http_get_request_method_and_url(this.#external); } + const method = this.#methodAndUri[0]; + const scheme = this.#methodAndUri[5] !== undefined + ? `${this.#methodAndUri[5]}://` + : this.#context.scheme; + const authority = this.#methodAndUri[1] ?? this.#context.fallbackHost; const path = this.#methodAndUri[2]; - // * is valid for OPTIONS - if (path === "*") { - return this.#urlValue = "*"; - } - // If the path is empty, return the authority (valid for CONNECT) - if (path == "") { + if (method == "CONNECT") { return this.#urlValue = this.#methodAndUri[1]; } - // CONNECT requires an authority - if (this.#methodAndUri[0] == "CONNECT") { - return this.#urlValue = this.#methodAndUri[1]; - } - - const hostname = this.#methodAndUri[1]; - if (hostname) { - // Construct a URL from the scheme, the hostname, and the path - return this.#urlValue = this.#context.scheme + hostname + path; - } - - // Construct a URL from the scheme, the fallback hostname, and the path - return this.#urlValue = this.#context.scheme + this.#context.fallbackHost + - path; + return this.#urlValue = scheme + authority + path; } get completed() { @@ -595,11 +582,13 @@ function serve(arg1, arg2) { options = { __proto__: null }; } - const canOverrideOptions = !ObjectHasOwn(options, "path") - && !ObjectHasOwn(options, "hostname") - && !ObjectHasOwn(options, "port"); - const env = Deno.permissions.querySync({ name: "env", variable: "DENO_SERVE_ADDRESS" }).state === "granted" - && Deno.env.get("DENO_SERVE_ADDRESS"); + const canOverrideOptions = !ObjectHasOwn(options, "path") && + !ObjectHasOwn(options, "hostname") && + !ObjectHasOwn(options, "port"); + const env = + Deno.permissions.querySync({ name: "env", variable: "DENO_SERVE_ADDRESS" }) + .state === "granted" && + Deno.env.get("DENO_SERVE_ADDRESS"); if (canOverrideOptions && env) { const delim = env.indexOf("/"); diff --git a/ext/http/http_next.rs b/ext/http/http_next.rs index 9bdb79f86b..0954a54c14 100644 --- a/ext/http/http_next.rs +++ b/ext/http/http_next.rs @@ -300,10 +300,10 @@ where .unwrap() .into(); - let authority: v8::Local = match request_properties.authority { - Some(authority) => v8::String::new_from_utf8( + let scheme: v8::Local = match request_parts.uri.scheme_str() { + Some(scheme) => v8::String::new_from_utf8( scope, - authority.as_ref(), + scheme.as_bytes(), v8::NewStringType::Normal, ) .unwrap() @@ -311,6 +311,27 @@ where None => v8::undefined(scope).into(), }; + let authority: v8::Local = + if let Some(authority) = request_parts.uri.authority() { + v8::String::new_from_utf8( + scope, + authority.as_str().as_ref(), + v8::NewStringType::Normal, + ) + .unwrap() + .into() + } else if let Some(authority) = request_properties.authority { + v8::String::new_from_utf8( + scope, + authority.as_ref(), + v8::NewStringType::Normal, + ) + .unwrap() + .into() + } else { + v8::undefined(scope).into() + }; + // Only extract the path part - we handle authority elsewhere let path = match &request_parts.uri.path_and_query() { Some(path_and_query) => path_and_query.to_string(), @@ -335,7 +356,7 @@ where None => v8::undefined(scope).into(), }; - let vec = [method, authority, path, peer_address, port]; + let vec = [method, authority, path, peer_address, port, scheme]; v8::Array::new_with_elements(scope, vec.as_slice()) } diff --git a/ext/http/request_properties.rs b/ext/http/request_properties.rs index 1422c7417d..1bbf24fcf2 100644 --- a/ext/http/request_properties.rs +++ b/ext/http/request_properties.rs @@ -269,12 +269,6 @@ fn req_host<'a>( addr_type: NetworkStreamType, port: u16, ) -> Option> { - // Unix sockets always use the socket address - #[cfg(unix)] - if addr_type == NetworkStreamType::Unix { - return None; - } - // It is rare that an authority will be passed, but if it does, it takes priority if let Some(auth) = uri.authority() { match addr_type {