Skip to content

Commit

Permalink
http: expose headers on an http.ClientRequest "information" event
Browse files Browse the repository at this point in the history
1xx intermediate status responses are allowed to have headers; so
expose the "httpVersion", "httpVersionMajor", "httpVersionMinor",
"headers", "rawHeaders", and "statusMessage" properties on this
event.

PR-URL: #28459
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information
awwright authored and Trott committed Jul 16, 2019
1 parent 2111207 commit d5737a8
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 4 deletions.
14 changes: 11 additions & 3 deletions doc/api/http.md
Expand Up @@ -421,10 +421,18 @@ added: v10.0.0
-->

* `info` {Object}
* `httpVersion` {string}
* `httpVersionMajor` {integer}
* `httpVersionMinor` {integer}
* `statusCode` {integer}

Emitted when the server sends a 1xx response (excluding 101 Upgrade). The
listeners of this event will receive an object containing the status code.
* `statusMessage` {string}
* `headers` {Object}
* `rawHeaders` {string[]}

Emitted when the server sends a 1xx intermediate response (excluding 101
Upgrade). The listeners of this event will receive an object containing the
HTTP version, status code, status message, key-value headers object,
and array with the raw header names followed by their respective values.

```js
const http = require('http');
Expand Down
10 changes: 9 additions & 1 deletion lib/_http_client.js
Expand Up @@ -549,7 +549,15 @@ function parserOnIncomingClient(res, shouldKeepAlive) {
req.emit('continue');
}
// Send information events to all 1xx responses except 101 Upgrade.
req.emit('information', { statusCode: res.statusCode });
req.emit('information', {
statusCode: res.statusCode,
statusMessage: res.statusMessage,
httpVersion: res.httpVersion,
httpVersionMajor: res.httpVersionMajor,
httpVersionMinor: res.httpVersionMinor,
headers: res.headers,
rawHeaders: res.rawHeaders
});

return 1; // Skip body but don't treat as Upgrade.
}
Expand Down
64 changes: 64 additions & 0 deletions test/parallel/test-http-information-headers.js
@@ -0,0 +1,64 @@
'use strict';
require('../common');
const assert = require('assert');
const http = require('http');
const Countdown = require('../common/countdown');

const test_res_body = 'other stuff!\n';
const countdown = new Countdown(2, () => server.close());

const server = http.createServer((req, res) => {
console.error('Server sending informational message #1...');
// These function calls may rewritten as necessary
// to call res.writeHead instead
res._writeRaw('HTTP/1.1 102 Processing\r\n');
res._writeRaw('Foo: Bar\r\n');
res._writeRaw('\r\n');
console.error('Server sending full response...');
res.writeHead(200, {
'Content-Type': 'text/plain',
'ABCD': '1'
});
res.end(test_res_body);
});

server.listen(0, function() {
const req = http.request({
port: this.address().port,
path: '/world'
});
req.end();
console.error('Client sending request...');

let body = '';

req.on('information', function(res) {
assert.strictEqual(res.httpVersion, '1.1');
assert.strictEqual(res.httpVersionMajor, 1);
assert.strictEqual(res.httpVersionMinor, 1);
assert.strictEqual(res.statusCode, 102,
`Received ${res.statusCode}, not 102.`);
assert.strictEqual(res.statusMessage, 'Processing',
`Received ${res.statusMessage}, not "Processing".`);
assert.strictEqual(res.headers.foo, 'Bar');
assert.strictEqual(res.rawHeaders[0], 'Foo');
assert.strictEqual(res.rawHeaders[1], 'Bar');
console.error('Client got 102 Processing...');
countdown.dec();
});

req.on('response', function(res) {
// Check that all 102 Processing received before full response received.
assert.strictEqual(countdown.remaining, 1);
assert.strictEqual(res.statusCode, 200,
`Final status code was ${res.statusCode}, not 200.`);
res.setEncoding('utf8');
res.on('data', function(chunk) { body += chunk; });
res.on('end', function() {
console.error('Got full response.');
assert.strictEqual(body, test_res_body);
assert.ok('abcd' in res.headers);
countdown.dec();
});
});
});

0 comments on commit d5737a8

Please sign in to comment.