1declare module "http" {
2    import * as events from "events";
3    import * as stream from "stream";
4    import { URL } from "url";
5    import { Socket, Server as NetServer } from "net";
6
7    // incoming headers will never contain number
8    interface IncomingHttpHeaders extends NodeJS.Dict<string | string[]> {
9        'accept'?: string;
10        'accept-language'?: string;
11        'accept-patch'?: string;
12        'accept-ranges'?: string;
13        'access-control-allow-credentials'?: string;
14        'access-control-allow-headers'?: string;
15        'access-control-allow-methods'?: string;
16        'access-control-allow-origin'?: string;
17        'access-control-expose-headers'?: string;
18        'access-control-max-age'?: string;
19        'age'?: string;
20        'allow'?: string;
21        'alt-svc'?: string;
22        'authorization'?: string;
23        'cache-control'?: string;
24        'connection'?: string;
25        'content-disposition'?: string;
26        'content-encoding'?: string;
27        'content-language'?: string;
28        'content-length'?: string;
29        'content-location'?: string;
30        'content-range'?: string;
31        'content-type'?: string;
32        'cookie'?: string;
33        'date'?: string;
34        'expect'?: string;
35        'expires'?: string;
36        'forwarded'?: string;
37        'from'?: string;
38        'host'?: string;
39        'if-match'?: string;
40        'if-modified-since'?: string;
41        'if-none-match'?: string;
42        'if-unmodified-since'?: string;
43        'last-modified'?: string;
44        'location'?: string;
45        'pragma'?: string;
46        'proxy-authenticate'?: string;
47        'proxy-authorization'?: string;
48        'public-key-pins'?: string;
49        'range'?: string;
50        'referer'?: string;
51        'retry-after'?: string;
52        'set-cookie'?: string[];
53        'strict-transport-security'?: string;
54        'tk'?: string;
55        'trailer'?: string;
56        'transfer-encoding'?: string;
57        'upgrade'?: string;
58        'user-agent'?: string;
59        'vary'?: string;
60        'via'?: string;
61        'warning'?: string;
62        'www-authenticate'?: string;
63    }
64
65    // outgoing headers allows numbers (as they are converted internally to strings)
66    interface OutgoingHttpHeaders extends NodeJS.Dict<number | string | string[]> {
67    }
68
69    interface ClientRequestArgs {
70        protocol?: string | null;
71        host?: string | null;
72        hostname?: string | null;
73        family?: number;
74        port?: number | string | null;
75        defaultPort?: number | string;
76        localAddress?: string;
77        socketPath?: string;
78        /**
79         * @default 8192
80         */
81        maxHeaderSize?: number;
82        method?: string;
83        path?: string | null;
84        headers?: OutgoingHttpHeaders;
85        auth?: string | null;
86        agent?: Agent | boolean;
87        _defaultAgent?: Agent;
88        timeout?: number;
89        setHost?: boolean;
90        // https://github.com/nodejs/node/blob/master/lib/_http_client.js#L278
91        createConnection?: (options: ClientRequestArgs, oncreate: (err: Error, socket: Socket) => void) => Socket;
92    }
93
94    interface ServerOptions {
95        IncomingMessage?: typeof IncomingMessage;
96        ServerResponse?: typeof ServerResponse;
97        /**
98         * Optionally overrides the value of
99         * [`--max-http-header-size`][] for requests received by this server, i.e.
100         * the maximum length of request headers in bytes.
101         * @default 8192
102         */
103        maxHeaderSize?: number;
104        /**
105         * Use an insecure HTTP parser that accepts invalid HTTP headers when true.
106         * Using the insecure parser should be avoided.
107         * See --insecure-http-parser for more information.
108         * @default false
109         */
110        insecureHTTPParser?: boolean;
111    }
112
113    type RequestListener = (req: IncomingMessage, res: ServerResponse) => void;
114
115    interface HttpBase {
116        setTimeout(msecs?: number, callback?: () => void): this;
117        setTimeout(callback: () => void): this;
118        /**
119         * Limits maximum incoming headers count. If set to 0, no limit will be applied.
120         * @default 2000
121         * {@link https://nodejs.org/api/http.html#http_server_maxheaderscount}
122         */
123        maxHeadersCount: number | null;
124        timeout: number;
125        /**
126         * Limit the amount of time the parser will wait to receive the complete HTTP headers.
127         * @default 60000
128         * {@link https://nodejs.org/api/http.html#http_server_headerstimeout}
129         */
130        headersTimeout: number;
131        keepAliveTimeout: number;
132    }
133
134    interface Server extends HttpBase {}
135    class Server extends NetServer {
136        constructor(requestListener?: RequestListener);
137        constructor(options: ServerOptions, requestListener?: RequestListener);
138    }
139
140    // https://github.com/nodejs/node/blob/master/lib/_http_outgoing.js
141    class OutgoingMessage extends stream.Writable {
142        upgrading: boolean;
143        chunkedEncoding: boolean;
144        shouldKeepAlive: boolean;
145        useChunkedEncodingByDefault: boolean;
146        sendDate: boolean;
147        /**
148         * @deprecated Use `writableEnded` instead.
149         */
150        finished: boolean;
151        headersSent: boolean;
152        /**
153         * @deprecate Use `socket` instead.
154         */
155        connection: Socket;
156        socket: Socket;
157
158        constructor();
159
160        setTimeout(msecs: number, callback?: () => void): this;
161        setHeader(name: string, value: number | string | string[]): void;
162        getHeader(name: string): number | string | string[] | undefined;
163        getHeaders(): OutgoingHttpHeaders;
164        getHeaderNames(): string[];
165        hasHeader(name: string): boolean;
166        removeHeader(name: string): void;
167        addTrailers(headers: OutgoingHttpHeaders | Array<[string, string]>): void;
168        flushHeaders(): void;
169    }
170
171    // https://github.com/nodejs/node/blob/master/lib/_http_server.js#L108-L256
172    class ServerResponse extends OutgoingMessage {
173        statusCode: number;
174        statusMessage: string;
175
176        constructor(req: IncomingMessage);
177
178        assignSocket(socket: Socket): void;
179        detachSocket(socket: Socket): void;
180        // https://github.com/nodejs/node/blob/master/test/parallel/test-http-write-callbacks.js#L53
181        // no args in writeContinue callback
182        writeContinue(callback?: () => void): void;
183        writeHead(statusCode: number, reasonPhrase?: string, headers?: OutgoingHttpHeaders): this;
184        writeHead(statusCode: number, headers?: OutgoingHttpHeaders): this;
185        writeProcessing(): void;
186    }
187
188    interface InformationEvent {
189        statusCode: number;
190        statusMessage: string;
191        httpVersion: string;
192        httpVersionMajor: number;
193        httpVersionMinor: number;
194        headers: IncomingHttpHeaders;
195        rawHeaders: string[];
196    }
197
198    // https://github.com/nodejs/node/blob/master/lib/_http_client.js#L77
199    class ClientRequest extends OutgoingMessage {
200        connection: Socket;
201        socket: Socket;
202        aborted: number;
203
204        constructor(url: string | URL | ClientRequestArgs, cb?: (res: IncomingMessage) => void);
205
206        method: string;
207        path: string;
208        abort(): void;
209        onSocket(socket: Socket): void;
210        setTimeout(timeout: number, callback?: () => void): this;
211        setNoDelay(noDelay?: boolean): void;
212        setSocketKeepAlive(enable?: boolean, initialDelay?: number): void;
213
214        addListener(event: 'abort', listener: () => void): this;
215        addListener(event: 'connect', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
216        addListener(event: 'continue', listener: () => void): this;
217        addListener(event: 'information', listener: (info: InformationEvent) => void): this;
218        addListener(event: 'response', listener: (response: IncomingMessage) => void): this;
219        addListener(event: 'socket', listener: (socket: Socket) => void): this;
220        addListener(event: 'timeout', listener: () => void): this;
221        addListener(event: 'upgrade', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
222        addListener(event: 'close', listener: () => void): this;
223        addListener(event: 'drain', listener: () => void): this;
224        addListener(event: 'error', listener: (err: Error) => void): this;
225        addListener(event: 'finish', listener: () => void): this;
226        addListener(event: 'pipe', listener: (src: stream.Readable) => void): this;
227        addListener(event: 'unpipe', listener: (src: stream.Readable) => void): this;
228        addListener(event: string | symbol, listener: (...args: any[]) => void): this;
229
230        on(event: 'abort', listener: () => void): this;
231        on(event: 'connect', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
232        on(event: 'continue', listener: () => void): this;
233        on(event: 'information', listener: (info: InformationEvent) => void): this;
234        on(event: 'response', listener: (response: IncomingMessage) => void): this;
235        on(event: 'socket', listener: (socket: Socket) => void): this;
236        on(event: 'timeout', listener: () => void): this;
237        on(event: 'upgrade', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
238        on(event: 'close', listener: () => void): this;
239        on(event: 'drain', listener: () => void): this;
240        on(event: 'error', listener: (err: Error) => void): this;
241        on(event: 'finish', listener: () => void): this;
242        on(event: 'pipe', listener: (src: stream.Readable) => void): this;
243        on(event: 'unpipe', listener: (src: stream.Readable) => void): this;
244        on(event: string | symbol, listener: (...args: any[]) => void): this;
245
246        once(event: 'abort', listener: () => void): this;
247        once(event: 'connect', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
248        once(event: 'continue', listener: () => void): this;
249        once(event: 'information', listener: (info: InformationEvent) => void): this;
250        once(event: 'response', listener: (response: IncomingMessage) => void): this;
251        once(event: 'socket', listener: (socket: Socket) => void): this;
252        once(event: 'timeout', listener: () => void): this;
253        once(event: 'upgrade', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
254        once(event: 'close', listener: () => void): this;
255        once(event: 'drain', listener: () => void): this;
256        once(event: 'error', listener: (err: Error) => void): this;
257        once(event: 'finish', listener: () => void): this;
258        once(event: 'pipe', listener: (src: stream.Readable) => void): this;
259        once(event: 'unpipe', listener: (src: stream.Readable) => void): this;
260        once(event: string | symbol, listener: (...args: any[]) => void): this;
261
262        prependListener(event: 'abort', listener: () => void): this;
263        prependListener(event: 'connect', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
264        prependListener(event: 'continue', listener: () => void): this;
265        prependListener(event: 'information', listener: (info: InformationEvent) => void): this;
266        prependListener(event: 'response', listener: (response: IncomingMessage) => void): this;
267        prependListener(event: 'socket', listener: (socket: Socket) => void): this;
268        prependListener(event: 'timeout', listener: () => void): this;
269        prependListener(event: 'upgrade', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
270        prependListener(event: 'close', listener: () => void): this;
271        prependListener(event: 'drain', listener: () => void): this;
272        prependListener(event: 'error', listener: (err: Error) => void): this;
273        prependListener(event: 'finish', listener: () => void): this;
274        prependListener(event: 'pipe', listener: (src: stream.Readable) => void): this;
275        prependListener(event: 'unpipe', listener: (src: stream.Readable) => void): this;
276        prependListener(event: string | symbol, listener: (...args: any[]) => void): this;
277
278        prependOnceListener(event: 'abort', listener: () => void): this;
279        prependOnceListener(event: 'connect', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
280        prependOnceListener(event: 'continue', listener: () => void): this;
281        prependOnceListener(event: 'information', listener: (info: InformationEvent) => void): this;
282        prependOnceListener(event: 'response', listener: (response: IncomingMessage) => void): this;
283        prependOnceListener(event: 'socket', listener: (socket: Socket) => void): this;
284        prependOnceListener(event: 'timeout', listener: () => void): this;
285        prependOnceListener(event: 'upgrade', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
286        prependOnceListener(event: 'close', listener: () => void): this;
287        prependOnceListener(event: 'drain', listener: () => void): this;
288        prependOnceListener(event: 'error', listener: (err: Error) => void): this;
289        prependOnceListener(event: 'finish', listener: () => void): this;
290        prependOnceListener(event: 'pipe', listener: (src: stream.Readable) => void): this;
291        prependOnceListener(event: 'unpipe', listener: (src: stream.Readable) => void): this;
292        prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this;
293    }
294
295    class IncomingMessage extends stream.Readable {
296        constructor(socket: Socket);
297
298        aborted: boolean;
299        httpVersion: string;
300        httpVersionMajor: number;
301        httpVersionMinor: number;
302        complete: boolean;
303        /**
304         * @deprecate Use `socket` instead.
305         */
306        connection: Socket;
307        socket: Socket;
308        headers: IncomingHttpHeaders;
309        rawHeaders: string[];
310        trailers: NodeJS.Dict<string>;
311        rawTrailers: string[];
312        setTimeout(msecs: number, callback?: () => void): this;
313        /**
314         * Only valid for request obtained from http.Server.
315         */
316        method?: string;
317        /**
318         * Only valid for request obtained from http.Server.
319         */
320        url?: string;
321        /**
322         * Only valid for response obtained from http.ClientRequest.
323         */
324        statusCode?: number;
325        /**
326         * Only valid for response obtained from http.ClientRequest.
327         */
328        statusMessage?: string;
329        destroy(error?: Error): void;
330    }
331
332    interface AgentOptions {
333        /**
334         * Keep sockets around in a pool to be used by other requests in the future. Default = false
335         */
336        keepAlive?: boolean;
337        /**
338         * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000.
339         * Only relevant if keepAlive is set to true.
340         */
341        keepAliveMsecs?: number;
342        /**
343         * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity
344         */
345        maxSockets?: number;
346        /**
347         * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256.
348         */
349        maxFreeSockets?: number;
350        /**
351         * Socket timeout in milliseconds. This will set the timeout after the socket is connected.
352         */
353        timeout?: number;
354    }
355
356    class Agent {
357        maxFreeSockets: number;
358        maxSockets: number;
359        readonly sockets: NodeJS.ReadOnlyDict<Socket[]>;
360        readonly requests: NodeJS.ReadOnlyDict<IncomingMessage[]>;
361
362        constructor(opts?: AgentOptions);
363
364        /**
365         * Destroy any sockets that are currently in use by the agent.
366         * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled,
367         * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise,
368         * sockets may hang open for quite a long time before the server terminates them.
369         */
370        destroy(): void;
371    }
372
373    const METHODS: string[];
374
375    const STATUS_CODES: {
376        [errorCode: number]: string | undefined;
377        [errorCode: string]: string | undefined;
378    };
379
380    function createServer(requestListener?: RequestListener): Server;
381    function createServer(options: ServerOptions, requestListener?: RequestListener): Server;
382
383    // although RequestOptions are passed as ClientRequestArgs to ClientRequest directly,
384    // create interface RequestOptions would make the naming more clear to developers
385    interface RequestOptions extends ClientRequestArgs { }
386    function request(options: RequestOptions | string | URL, callback?: (res: IncomingMessage) => void): ClientRequest;
387    function request(url: string | URL, options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest;
388    function get(options: RequestOptions | string | URL, callback?: (res: IncomingMessage) => void): ClientRequest;
389    function get(url: string | URL, options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest;
390    let globalAgent: Agent;
391
392    /**
393     * Read-only property specifying the maximum allowed size of HTTP headers in bytes.
394     * Defaults to 16KB. Configurable using the [`--max-http-header-size`][] CLI option.
395     */
396    const maxHeaderSize: number;
397}
398