diff --git a/doc/api/http.md b/doc/api/http.md index cc0c7ae1ce4917..02c5859dc253e3 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -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'); diff --git a/lib/_http_client.js b/lib/_http_client.js index 4af23fa8c574f0..99b254f1e1c0f6 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -547,7 +547,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. } diff --git a/test/parallel/test-http-information-headers.js b/test/parallel/test-http-information-headers.js new file mode 100644 index 00000000000000..f5cfa5078b85ac --- /dev/null +++ b/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(); + }); + }); +});