mirror of https://github.com/lukechilds/node.git
Browse Source
includes parsing improvements to ensure closer HTTP spec conformance PR-URL: https://github.com/nodejs/node-private/pull/22v0.10
James M Snell
9 years ago
12 changed files with 393 additions and 8 deletions
@ -0,0 +1,26 @@ |
|||||
|
var common = require('../common'); |
||||
|
var http = require('http'); |
||||
|
var net = require('net'); |
||||
|
var assert = require('assert'); |
||||
|
|
||||
|
var reqstr = 'HTTP/1.1 200 OK\r\n' + |
||||
|
'Content-Length: 1\r\n' + |
||||
|
'Transfer-Encoding: chunked\r\n\r\n'; |
||||
|
|
||||
|
var server = net.createServer(function(socket) { |
||||
|
socket.write(reqstr); |
||||
|
}); |
||||
|
|
||||
|
server.listen(common.PORT, function() { |
||||
|
// The callback should not be called because the server is sending
|
||||
|
// both a Content-Length header and a Transfer-Encoding: chunked
|
||||
|
// header, which is a violation of the HTTP spec.
|
||||
|
var req = http.get({port:common.PORT}, function(res) { |
||||
|
assert.fail(null, null, 'callback should not be called'); |
||||
|
}); |
||||
|
req.on('error', common.mustCall(function(err) { |
||||
|
assert(/^Parse Error/.test(err.message)); |
||||
|
assert.equal(err.code, 'HPE_UNEXPECTED_CONTENT_LENGTH'); |
||||
|
server.close(); |
||||
|
})); |
||||
|
}); |
@ -0,0 +1,25 @@ |
|||||
|
var common = require('../common'); |
||||
|
var http = require('http'); |
||||
|
var net = require('net'); |
||||
|
var assert = require('assert'); |
||||
|
|
||||
|
var reqstr = 'HTTP/1.1 200 OK\r\n' + |
||||
|
'Foo: Bar\r' + |
||||
|
'Content-Length: 1\r\n\r\n'; |
||||
|
|
||||
|
var server = net.createServer(function(socket) { |
||||
|
socket.write(reqstr); |
||||
|
}); |
||||
|
|
||||
|
server.listen(common.PORT, function() { |
||||
|
// The callback should not be called because the server is sending a
|
||||
|
// header field that ends only in \r with no following \n
|
||||
|
var req = http.get({port:common.PORT}, function(res) { |
||||
|
assert.fail(null, null, 'callback should not be called'); |
||||
|
}); |
||||
|
req.on('error', common.mustCall(function(err) { |
||||
|
assert(/^Parse Error/.test(err.message)); |
||||
|
assert.equal(err.code, 'HPE_LF_EXPECTED'); |
||||
|
server.close(); |
||||
|
})); |
||||
|
}); |
@ -0,0 +1,31 @@ |
|||||
|
var common = require('../common'); |
||||
|
var http = require('http'); |
||||
|
var assert = require('assert'); |
||||
|
|
||||
|
// The callback should never be invoked because the server
|
||||
|
// should respond with a 400 Client Error when a double
|
||||
|
// Content-Length header is received.
|
||||
|
var server = http.createServer(function(req, res) { |
||||
|
assert(false, 'callback should not have been invoked'); |
||||
|
res.end(); |
||||
|
}); |
||||
|
server.on('clientError', common.mustCall(function(err, socket) { |
||||
|
assert(/^Parse Error/.test(err.message)); |
||||
|
assert.equal(err.code, 'HPE_UNEXPECTED_CONTENT_LENGTH'); |
||||
|
socket.destroy(); |
||||
|
})); |
||||
|
|
||||
|
server.listen(common.PORT, function() { |
||||
|
var req = http.get({ |
||||
|
port: common.PORT, |
||||
|
// Send two content-length header values.
|
||||
|
headers: {'Content-Length': [1, 2]}}, |
||||
|
function(res) { |
||||
|
assert.fail(null, null, 'an error should have occurred'); |
||||
|
server.close(); |
||||
|
} |
||||
|
); |
||||
|
req.on('error', common.mustCall(function() { |
||||
|
server.close(); |
||||
|
})); |
||||
|
}); |
@ -0,0 +1,50 @@ |
|||||
|
var common = require('../common'); |
||||
|
var http = require('http'); |
||||
|
var assert = require('assert'); |
||||
|
|
||||
|
var MAX_COUNT = 2; |
||||
|
|
||||
|
var server = http.createServer(function(req, res) { |
||||
|
var num = req.headers['x-num']; |
||||
|
// TODO(@jasnell) At some point this should be refactored as the API
|
||||
|
// should not be allowing users to set multiple content-length values
|
||||
|
// in the first place.
|
||||
|
switch (num) { |
||||
|
case '1': |
||||
|
res.setHeader('content-length', [2, 1]); |
||||
|
break; |
||||
|
case '2': |
||||
|
res.writeHead(200, {'content-length': [1, 2]}); |
||||
|
break; |
||||
|
default: |
||||
|
assert.fail(null, null, 'should never get here'); |
||||
|
} |
||||
|
res.end('ok'); |
||||
|
}); |
||||
|
|
||||
|
var count = 0; |
||||
|
|
||||
|
server.listen(common.PORT, common.mustCall(function() { |
||||
|
for (var n = 1; n <= MAX_COUNT ; n++) { |
||||
|
// This runs twice, the first time, the server will use
|
||||
|
// setHeader, the second time it uses writeHead. In either
|
||||
|
// case, the error handler must be called because the client
|
||||
|
// is not allowed to accept multiple content-length headers.
|
||||
|
http.get( |
||||
|
{port:common.PORT, headers:{'x-num': n}}, |
||||
|
function(res) { |
||||
|
assert(false, 'client allowed multiple content-length headers.'); |
||||
|
} |
||||
|
).on('error', common.mustCall(function(err) { |
||||
|
assert(/^Parse Error/.test(err.message)); |
||||
|
assert.equal(err.code, 'HPE_UNEXPECTED_CONTENT_LENGTH'); |
||||
|
count++; |
||||
|
if (count === MAX_COUNT) |
||||
|
server.close(); |
||||
|
})); |
||||
|
} |
||||
|
})); |
||||
|
|
||||
|
process.on('exit', function() { |
||||
|
assert.equal(count, MAX_COUNT); |
||||
|
}); |
@ -0,0 +1,29 @@ |
|||||
|
var common = require('../common'); |
||||
|
var http = require('http'); |
||||
|
var net = require('net'); |
||||
|
var assert = require('assert'); |
||||
|
|
||||
|
var reqstr = 'POST / HTTP/1.1\r\n' + |
||||
|
'Content-Length: 1\r\n' + |
||||
|
'Transfer-Encoding: chunked\r\n\r\n'; |
||||
|
|
||||
|
var server = http.createServer(function(req, res) { |
||||
|
assert.fail(null, null, 'callback should not be invoked'); |
||||
|
}); |
||||
|
server.on('clientError', common.mustCall(function(err) { |
||||
|
assert(/^Parse Error/.test(err.message)); |
||||
|
assert.equal(err.code, 'HPE_UNEXPECTED_CONTENT_LENGTH'); |
||||
|
server.close(); |
||||
|
})); |
||||
|
server.listen(common.PORT, function() { |
||||
|
var client = net.connect({port: common.PORT}, function() { |
||||
|
client.write(reqstr); |
||||
|
client.end(); |
||||
|
}); |
||||
|
client.on('data', function(data) { |
||||
|
// Should not get to this point because the server should simply
|
||||
|
// close the connection without returning any data.
|
||||
|
assert.fail(null, null, 'no data should be returned by the server'); |
||||
|
}); |
||||
|
client.on('end', common.mustCall(function() {})); |
||||
|
}); |
@ -0,0 +1,28 @@ |
|||||
|
var common = require('../common'); |
||||
|
var net = require('net'); |
||||
|
var http = require('http'); |
||||
|
var assert = require('assert'); |
||||
|
|
||||
|
var str = 'GET / HTTP/1.1\r\n' + |
||||
|
'Dummy: Header\r' + |
||||
|
'Content-Length: 1\r\n' + |
||||
|
'\r\n'; |
||||
|
|
||||
|
var server = http.createServer(function(req, res) { |
||||
|
assert.fail(null, null, 'this should not be called'); |
||||
|
}); |
||||
|
server.on('clientError', common.mustCall(function(err) { |
||||
|
assert(/^Parse Error/.test(err.message)); |
||||
|
assert.equal(err.code, 'HPE_LF_EXPECTED'); |
||||
|
server.close(); |
||||
|
})); |
||||
|
server.listen(common.PORT, function() { |
||||
|
var client = net.connect({port:common.PORT}, function() { |
||||
|
client.on('data', function(chunk) { |
||||
|
assert.fail(null, null, 'this should not be called'); |
||||
|
}); |
||||
|
client.on('end', common.mustCall(function() {})); |
||||
|
client.write(str); |
||||
|
client.end(); |
||||
|
}); |
||||
|
}); |
Loading…
Reference in new issue