diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index cb9bfc37ce2cd7..0ea3ca75f4d43e 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -20,8 +20,9 @@ const { onServerStream, Http2ServerResponse, } = require('internal/http2/compat'); const { utcDate } = require('internal/http'); +const { promisify } = require('internal/util'); const { _connectionListener: httpConnectionListener } = require('http'); -const { isUint8Array } = process.binding('util'); +const { isUint8Array, createPromise, promiseResolve } = process.binding('util'); const debug = util.debuglog('http2'); @@ -2454,6 +2455,17 @@ function connect(authority, options, listener) { return session; } +// Support util.promisify +Object.defineProperty(connect, promisify.custom, { + value: (authority, options) => { + const promise = createPromise(); + const server = connect(authority, + options, + () => promiseResolve(promise, server)); + return promise; + } +}); + function createSecureServer(options, handler) { if (options == null || typeof options !== 'object') { throw new errors.TypeError('ERR_INVALID_ARG_TYPE', diff --git a/src/node_http2_core-inl.h b/src/node_http2_core-inl.h index c6654123dda656..0d2a697a9d73e0 100644 --- a/src/node_http2_core-inl.h +++ b/src/node_http2_core-inl.h @@ -52,17 +52,19 @@ inline int Nghttp2Session::OnBeginHeadersCallback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data) { Nghttp2Session* handle = static_cast(user_data); + // If this is a push promise frame, we want to grab the handle of + // the promised stream. int32_t id = (frame->hd.type == NGHTTP2_PUSH_PROMISE) ? - frame->push_promise.promised_stream_id : - frame->hd.stream_id; + frame->push_promise.promised_stream_id : + frame->hd.stream_id; DEBUG_HTTP2("Nghttp2Session %s: beginning headers for stream %d\n", handle->TypeName(handle->type()), id); Nghttp2Stream* stream = handle->FindStream(id); if (stream == nullptr) { - Nghttp2Stream::Init(id, handle, frame->headers.cat); + Nghttp2Stream::Init(id, handle, frame->headers.cat); } else { - stream->StartHeaders(frame->headers.cat); + stream->StartHeaders(frame->headers.cat); } return 0; } @@ -77,9 +79,11 @@ inline int Nghttp2Session::OnHeaderCallback(nghttp2_session* session, uint8_t flags, void* user_data) { Nghttp2Session* handle = static_cast(user_data); + // If this is a push promise frame, we want to grab the handle of + // the promised stream. int32_t id = (frame->hd.type == NGHTTP2_PUSH_PROMISE) ? - frame->push_promise.promised_stream_id : - frame->hd.stream_id; + frame->push_promise.promised_stream_id : + frame->hd.stream_id; Nghttp2Stream* stream = handle->FindStream(id); nghttp2_header_list* header = header_free_list.pop(); header->name = name; diff --git a/src/node_http2_core.h b/src/node_http2_core.h index 2cd669f118a403..69b9891d5871cb 100644 --- a/src/node_http2_core.h +++ b/src/node_http2_core.h @@ -141,9 +141,9 @@ class Nghttp2Session { inline ssize_t Write(const uv_buf_t* bufs, unsigned int nbufs); // Returns the nghttp2 library session - inline nghttp2_session* session() { return session_; } + inline nghttp2_session* session() const { return session_; } - nghttp2_session_type type() { + nghttp2_session_type type() const { return session_type_; } diff --git a/test/parallel/test-http2-client-promisify-connect.js b/test/parallel/test-http2-client-promisify-connect.js new file mode 100644 index 00000000000000..5b6dccad6a223e --- /dev/null +++ b/test/parallel/test-http2-client-promisify-connect.js @@ -0,0 +1,34 @@ +// Flags: --expose-http2 +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); +const util = require('util'); + +const server = http2.createServer(); +server.on('stream', common.mustCall((stream) => { + stream.respond(); + stream.end('ok'); +})); +server.listen(0, common.mustCall(() => { + + const connect = util.promisify(http2.connect); + + connect(`http://localhost:${server.address().port}`) + .catch(common.mustNotCall()) + .then(common.mustCall((client) => { + assert(client); + const req = client.request(); + let data = ''; + req.setEncoding('utf8'); + req.on('data', (chunk) => data += chunk); + req.on('end', common.mustCall(() => { + assert.strictEqual(data, 'ok'); + client.destroy(); + server.close(); + })); + })); +}));