feat: stabilize Deno.createHttpClient() (#25569)

Closes #25518
This commit is contained in:
Asher Gomez 2024-09-12 10:46:48 +10:00 committed by GitHub
parent 3a3837545c
commit 8476bbff9a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 127 additions and 203 deletions

View file

@ -364,13 +364,6 @@ fn get_suggestions_for_terminal_errors(e: &JsError) -> Vec<FixSuggestion> {
"Run again with `--unstable-cron` flag to enable this API.",
),
];
} else if msg.contains("createHttpClient is not a function") {
return vec![
FixSuggestion::info("Deno.createHttpClient() is an unstable API."),
FixSuggestion::hint(
"Run again with `--unstable-http` flag to enable this API.",
),
];
} else if msg.contains("WebSocketStream is not defined") {
return vec![
FixSuggestion::info("new WebSocketStream() is an unstable API."),

View file

@ -32,9 +32,7 @@ delete Object.prototype.__proto__;
/** @type {ReadonlySet<string>} */
const unstableDenoProps = new Set([
"AtomicOperation",
"CreateHttpClientOptions",
"DatagramConn",
"HttpClient",
"Kv",
"KvListIterator",
"KvU64",
@ -44,7 +42,6 @@ delete Object.prototype.__proto__;
"UnsafeFnPointer",
"UnixConnectOptions",
"UnixListenOptions",
"createHttpClient",
"dlopen",
"listen",
"listenDatagram",

View file

@ -6087,4 +6087,126 @@ declare namespace Deno {
filename: string | URL,
symbols: S,
): DynamicLibrary<S>;
/**
* A custom `HttpClient` for use with {@linkcode fetch} function. This is
* designed to allow custom certificates or proxies to be used with `fetch()`.
*
* @example ```ts
* const caCert = await Deno.readTextFile("./ca.pem");
* const client = Deno.createHttpClient({ caCerts: [ caCert ] });
* const req = await fetch("https://myserver.com", { client });
* ```
*
* @category Fetch
*/
export interface HttpClient extends Disposable {
/** Close the HTTP client. */
close(): void;
}
/**
* The options used when creating a {@linkcode Deno.HttpClient}.
*
* @category Fetch
*/
export interface CreateHttpClientOptions {
/** A list of root certificates that will be used in addition to the
* default root certificates to verify the peer's certificate.
*
* Must be in PEM format. */
caCerts?: string[];
/** A HTTP proxy to use for new connections. */
proxy?: Proxy;
/** Sets the maximum number of idle connections per host allowed in the pool. */
poolMaxIdlePerHost?: number;
/** Set an optional timeout for idle sockets being kept-alive.
* Set to false to disable the timeout. */
poolIdleTimeout?: number | false;
/**
* Whether HTTP/1.1 is allowed or not.
*
* @default {true}
*/
http1?: boolean;
/** Whether HTTP/2 is allowed or not.
*
* @default {true}
*/
http2?: boolean;
/** Whether setting the host header is allowed or not.
*
* @default {false}
*/
allowHost?: boolean;
}
/**
* The definition of a proxy when specifying
* {@linkcode Deno.CreateHttpClientOptions}.
*
* @category Fetch
*/
export interface Proxy {
/** The string URL of the proxy server to use. */
url: string;
/** The basic auth credentials to be used against the proxy server. */
basicAuth?: BasicAuth;
}
/**
* Basic authentication credentials to be used with a {@linkcode Deno.Proxy}
* server when specifying {@linkcode Deno.CreateHttpClientOptions}.
*
* @category Fetch
*/
export interface BasicAuth {
/** The username to be used against the proxy server. */
username: string;
/** The password to be used against the proxy server. */
password: string;
}
/** Create a custom HttpClient to use with {@linkcode fetch}. This is an
* extension of the web platform Fetch API which allows Deno to use custom
* TLS certificates and connect via a proxy while using `fetch()`.
*
* @example ```ts
* const caCert = await Deno.readTextFile("./ca.pem");
* const client = Deno.createHttpClient({ caCerts: [ caCert ] });
* const response = await fetch("https://myserver.com", { client });
* ```
*
* @example ```ts
* const client = Deno.createHttpClient({
* proxy: { url: "http://myproxy.com:8080" }
* });
* const response = await fetch("https://myserver.com", { client });
* ```
*
* @category Fetch
*/
export function createHttpClient(
options: CreateHttpClientOptions,
): HttpClient;
/**
* Create a custom HttpClient to use with {@linkcode fetch}. This is an
* extension of the web platform Fetch API which allows Deno to use custom
* TLS certificates and connect via a proxy while using `fetch()`.
*
* @example ```ts
* const caCert = await Deno.readTextFile("./ca.pem");
* // Load a client key and certificate that we'll use to connect
* const key = await Deno.readTextFile("./key.key");
* const cert = await Deno.readTextFile("./cert.crt");
* const client = Deno.createHttpClient({ caCerts: [ caCert ], key, cert });
* const response = await fetch("https://myserver.com", { client });
* ```
*
* @category Fetch
*/
export function createHttpClient(
options: CreateHttpClientOptions & TlsCertifiedKeyPem,
): HttpClient;
}

View file

@ -36,141 +36,6 @@ declare namespace Deno {
present(): void;
}
/** **UNSTABLE**: New API, yet to be vetted.
*
* A custom `HttpClient` for use with {@linkcode fetch} function. This is
* designed to allow custom certificates or proxies to be used with `fetch()`.
*
* @example ```ts
* const caCert = await Deno.readTextFile("./ca.pem");
* const client = Deno.createHttpClient({ caCerts: [ caCert ] });
* const req = await fetch("https://myserver.com", { client });
* ```
*
* @category Fetch
* @experimental
*/
export interface HttpClient extends Disposable {
/** Close the HTTP client. */
close(): void;
}
/** **UNSTABLE**: New API, yet to be vetted.
*
* The options used when creating a {@linkcode Deno.HttpClient}.
*
* @category Fetch
* @experimental
*/
export interface CreateHttpClientOptions {
/** A list of root certificates that will be used in addition to the
* default root certificates to verify the peer's certificate.
*
* Must be in PEM format. */
caCerts?: string[];
/** A HTTP proxy to use for new connections. */
proxy?: Proxy;
/** Sets the maximum number of idle connections per host allowed in the pool. */
poolMaxIdlePerHost?: number;
/** Set an optional timeout for idle sockets being kept-alive.
* Set to false to disable the timeout. */
poolIdleTimeout?: number | false;
/**
* Whether HTTP/1.1 is allowed or not.
*
* @default {true}
*/
http1?: boolean;
/** Whether HTTP/2 is allowed or not.
*
* @default {true}
*/
http2?: boolean;
/** Whether setting the host header is allowed or not.
*
* @default {false}
*/
allowHost?: boolean;
}
/** **UNSTABLE**: New API, yet to be vetted.
*
* The definition of a proxy when specifying
* {@linkcode Deno.CreateHttpClientOptions}.
*
* @category Fetch
* @experimental
*/
export interface Proxy {
/** The string URL of the proxy server to use. */
url: string;
/** The basic auth credentials to be used against the proxy server. */
basicAuth?: BasicAuth;
}
/** **UNSTABLE**: New API, yet to be vetted.
*
* Basic authentication credentials to be used with a {@linkcode Deno.Proxy}
* server when specifying {@linkcode Deno.CreateHttpClientOptions}.
*
* @category Fetch
* @experimental
*/
export interface BasicAuth {
/** The username to be used against the proxy server. */
username: string;
/** The password to be used against the proxy server. */
password: string;
}
/** **UNSTABLE**: New API, yet to be vetted.
*
* Create a custom HttpClient to use with {@linkcode fetch}. This is an
* extension of the web platform Fetch API which allows Deno to use custom
* TLS certificates and connect via a proxy while using `fetch()`.
*
* @example ```ts
* const caCert = await Deno.readTextFile("./ca.pem");
* const client = Deno.createHttpClient({ caCerts: [ caCert ] });
* const response = await fetch("https://myserver.com", { client });
* ```
*
* @example ```ts
* const client = Deno.createHttpClient({
* proxy: { url: "http://myproxy.com:8080" }
* });
* const response = await fetch("https://myserver.com", { client });
* ```
*
* @category Fetch
* @experimental
*/
export function createHttpClient(
options: CreateHttpClientOptions,
): HttpClient;
/** **UNSTABLE**: New API, yet to be vetted.
*
* Create a custom HttpClient to use with {@linkcode fetch}. This is an
* extension of the web platform Fetch API which allows Deno to use custom
* TLS certificates and connect via a proxy while using `fetch()`.
*
* @example ```ts
* const caCert = await Deno.readTextFile("./ca.pem");
* // Load a client key and certificate that we'll use to connect
* const key = await Deno.readTextFile("./key.key");
* const cert = await Deno.readTextFile("./cert.crt");
* const client = Deno.createHttpClient({ caCerts: [ caCert ], key, cert });
* const response = await fetch("https://myserver.com", { client });
* ```
*
* @category Fetch
* @experimental
*/
export function createHttpClient(
options: CreateHttpClientOptions & TlsCertifiedKeyPem,
): HttpClient;
/** **UNSTABLE**: New API, yet to be vetted.
*
* Represents membership of a IPv4 multicast group.

View file

@ -90,13 +90,6 @@ static USE_WRITEV: Lazy<bool> = Lazy::new(|| {
false
});
// NOTE(bartlomieju): currently we don't have any unstable HTTP features,
// but let's keep this const here, because:
// a) we still need to support `--unstable-http` flag to not break user's CLI;
// b) we might add more unstable features in the future.
#[allow(dead_code)]
pub const UNSTABLE_FEATURE_NAME: &str = "http";
/// All HTTP/2 connections start with this byte string.
///
/// In HTTP/2, each endpoint is required to send a connection preface as a final confirmation

View file

@ -126,6 +126,8 @@ const denoNs = {
uid: os.uid,
Command: process.Command,
ChildProcess: process.ChildProcess,
httpClient: httpClient.httpClient,
createHttpClient: httpClient.createHttpClient,
};
// NOTE(bartlomieju): keep IDs in sync with `cli/main.rs`

View file

@ -83,7 +83,7 @@ pub static UNSTABLE_GRANULAR_FLAGS: &[UnstableGranularFlag] = &[
UnstableGranularFlag {
name: ops::http::UNSTABLE_FEATURE_NAME,
help_text: "Enable unstable HTTP APIs",
show_in_help: true,
show_in_help: false,
id: 5,
},
UnstableGranularFlag {

View file

@ -57,8 +57,6 @@ fn op_http_start(
.resource_table
.take::<deno_net::io::UnixStreamResource>(tcp_stream_rid)
{
super::check_unstable(state, UNSTABLE_FEATURE_NAME, "Deno.serveHttp");
// This UNIX socket might be used somewhere else. If it's the case, we cannot proceed with the
// process of starting a HTTP server on top of this UNIX socket, so we just return a bad
// resource error. See also: https://github.com/denoland/deno/pull/16242

View file

@ -122,9 +122,8 @@ fn js_unit_test(test: String) {
.arg("--no-lock")
// TODO(bartlomieju): would be better if we could apply this unstable
// flag to particular files, but there's many of them that rely on unstable
// net APIs (`reusePort` in `listen` and `listenTls`; `listenDatagram`, `createHttpClient`)
// net APIs (`reusePort` in `listen` and `listenTls`; `listenDatagram`)
.arg("--unstable-net")
.arg("--unstable-http")
.arg("--location=http://127.0.0.1:4545/")
.arg("--no-prompt");

View file

@ -112,7 +112,6 @@ fn node_unit_test(test: String) {
.arg(deno_config_path())
.arg("--no-lock")
.arg("--unstable-broadcast-channel")
.arg("--unstable-http")
.arg("--unstable-net")
// TODO(kt3k): This option is required to pass tls_test.ts,
// but this shouldn't be necessary. tls.connect currently doesn't

View file

@ -1829,17 +1829,6 @@ itest!(unstable_cron_enabled {
output: "run/unstable_cron.enabled.out",
});
itest!(unstable_http_disabled {
args: "run --quiet --reload --allow-read run/unstable_http.js",
output: "run/unstable_http.disabled.out",
});
itest!(unstable_http_enabled {
args:
"run --quiet --reload --allow-read --unstable-http run/unstable_http.js",
output: "run/unstable_http.enabled.out",
});
itest!(unstable_net_disabled {
args: "run --quiet --reload --allow-read run/unstable_net.js",
output: "run/unstable_net.disabled.out",

View file

@ -108,7 +108,6 @@ async function testFetchProgrammaticProxy() {
"--quiet",
"--reload",
"--allow-net=localhost:4545,localhost:4555",
"--unstable-http",
"programmatic_proxy_client.ts",
],
}).output();

View file

@ -10,11 +10,6 @@
"exitCode": 1,
"output": "cron.out"
},
"http": {
"args": "run http.ts",
"exitCode": 1,
"output": "http.out"
},
"http_wss": {
"args": "run http_wss.ts",
"exitCode": 1,

View file

@ -1,7 +0,0 @@
error: Uncaught (in promise) TypeError: Deno.createHttpClient is not a function
Deno.createHttpClient();
^
at [WILDCARD]http.ts:1:6
info: Deno.createHttpClient() is an unstable API.
hint: Run again with `--unstable-http` flag to enable this API.

View file

@ -1 +0,0 @@
Deno.createHttpClient();

View file

@ -1,4 +0,0 @@
main undefined
main undefined
worker undefined
worker undefined

View file

@ -1,4 +0,0 @@
main [class HttpClient]
main [Function: createHttpClient]
worker [class HttpClient]
worker [Function: createHttpClient]

View file

@ -1,11 +0,0 @@
const scope = import.meta.url.slice(-7) === "#worker" ? "worker" : "main";
console.log(scope, Deno.HttpClient);
console.log(scope, Deno.createHttpClient);
if (scope === "worker") {
postMessage("done");
} else {
const worker = new Worker(`${import.meta.url}#worker`, { type: "module" });
worker.onmessage = () => Deno.exit(0);
}

View file

@ -220,7 +220,7 @@ async function ensureNoNewITests() {
"pm_tests.rs": 0,
"publish_tests.rs": 0,
"repl_tests.rs": 0,
"run_tests.rs": 338,
"run_tests.rs": 336,
"shared_library_tests.rs": 0,
"task_tests.rs": 4,
"test_tests.rs": 74,