popsicle-transport-http
Version:
Popsicle transport for sending requests over HTTP1 and HTTP2
203 lines (202 loc) • 6.91 kB
TypeScript
/// <reference types="node" />
import { URL } from "url";
import { BaseError } from "make-error-cause";
import { Socket, NetConnectOpts } from "net";
import { SecureContext, TLSSocket, ConnectionOptions as TlsConnectOpts } from "tls";
import { ClientHttp2Session } from "http2";
import { LookupOptions } from "dns";
import { Request, Response, CreateBody, ResponseOptions } from "servie/dist/node";
/**
* Add HTTP signals to servie events.
*/
declare module "servie/dist/signal" {
interface SignalEvents {
error: [Error];
}
}
/**
* Address information from the HTTP request.
*/
export interface Connection {
localPort: number;
localAddress: string;
remotePort: number;
remoteAddress: string;
encrypted: boolean;
}
/**
* Extend response with URL.
*/
export interface HttpResponseOptions extends ResponseOptions {
url: string;
connection: Connection;
httpVersion: string;
}
/**
* HTTP responses implement a node.js body.
*/
export declare class HttpResponse extends Response implements HttpResponseOptions {
url: string;
httpVersion: string;
connection: Connection;
constructor(body: CreateBody, options: HttpResponseOptions);
}
export declare class Http2Response extends HttpResponse {
}
/**
* Abstract connection manager.
*/
export interface ConnectionManager<T> {
/**
* Request a connection and initialize in `onReady` once available.
*/
ready(key: string, onReady: (connection: T | undefined) => T | Promise<T>): Promise<T>;
/**
* Create a connection within the `create` callback for tracking.
*/
creating(key: string, create: () => Promise<T>): Promise<T>;
/**
* Claims an existing connection as "in-use".
*/
used(key: string, connection: T): void;
/**
* Removes a connection from "in-use" using the connection key and connection.
* Return `true` when the connection has been deleted from the manager and the
* connection must be destroyed.
*/
freed(key: string, connection: T): boolean;
/**
* Gets any connection (or `undefined` when none exist) using the connection key.
*/
get(key: string): T | undefined;
/**
* Gets a free connection (or `undefined` if none are free) using the connection key.
*/
free(key: string): T | undefined;
/**
* Deletes a connection from free and in-use using the connection key.
*/
delete(key: string, connection: T): void;
}
/**
* Set of connections for HTTP pooling.
*/
export declare class SocketSet<T> {
creating: number;
free: Set<T>;
sockets: Set<T>;
pending: Array<(connection: T | undefined) => void>;
size(): number;
isEmpty(): boolean;
}
/**
* Manage socket reuse.
*/
export declare class SocketConnectionManager<T extends Socket | TLSSocket> implements ConnectionManager<T> {
maxFreeConnections: number;
maxConnections: number;
pools: Map<string, SocketSet<T>>;
constructor(maxFreeConnections?: number, maxConnections?: number);
/**
* Creates a connection when available.
*/
ready(key: string, onReady: (connection: T | undefined) => T | Promise<T>): Promise<T>;
creating(key: string, onCreate: () => Promise<T>): Promise<T>;
pool(key: string): SocketSet<T>;
used(key: string, socket: T): void;
freed(key: string, socket: T): boolean;
private _delete;
get(key: string): T | undefined;
free(key: string): T | undefined;
delete(key: string, socket: T): void;
}
export declare class Http2ConnectionManager implements ConnectionManager<ClientHttp2Session> {
sessions: Map<string, ClientHttp2Session>;
refs: WeakMap<ClientHttp2Session, number>;
ready(key: string, onReady: (session: ClientHttp2Session | undefined) => ClientHttp2Session | Promise<ClientHttp2Session>): Promise<ClientHttp2Session>;
creating(key: string, create: () => Promise<ClientHttp2Session>): Promise<ClientHttp2Session>;
used(key: string, session: ClientHttp2Session): void;
freed(key: string, session: ClientHttp2Session): boolean;
get(key: string): ClientHttp2Session | undefined;
free(key: string): ClientHttp2Session | undefined;
delete(key: string, session: ClientHttp2Session): void;
}
export declare const defaultNetConnect: CreateNetConnection;
export declare const defaultTlsConnect: CreateTlsConnection;
export declare const defaultHttp2Connect: CreateHttp2Connection;
/**
* Used as a cause for the connection error.
*/
export declare class CausedByEarlyCloseError extends Error {
constructor();
}
/**
* Used as a cause for the connection error.
*/
export declare class CausedByTimeoutError extends Error {
constructor();
}
/**
* Expose connection errors.
*/
export declare class ConnectionError extends BaseError {
request: Request;
code: string;
constructor(request: Request, message: string, cause: Error);
}
/**
* ALPN validation error.
*/
export declare class ALPNError extends Error {
request: Request;
code: string;
constructor(request: Request, message: string);
}
/**
* Configure HTTP version negotiation.
*/
export declare enum NegotiateHttpVersion {
HTTP1_ONLY = 0,
HTTP2_FOR_HTTPS = 1,
HTTP2_ONLY = 2
}
export declare type CreateNetConnection = (options: NetConnectOpts) => Socket | Promise<Socket>;
export declare type CreateTlsConnection = (options: TlsConnectOpts) => TLSSocket | Promise<TLSSocket>;
export declare type CreateHttp2Connection = (authority: URL, socket: Socket | TLSSocket) => ClientHttp2Session | Promise<ClientHttp2Session>;
export declare type LookupFunction = (hostname: string, options: LookupOptions, callback: (err: Error | null, address: string, family: number) => void) => void;
/**
* Node.js HTTP request options.
*/
export interface TransportOptions {
keepAlive?: number;
idleSocketTimeout?: number;
idleRequestTimeout?: number;
servername?: string;
rejectUnauthorized?: boolean;
negotiateHttpVersion?: NegotiateHttpVersion;
ca?: string | Buffer | Array<string | Buffer>;
cert?: string | Buffer;
key?: string | Buffer;
secureContext?: SecureContext;
secureProtocol?: string;
secureOptions?: number;
tlsSockets?: ConnectionManager<TLSSocket>;
netSockets?: ConnectionManager<Socket>;
http2Sessions?: ConnectionManager<ClientHttp2Session>;
lookup?: LookupFunction;
createHttp2Connection?: CreateHttp2Connection;
createNetConnection?: CreateNetConnection;
createTlsConnection?: CreateTlsConnection;
}
/**
* Custom abort error instance.
*/
export declare class AbortError extends Error {
request: Request;
code: string;
constructor(request: Request, message: string);
}
/**
* Forward request over HTTP1/1 or HTTP2, with TLS support.
*/
export declare function transport(options?: TransportOptions): (req: Request, next: () => Promise<Response>) => Promise<Response>;