From f54889ae000f2d01039ceaaa158dbba99a5b933f Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sun, 22 Oct 2017 17:05:05 +0200 Subject: [PATCH 1/2] test: add `makeDuplexPair()` helper Add a utility for adding simple, streams-API based duplex pairs. PR-URL: https://github.com/nodejs/node/pull/16269 Reviewed-By: Anatoli Papirovski Reviewed-By: James M Snell --- test/common/README.md | 9 ++++++++ test/common/duplexpair.js | 45 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 test/common/duplexpair.js diff --git a/test/common/README.md b/test/common/README.md index 93106ad076e2e1..46eb001df86cf6 100644 --- a/test/common/README.md +++ b/test/common/README.md @@ -8,6 +8,7 @@ This directory contains modules used to test the Node.js implementation. * [Common module API](#common-module-api) * [Countdown module](#countdown-module) * [DNS module](#dns-module) +* [Duplex pair helper](#duplex-pair-helper) * [Fixtures module](#fixtures-module) * [WPT module](#wpt-module) @@ -458,6 +459,14 @@ Reads a Domain String and returns a Buffer containing the domain. Takes in a parsed Object and writes its fields to a DNS packet as a Buffer object. +## Duplex pair helper + +The `common/duplexpair` module exports a single function `makeDuplexPair`, +which returns an object `{ clientSide, serverSide }` where each side is a +`Duplex` stream connected to the other side. + +There is no difference between client or server side beyond their names. + ## Fixtures Module The `common/fixtures` module provides convenience methods for working with diff --git a/test/common/duplexpair.js b/test/common/duplexpair.js new file mode 100644 index 00000000000000..ea5bd86a041b24 --- /dev/null +++ b/test/common/duplexpair.js @@ -0,0 +1,45 @@ +/* eslint-disable required-modules */ +'use strict'; +const { Duplex } = require('stream'); +const assert = require('assert'); + +const kCallback = Symbol('Callback'); +const kOtherSide = Symbol('Other'); + +class DuplexSocket extends Duplex { + constructor() { + super(); + this[kCallback] = null; + this[kOtherSide] = null; + } + + _read() { + const callback = this[kCallback]; + if (callback) { + this[kCallback] = null; + callback(); + } + } + + _write(chunk, encoding, callback) { + assert.notStrictEqual(this[kOtherSide], null); + assert.strictEqual(this[kOtherSide][kCallback], null); + this[kOtherSide][kCallback] = callback; + this[kOtherSide].push(chunk); + } + + _final(callback) { + this[kOtherSide].on('end', callback); + this[kOtherSide].push(null); + } +} + +function makeDuplexPair() { + const clientSide = new DuplexSocket(); + const serverSide = new DuplexSocket(); + clientSide[kOtherSide] = serverSide; + serverSide[kOtherSide] = clientSide; + return { clientSide, serverSide }; +} + +module.exports = makeDuplexPair; From e5a0fdde24dffe6b1a072b67a045825d5f2d05d3 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 17 Oct 2017 22:19:27 +0200 Subject: [PATCH 2/2] http: support generic `Duplex` streams Support generic `Duplex` streams through more duck typing on the server and client sides. Since HTTP is, as a protocol, independent of its underlying transport layer, Node.js should not enforce any restrictions on what streams its HTTP parser may use. Ref: https://github.com/nodejs/node/issues/16256 PR-URL: https://github.com/nodejs/node/pull/16267 Reviewed-By: James M Snell Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig --- doc/api/http.md | 16 +++--- lib/_http_client.js | 5 +- lib/_http_server.js | 22 +++++--- test/parallel/test-http-generic-streams.js | 60 ++++++++++++++++++++++ 4 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 test/parallel/test-http-generic-streams.js diff --git a/doc/api/http.md b/doc/api/http.md index e4300cc4299f50..4a84e50ba0b029 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -797,11 +797,14 @@ added: v0.1.0 * `socket` {net.Socket} -When a new TCP stream is established. `socket` is an object of type -[`net.Socket`][]. Usually users will not want to access this event. In -particular, the socket will not emit `'readable'` events because of how -the protocol parser attaches to the socket. The `socket` can also be -accessed at `request.connection`. +This event is emitted when a new TCP stream is established. `socket` is +typically an object of type [`net.Socket`][]. Usually users will not want to +access this event. In particular, the socket will not emit `'readable'` events +because of how the protocol parser attaches to the socket. The `socket` can +also be accessed at `request.connection`. + +*Note*: This event can also be explicitly emitted by users to inject connections +into the HTTP server. In that case, any [`Duplex`][] stream can be passed. ### Event: 'request'