parser.incoming.statusMessage = statusMessage;
}
+ // The client made non-upgrade request, and server is just advertising
+ // supported protocols.
+ //
+ // See RFC7230 Section 6.7
+ //
+ // NOTE: RegExp below matches `upgrade` in `Connection: abc, upgrade, def`
+ // header.
+ if (upgrade &&
+ parser.outgoing !== null &&
+ (parser.outgoing._headers.upgrade === undefined ||
+ !/(^|\W)upgrade(\W|$)/i.test(parser.outgoing._headers.connection))) {
+ upgrade = false;
+ }
+
parser.incoming.upgrade = upgrade;
var skipBody = false; // response to HEAD or CONNECT
parser._url = '';
parser._consumed = false;
+ parser.socket = null;
+ parser.incoming = null;
+ parser.outgoing = null;
+
// Only called in the slow case where slow means
// that the request headers were either fragmented
// across multiple TCP packets or too large to be
parser.socket.parser = null;
parser.socket = null;
parser.incoming = null;
+ parser.outgoing = null;
if (parsers.free(parser) === false)
parser.close();
parser = null;
--- /dev/null
+'use strict';
+
+const common = require('../common');
+const assert = require('assert');
+const http = require('http');
+
+const tests = [
+ { headers: {}, expected: 'regular' },
+ { headers: { upgrade: 'h2c' }, expected: 'regular' },
+ { headers: { connection: 'upgrade' }, expected: 'regular' },
+ { headers: { connection: 'upgrade', upgrade: 'h2c' }, expected: 'upgrade' }
+];
+
+function fire() {
+ if (tests.length === 0)
+ return server.close();
+
+ const test = tests.shift();
+
+ const done = common.mustCall(function done(result) {
+ assert.equal(result, test.expected);
+
+ fire();
+ });
+
+ const req = http.request({
+ port: common.PORT,
+ path: '/',
+ headers: test.headers
+ }, function onResponse(res) {
+ res.resume();
+ done('regular');
+ });
+
+ req.on('upgrade', function onUpgrade(res, socket) {
+ socket.destroy();
+ done('upgrade');
+ });
+
+ req.end();
+}
+
+const server = http.createServer(function(req, res) {
+ res.writeHead(200, {
+ Connection: 'upgrade, keep-alive',
+ Upgrade: 'h2c'
+ });
+ res.end('hello world');
+}).on('upgrade', function(req, socket) {
+ socket.end('HTTP/1.1 101 Switching protocols\r\n' +
+ 'Connection: upgrade\r\n' +
+ 'Upgrade: h2c\r\n\r\n' +
+ 'ohai');
+}).listen(common.PORT, fire);
srv.listen(common.PORT, '127.0.0.1', function() {
- var req = http.get({ port: common.PORT });
+ var req = http.get({
+ port: common.PORT,
+ headers: {
+ connection: 'upgrade',
+ upgrade: 'websocket'
+ }
+ });
req.on('upgrade', function(res, socket, upgradeHead) {
var recvData = upgradeHead;
socket.on('data', function(d) {