1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

feat(ext/fetch): Make fetch client parameters configurable (#26909)

This commit makes HTTP client parameters used in `fetch` API
configurable on the extension initialization via a callback
`client_builder_hook` that users can provide.

The main motivation behind this change is to allow `deno_fetch` users to
tune the HTTP/2 client to suit their needs, although Deno CLI users will
not benefit from it as no JavaScript interface is exposed to set these
parameters currently.

It is up to users whether to provide a hook function. If not provided,
the default configuration from hyper crate will be used.

Ref #26785
This commit is contained in:
Yusuke Tanaka 2024-11-19 10:48:57 +09:00 committed by GitHub
parent 9f26ca4509
commit 0e2f6e38e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 2 deletions

View file

@ -67,6 +67,7 @@ use http_body_util::BodyExt;
use hyper::body::Frame; use hyper::body::Frame;
use hyper_util::client::legacy::connect::HttpConnector; use hyper_util::client::legacy::connect::HttpConnector;
use hyper_util::client::legacy::connect::HttpInfo; use hyper_util::client::legacy::connect::HttpInfo;
use hyper_util::client::legacy::Builder as HyperClientBuilder;
use hyper_util::rt::TokioExecutor; use hyper_util::rt::TokioExecutor;
use hyper_util::rt::TokioTimer; use hyper_util::rt::TokioTimer;
use serde::Deserialize; use serde::Deserialize;
@ -85,6 +86,16 @@ pub struct Options {
pub user_agent: String, pub user_agent: String,
pub root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>, pub root_cert_store_provider: Option<Arc<dyn RootCertStoreProvider>>,
pub proxy: Option<Proxy>, pub proxy: Option<Proxy>,
/// A callback to customize HTTP client configuration.
///
/// The settings applied with this hook may be overridden by the options
/// provided through `Deno.createHttpClient()` API. For instance, if the hook
/// calls [`hyper_util::client::legacy::Builder::pool_max_idle_per_host`] with
/// a value of 99, and a user calls `Deno.createHttpClient({ poolMaxIdlePerHost: 42 })`,
/// the value that will take effect is 42.
///
/// For more info on what can be configured, see [`hyper_util::client::legacy::Builder`].
pub client_builder_hook: Option<fn(HyperClientBuilder) -> HyperClientBuilder>,
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub request_builder_hook: Option< pub request_builder_hook: Option<
fn(&mut http::Request<ReqBody>) -> Result<(), deno_core::error::AnyError>, fn(&mut http::Request<ReqBody>) -> Result<(), deno_core::error::AnyError>,
@ -112,6 +123,7 @@ impl Default for Options {
user_agent: "".to_string(), user_agent: "".to_string(),
root_cert_store_provider: None, root_cert_store_provider: None,
proxy: None, proxy: None,
client_builder_hook: None,
request_builder_hook: None, request_builder_hook: None,
unsafely_ignore_certificate_errors: None, unsafely_ignore_certificate_errors: None,
client_cert_chain_and_key: TlsKeys::Null, client_cert_chain_and_key: TlsKeys::Null,
@ -271,6 +283,7 @@ pub fn create_client_from_options(
pool_idle_timeout: None, pool_idle_timeout: None,
http1: true, http1: true,
http2: true, http2: true,
client_builder_hook: options.client_builder_hook,
}, },
) )
} }
@ -908,6 +921,7 @@ where
), ),
http1: args.http1, http1: args.http1,
http2: args.http2, http2: args.http2,
client_builder_hook: options.client_builder_hook,
}, },
)?; )?;
@ -929,6 +943,7 @@ pub struct CreateHttpClientOptions {
pub pool_idle_timeout: Option<Option<u64>>, pub pool_idle_timeout: Option<Option<u64>>,
pub http1: bool, pub http1: bool,
pub http2: bool, pub http2: bool,
pub client_builder_hook: Option<fn(HyperClientBuilder) -> HyperClientBuilder>,
} }
impl Default for CreateHttpClientOptions { impl Default for CreateHttpClientOptions {
@ -944,6 +959,7 @@ impl Default for CreateHttpClientOptions {
pool_idle_timeout: None, pool_idle_timeout: None,
http1: true, http1: true,
http2: true, http2: true,
client_builder_hook: None,
} }
} }
} }
@ -999,11 +1015,14 @@ pub fn create_http_client(
HttpClientCreateError::InvalidUserAgent(user_agent.to_string()) HttpClientCreateError::InvalidUserAgent(user_agent.to_string())
})?; })?;
let mut builder = let mut builder = HyperClientBuilder::new(TokioExecutor::new());
hyper_util::client::legacy::Builder::new(TokioExecutor::new());
builder.timer(TokioTimer::new()); builder.timer(TokioTimer::new());
builder.pool_timer(TokioTimer::new()); builder.pool_timer(TokioTimer::new());
if let Some(client_builder_hook) = options.client_builder_hook {
builder = client_builder_hook(builder);
}
let mut proxies = proxy::from_env(); let mut proxies = proxy::from_env();
if let Some(proxy) = options.proxy { if let Some(proxy) = options.proxy {
let mut intercept = proxy::Intercept::all(&proxy.url) let mut intercept = proxy::Intercept::all(&proxy.url)

View file

@ -126,6 +126,7 @@ async fn rust_test_client_with_resolver(
dns_resolver: resolver, dns_resolver: resolver,
http1: true, http1: true,
http2: true, http2: true,
client_builder_hook: None,
}, },
) )
.unwrap(); .unwrap();

View file

@ -210,6 +210,7 @@ impl<P: RemoteDbHandlerPermissions + 'static> DatabaseHandler
pool_idle_timeout: None, pool_idle_timeout: None,
http1: false, http1: false,
http2: true, http2: true,
client_builder_hook: None,
}, },
)?; )?;
let fetch_client = FetchClient(client); let fetch_client = FetchClient(client);