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