@httptoolkit/httpolyglot 2.0.1 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ /// <reference types="node" />
5
+ /// <reference types="node" />
2
6
  import * as net from 'net';
7
+ import * as tls from 'tls';
3
8
  import * as http from 'http';
4
9
  import * as https from 'https';
5
10
  declare module 'net' {
@@ -11,10 +16,41 @@ export declare class Server extends net.Server {
11
16
  private _httpServer;
12
17
  private _http2Server;
13
18
  private _tlsServer;
19
+ /**
20
+ * Create an Httpolyglot instance with just a request listener to support plain-text
21
+ * HTTP & HTTP/2 on the same port, with incoming TLS connections being closed immediately.
22
+ */
14
23
  constructor(requestListener: http.RequestListener);
15
- constructor(tlsConfig: https.ServerOptions, requestListener: http.RequestListener);
24
+ /**
25
+ * Call with a full TLS configuration to create a TLS+HTTP+HTTP/2 server, which can
26
+ * support all protocols on the same port.
27
+ */
28
+ constructor(config: https.ServerOptions, requestListener: http.RequestListener);
29
+ /**
30
+ * Pass an existing TLS server, instead of TLS configuration, to create a TLS+HTTP+HTTP/2
31
+ * server. All incoming TLS requests will be emitted as 'connection' events on the given
32
+ * TLS server, and all 'secureConnection' events coming from the TLS server will be
33
+ * handled according to the connection type detected on that socket.
34
+ */
35
+ constructor(tlsServer: tls.Server, requestListener: http.RequestListener);
16
36
  private connectionListener;
37
+ private tlsListener;
17
38
  private http2Listener;
18
39
  }
40
+ /**
41
+ * Create an Httpolyglot instance with just a request listener to support plain-text
42
+ * HTTP & HTTP/2 on the same port, with incoming TLS connections being closed immediately.
43
+ */
19
44
  export declare function createServer(requestListener: http.RequestListener): Server;
45
+ /**
46
+ * Create an instance with a full TLS configuration to create a TLS+HTTP+HTTP/2 server, which can
47
+ * support all protocols on the same port.
48
+ */
20
49
  export declare function createServer(tlsConfig: https.ServerOptions, requestListener: http.RequestListener): Server;
50
+ /**
51
+ * Create an instance around an existing TLS server, instead of TLS configuration, to create a
52
+ * TLS+HTTP+HTTP/2 server with custom TLS handling. All incoming TLS requests will be emitted as
53
+ * 'connection' events on the given TLS server, and all 'secureConnection' events coming from the
54
+ * TLS server will be handled according to the connection type detected on that socket.
55
+ */
56
+ export declare function createServer(tlsServer: tls.Server, requestListener: http.RequestListener): Server;
package/dist/index.js CHANGED
@@ -12,18 +12,23 @@ const HTTP2_PREFACE = 'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n';
12
12
  const HTTP2_PREFACE_BUFFER = Buffer.from(HTTP2_PREFACE);
13
13
  const NODE_MAJOR_VERSION = parseInt(process.version.slice(1).split('.')[0], 10);
14
14
  class Server extends net.Server {
15
- constructor(configOrListener, listener) {
15
+ constructor(configOrServerOrListener, listener) {
16
16
  // We just act as a plain TCP server, accepting and examing
17
17
  // each connection, then passing it to the right subserver.
18
18
  super((socket) => this.connectionListener(socket));
19
19
  let tlsConfig;
20
+ let tlsServer;
20
21
  let requestListener;
21
- if (typeof configOrListener === 'function') {
22
- requestListener = configOrListener;
22
+ if (typeof configOrServerOrListener === 'function') {
23
+ requestListener = configOrServerOrListener;
23
24
  tlsConfig = undefined;
24
25
  }
26
+ else if (configOrServerOrListener instanceof tls.Server) {
27
+ tlsServer = configOrServerOrListener;
28
+ requestListener = listener;
29
+ }
25
30
  else {
26
- tlsConfig = configOrListener;
31
+ tlsConfig = configOrServerOrListener;
27
32
  requestListener = listener;
28
33
  }
29
34
  // We bind the request listener, so 'this' always refers to us, not each subserver.
@@ -32,17 +37,16 @@ class Server extends net.Server {
32
37
  // Create subservers for each supported protocol:
33
38
  this._httpServer = new http.Server(boundListener);
34
39
  this._http2Server = http2.createServer({}, boundListener);
35
- if (typeof tlsConfig === 'object') {
40
+ if (tlsServer) {
41
+ // If we've been given a preconfigured TLS server, we use that directly, and
42
+ // subscribe to connections there
43
+ this._tlsServer = tlsServer;
44
+ this._tlsServer.on('secureConnection', this.tlsListener.bind(this));
45
+ }
46
+ else if (typeof tlsConfig === 'object') {
36
47
  // If we have TLS config, create a TLS server, which will pass sockets to
37
48
  // the relevant subserver once the TLS connection is set up.
38
- this._tlsServer = new tls.Server(tlsConfig, (tlsSocket) => {
39
- if (tlsSocket.alpnProtocol === false || tlsSocket.alpnProtocol === 'http/1.1') {
40
- this._httpServer.emit('connection', tlsSocket);
41
- }
42
- else {
43
- this._http2Server.emit('connection', tlsSocket);
44
- }
45
- });
49
+ this._tlsServer = new tls.Server(tlsConfig, this.tlsListener.bind(this));
46
50
  }
47
51
  else {
48
52
  // Fake server that rejects all connections:
@@ -100,6 +104,17 @@ class Server extends net.Server {
100
104
  }
101
105
  }
102
106
  }
107
+ tlsListener(tlsSocket) {
108
+ if (tlsSocket.alpnProtocol === false || // Old non-ALPN client
109
+ tlsSocket.alpnProtocol === 'http/1.1' || // Modern HTTP/1.1 ALPN client
110
+ tlsSocket.alpnProtocol === 'http 1.1' // Broken ALPN client (e.g. https-proxy-agent)
111
+ ) {
112
+ this._httpServer.emit('connection', tlsSocket);
113
+ }
114
+ else {
115
+ this._http2Server.emit('connection', tlsSocket);
116
+ }
117
+ }
103
118
  http2Listener(socket, pastData) {
104
119
  const h1Server = this._httpServer;
105
120
  const h2Server = this._http2Server;
@@ -145,8 +160,8 @@ class Server extends net.Server {
145
160
  }
146
161
  }
147
162
  exports.Server = Server;
148
- function createServer(configOrListener, listener) {
149
- return new Server(configOrListener, listener);
163
+ function createServer(configOrServerOrListener, listener) {
164
+ return new Server(configOrServerOrListener, listener);
150
165
  }
151
166
  exports.createServer = createServer;
152
167
  ;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httptoolkit/httpolyglot",
3
- "version": "2.0.1",
3
+ "version": "2.1.1",
4
4
  "author": "Tim Perry <pimterry@gmail.com>",
5
5
  "description": "Serve http and https connections over the same port with node.js",
6
6
  "main": "./dist/index.js",
package/src/index.ts CHANGED
@@ -28,21 +28,46 @@ export class Server extends net.Server {
28
28
  private _http2Server: http2.Http2Server;
29
29
  private _tlsServer: EventEmitter;
30
30
 
31
+ /**
32
+ * Create an Httpolyglot instance with just a request listener to support plain-text
33
+ * HTTP & HTTP/2 on the same port, with incoming TLS connections being closed immediately.
34
+ */
31
35
  constructor(requestListener: http.RequestListener);
32
- constructor(tlsConfig: https.ServerOptions, requestListener: http.RequestListener);
33
- constructor(configOrListener: https.ServerOptions | http.RequestListener, listener?: http.RequestListener) {
36
+ /**
37
+ * Call with a full TLS configuration to create a TLS+HTTP+HTTP/2 server, which can
38
+ * support all protocols on the same port.
39
+ */
40
+ constructor(config: https.ServerOptions, requestListener: http.RequestListener);
41
+ /**
42
+ * Pass an existing TLS server, instead of TLS configuration, to create a TLS+HTTP+HTTP/2
43
+ * server. All incoming TLS requests will be emitted as 'connection' events on the given
44
+ * TLS server, and all 'secureConnection' events coming from the TLS server will be
45
+ * handled according to the connection type detected on that socket.
46
+ */
47
+ constructor(tlsServer: tls.Server, requestListener: http.RequestListener);
48
+ constructor(
49
+ configOrServerOrListener:
50
+ | https.ServerOptions
51
+ | tls.Server
52
+ | http.RequestListener,
53
+ listener?: http.RequestListener
54
+ ) {
34
55
  // We just act as a plain TCP server, accepting and examing
35
56
  // each connection, then passing it to the right subserver.
36
57
  super((socket) => this.connectionListener(socket));
37
58
 
38
59
  let tlsConfig: https.ServerOptions | undefined;
60
+ let tlsServer: tls.Server | undefined;
39
61
  let requestListener: http.RequestListener;
40
62
 
41
- if (typeof configOrListener === 'function') {
42
- requestListener = configOrListener;
63
+ if (typeof configOrServerOrListener === 'function') {
64
+ requestListener = configOrServerOrListener;
43
65
  tlsConfig = undefined;
66
+ } else if (configOrServerOrListener instanceof tls.Server) {
67
+ tlsServer = configOrServerOrListener;
68
+ requestListener = listener!;
44
69
  } else {
45
- tlsConfig = configOrListener;
70
+ tlsConfig = configOrServerOrListener;
46
71
  requestListener = listener!;
47
72
  }
48
73
 
@@ -54,16 +79,15 @@ export class Server extends net.Server {
54
79
  this._httpServer = new http.Server(boundListener);
55
80
  this._http2Server = http2.createServer({}, boundListener as any as Http2Listener);
56
81
 
57
- if (typeof tlsConfig === 'object') {
82
+ if (tlsServer) {
83
+ // If we've been given a preconfigured TLS server, we use that directly, and
84
+ // subscribe to connections there
85
+ this._tlsServer = tlsServer;
86
+ this._tlsServer.on('secureConnection', this.tlsListener.bind(this));
87
+ } else if (typeof tlsConfig === 'object') {
58
88
  // If we have TLS config, create a TLS server, which will pass sockets to
59
89
  // the relevant subserver once the TLS connection is set up.
60
- this._tlsServer = new tls.Server(tlsConfig, (tlsSocket) => {
61
- if (tlsSocket.alpnProtocol === false || tlsSocket.alpnProtocol === 'http/1.1') {
62
- this._httpServer.emit('connection', tlsSocket);
63
- } else {
64
- this._http2Server.emit('connection', tlsSocket);
65
- }
66
- });
90
+ this._tlsServer = new tls.Server(tlsConfig, this.tlsListener.bind(this));
67
91
  } else {
68
92
  // Fake server that rejects all connections:
69
93
  this._tlsServer = new EventEmitter();
@@ -126,6 +150,18 @@ export class Server extends net.Server {
126
150
  }
127
151
  }
128
152
 
153
+ private tlsListener(tlsSocket: tls.TLSSocket) {
154
+ if (
155
+ tlsSocket.alpnProtocol === false || // Old non-ALPN client
156
+ tlsSocket.alpnProtocol === 'http/1.1' || // Modern HTTP/1.1 ALPN client
157
+ tlsSocket.alpnProtocol === 'http 1.1' // Broken ALPN client (e.g. https-proxy-agent)
158
+ ) {
159
+ this._httpServer.emit('connection', tlsSocket);
160
+ } else {
161
+ this._http2Server.emit('connection', tlsSocket);
162
+ }
163
+ }
164
+
129
165
  private http2Listener(socket: net.Socket, pastData?: Buffer) {
130
166
  const h1Server = this._httpServer;
131
167
  const h2Server = this._http2Server;
@@ -173,8 +209,28 @@ export class Server extends net.Server {
173
209
  }
174
210
  }
175
211
 
212
+ /**
213
+ * Create an Httpolyglot instance with just a request listener to support plain-text
214
+ * HTTP & HTTP/2 on the same port, with incoming TLS connections being closed immediately.
215
+ */
176
216
  export function createServer(requestListener: http.RequestListener): Server;
217
+ /**
218
+ * Create an instance with a full TLS configuration to create a TLS+HTTP+HTTP/2 server, which can
219
+ * support all protocols on the same port.
220
+ */
177
221
  export function createServer(tlsConfig: https.ServerOptions, requestListener: http.RequestListener): Server;
178
- export function createServer(configOrListener: https.ServerOptions | http.RequestListener, listener?: http.RequestListener) {
179
- return new Server(configOrListener as any, listener as any);
222
+ /**
223
+ * Create an instance around an existing TLS server, instead of TLS configuration, to create a
224
+ * TLS+HTTP+HTTP/2 server with custom TLS handling. All incoming TLS requests will be emitted as
225
+ * 'connection' events on the given TLS server, and all 'secureConnection' events coming from the
226
+ * TLS server will be handled according to the connection type detected on that socket.
227
+ */
228
+ export function createServer(tlsServer: tls.Server, requestListener: http.RequestListener): Server;
229
+ export function createServer(configOrServerOrListener:
230
+ | https.ServerOptions
231
+ | http.RequestListener
232
+ | tls.Server,
233
+ listener?: http.RequestListener
234
+ ) {
235
+ return new Server(configOrServerOrListener as any, listener as any);
180
236
  };