Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions impit-node/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,8 @@ export interface ImpitOptions {
* @default `undefined` (no proxy)
*/
proxyUrl?: string
/** Default timeout for this Impit instance in milliseconds. */
timeout?: number
/** Default timeout for this Impit instance in milliseconds, or `null` to disable the timeout. */
timeout?: number | null
/**
* Enable HTTP/3 support.
*
Expand Down Expand Up @@ -411,8 +411,8 @@ export interface RequestInit {
headers?: Headers | Record<string, string> | [string, string][]
/** Request body. Can be a string, Buffer, ArrayBuffer, TypedArray, DataView, Blob, File, URLSearchParams, FormData or ReadableStream. */
body?: string | ArrayBuffer | Uint8Array | DataView | Blob | File | URLSearchParams | FormData | ReadableStream
/** Request timeout in milliseconds. Overrides the Impit-wide timeout option from {@link ImpitOptions.timeout}. */
timeout?: number
/** Request timeout in milliseconds, or `null` to disable the timeout. Overrides the Impit-wide timeout option from {@link ImpitOptions.timeout}. */
timeout?: number | null
/** Force the request to use HTTP/3. If the server doesn't expect HTTP/3 or the Impit instance doesn't have HTTP/3 enabled (via the {@link ImpitOptions.http3} option), the request will fail. */
forceHttp3?: boolean
/** Abort signal to cancel the request. */
Expand Down
11 changes: 7 additions & 4 deletions impit-node/src/impit_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use impit::{
impit::{ImpitBuilder, RedirectBehavior},
};

use napi::bindgen_prelude::Object;
use napi::bindgen_prelude::{Either, Null, Object};
use napi_derive::napi;

use crate::cookies::NodeCookieJar;
Expand Down Expand Up @@ -71,8 +71,8 @@ pub struct ImpitOptions<'a> {
///
/// @default `undefined` (no proxy)
pub proxy_url: Option<String>,
/// Default timeout for this Impit instance in milliseconds.
pub timeout: Option<u32>,
/// Default timeout for this Impit instance in milliseconds, or `null` to disable the timeout.
pub timeout: Option<Either<u32, Null>>,
/// Enable HTTP/3 support.
///
/// **Warning:** Proxies are not supported when HTTP/3 is enabled.
Expand Down Expand Up @@ -168,7 +168,10 @@ impl ImpitOptions<'_> {
config = config.with_proxy(proxy_url);
}
if let Some(timeout) = self.timeout {
config = config.with_default_timeout(Duration::from_millis(timeout.into()));
config = config.with_default_timeout(match timeout {
Either::A(millis) => Duration::from_millis(millis.into()),
Either::B(_) => Duration::MAX,
});
}
if let Some(http3) = self.http3 {
if http3 {
Expand Down
10 changes: 8 additions & 2 deletions impit-node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use impit::{
impit::Impit,
request::{ImpitBody, RequestOptions},
};
use napi::{bindgen_prelude::ObjectFinalize, Env};
use napi::{
bindgen_prelude::{Either, ObjectFinalize},
Env,
};
use napi_derive::napi;

mod abortable_stream;
Expand Down Expand Up @@ -132,7 +135,10 @@ impl ImpitWrapper {

let request_options = Some(RequestOptions {
headers: headers.unwrap_or_default(),
timeout: timeout.map(|timeout| Some(Duration::from_millis(timeout.into()))),
timeout: timeout.map(|timeout| match timeout {
Either::A(millis) => Some(Duration::from_millis(millis.into())),
Either::B(_) => None,
Comment on lines +139 to +140

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not know what is idiomatic in Rust, but to me it seems less readable.

When using Either::A(...), Either::B(...) I do not have enough context to read that line. I need to find the type in a different file and see what was the first option and what was the second option. I would prefer a named variant where I would get all the context from the variant name already.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, but this Either<...,...> is from the napi-rs lib (has effect on the generated TS types etc). Making a custom type compatible with this would take more effort than this is worth imo :/

}),
http3_prior_knowledge: force_http3.unwrap_or_default(),
});

Expand Down
6 changes: 3 additions & 3 deletions impit-node/src/request.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bytes::Bytes;
use futures_util::{Stream, TryStreamExt};
use napi::bindgen_prelude::{sys, FromNapiValue, ReadableStream, Reader, Uint8Array};
use napi::bindgen_prelude::{sys, Either, FromNapiValue, Null, ReadableStream, Reader, Uint8Array};

use napi_derive::napi;

Expand Down Expand Up @@ -68,8 +68,8 @@ pub struct RequestInit {
/// Set by the JS wrapper instead of `body` when the body is a stream. Takes precedence over `body`.
#[napi(skip_typescript)]
pub body_stream: Option<BodyStream>,
/// Request timeout in milliseconds. Overrides the Impit-wide timeout option from {@link ImpitOptions.timeout}.
pub timeout: Option<u32>,
/// Request timeout in milliseconds, or `null` to disable the timeout. Overrides the Impit-wide timeout option from {@link ImpitOptions.timeout}.
pub timeout: Option<Either<u32, Null>>,
/// Force the request to use HTTP/3. If the server doesn't expect HTTP/3 or the Impit instance doesn't have HTTP/3 enabled (via the {@link ImpitOptions.http3} option), the request will fail.
pub force_http3: Option<bool>,
/// Abort signal to cancel the request.
Expand Down
21 changes: 21 additions & 0 deletions impit-node/test/basics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,27 @@ describe.each([
});
});

describe('timeout', () => {
test('`null` disables the client timeout for a request', async () => {
const server = await getServer();
const url = `http://127.0.0.1:${(server?.address() as AddressInfo).port}/delay/500`;
const shortTimeoutImpit = new Impit({ browser, timeout: 100 });

await expect(shortTimeoutImpit.fetch(url).then((x) => x.text())).rejects.toThrow();

const response = await shortTimeoutImpit.fetch(url, { timeout: null });
await expect(response.text()).resolves.toContain('Body sent after delay.');
});

test('`null` disables the client-wide timeout', async () => {
const server = await getServer();
const url = `http://127.0.0.1:${(server?.address() as AddressInfo).port}/delay/500`;

const response = await new Impit({ browser, timeout: null }).fetch(url);
await expect(response.text()).resolves.toContain('Body sent after delay.');
});
});

describe('AbortSignal', () => {
test('aborts immediately if signal is already aborted', async () => {
const controller = new AbortController();
Expand Down
Loading