• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22'use strict';
23// Verify that the 'upgrade' header causes an 'upgrade' event to be emitted to
24// the HTTP client. This test uses a raw TCP server to better control server
25// behavior.
26
27const common = require('../common');
28const assert = require('assert');
29
30const http = require('http');
31const net = require('net');
32
33// Create a TCP server
34const server = net.createServer(function(c) {
35  c.on('data', function(d) {
36    c.write('HTTP/1.1 101\r\n');
37    c.write('hello: world\r\n');
38    c.write('connection: upgrade\r\n');
39    c.write('upgrade: websocket\r\n');
40    c.write('\r\n');
41    c.write('nurtzo');
42  });
43
44  c.on('end', function() {
45    c.end();
46  });
47});
48
49server.listen(0, '127.0.0.1', common.mustCall(function() {
50
51  const options = {
52    port: this.address().port,
53    host: '127.0.0.1',
54    headers: {
55      'connection': 'upgrade',
56      'upgrade': 'websocket'
57    }
58  };
59  const name = `${options.host}:${options.port}`;
60
61  const req = http.request(options);
62  req.end();
63
64  req.on('socket', common.mustCall(function() {
65    assert.strictEqual(req.agent.totalSocketCount, 1);
66  }));
67
68  req.on('upgrade', common.mustCall(function(res, socket, upgradeHead) {
69    assert.strictEqual(req.agent.totalSocketCount, 0);
70    let recvData = upgradeHead;
71    socket.on('data', function(d) {
72      recvData += d;
73    });
74
75    socket.on('close', common.mustCall(function() {
76      assert.strictEqual(recvData.toString(), 'nurtzo');
77    }));
78
79    const expectedHeaders = { 'hello': 'world',
80                              'connection': 'upgrade',
81                              'upgrade': 'websocket' };
82    assert.deepStrictEqual(expectedHeaders, res.headers);
83
84    // Make sure this request got removed from the pool.
85    assert(!(name in req.agent.sockets));
86
87    req.on('close', common.mustCall(function() {
88      socket.end();
89      server.close();
90    }));
91  }));
92}));
93