Skip to content

feat: add requestHandler ctor pass through type #1089

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 1, 2023
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
7 changes: 7 additions & 0 deletions .changeset/sixty-fireants-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@smithy/fetch-http-handler": minor
"@smithy/node-http-handler": minor
"@smithy/types": minor
---

move default fetch and http handler ctor types to the types package
36 changes: 15 additions & 21 deletions packages/fetch-http-handler/src/fetch-http-handler.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,13 @@
import { HttpHandler, HttpRequest, HttpResponse } from "@smithy/protocol-http";
import { buildQueryString } from "@smithy/querystring-builder";
import type { FetchHttpHandlerOptions } from "@smithy/types";
import { HeaderBag, HttpHandlerOptions, Provider } from "@smithy/types";

import { requestTimeout } from "./request-timeout";

declare let AbortController: any;

/**
* Represents the http options that can be passed to a browser http client.
*/
export interface FetchHttpHandlerOptions {
/**
* The number of milliseconds a request can take before being automatically
* terminated.
*/
requestTimeout?: number;

/**
* Whether to allow the request to outlive the page. Default value is false.
*
* There may be limitations to the payload size, number of concurrent requests,
* request duration etc. when using keepalive in browsers.
*
* These may change over time, so look for up to date information about
* these limitations before enabling keepalive.
*/
keepAlive?: boolean;
}
export { FetchHttpHandlerOptions };

type FetchHttpHandlerConfig = FetchHttpHandlerOptions;

Expand All @@ -47,6 +28,19 @@ export class FetchHttpHandler implements HttpHandler<FetchHttpHandlerConfig> {
private config?: FetchHttpHandlerConfig;
private configProvider: Promise<FetchHttpHandlerConfig>;

/**
* @returns the input if it is an HttpHandler of any class,
* or instantiates a new instance of this handler.
*/
public static create(instanceOrOptions?: HttpHandler<any> | FetchHttpHandlerConfig) {
if (typeof (instanceOrOptions as any)?.handle === "function") {
// is already an instance of HttpHandler.
return instanceOrOptions as HttpHandler<any>;
}
// input is ctor options or undefined.
return new FetchHttpHandler(instanceOrOptions as FetchHttpHandlerConfig);
}

constructor(options?: FetchHttpHandlerOptions | Provider<FetchHttpHandlerOptions | undefined>) {
if (typeof options === "function") {
this.configProvider = options().then((opts) => opts || {});
Expand Down
44 changes: 15 additions & 29 deletions packages/node-http-handler/src/node-http-handler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { HttpHandler, HttpRequest, HttpResponse } from "@smithy/protocol-http";
import { buildQueryString } from "@smithy/querystring-builder";
import type { NodeHttpHandlerOptions } from "@smithy/types";
import { HttpHandlerOptions, Provider } from "@smithy/types";
import { Agent as hAgent, request as hRequest } from "http";
import { Agent as hsAgent, request as hsRequest, RequestOptions } from "https";
Expand All @@ -11,35 +12,7 @@ import { setSocketKeepAlive } from "./set-socket-keep-alive";
import { setSocketTimeout } from "./set-socket-timeout";
import { writeRequestBody } from "./write-request-body";

/**
* Represents the http options that can be passed to a node http client.
*/
export interface NodeHttpHandlerOptions {
/**
* The maximum time in milliseconds that the connection phase of a request
* may take before the connection attempt is abandoned.
*
* Defaults to 0, which disables the timeout.
*/
connectionTimeout?: number;

/**
* The number of milliseconds a request can take before automatically being terminated.
* Defaults to 0, which disables the timeout.
*/
requestTimeout?: number;

/**
* @deprecated Use {@link requestTimeout}
*
* The maximum time in milliseconds that a socket may remain idle before it
* is closed.
*/
socketTimeout?: number;

httpAgent?: hAgent;
httpsAgent?: hsAgent;
}
export { NodeHttpHandlerOptions };

interface ResolvedNodeHttpHandlerConfig {
requestTimeout?: number;
Expand All @@ -57,6 +30,19 @@ export class NodeHttpHandler implements HttpHandler<NodeHttpHandlerOptions> {
// Node http handler is hard-coded to http/1.1: https://github.com/nodejs/node/blob/ff5664b83b89c55e4ab5d5f60068fb457f1f5872/lib/_http_server.js#L286
public readonly metadata = { handlerProtocol: "http/1.1" };

/**
* @returns the input if it is an HttpHandler of any class,
* or instantiates a new instance of this handler.
*/
public static create(instanceOrOptions?: HttpHandler<any> | NodeHttpHandlerOptions) {
if (typeof (instanceOrOptions as any)?.handle === "function") {
// is already an instance of HttpHandler.
return instanceOrOptions as HttpHandler<any>;
}
// input is ctor options or undefined.
return new NodeHttpHandler(instanceOrOptions as NodeHttpHandlerOptions);
}

constructor(options?: NodeHttpHandlerOptions | Provider<NodeHttpHandlerOptions | void>) {
this.configProvider = new Promise((resolve, reject) => {
if (typeof options === "function") {
Expand Down
13 changes: 13 additions & 0 deletions packages/node-http-handler/src/node-http2-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,19 @@ export class NodeHttp2Handler implements HttpHandler<NodeHttp2HandlerOptions> {

private readonly connectionManager: NodeHttp2ConnectionManager = new NodeHttp2ConnectionManager({});

/**
* @returns the input if it is an HttpHandler of any class,
* or instantiates a new instance of this handler.
*/
public static create(instanceOrOptions?: HttpHandler<any> | NodeHttp2HandlerOptions) {
if (typeof (instanceOrOptions as any)?.handle === "function") {
// is already an instance of HttpHandler.
return instanceOrOptions as HttpHandler<any>;
}
// input is ctor options or undefined.
return new NodeHttp2Handler(instanceOrOptions as NodeHttp2HandlerOptions);
}

constructor(options?: NodeHttp2HandlerOptions | Provider<NodeHttp2HandlerOptions | void>) {
this.configProvider = new Promise((resolve, reject) => {
if (typeof options === "function") {
Expand Down
70 changes: 70 additions & 0 deletions packages/types/src/http/httpHandlerInitialization.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import type { Agent as hAgent } from "http";
import type { Agent as hsAgent } from "https";

/**
*
* This type represents an alternate client constructor option for the entry
* "requestHandler". Instead of providing an instance of a requestHandler, the user
* may provide the requestHandler's constructor options for either the
* NodeHttpHandler or FetchHttpHandler.
*
* For other RequestHandlers like HTTP2 or WebSocket,
* constructor parameter passthrough is not currently available.
*
* @public
*/
export type RequestHandlerParams = NodeHttpHandlerOptions | FetchHttpHandlerOptions;

/**
* Represents the http options that can be passed to a node http client.
* @public
*/
export interface NodeHttpHandlerOptions {
/**
* The maximum time in milliseconds that the connection phase of a request
* may take before the connection attempt is abandoned.
*
* Defaults to 0, which disables the timeout.
*/
connectionTimeout?: number;

/**
* The number of milliseconds a request can take before automatically being terminated.
* Defaults to 0, which disables the timeout.
*/
requestTimeout?: number;

/**
* @deprecated Use {@link requestTimeout}
*
* The maximum time in milliseconds that a socket may remain idle before it
* is closed.
*/
socketTimeout?: number;

httpAgent?: hAgent;
httpsAgent?: hsAgent;
}

/**
* Represents the http options that can be passed to a browser http client.
* @public
*/
export interface FetchHttpHandlerOptions {
/**
* The number of milliseconds a request can take before being automatically
* terminated.
*/
requestTimeout?: number;

/**
* Whether to allow the request to outlive the page. Default value is false.
*
* There may be limitations to the payload size, number of concurrent requests,
* request duration etc. when using keepalive in browsers.
*
* These may change over time, so look for up to date information about
* these limitations before enabling keepalive.
*/
keepAlive?: boolean;
}
1 change: 1 addition & 0 deletions packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export * from "./endpoints";
export * from "./eventStream";
export * from "./extensions";
export * from "./http";
export * from "./http/httpHandlerInitialization";
export * from "./identity";
export * from "./logger";
export * from "./middleware";
Expand Down