diff options
author | Miles Elam <miles.elam@productops.com> | 2018-01-08 00:11:05 -0800 |
---|---|---|
committer | Matteo Collina <hello@matteocollina.com> | 2018-02-15 11:57:57 +0100 |
commit | baf84950781f253ab0244779a9e40b5dc0f4930e (patch) | |
tree | d58fc3d495bcd25ffc25914438c4c33348d37def /lib/_http_client.js | |
parent | cfad44105d6baae44a7b5dd6ea179f7550a5038f (diff) | |
download | android-node-v8-baf84950781f253ab0244779a9e40b5dc0f4930e.tar.gz android-node-v8-baf84950781f253ab0244779a9e40b5dc0f4930e.tar.bz2 android-node-v8-baf84950781f253ab0244779a9e40b5dc0f4930e.zip |
http: process 100, 102-199 according to specs.
Adding ServerResponse.writeProcessing to send 102 status codes.
Added an `'information'` event to ClientRequest to handle
1xx status codes except 101 Upgrade.
101 Upgrade is excluded due to its non-informational
processing according to RFC7231, Section 6.2.2.
This affects several modules downstream that use the http
module, e.g., node-fetch, all of whom violate HTTP RFCs
due to this module. As such, this could introduce a
breaking change for downstream if HTTP standards were
ignored in an ad-hoc fashion.
See also RFC2518 RFC8297.
PR-URL: https://github.com/nodejs/node/pull/18033
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Diffstat (limited to 'lib/_http_client.js')
-rw-r--r-- | lib/_http_client.js | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/lib/_http_client.js b/lib/_http_client.js index 9880581082..cab11ae8f2 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -447,16 +447,25 @@ function socketOnData(d) { socket.destroy(); } } else if (parser.incoming && parser.incoming.complete && - // When the status code is 100 (Continue), the server will - // send a final response after this client sends a request - // body. So, we must not free the parser. - parser.incoming.statusCode !== 100) { + // When the status code is informational (100, 102-199), + // the server will send a final response after this client + // sends a request body, so we must not free the parser. + // 101 (Switching Protocols) and all other status codes + // should be processed normally. + !statusIsInformational(parser.incoming.statusCode)) { socket.removeListener('data', socketOnData); socket.removeListener('end', socketOnEnd); freeParser(parser, req, socket); } } +function statusIsInformational(status) { + // 100 (Continue) RFC7231 Section 6.2.1 + // 102 (Processing) RFC2518 + // 103 (Early Hints) RFC8297 + // 104-199 (Unassigned) + return (status < 200 && status >= 100 && status !== 101); +} // client function parserOnIncomingClient(res, shouldKeepAlive) { @@ -480,10 +489,16 @@ function parserOnIncomingClient(res, shouldKeepAlive) { return 2; // Skip body and treat as Upgrade. } - if (res.statusCode === 100) { - // restart the parser, as this is a continue message. + if (statusIsInformational(res.statusCode)) { + // Restart the parser, as this is a 1xx informational message. req.res = null; // Clear res so that we don't hit double-responses. - req.emit('continue'); + // Maintain compatibility by sending 100-specific events + if (res.statusCode === 100) { + req.emit('continue'); + } + // Send information events to all 1xx responses except 101 Upgrade. + req.emit('information', { statusCode: res.statusCode }); + return 1; // Skip body but don't treat as Upgrade. } |