@httptoolkit/httpolyglot 2.0.1 → 2.1.0

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,6 @@
1
1
  /// <reference types="node" />
2
2
  import * as net from 'net';
3
+ import * as tls from 'tls';
3
4
  import * as http from 'http';
4
5
  import * as https from 'https';
5
6
  declare module 'net' {
@@ -11,10 +12,41 @@ export declare class Server extends net.Server {
11
12
  private _httpServer;
12
13
  private _http2Server;
13
14
  private _tlsServer;
15
+ /**
16
+ * Create an Httpolyglot instance with just a request listener to support plain-text
17
+ * HTTP & HTTP/2 on the same port, with incoming TLS connections being closed immediately.
18
+ */
14
19
  constructor(requestListener: http.RequestListener);
15
- constructor(tlsConfig: https.ServerOptions, requestListener: http.RequestListener);
20
+ /**
21
+ * Call with a full TLS configuration to create a TLS+HTTP+HTTP/2 server, which can
22
+ * support all protocols on the same port.
23
+ */
24
+ constructor(config: https.ServerOptions, requestListener: http.RequestListener);
25
+ /**
26
+ * Pass an existing TLS server, instead of TLS configuration, to create a TLS+HTTP+HTTP/2
27
+ * server. All incoming TLS requests will be emitted as 'connection' events on the given
28
+ * TLS server, and all 'secureConnection' events coming from the TLS server will be
29
+ * handled according to the connection type detected on that socket.
30
+ */
31
+ constructor(tlsServer: tls.Server, requestListener: http.RequestListener);
16
32
  private connectionListener;
33
+ private tlsListener;
17
34
  private http2Listener;
18
35
  }
36
+ /**
37
+ * Create an Httpolyglot instance with just a request listener to support plain-text
38
+ * HTTP & HTTP/2 on the same port, with incoming TLS connections being closed immediately.
39
+ */
19
40
  export declare function createServer(requestListener: http.RequestListener): Server;
41
+ /**
42
+ * Create an instance with a full TLS configuration to create a TLS+HTTP+HTTP/2 server, which can
43
+ * support all protocols on the same port.
44
+ */
20
45
  export declare function createServer(tlsConfig: https.ServerOptions, requestListener: http.RequestListener): Server;
46
+ /**
47
+ * Create an instance around an existing TLS server, instead of TLS configuration, to create a
48
+ * TLS+HTTP+HTTP/2 server with custom TLS handling. All incoming TLS requests will be emitted as
49
+ * 'connection' events on the given TLS server, and all 'secureConnection' events coming from the
50
+ * TLS server will be handled according to the connection type detected on that socket.
51
+ */
52
+ 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,14 @@ class Server extends net.Server {
100
104
  }
101
105
  }
102
106
  }
107
+ tlsListener(tlsSocket) {
108
+ if (tlsSocket.alpnProtocol === false || tlsSocket.alpnProtocol === 'http/1.1') {
109
+ this._httpServer.emit('connection', tlsSocket);
110
+ }
111
+ else {
112
+ this._http2Server.emit('connection', tlsSocket);
113
+ }
114
+ }
103
115
  http2Listener(socket, pastData) {
104
116
  const h1Server = this._httpServer;
105
117
  const h2Server = this._http2Server;
@@ -145,8 +157,8 @@ class Server extends net.Server {
145
157
  }
146
158
  }
147
159
  exports.Server = Server;
148
- function createServer(configOrListener, listener) {
149
- return new Server(configOrListener, listener);
160
+ function createServer(configOrServerOrListener, listener) {
161
+ return new Server(configOrServerOrListener, listener);
150
162
  }
151
163
  exports.createServer = createServer;
152
164
  ;
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.0",
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,14 @@ export class Server extends net.Server {
126
150
  }
127
151
  }
128
152
 
153
+ private tlsListener(tlsSocket: tls.TLSSocket) {
154
+ if (tlsSocket.alpnProtocol === false || tlsSocket.alpnProtocol === 'http/1.1') {
155
+ this._httpServer.emit('connection', tlsSocket);
156
+ } else {
157
+ this._http2Server.emit('connection', tlsSocket);
158
+ }
159
+ }
160
+
129
161
  private http2Listener(socket: net.Socket, pastData?: Buffer) {
130
162
  const h1Server = this._httpServer;
131
163
  const h2Server = this._http2Server;
@@ -173,8 +205,28 @@ export class Server extends net.Server {
173
205
  }
174
206
  }
175
207
 
208
+ /**
209
+ * Create an Httpolyglot instance with just a request listener to support plain-text
210
+ * HTTP & HTTP/2 on the same port, with incoming TLS connections being closed immediately.
211
+ */
176
212
  export function createServer(requestListener: http.RequestListener): Server;
213
+ /**
214
+ * Create an instance with a full TLS configuration to create a TLS+HTTP+HTTP/2 server, which can
215
+ * support all protocols on the same port.
216
+ */
177
217
  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);
218
+ /**
219
+ * Create an instance around an existing TLS server, instead of TLS configuration, to create a
220
+ * TLS+HTTP+HTTP/2 server with custom TLS handling. All incoming TLS requests will be emitted as
221
+ * 'connection' events on the given TLS server, and all 'secureConnection' events coming from the
222
+ * TLS server will be handled according to the connection type detected on that socket.
223
+ */
224
+ export function createServer(tlsServer: tls.Server, requestListener: http.RequestListener): Server;
225
+ export function createServer(configOrServerOrListener:
226
+ | https.ServerOptions
227
+ | http.RequestListener
228
+ | tls.Server,
229
+ listener?: http.RequestListener
230
+ ) {
231
+ return new Server(configOrServerOrListener as any, listener as any);
180
232
  };