summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Kettmeir <crowlkats@toaxl.com>2023-07-28 09:01:06 +0200
committerGitHub <noreply@github.com>2023-07-28 09:01:06 +0200
commit5cb1d18439f562c8004a941b0f56ed034a44b052 (patch)
treee0b3ae76685760a50c1089c8885b6f6369d49282
parentcbfa98ea0bf4ee994bf564671ece514eb4efae1f (diff)
feat: Deno.createHttpClient allowHost (#19689)
This adds an option to allow using the host header in a fetch call. Closes https://github.com/denoland/deno/issues/16840 Ref https://github.com/denoland/deno/issues/11017
-rw-r--r--cli/tests/unit/fetch_test.ts19
-rw-r--r--cli/tsc/dts/lib.deno.unstable.d.ts5
-rw-r--r--ext/fetch/lib.rs19
-rw-r--r--test_util/src/lib.rs5
4 files changed, 37 insertions, 11 deletions
diff --git a/cli/tests/unit/fetch_test.ts b/cli/tests/unit/fetch_test.ts
index e89abef30..35fe48dca 100644
--- a/cli/tests/unit/fetch_test.ts
+++ b/cli/tests/unit/fetch_test.ts
@@ -1569,6 +1569,25 @@ Deno.test(
},
);
+Deno.test(
+ { permissions: { net: true, read: true } },
+ async function createHttpClientAllowHost() {
+ const client = Deno.createHttpClient({
+ allowHost: true,
+ });
+ const res = await fetch("http://localhost:4545/echo_server", {
+ headers: {
+ "host": "example.com",
+ },
+ client,
+ });
+ assert(res.ok);
+ assertEquals(res.headers.get("host"), "example.com");
+ await res.body?.cancel();
+ client.close();
+ },
+);
+
Deno.test({ permissions: { read: false } }, async function fetchFilePerm() {
await assertRejects(async () => {
await fetch(import.meta.resolve("../testdata/subdir/json_1.json"));
diff --git a/cli/tsc/dts/lib.deno.unstable.d.ts b/cli/tsc/dts/lib.deno.unstable.d.ts
index 1aa655646..eb612a655 100644
--- a/cli/tsc/dts/lib.deno.unstable.d.ts
+++ b/cli/tsc/dts/lib.deno.unstable.d.ts
@@ -837,6 +837,11 @@ declare namespace Deno {
* @default {true}
*/
http2?: boolean;
+ /** Whether setting the host header is allowed or not.
+ *
+ * @default {false}
+ */
+ allowHost?: boolean;
}
/** **UNSTABLE**: New API, yet to be vetted.
diff --git a/ext/fetch/lib.rs b/ext/fetch/lib.rs
index a3daff040..48f6a0294 100644
--- a/ext/fetch/lib.rs
+++ b/ext/fetch/lib.rs
@@ -237,11 +237,11 @@ pub fn op_fetch<FP>(
where
FP: FetchPermissions + 'static,
{
- let client = if let Some(rid) = client_rid {
+ let (client, allow_host) = if let Some(rid) = client_rid {
let r = state.resource_table.get::<HttpClientResource>(rid)?;
- r.client.clone()
+ (r.client.clone(), r.allow_host)
} else {
- get_or_create_client_from_state(state)?
+ (get_or_create_client_from_state(state)?, false)
};
let method = Method::from_bytes(&method)?;
@@ -334,7 +334,7 @@ where
let v = HeaderValue::from_bytes(&value)
.map_err(|err| type_error(err.to_string()))?;
- if !matches!(name, HOST | CONTENT_LENGTH) {
+ if (name != HOST || allow_host) && name != CONTENT_LENGTH {
header_map.append(name, v);
}
}
@@ -761,6 +761,7 @@ impl Resource for FetchResponseResource {
pub struct HttpClientResource {
pub client: Client,
+ pub allow_host: bool,
}
impl Resource for HttpClientResource {
@@ -770,8 +771,8 @@ impl Resource for HttpClientResource {
}
impl HttpClientResource {
- fn new(client: Client) -> Self {
- Self { client }
+ fn new(client: Client, allow_host: bool) -> Self {
+ Self { client, allow_host }
}
}
@@ -795,6 +796,8 @@ pub struct CreateHttpClientArgs {
http1: bool,
#[serde(default = "default_true")]
http2: bool,
+ #[serde(default)]
+ allow_host: bool,
}
fn default_true() -> bool {
@@ -860,7 +863,9 @@ where
},
)?;
- let rid = state.resource_table.add(HttpClientResource::new(client));
+ let rid = state
+ .resource_table
+ .add(HttpClientResource::new(client, args.allow_host));
Ok(rid)
}
diff --git a/test_util/src/lib.rs b/test_util/src/lib.rs
index 12d5675d2..dcf12d860 100644
--- a/test_util/src/lib.rs
+++ b/test_util/src/lib.rs
@@ -728,10 +728,7 @@ async fn main_server(
req: Request<Body>,
) -> Result<Response<Body>, hyper::http::Error> {
return match (req.method(), req.uri().path()) {
- (
- &hyper::Method::POST | &hyper::Method::PATCH | &hyper::Method::PUT,
- "/echo_server",
- ) => {
+ (_, "/echo_server") => {
let (parts, body) = req.into_parts();
let mut response = Response::new(body);