• 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';
23const common = require('../common');
24const assert = require('assert');
25const net = require('net');
26const http = require('http');
27
28const body = 'hello world\n';
29
30function test(handler, request_generator, response_validator) {
31  const server = http.createServer(handler);
32
33  let client_got_eof = false;
34  let server_response = '';
35
36  server.listen(0);
37  server.on('listening', function() {
38    const c = net.createConnection(this.address().port);
39
40    c.setEncoding('utf8');
41
42    c.on('connect', function() {
43      c.write(request_generator());
44    });
45
46    c.on('data', function(chunk) {
47      server_response += chunk;
48    });
49
50    c.on('end', common.mustCall(function() {
51      client_got_eof = true;
52      c.end();
53      server.close();
54      response_validator(server_response, client_got_eof, false);
55    }));
56  });
57}
58
59{
60  function handler(req, res) {
61    assert.strictEqual(req.httpVersion, '1.0');
62    assert.strictEqual(req.httpVersionMajor, 1);
63    assert.strictEqual(req.httpVersionMinor, 0);
64    res.writeHead(200, { 'Content-Type': 'text/plain' });
65    res.end(body);
66  }
67
68  function request_generator() {
69    return 'GET / HTTP/1.0\r\n\r\n';
70  }
71
72  function response_validator(server_response, client_got_eof, timed_out) {
73    const m = server_response.split('\r\n\r\n');
74    assert.strictEqual(m[1], body);
75    assert.strictEqual(client_got_eof, true);
76    assert.strictEqual(timed_out, false);
77  }
78
79  test(handler, request_generator, response_validator);
80}
81
82//
83// Don't send HTTP/1.1 status lines to HTTP/1.0 clients.
84//
85// https://github.com/joyent/node/issues/1234
86//
87{
88  function handler(req, res) {
89    assert.strictEqual(req.httpVersion, '1.0');
90    assert.strictEqual(req.httpVersionMajor, 1);
91    assert.strictEqual(req.httpVersionMinor, 0);
92    res.sendDate = false;
93    res.writeHead(200, { 'Content-Type': 'text/plain' });
94    res.write('Hello, '); res._send('');
95    res.write('world!'); res._send('');
96    res.end();
97  }
98
99  function request_generator() {
100    return ('GET / HTTP/1.0\r\n' +
101        'User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 ' +
102        'OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15\r\n' +
103        'Host: 127.0.0.1:1337\r\n' +
104        'Accept: */*\r\n' +
105        '\r\n');
106  }
107
108  function response_validator(server_response, client_got_eof, timed_out) {
109    const expected_response = 'HTTP/1.1 200 OK\r\n' +
110                              'Content-Type: text/plain\r\n' +
111                              'Connection: close\r\n' +
112                              '\r\n' +
113                              'Hello, world!';
114
115    assert.strictEqual(server_response, expected_response);
116    assert.strictEqual(client_got_eof, true);
117    assert.strictEqual(timed_out, false);
118  }
119
120  test(handler, request_generator, response_validator);
121}
122
123{
124  function handler(req, res) {
125    assert.strictEqual(req.httpVersion, '1.1');
126    assert.strictEqual(req.httpVersionMajor, 1);
127    assert.strictEqual(req.httpVersionMinor, 1);
128    res.sendDate = false;
129    res.writeHead(200, { 'Content-Type': 'text/plain' });
130    res.write('Hello, '); res._send('');
131    res.write('world!'); res._send('');
132    res.end();
133  }
134
135  function request_generator() {
136    return 'GET / HTTP/1.1\r\n' +
137        'User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 ' +
138        'OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15\r\n' +
139        'Connection: close\r\n' +
140        'Host: 127.0.0.1:1337\r\n' +
141        'Accept: */*\r\n' +
142        '\r\n';
143  }
144
145  function response_validator(server_response, client_got_eof, timed_out) {
146    const expected_response = 'HTTP/1.1 200 OK\r\n' +
147                              'Content-Type: text/plain\r\n' +
148                              'Connection: close\r\n' +
149                              'Transfer-Encoding: chunked\r\n' +
150                              '\r\n' +
151                              '7\r\n' +
152                              'Hello, \r\n' +
153                              '6\r\n' +
154                              'world!\r\n' +
155                              '0\r\n' +
156                              '\r\n';
157
158    assert.strictEqual(server_response, expected_response);
159    assert.strictEqual(client_got_eof, true);
160    assert.strictEqual(timed_out, false);
161  }
162
163  test(handler, request_generator, response_validator);
164}
165