Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d8aa2ba

Browse filesBrowse files
devsnektargos
authored andcommitted
http2: add server handshake utility
PR-URL: #51172 Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 119e045 commit d8aa2ba
Copy full SHA for d8aa2ba

File tree

Expand file treeCollapse file tree

5 files changed

+85
-7
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+85
-7
lines changed
Open diff view settings
Collapse file

‎doc/api/http2.md‎

Copy file name to clipboardExpand all lines: doc/api/http2.md
+13Lines changed: 13 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -2890,6 +2890,19 @@ added: v8.4.0
28902890
Returns a [HTTP/2 Settings Object][] containing the deserialized settings from
28912891
the given `Buffer` as generated by `http2.getPackedSettings()`.
28922892

2893+
### `http2.performServerHandshake(socket[, options])`
2894+
2895+
<!-- YAML
2896+
added: REPLACEME
2897+
-->
2898+
2899+
* `socket` {stream.Duplex}
2900+
* `options` {Object}
2901+
* ...: Any [`http2.createServer()`][] option can be provided.
2902+
* Returns: {ServerHttp2Session}
2903+
2904+
Create an HTTP/2 server session from an existing socket.
2905+
28932906
### `http2.sensitiveHeaders`
28942907

28952908
<!-- YAML
Collapse file

‎lib/http2.js‎

Copy file name to clipboardExpand all lines: lib/http2.js
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const {
88
getDefaultSettings,
99
getPackedSettings,
1010
getUnpackedSettings,
11+
performServerHandshake,
1112
sensitiveHeaders,
1213
Http2ServerRequest,
1314
Http2ServerResponse,
@@ -21,6 +22,7 @@ module.exports = {
2122
getDefaultSettings,
2223
getPackedSettings,
2324
getUnpackedSettings,
25+
performServerHandshake,
2426
sensitiveHeaders,
2527
Http2ServerRequest,
2628
Http2ServerResponse,
Collapse file

‎lib/internal/http2/core.js‎

Copy file name to clipboardExpand all lines: lib/internal/http2/core.js
+13-7Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,12 +1228,6 @@ class Http2Session extends EventEmitter {
12281228
constructor(type, options, socket) {
12291229
super();
12301230

1231-
if (!socket._handle || !socket._handle.isStreamBase) {
1232-
socket = new JSStreamSocket(socket);
1233-
}
1234-
socket.on('error', socketOnError);
1235-
socket.on('close', socketOnClose);
1236-
12371231
// No validation is performed on the input parameters because this
12381232
// constructor is not exported directly for users.
12391233

@@ -1245,6 +1239,12 @@ class Http2Session extends EventEmitter {
12451239

12461240
socket[kSession] = this;
12471241

1242+
if (!socket._handle || !socket._handle.isStreamBase) {
1243+
socket = new JSStreamSocket(socket);
1244+
}
1245+
socket.on('error', socketOnError);
1246+
socket.on('close', socketOnClose);
1247+
12481248
this[kState] = {
12491249
destroyCode: NGHTTP2_NO_ERROR,
12501250
flags: SESSION_FLAGS_PENDING,
@@ -1644,7 +1644,7 @@ class ServerHttp2Session extends Http2Session {
16441644
// not be an issue in practice. Additionally, the 'priority' event on
16451645
// server instances (or any other object) is fully undocumented.
16461646
this[kNativeFields][kSessionPriorityListenerCount] =
1647-
server.listenerCount('priority');
1647+
server ? server.listenerCount('priority') : 0;
16481648
}
16491649

16501650
get server() {
@@ -3435,6 +3435,11 @@ function getUnpackedSettings(buf, options = kEmptyObject) {
34353435
return settings;
34363436
}
34373437

3438+
function performServerHandshake(socket, options = {}) {
3439+
options = initializeOptions(options);
3440+
return new ServerHttp2Session(options, socket, undefined);
3441+
}
3442+
34383443
binding.setCallbackFunctions(
34393444
onSessionInternalError,
34403445
onPriority,
@@ -3458,6 +3463,7 @@ module.exports = {
34583463
getDefaultSettings,
34593464
getPackedSettings,
34603465
getUnpackedSettings,
3466+
performServerHandshake,
34613467
sensitiveHeaders: kSensitiveHeaders,
34623468
Http2Session,
34633469
Http2Stream,
Collapse file

‎lib/internal/js_stream_socket.js‎

Copy file name to clipboardExpand all lines: lib/internal/js_stream_socket.js
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ let debug = require('internal/util/debuglog').debuglog(
1717
);
1818
const { owner_symbol } = require('internal/async_hooks').symbols;
1919
const { ERR_STREAM_WRAP } = require('internal/errors').codes;
20+
const { kSession } = require('internal/stream_base_commons');
2021

2122
const kCurrentWriteRequest = Symbol('kCurrentWriteRequest');
2223
const kCurrentShutdownRequest = Symbol('kCurrentShutdownRequest');
@@ -263,6 +264,14 @@ class JSStreamSocket extends Socket {
263264
cb();
264265
});
265266
}
267+
268+
get [kSession]() {
269+
return this.stream[kSession];
270+
}
271+
272+
set [kSession](session) {
273+
this.stream[kSession] = session;
274+
}
266275
}
267276

268277
module.exports = JSStreamSocket;
Collapse file
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
5+
if (!common.hasCrypto)
6+
common.skip('missing crypto');
7+
8+
const assert = require('assert');
9+
const http2 = require('http2');
10+
const stream = require('stream');
11+
const makeDuplexPair = require('../common/duplexpair');
12+
13+
// Basic test
14+
{
15+
const { clientSide, serverSide } = makeDuplexPair();
16+
17+
const client = http2.connect('http://example.com', {
18+
createConnection: () => clientSide,
19+
});
20+
21+
const session = http2.performServerHandshake(serverSide);
22+
23+
session.on('stream', common.mustCall((stream, headers) => {
24+
assert.strictEqual(headers[':path'], '/test');
25+
stream.respond({
26+
':status': 200,
27+
});
28+
stream.end('hi!');
29+
}));
30+
31+
const req = client.request({ ':path': '/test' });
32+
req.on('response', common.mustCall());
33+
req.end();
34+
}
35+
36+
// Double bind should fail
37+
{
38+
const socket = new stream.Duplex({
39+
read() {},
40+
write() {},
41+
});
42+
43+
http2.performServerHandshake(socket);
44+
45+
assert.throws(() => {
46+
http2.performServerHandshake(socket);
47+
}, { code: 'ERR_HTTP2_SOCKET_BOUND' });
48+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.