summaryrefslogtreecommitdiff
path: root/lib/_http_client.js
diff options
context:
space:
mode:
authorMiles Elam <miles.elam@productops.com>2018-01-08 00:11:05 -0800
committerMatteo Collina <hello@matteocollina.com>2018-02-15 11:57:57 +0100
commitbaf84950781f253ab0244779a9e40b5dc0f4930e (patch)
treed58fc3d495bcd25ffc25914438c4c33348d37def /lib/_http_client.js
parentcfad44105d6baae44a7b5dd6ea179f7550a5038f (diff)
downloadandroid-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.js29
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.
}