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 {
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        [header: string]: string | string[] | undefined;
64    }
65
66    // outgoing headers allows numbers (as they are converted internally to strings)
67    interface OutgoingHttpHeaders {
68        [header: string]: number | string | string[] | undefined;
69    }
70
71    interface ClientRequestArgs {
72        protocol?: string | null;
73        host?: string | null;
74        hostname?: string | null;
75        family?: number;
76        port?: number | string | null;
77        defaultPort?: number | string;
78        localAddress?: string;
79        socketPath?: string;
80        method?: string;
81        path?: string | null;
82        headers?: OutgoingHttpHeaders;
83        auth?: string | null;
84        agent?: Agent | boolean;
85        _defaultAgent?: Agent;
86        timeout?: number;
87        setHost?: boolean;
88        // https://github.com/nodejs/node/blob/master/lib/_http_client.js#L278
89        createConnection?: (options: ClientRequestArgs, oncreate: (err: Error, socket: Socket) => void) => Socket;
90    }
91
92    interface ServerOptions {
93        IncomingMessage?: typeof IncomingMessage;
94        ServerResponse?: typeof ServerResponse;
95    }
96
97    type RequestListener = (req: IncomingMessage, res: ServerResponse) => void;
98
99    class Server extends NetServer {
100        constructor(requestListener?: RequestListener);
101        constructor(options: ServerOptions, requestListener?: RequestListener);
102
103        setTimeout(msecs?: number, callback?: () => void): this;
104        setTimeout(callback: () => void): this;
105        /**
106         * Limits maximum incoming headers count. If set to 0, no limit will be applied.
107         * @default 2000
108         * {@link https://nodejs.org/api/http.html#http_server_maxheaderscount}
109         */
110        maxHeadersCount: number | null;
111        timeout: number;
112        /**
113         * Limit the amount of time the parser will wait to receive the complete HTTP headers.
114         * @default 40000
115         * {@link https://nodejs.org/api/http.html#http_server_headerstimeout}
116         */
117        headersTimeout: number;
118        keepAliveTimeout: number;
119    }
120
121    // https://github.com/nodejs/node/blob/master/lib/_http_outgoing.js
122    class OutgoingMessage extends stream.Writable {
123        upgrading: boolean;
124        chunkedEncoding: boolean;
125        shouldKeepAlive: boolean;
126        useChunkedEncodingByDefault: boolean;
127        sendDate: boolean;
128        finished: boolean;
129        headersSent: boolean;
130        connection: Socket;
131
132        constructor();
133
134        setTimeout(msecs: number, callback?: () => void): this;
135        setHeader(name: string, value: number | string | string[]): void;
136        getHeader(name: string): number | string | string[] | undefined;
137        getHeaders(): OutgoingHttpHeaders;
138        getHeaderNames(): string[];
139        hasHeader(name: string): boolean;
140        removeHeader(name: string): void;
141        addTrailers(headers: OutgoingHttpHeaders | Array<[string, string]>): void;
142        flushHeaders(): void;
143    }
144
145    // https://github.com/nodejs/node/blob/master/lib/_http_server.js#L108-L256
146    class ServerResponse extends OutgoingMessage {
147        statusCode: number;
148        statusMessage: string;
149        writableFinished: boolean;
150
151        constructor(req: IncomingMessage);
152
153        assignSocket(socket: Socket): void;
154        detachSocket(socket: Socket): void;
155        // https://github.com/nodejs/node/blob/master/test/parallel/test-http-write-callbacks.js#L53
156        // no args in writeContinue callback
157        writeContinue(callback?: () => void): void;
158        writeHead(statusCode: number, reasonPhrase?: string, headers?: OutgoingHttpHeaders): this;
159        writeHead(statusCode: number, headers?: OutgoingHttpHeaders): this;
160        writeProcessing(): void;
161    }
162
163    interface InformationEvent {
164        statusCode: number;
165        statusMessage: string;
166        httpVersion: string;
167        httpVersionMajor: number;
168        httpVersionMinor: number;
169        headers: IncomingHttpHeaders;
170        rawHeaders: string[];
171    }
172
173    // https://github.com/nodejs/node/blob/master/lib/_http_client.js#L77
174    class ClientRequest extends OutgoingMessage {
175        connection: Socket;
176        socket: Socket;
177        aborted: number;
178
179        constructor(url: string | URL | ClientRequestArgs, cb?: (res: IncomingMessage) => void);
180
181        readonly path: string;
182        abort(): void;
183        onSocket(socket: Socket): void;
184        setTimeout(timeout: number, callback?: () => void): this;
185        setNoDelay(noDelay?: boolean): void;
186        setSocketKeepAlive(enable?: boolean, initialDelay?: number): void;
187
188        addListener(event: 'abort', listener: () => void): this;
189        addListener(event: 'connect', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
190        addListener(event: 'continue', listener: () => void): this;
191        addListener(event: 'information', listener: (info: InformationEvent) => void): this;
192        addListener(event: 'response', listener: (response: IncomingMessage) => void): this;
193        addListener(event: 'socket', listener: (socket: Socket) => void): this;
194        addListener(event: 'timeout', listener: () => void): this;
195        addListener(event: 'upgrade', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
196        addListener(event: 'close', listener: () => void): this;
197        addListener(event: 'drain', listener: () => void): this;
198        addListener(event: 'error', listener: (err: Error) => void): this;
199        addListener(event: 'finish', listener: () => void): this;
200        addListener(event: 'pipe', listener: (src: stream.Readable) => void): this;
201        addListener(event: 'unpipe', listener: (src: stream.Readable) => void): this;
202        addListener(event: string | symbol, listener: (...args: any[]) => void): this;
203
204        on(event: 'abort', listener: () => void): this;
205        on(event: 'connect', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
206        on(event: 'continue', listener: () => void): this;
207        on(event: 'information', listener: (info: InformationEvent) => void): this;
208        on(event: 'response', listener: (response: IncomingMessage) => void): this;
209        on(event: 'socket', listener: (socket: Socket) => void): this;
210        on(event: 'timeout', listener: () => void): this;
211        on(event: 'upgrade', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
212        on(event: 'close', listener: () => void): this;
213        on(event: 'drain', listener: () => void): this;
214        on(event: 'error', listener: (err: Error) => void): this;
215        on(event: 'finish', listener: () => void): this;
216        on(event: 'pipe', listener: (src: stream.Readable) => void): this;
217        on(event: 'unpipe', listener: (src: stream.Readable) => void): this;
218        on(event: string | symbol, listener: (...args: any[]) => void): this;
219
220        once(event: 'abort', listener: () => void): this;
221        once(event: 'connect', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
222        once(event: 'continue', listener: () => void): this;
223        once(event: 'information', listener: (info: InformationEvent) => void): this;
224        once(event: 'response', listener: (response: IncomingMessage) => void): this;
225        once(event: 'socket', listener: (socket: Socket) => void): this;
226        once(event: 'timeout', listener: () => void): this;
227        once(event: 'upgrade', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
228        once(event: 'close', listener: () => void): this;
229        once(event: 'drain', listener: () => void): this;
230        once(event: 'error', listener: (err: Error) => void): this;
231        once(event: 'finish', listener: () => void): this;
232        once(event: 'pipe', listener: (src: stream.Readable) => void): this;
233        once(event: 'unpipe', listener: (src: stream.Readable) => void): this;
234        once(event: string | symbol, listener: (...args: any[]) => void): this;
235
236        prependListener(event: 'abort', listener: () => void): this;
237        prependListener(event: 'connect', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
238        prependListener(event: 'continue', listener: () => void): this;
239        prependListener(event: 'information', listener: (info: InformationEvent) => void): this;
240        prependListener(event: 'response', listener: (response: IncomingMessage) => void): this;
241        prependListener(event: 'socket', listener: (socket: Socket) => void): this;
242        prependListener(event: 'timeout', listener: () => void): this;
243        prependListener(event: 'upgrade', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
244        prependListener(event: 'close', listener: () => void): this;
245        prependListener(event: 'drain', listener: () => void): this;
246        prependListener(event: 'error', listener: (err: Error) => void): this;
247        prependListener(event: 'finish', listener: () => void): this;
248        prependListener(event: 'pipe', listener: (src: stream.Readable) => void): this;
249        prependListener(event: 'unpipe', listener: (src: stream.Readable) => void): this;
250        prependListener(event: string | symbol, listener: (...args: any[]) => void): this;
251
252        prependOnceListener(event: 'abort', listener: () => void): this;
253        prependOnceListener(event: 'connect', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
254        prependOnceListener(event: 'continue', listener: () => void): this;
255        prependOnceListener(event: 'information', listener: (info: InformationEvent) => void): this;
256        prependOnceListener(event: 'response', listener: (response: IncomingMessage) => void): this;
257        prependOnceListener(event: 'socket', listener: (socket: Socket) => void): this;
258        prependOnceListener(event: 'timeout', listener: () => void): this;
259        prependOnceListener(event: 'upgrade', listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
260        prependOnceListener(event: 'close', listener: () => void): this;
261        prependOnceListener(event: 'drain', listener: () => void): this;
262        prependOnceListener(event: 'error', listener: (err: Error) => void): this;
263        prependOnceListener(event: 'finish', listener: () => void): this;
264        prependOnceListener(event: 'pipe', listener: (src: stream.Readable) => void): this;
265        prependOnceListener(event: 'unpipe', listener: (src: stream.Readable) => void): this;
266        prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this;
267    }
268
269    class IncomingMessage extends stream.Readable {
270        constructor(socket: Socket);
271
272        httpVersion: string;
273        httpVersionMajor: number;
274        httpVersionMinor: number;
275        complete: boolean;
276        connection: Socket;
277        headers: IncomingHttpHeaders;
278        rawHeaders: string[];
279        trailers: { [key: string]: string | undefined };
280        rawTrailers: string[];
281        setTimeout(msecs: number, callback?: () => void): this;
282        /**
283         * Only valid for request obtained from http.Server.
284         */
285        method?: string;
286        /**
287         * Only valid for request obtained from http.Server.
288         */
289        url?: string;
290        /**
291         * Only valid for response obtained from http.ClientRequest.
292         */
293        statusCode?: number;
294        /**
295         * Only valid for response obtained from http.ClientRequest.
296         */
297        statusMessage?: string;
298        socket: Socket;
299        destroy(error?: Error): void;
300    }
301
302    interface AgentOptions {
303        /**
304         * Keep sockets around in a pool to be used by other requests in the future. Default = false
305         */
306        keepAlive?: boolean;
307        /**
308         * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000.
309         * Only relevant if keepAlive is set to true.
310         */
311        keepAliveMsecs?: number;
312        /**
313         * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity
314         */
315        maxSockets?: number;
316        /**
317         * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256.
318         */
319        maxFreeSockets?: number;
320        /**
321         * Socket timeout in milliseconds. This will set the timeout after the socket is connected.
322         */
323        timeout?: number;
324    }
325
326    class Agent {
327        maxFreeSockets: number;
328        maxSockets: number;
329        readonly sockets: {
330            readonly [key: string]: Socket[];
331        };
332        readonly requests: {
333            readonly [key: string]: IncomingMessage[];
334        };
335
336        constructor(opts?: AgentOptions);
337
338        /**
339         * Destroy any sockets that are currently in use by the agent.
340         * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled,
341         * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise,
342         * sockets may hang open for quite a long time before the server terminates them.
343         */
344        destroy(): void;
345    }
346
347    const METHODS: string[];
348
349    const STATUS_CODES: {
350        [errorCode: number]: string | undefined;
351        [errorCode: string]: string | undefined;
352    };
353
354    function createServer(requestListener?: RequestListener): Server;
355    function createServer(options: ServerOptions, requestListener?: RequestListener): Server;
356
357    // although RequestOptions are passed as ClientRequestArgs to ClientRequest directly,
358    // create interface RequestOptions would make the naming more clear to developers
359    interface RequestOptions extends ClientRequestArgs { }
360    function request(options: RequestOptions | string | URL, callback?: (res: IncomingMessage) => void): ClientRequest;
361    function request(url: string | URL, options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest;
362    function get(options: RequestOptions | string | URL, callback?: (res: IncomingMessage) => void): ClientRequest;
363    function get(url: string | URL, options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest;
364    let globalAgent: Agent;
365
366    /**
367     * Read-only property specifying the maximum allowed size of HTTP headers in bytes.
368     * Defaults to 8KB. Configurable using the [`--max-http-header-size`][] CLI option.
369     */
370    const maxHeaderSize: number;
371}
372