Skip to content

Commit

Permalink
squash: add method setter validation & warn on accessing socket
Browse files Browse the repository at this point in the history
  • Loading branch information
apapirovski committed Sep 28, 2017
1 parent 2e32a51 commit 680e507
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 0 deletions.
20 changes: 20 additions & 0 deletions lib/internal/http2/compat.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const {
HTTP_STATUS_OK
} = constants;

let socketWarned = false;
let statusMessageWarned = false;

// Defines and implements an API compatibility layer on top of the core
Expand Down Expand Up @@ -71,6 +72,18 @@ function statusMessageWarn() {
}
}

function socketWarn() {
if (socketWarned === false) {
process.emitWarning(
'Because the of the specific serialization and processing requirements ' +
'imposed by the HTTP/2 protocol, it is not recommended for user code ' +
'to read data from or write data to a Socket instance.',
'UnsupportedWarning'
);
socketWarned = true;
}
}

function onStreamData(chunk) {
if (!this[kRequest].push(chunk))
this.pause();
Expand Down Expand Up @@ -212,6 +225,8 @@ class Http2ServerRequest extends Readable {
}

get socket() {
socketWarn();

const stream = this[kStream];
if (stream === undefined)
return;
Expand All @@ -236,6 +251,9 @@ class Http2ServerRequest extends Readable {
}

set method(method) {
if (typeof method !== 'string' || method.trim() === '')
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'method', 'string');

this[kHeaders][HTTP2_HEADER_METHOD] = method;
}

Expand Down Expand Up @@ -313,6 +331,8 @@ class Http2ServerResponse extends Stream {


get socket() {
socketWarn();

const stream = this[kStream];
if (stream === undefined)
return;
Expand Down
16 changes: 16 additions & 0 deletions test/parallel/test-http2-compat-serverrequest-headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ server.listen(0, common.mustCall(function() {
// change the request method
request.method = 'POST';
assert.strictEqual(request.method, 'POST');
common.expectsError(
() => request.method = ' ',
{
code: 'ERR_INVALID_ARG_TYPE',
type: TypeError,
message: 'The "method" argument must be of type string'
}
);
common.expectsError(
() => request.method = true,
{
code: 'ERR_INVALID_ARG_TYPE',
type: TypeError,
message: 'The "method" argument must be of type string'
}
);

response.on('finish', common.mustCall(function() {
server.close();
Expand Down
47 changes: 47 additions & 0 deletions test/parallel/test-http2-compat-serverrequest-socket-warn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Flags: --expose-http2
'use strict';

const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const h2 = require('http2');

// Http2ServerRequest.socket should warn one time when being accessed

const unsupportedWarned = common.mustCall(1);
process.on('warning', ({ name, message }) => {
const expectedMessage =
'Because the of the specific serialization and processing requirements ' +
'imposed by the HTTP/2 protocol, it is not recommended for user code ' +
'to read data from or write data to a Socket instance.';
if (name === 'UnsupportedWarning' && message === expectedMessage)
unsupportedWarned();
});

const server = h2.createServer();
server.listen(0, common.mustCall(function() {
const port = server.address().port;
server.once('request', common.mustCall(function(request, response) {
request.socket;
request.socket; // should not warn
response.socket; // should not warn
response.end();
}));

const url = `http://localhost:${port}`;
const client = h2.connect(url, common.mustCall(function() {
const headers = {
':path': '/',
':method': 'GET',
':scheme': 'http',
':authority': `localhost:${port}`
};
const request = client.request(headers);
request.on('end', common.mustCall(function() {
client.destroy();
server.close();
}));
request.end();
request.resume();
}));
}));
47 changes: 47 additions & 0 deletions test/parallel/test-http2-compat-serverresponse-socket-warn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Flags: --expose-http2
'use strict';

const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const h2 = require('http2');

// Http2ServerResponse.socket should warn one time when being accessed

const unsupportedWarned = common.mustCall(1);
process.on('warning', ({ name, message }) => {
const expectedMessage =
'Because the of the specific serialization and processing requirements ' +
'imposed by the HTTP/2 protocol, it is not recommended for user code ' +
'to read data from or write data to a Socket instance.';
if (name === 'UnsupportedWarning' && message === expectedMessage)
unsupportedWarned();
});

const server = h2.createServer();
server.listen(0, common.mustCall(function() {
const port = server.address().port;
server.once('request', common.mustCall(function(request, response) {
response.socket;
response.socket; // should not warn
request.socket; // should not warn
response.end();
}));

const url = `http://localhost:${port}`;
const client = h2.connect(url, common.mustCall(function() {
const headers = {
':path': '/',
':method': 'GET',
':scheme': 'http',
':authority': `localhost:${port}`
};
const request = client.request(headers);
request.on('end', common.mustCall(function() {
client.destroy();
server.close();
}));
request.end();
request.resume();
}));
}));

0 comments on commit 680e507

Please sign in to comment.