test: improvements to various http tests
* Add common/countdown utility * Numerous improvements to http tests PR-URL: https://github.com/nodejs/node/pull/14315 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
parent
ed21cb1774
commit
b0a8a7c6ba
@ -338,6 +338,42 @@ The realpath of the 'tmp' directory.
|
||||
|
||||
Name of the temp directory used by tests.
|
||||
|
||||
## Countdown Module
|
||||
|
||||
The `Countdown` module provides a simple countdown mechanism for tests that
|
||||
require a particular action to be taken after a given number of completed
|
||||
tasks (for instance, shutting down an HTTP server after a specific number of
|
||||
requests).
|
||||
|
||||
<!-- eslint-disable strict, required-modules -->
|
||||
```js
|
||||
const Countdown = require('../common/countdown');
|
||||
|
||||
function doSomething() {
|
||||
console.log('.');
|
||||
}
|
||||
|
||||
const countdown = new Countdown(2, doSomething);
|
||||
countdown.dec();
|
||||
countdown.dec();
|
||||
```
|
||||
|
||||
### new Countdown(limit, callback)
|
||||
|
||||
* `limit` {number}
|
||||
* `callback` {function}
|
||||
|
||||
Creates a new `Countdown` instance.
|
||||
|
||||
### Countdown.prototype.dec()
|
||||
|
||||
Decrements the `Countdown` counter.
|
||||
|
||||
### Coutndown.prototype.remaining
|
||||
|
||||
Specifies the remaining number of times `Countdown.prototype.dec()` must be
|
||||
called before the callback is invoked.
|
||||
|
||||
## WPT Module
|
||||
|
||||
The wpt.js module is a port of parts of
|
||||
|
27
test/common/countdown.js
Normal file
27
test/common/countdown.js
Normal file
@ -0,0 +1,27 @@
|
||||
/* eslint-disable required-modules */
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const kLimit = Symbol('limit');
|
||||
const kCallback = Symbol('callback');
|
||||
|
||||
class Countdown {
|
||||
constructor(limit, cb) {
|
||||
assert.strictEqual(typeof limit, 'number');
|
||||
assert.strictEqual(typeof cb, 'function');
|
||||
this[kLimit] = limit;
|
||||
this[kCallback] = cb;
|
||||
}
|
||||
|
||||
dec() {
|
||||
assert(this[kLimit] > 0, 'Countdown expired');
|
||||
if (--this[kLimit] === 0)
|
||||
this[kCallback]();
|
||||
}
|
||||
|
||||
get remaining() {
|
||||
return this[kLimit];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Countdown;
|
15
test/parallel/test-common-countdown.js
Normal file
15
test/parallel/test-common-countdown.js
Normal file
@ -0,0 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const Countdown = require('../common/countdown');
|
||||
|
||||
let done = '';
|
||||
|
||||
const countdown = new Countdown(2, common.mustCall(() => done = true));
|
||||
assert.strictEqual(countdown.remaining, 2);
|
||||
countdown.dec();
|
||||
assert.strictEqual(countdown.remaining, 1);
|
||||
countdown.dec();
|
||||
assert.strictEqual(countdown.remaining, 0);
|
||||
assert.strictEqual(done, true);
|
@ -24,42 +24,24 @@ const common = require('../common');
|
||||
const http = require('http');
|
||||
|
||||
let serverRes;
|
||||
const server = http.Server(function(req, res) {
|
||||
console.log('Server accepted request.');
|
||||
const server = http.Server((req, res) => {
|
||||
serverRes = res;
|
||||
res.writeHead(200);
|
||||
res.write('Part of my res.');
|
||||
});
|
||||
|
||||
server.listen(0, common.mustCall(function() {
|
||||
server.listen(0, common.mustCall(() => {
|
||||
http.get({
|
||||
port: this.address().port,
|
||||
port: server.address().port,
|
||||
headers: { connection: 'keep-alive' }
|
||||
}, common.mustCall(function(res) {
|
||||
}, common.mustCall((res) => {
|
||||
server.close();
|
||||
serverRes.destroy();
|
||||
|
||||
console.log(`Got res: ${res.statusCode}`);
|
||||
console.dir(res.headers);
|
||||
|
||||
res.on('data', function(chunk) {
|
||||
console.log(`Read ${chunk.length} bytes`);
|
||||
console.log(' chunk=%j', chunk.toString());
|
||||
});
|
||||
|
||||
res.on('end', function() {
|
||||
console.log('Response ended.');
|
||||
});
|
||||
|
||||
res.on('aborted', function() {
|
||||
console.log('Response aborted.');
|
||||
});
|
||||
|
||||
res.socket.on('close', function() {
|
||||
console.log('socket closed, but not res');
|
||||
});
|
||||
|
||||
// it would be nice if this worked:
|
||||
res.resume();
|
||||
res.on('end', common.mustCall());
|
||||
res.on('aborted', common.mustCall());
|
||||
res.on('close', common.mustCall());
|
||||
res.socket.on('close', common.mustCall());
|
||||
}));
|
||||
}));
|
||||
|
@ -20,13 +20,13 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
|
||||
let complete;
|
||||
|
||||
const server = http.createServer(function(req, res) {
|
||||
const server = http.createServer((req, res) => {
|
||||
// We should not see the queued /thatotherone request within the server
|
||||
// as it should be aborted before it is sent.
|
||||
assert.strictEqual(req.url, '/');
|
||||
@ -40,9 +40,7 @@ const server = http.createServer(function(req, res) {
|
||||
});
|
||||
|
||||
|
||||
server.listen(0, function() {
|
||||
console.log('listen', server.address().port);
|
||||
|
||||
server.listen(0, () => {
|
||||
const agent = new http.Agent({ maxSockets: 1 });
|
||||
assert.strictEqual(Object.keys(agent.sockets).length, 0);
|
||||
|
||||
@ -55,7 +53,7 @@ server.listen(0, function() {
|
||||
};
|
||||
|
||||
const req1 = http.request(options);
|
||||
req1.on('response', function(res1) {
|
||||
req1.on('response', (res1) => {
|
||||
assert.strictEqual(Object.keys(agent.sockets).length, 1);
|
||||
assert.strictEqual(Object.keys(agent.requests).length, 0);
|
||||
|
||||
@ -69,7 +67,9 @@ server.listen(0, function() {
|
||||
assert.strictEqual(Object.keys(agent.sockets).length, 1);
|
||||
assert.strictEqual(Object.keys(agent.requests).length, 1);
|
||||
|
||||
req2.on('error', function(err) {
|
||||
// TODO(jasnell): This event does not appear to currently be triggered.
|
||||
// is this handler actually required?
|
||||
req2.on('error', (err) => {
|
||||
// This is expected in response to our explicit abort call
|
||||
assert.strictEqual(err.code, 'ECONNRESET');
|
||||
});
|
||||
@ -80,25 +80,16 @@ server.listen(0, function() {
|
||||
assert.strictEqual(Object.keys(agent.sockets).length, 1);
|
||||
assert.strictEqual(Object.keys(agent.requests).length, 1);
|
||||
|
||||
console.log(`Got res: ${res1.statusCode}`);
|
||||
console.dir(res1.headers);
|
||||
res1.on('data', (chunk) => complete());
|
||||
|
||||
res1.on('data', function(chunk) {
|
||||
console.log(`Read ${chunk.length} bytes`);
|
||||
console.log(' chunk=%j', chunk.toString());
|
||||
complete();
|
||||
});
|
||||
|
||||
res1.on('end', function() {
|
||||
console.log('Response ended.');
|
||||
|
||||
setTimeout(function() {
|
||||
res1.on('end', common.mustCall(() => {
|
||||
setTimeout(common.mustCall(() => {
|
||||
assert.strictEqual(Object.keys(agent.sockets).length, 0);
|
||||
assert.strictEqual(Object.keys(agent.requests).length, 0);
|
||||
|
||||
server.close();
|
||||
}, 100);
|
||||
});
|
||||
}), 100);
|
||||
}));
|
||||
});
|
||||
|
||||
req1.end();
|
||||
|
@ -20,7 +20,7 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
|
||||
const http = require('http');
|
||||
@ -28,20 +28,21 @@ const http = require('http');
|
||||
const maxSize = 1024;
|
||||
let size = 0;
|
||||
|
||||
const s = http.createServer(function(req, res) {
|
||||
this.close();
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
server.close();
|
||||
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
for (let i = 0; i < maxSize; i++) {
|
||||
res.write('x' + i);
|
||||
res.write(`x${i}`);
|
||||
}
|
||||
res.end();
|
||||
});
|
||||
}));
|
||||
|
||||
let aborted = false;
|
||||
s.listen(0, function() {
|
||||
const req = http.get('http://localhost:' + s.address().port, function(res) {
|
||||
res.on('data', function(chunk) {
|
||||
server.listen(0, () => {
|
||||
|
||||
const res = common.mustCall((res) => {
|
||||
res.on('data', (chunk) => {
|
||||
size += chunk.length;
|
||||
assert(!aborted, 'got data after abort');
|
||||
if (size > maxSize) {
|
||||
@ -50,11 +51,9 @@ s.listen(0, function() {
|
||||
size = maxSize;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
process.on('exit', function() {
|
||||
assert(aborted);
|
||||
assert.strictEqual(size, maxSize);
|
||||
console.log('ok');
|
||||
req.on('abort', common.mustCall(() => assert.strictEqual(size, maxSize)));
|
||||
});
|
||||
|
||||
const req = http.get(`http://localhost:${server.address().port}`, res);
|
||||
});
|
||||
|
@ -23,61 +23,51 @@
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
const Countdown = require('../common/countdown');
|
||||
|
||||
let clientResponses = 0;
|
||||
|
||||
const server = http.createServer(common.mustCall(function(req, res) {
|
||||
console.error('Server got GET request');
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
req.resume();
|
||||
res.writeHead(200);
|
||||
res.write('');
|
||||
setTimeout(function() {
|
||||
res.end(req.url);
|
||||
}, 50);
|
||||
setTimeout(() => res.end(req.url), 50);
|
||||
}, 2));
|
||||
server.on('connect', common.mustCall(function(req, socket) {
|
||||
console.error('Server got CONNECT request');
|
||||
|
||||
const countdown = new Countdown(2, common.mustCall(() => server.close()));
|
||||
|
||||
server.on('connect', common.mustCall((req, socket) => {
|
||||
socket.write('HTTP/1.1 200 Connection established\r\n\r\n');
|
||||
socket.resume();
|
||||
socket.on('end', function() {
|
||||
socket.end();
|
||||
});
|
||||
socket.on('end', () => socket.end());
|
||||
}));
|
||||
server.listen(0, function() {
|
||||
|
||||
server.listen(0, common.mustCall(() => {
|
||||
const req = http.request({
|
||||
port: this.address().port,
|
||||
port: server.address().port,
|
||||
method: 'CONNECT',
|
||||
path: 'google.com:80'
|
||||
});
|
||||
req.on('connect', common.mustCall(function(res, socket) {
|
||||
console.error('Client got CONNECT response');
|
||||
req.on('connect', common.mustCall((res, socket) => {
|
||||
socket.end();
|
||||
socket.on('end', function() {
|
||||
socket.on('end', common.mustCall(() => {
|
||||
doRequest(0);
|
||||
doRequest(1);
|
||||
});
|
||||
}));
|
||||
socket.resume();
|
||||
}));
|
||||
req.end();
|
||||
});
|
||||
}));
|
||||
|
||||
function doRequest(i) {
|
||||
http.get({
|
||||
port: server.address().port,
|
||||
path: `/request${i}`
|
||||
}, common.mustCall(function(res) {
|
||||
console.error('Client got GET response');
|
||||
}, common.mustCall((res) => {
|
||||
let data = '';
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', function(chunk) {
|
||||
data += chunk;
|
||||
});
|
||||
res.on('end', function() {
|
||||
res.on('data', (chunk) => data += chunk);
|
||||
res.on('end', common.mustCall(() => {
|
||||
assert.strictEqual(data, `/request${i}`);
|
||||
++clientResponses;
|
||||
if (clientResponses === 2) {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
countdown.dec();
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
@ -23,35 +23,30 @@
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
const Countdown = require('../common/countdown');
|
||||
|
||||
const server = http.createServer(function(req, res) {
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||
res.end('Hello World\n');
|
||||
}).listen(0, common.mustCall(function() {
|
||||
}, 2)).listen(0, common.mustCall(() => {
|
||||
const agent = new http.Agent({ maxSockets: 1 });
|
||||
|
||||
agent.on('free', function(socket) {
|
||||
console.log('freeing socket. destroyed? ', socket.destroyed);
|
||||
});
|
||||
agent.on('free', common.mustCall(3));
|
||||
|
||||
const requestOptions = {
|
||||
agent: agent,
|
||||
host: 'localhost',
|
||||
port: this.address().port,
|
||||
port: server.address().port,
|
||||
path: '/'
|
||||
};
|
||||
|
||||
const request1 = http.get(requestOptions, common.mustCall(function(response) {
|
||||
const request1 = http.get(requestOptions, common.mustCall((response) => {
|
||||
// assert request2 is queued in the agent
|
||||
const key = agent.getName(requestOptions);
|
||||
assert.strictEqual(agent.requests[key].length, 1);
|
||||
console.log('got response1');
|
||||
request1.socket.on('close', function() {
|
||||
console.log('request1 socket closed');
|
||||
});
|
||||
response.pipe(process.stdout);
|
||||
response.on('end', common.mustCall(function() {
|
||||
console.log('response1 done');
|
||||
request1.socket.on('close', common.mustCall());
|
||||
response.resume();
|
||||
response.on('end', common.mustCall(() => {
|
||||
/////////////////////////////////
|
||||
//
|
||||
// THE IMPORTANT PART
|
||||
@ -65,43 +60,29 @@ const server = http.createServer(function(req, res) {
|
||||
// is triggered.
|
||||
request1.socket.destroy();
|
||||
|
||||
response.once('close', function() {
|
||||
// TODO(jasnell): This close event does not appear to be triggered.
|
||||
// is it necessary?
|
||||
response.once('close', () => {
|
||||
// assert request2 was removed from the queue
|
||||
assert(!agent.requests[key]);
|
||||
console.log("waiting for request2.onSocket's nextTick");
|
||||
process.nextTick(common.mustCall(function() {
|
||||
process.nextTick(() => {
|
||||
// assert that the same socket was not assigned to request2,
|
||||
// since it was destroyed.
|
||||
assert.notStrictEqual(request1.socket, request2.socket);
|
||||
assert(!request2.socket.destroyed, 'the socket is destroyed');
|
||||
}));
|
||||
});
|
||||
});
|
||||
}));
|
||||
}));
|
||||
|
||||
const request2 = http.get(requestOptions, common.mustCall(function(response) {
|
||||
const request2 = http.get(requestOptions, common.mustCall((response) => {
|
||||
assert(!request2.socket.destroyed);
|
||||
assert(request1.socket.destroyed);
|
||||
// assert not reusing the same socket, since it was destroyed.
|
||||
assert.notStrictEqual(request1.socket, request2.socket);
|
||||
console.log('got response2');
|
||||
let gotClose = false;
|
||||
let gotResponseEnd = false;
|
||||
request2.socket.on('close', function() {
|
||||
console.log('request2 socket closed');
|
||||
gotClose = true;
|
||||
done();
|
||||
});
|
||||
response.pipe(process.stdout);
|
||||
response.on('end', function() {
|
||||
console.log('response2 done');
|
||||
gotResponseEnd = true;
|
||||
done();
|
||||
});
|
||||
|
||||
function done() {
|
||||
if (gotResponseEnd && gotClose)
|
||||
server.close();
|
||||
}
|
||||
const countdown = new Countdown(2, common.mustCall(() => server.close()));
|
||||
request2.socket.on('close', common.mustCall(() => countdown.dec()));
|
||||
response.on('end', common.mustCall(() => countdown.dec()));
|
||||
response.resume();
|
||||
}));
|
||||
}));
|
||||
|
@ -1,32 +1,31 @@
|
||||
'use strict';
|
||||
require('../common');
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
const Agent = http.Agent;
|
||||
|
||||
const server = http.createServer(function(req, res) {
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.end('hello world');
|
||||
});
|
||||
}, 2));
|
||||
|
||||
server.listen(0, function() {
|
||||
const agent = new Agent({
|
||||
keepAlive: true,
|
||||
});
|
||||
server.listen(0, () => {
|
||||
const agent = new Agent({ keepAlive: true });
|
||||
|
||||
const requestParams = {
|
||||
host: 'localhost',
|
||||
port: this.address().port,
|
||||
port: server.address().port,
|
||||
agent: agent,
|
||||
path: '/'
|
||||
};
|
||||
|
||||
const socketKey = agent.getName(requestParams);
|
||||
|
||||
get(function(res) {
|
||||
http.get(requestParams, common.mustCall((res) => {
|
||||
assert.strictEqual(res.statusCode, 200);
|
||||
res.resume();
|
||||
res.on('end', function() {
|
||||
process.nextTick(function() {
|
||||
res.on('end', common.mustCall(() => {
|
||||
process.nextTick(common.mustCall(() => {
|
||||
const freeSockets = agent.freeSockets[socketKey];
|
||||
assert.strictEqual(freeSockets.length, 1,
|
||||
`expect a free socket on ${socketKey}`);
|
||||
@ -35,14 +34,10 @@ server.listen(0, function() {
|
||||
const freeSocket = freeSockets[0];
|
||||
freeSocket.emit('error', new Error('ECONNRESET: test'));
|
||||
|
||||
get(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function get(callback) {
|
||||
return http.get(requestParams, callback);
|
||||
}
|
||||
http.get(requestParams, done);
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
|
||||
function done() {
|
||||
assert.strictEqual(Object.keys(agent.freeSockets).length, 0,
|
||||
@ -50,6 +45,5 @@ server.listen(0, function() {
|
||||
|
||||
agent.destroy();
|
||||
server.close();
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
|
@ -20,8 +20,7 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const assert = require('assert');
|
||||
const common = require('../common');
|
||||
const http = require('http');
|
||||
|
||||
// sending `agent: false` when `port: null` is also passed in (i.e. the result
|
||||
@ -35,20 +34,13 @@ const opts = {
|
||||
agent: false
|
||||
};
|
||||
|
||||
let good = false;
|
||||
process.on('exit', function() {
|
||||
assert(good, 'expected either an "error" or "response" event');
|
||||
});
|
||||
|
||||
// we just want an "error" (no local HTTP server on port 80) or "response"
|
||||
// to happen (user happens ot have HTTP server running on port 80).
|
||||
// As long as the process doesn't crash from a C++ assertion then we're good.
|
||||
const req = http.request(opts);
|
||||
req.on('response', function(res) {
|
||||
good = true;
|
||||
});
|
||||
req.on('error', function(err) {
|
||||
// an "error" event is ok, don't crash the process
|
||||
good = true;
|
||||
});
|
||||
|
||||
// Will be called by either the response event or error event, not both
|
||||
const oneResponse = common.mustCall();
|
||||
req.on('response', oneResponse);
|
||||
req.on('error', oneResponse);
|
||||
req.end();
|
||||
|
@ -34,19 +34,17 @@ const agent = new Agent({
|
||||
maxFreeSockets: 5
|
||||
});
|
||||
|
||||
const server = http.createServer(function(req, res) {
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
if (req.url === '/error') {
|
||||
res.destroy();
|
||||
return;
|
||||
} else if (req.url === '/remote_close') {
|
||||
// cache the socket, close it after a short delay
|
||||
const socket = res.connection;
|
||||
setImmediate(function() {
|
||||
socket.end();
|
||||
});
|
||||
setImmediate(common.mustCall(() => socket.end()));
|
||||
}
|
||||
res.end('hello world');
|
||||
});
|
||||
}, 4));
|
||||
|
||||
function get(path, callback) {
|
||||
return http.get({
|
||||
@ -65,82 +63,75 @@ function checkDataAndSockets(body) {
|
||||
|
||||
function second() {
|
||||
// request second, use the same socket
|
||||
get('/second', function(res) {
|
||||
get('/second', common.mustCall((res) => {
|
||||
assert.strictEqual(res.statusCode, 200);
|
||||
res.on('data', checkDataAndSockets);
|
||||
res.on('end', function() {
|
||||
res.on('end', common.mustCall(() => {
|
||||
assert.strictEqual(agent.sockets[name].length, 1);
|
||||
assert.strictEqual(agent.freeSockets[name], undefined);
|
||||
process.nextTick(function() {
|
||||
process.nextTick(common.mustCall(() => {
|
||||
assert.strictEqual(agent.sockets[name], undefined);
|
||||
assert.strictEqual(agent.freeSockets[name].length, 1);
|
||||
remoteClose();
|
||||
});
|
||||
});
|
||||
});
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
function remoteClose() {
|
||||
// mock remote server close the socket
|
||||
get('/remote_close', function(res) {
|
||||
get('/remote_close', common.mustCall((res) => {
|
||||
assert.deepStrictEqual(res.statusCode, 200);
|
||||
res.on('data', checkDataAndSockets);
|
||||
res.on('end', function() {
|
||||
res.on('end', common.mustCall(() => {
|
||||
assert.strictEqual(agent.sockets[name].length, 1);
|
||||
assert.strictEqual(agent.freeSockets[name], undefined);
|
||||
process.nextTick(function() {
|
||||
process.nextTick(common.mustCall(() => {
|
||||
assert.strictEqual(agent.sockets[name], undefined);
|
||||
assert.strictEqual(agent.freeSockets[name].length, 1);
|
||||
// waitting remote server close the socket
|
||||
setTimeout(function() {
|
||||
setTimeout(common.mustCall(() => {
|
||||
assert.strictEqual(agent.sockets[name], undefined);
|
||||
assert.strictEqual(agent.freeSockets[name], undefined,
|
||||
'freeSockets is not empty');
|
||||
remoteError();
|
||||
}, common.platformTimeout(200));
|
||||
});
|
||||
});
|
||||
});
|
||||
}), common.platformTimeout(200));
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
function remoteError() {
|
||||
// remove server will destroy ths socket
|
||||
const req = get('/error', function(res) {
|
||||
throw new Error('should not call this function');
|
||||
});
|
||||
req.on('error', function(err) {
|
||||
assert.ok(err);
|
||||
const req = get('/error', common.mustNotCall());
|
||||
req.on('error', common.mustCall((err) => {
|
||||
assert(err);
|
||||
assert.strictEqual(err.message, 'socket hang up');
|
||||
assert.strictEqual(agent.sockets[name].length, 1);
|
||||
assert.strictEqual(agent.freeSockets[name], undefined);
|
||||
// Wait socket 'close' event emit
|
||||
setTimeout(function() {
|
||||
setTimeout(common.mustCall(() => {
|
||||
assert.strictEqual(agent.sockets[name], undefined);
|
||||
assert.strictEqual(agent.freeSockets[name], undefined);
|
||||
done();
|
||||
}, common.platformTimeout(1));
|
||||
});
|
||||
server.close();
|
||||
}), common.platformTimeout(1));
|
||||
}));
|
||||
}
|
||||
|
||||
function done() {
|
||||
console.log('http keepalive agent test success.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
server.listen(0, function() {
|
||||
server.listen(0, common.mustCall(() => {
|
||||
name = `localhost:${server.address().port}:`;
|
||||
// request first, and keep alive
|
||||
get('/first', function(res) {
|
||||
get('/first', common.mustCall((res) => {
|
||||
assert.strictEqual(res.statusCode, 200);
|
||||
res.on('data', checkDataAndSockets);
|
||||
res.on('end', function() {
|
||||
res.on('end', common.mustCall(() => {
|
||||
assert.strictEqual(agent.sockets[name].length, 1);
|
||||
assert.strictEqual(agent.freeSockets[name], undefined);
|
||||
process.nextTick(function() {
|
||||
process.nextTick(common.mustCall(() => {
|
||||
assert.strictEqual(agent.sockets[name], undefined);
|
||||
assert.strictEqual(agent.freeSockets[name].length, 1);
|
||||
second();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
|
@ -1,7 +1,8 @@
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
const Countdown = require('../common/countdown');
|
||||
|
||||
const MAX_SOCKETS = 2;
|
||||
|
||||
@ -12,9 +13,11 @@ const agent = new http.Agent({
|
||||
maxFreeSockets: 2
|
||||
});
|
||||
|
||||
const server = http.createServer(function(req, res) {
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.end('hello world');
|
||||
});
|
||||
}, 6));
|
||||
|
||||
const countdown = new Countdown(6, common.mustCall(() => server.close()));
|
||||
|
||||
function get(path, callback) {
|
||||
return http.get({
|
||||
@ -25,19 +28,14 @@ function get(path, callback) {
|
||||
}, callback);
|
||||
}
|
||||
|
||||
server.listen(0, function() {
|
||||
let finished = 0;
|
||||
const num_requests = 6;
|
||||
for (let i = 0; i < num_requests; i++) {
|
||||
const request = get('/1', function() {
|
||||
});
|
||||
request.on('response', function() {
|
||||
server.listen(0, common.mustCall(() => {
|
||||
for (let i = 0; i < 6; i++) {
|
||||
const request = get('/1', common.mustCall());
|
||||
request.on('response', common.mustCall(() => {
|
||||
request.abort();
|
||||
const sockets = agent.sockets[Object.keys(agent.sockets)[0]];
|
||||
assert(sockets.length <= MAX_SOCKETS);
|
||||
if (++finished === num_requests) {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
countdown.dec();
|
||||
}));
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
@ -1,7 +1,8 @@
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
const Countdown = require('../common/countdown');
|
||||
|
||||
const agent = new http.Agent({
|
||||
keepAlive: true,
|
||||
@ -10,9 +11,9 @@ const agent = new http.Agent({
|
||||
maxFreeSockets: 2
|
||||
});
|
||||
|
||||
const server = http.createServer(function(req, res) {
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.end('hello world');
|
||||
});
|
||||
}, 2));
|
||||
|
||||
function get(path, callback) {
|
||||
return http.get({
|
||||
@ -23,32 +24,25 @@ function get(path, callback) {
|
||||
}, callback);
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
function done() {
|
||||
if (++count !== 2) {
|
||||
return;
|
||||
}
|
||||
const countdown = new Countdown(2, common.mustCall(() => {
|
||||
const freepool = agent.freeSockets[Object.keys(agent.freeSockets)[0]];
|
||||
assert.strictEqual(freepool.length, 2,
|
||||
`expect keep 2 free sockets, but got ${freepool.length}`);
|
||||
agent.destroy();
|
||||
server.close();
|
||||
}));
|
||||
|
||||
function dec() {
|
||||
process.nextTick(() => countdown.dec());
|
||||
}
|
||||
|
||||
server.listen(0, function() {
|
||||
get('/1', function(res) {
|
||||
assert.strictEqual(res.statusCode, 200);
|
||||
res.resume();
|
||||
res.on('end', function() {
|
||||
process.nextTick(done);
|
||||
});
|
||||
});
|
||||
function onGet(res) {
|
||||
assert.strictEqual(res.statusCode, 200);
|
||||
res.resume();
|
||||
res.on('end', common.mustCall(dec));
|
||||
}
|
||||
|
||||
get('/2', function(res) {
|
||||
assert.strictEqual(res.statusCode, 200);
|
||||
res.resume();
|
||||
res.on('end', function() {
|
||||
process.nextTick(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
server.listen(0, common.mustCall(() => {
|
||||
get('/1', common.mustCall(onGet));
|
||||
get('/2', common.mustCall(onGet));
|
||||
}));
|
||||
|
@ -24,17 +24,17 @@ const common = require('../common');
|
||||
const http = require('http');
|
||||
const url = require('url');
|
||||
|
||||
const server = http.createServer(common.mustCall(function(req, res) {
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.end();
|
||||
})).listen(0, '127.0.0.1', common.mustCall(function() {
|
||||
const opts = url.parse(`http://127.0.0.1:${this.address().port}/`);
|
||||
})).listen(0, '127.0.0.1', common.mustCall(() => {
|
||||
const opts = url.parse(`http://127.0.0.1:${server.address().port}/`);
|
||||
|
||||
// remove the `protocol` field… the `http` module should fall back
|
||||
// to "http:", as defined by the global, default `http.Agent` instance.
|
||||
opts.agent = new http.Agent();
|
||||
opts.agent.protocol = null;
|
||||
|
||||
http.get(opts, common.mustCall(function(res) {
|
||||
http.get(opts, common.mustCall((res) => {
|
||||
res.resume();
|
||||
server.close();
|
||||
}));
|
||||
|
@ -23,14 +23,14 @@
|
||||
const common = require('../common');
|
||||
const http = require('http');
|
||||
|
||||
const server = http.createServer(common.mustCall(function(req, res) {
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.end();
|
||||
})).listen(0, common.mustCall(function() {
|
||||
})).listen(0, common.mustCall(() => {
|
||||
const options = {
|
||||
agent: null,
|
||||
port: this.address().port
|
||||
port: server.address().port
|
||||
};
|
||||
http.get(options, common.mustCall(function(res) {
|
||||
http.get(options, common.mustCall((res) => {
|
||||
res.resume();
|
||||
server.close();
|
||||
}));
|
||||
|
@ -1,23 +1,23 @@
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
|
||||
const server = http.createServer(function(req, res) {
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.setHeader('X-Date', 'foo');
|
||||
res.setHeader('X-Connection', 'bar');
|
||||
res.setHeader('X-Content-Length', 'baz');
|
||||
res.end();
|
||||
});
|
||||
}));
|
||||
server.listen(0);
|
||||
|
||||
server.on('listening', function() {
|
||||
const agent = new http.Agent({ port: this.address().port, maxSockets: 1 });
|
||||
server.on('listening', common.mustCall(() => {
|
||||
const agent = new http.Agent({ port: server.address().port, maxSockets: 1 });
|
||||
http.get({
|
||||
port: this.address().port,
|
||||
port: server.address().port,
|
||||
path: '/hello',
|
||||
agent: agent
|
||||
}, function(res) {
|
||||
}, common.mustCall((res) => {
|
||||
assert.strictEqual(res.statusCode, 200);
|
||||
assert.strictEqual(res.headers['x-date'], 'foo');
|
||||
assert.strictEqual(res.headers['x-connection'], 'bar');
|
||||
@ -27,5 +27,5 @@ server.on('listening', function() {
|
||||
assert.strictEqual(res.headers['content-length'], '0');
|
||||
server.close();
|
||||
agent.destroy();
|
||||
});
|
||||
});
|
||||
}));
|
||||
}));
|
||||
|
@ -25,34 +25,29 @@ const assert = require('assert');
|
||||
const http = require('http');
|
||||
const net = require('net');
|
||||
|
||||
const server = http.createServer(common.mustCall(function(req, res) {
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
assert.strictEqual('GET', req.method);
|
||||
assert.strictEqual('/blah', req.url);
|
||||
assert.deepStrictEqual({
|
||||
host: 'mapdevel.trolologames.ru:443',
|
||||
origin: 'http://mapdevel.trolologames.ru',
|
||||
host: 'example.org:443',
|
||||
origin: 'http://example.org',
|
||||
cookie: ''
|
||||
}, req.headers);
|
||||
}));
|
||||
|
||||
|
||||
server.listen(0, function() {
|
||||
const c = net.createConnection(this.address().port);
|
||||
server.listen(0, common.mustCall(() => {
|
||||
const c = net.createConnection(server.address().port);
|
||||
|
||||
c.on('connect', function() {
|
||||
c.on('connect', common.mustCall(() => {
|
||||
c.write('GET /blah HTTP/1.1\r\n' +
|
||||
'Host: mapdevel.trolologames.ru:443\r\n' +
|
||||
'Host: example.org:443\r\n' +
|
||||
'Cookie:\r\n' +
|
||||
'Origin: http://mapdevel.trolologames.ru\r\n' +
|
||||
'Origin: http://example.org\r\n' +
|
||||
'\r\n\r\nhello world'
|
||||
);
|
||||
});
|
||||
}));
|
||||
|
||||
c.on('end', function() {
|
||||
c.end();
|
||||
});
|
||||
|
||||
c.on('close', function() {
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
c.on('end', common.mustCall(() => c.end()));
|
||||
c.on('close', common.mustCall(() => server.close()));
|
||||
}));
|
||||
|
@ -32,16 +32,12 @@ for (let i = 0; i < buffer.length; i++) {
|
||||
buffer[i] = i % 256;
|
||||
}
|
||||
|
||||
|
||||
const web = http.Server(function(req, res) {
|
||||
web.close();
|
||||
|
||||
console.log(req.headers);
|
||||
const server = http.Server(function(req, res) {
|
||||
server.close();
|
||||
|
||||
let i = 0;
|
||||
|
||||
req.on('data', function(d) {
|
||||
process.stdout.write(',');
|
||||
req.on('data', (d) => {
|
||||
measuredSize += d.length;
|
||||
for (let j = 0; j < d.length; j++) {
|
||||
assert.strictEqual(buffer[i], d[j]);
|
||||
@ -49,39 +45,27 @@ const web = http.Server(function(req, res) {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
req.on('end', function() {
|
||||
req.on('end', common.mustCall(() => {
|
||||
assert.strictEqual(bufferSize, measuredSize);
|
||||
res.writeHead(200);
|
||||
res.write('thanks');
|
||||
res.end();
|
||||
console.log('response with \'thanks\'');
|
||||
});
|
||||
|
||||
req.connection.on('error', function(e) {
|
||||
console.log(`http server-side error: ${e.message}`);
|
||||
process.exit(1);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
web.listen(0, common.mustCall(function() {
|
||||
console.log('Making request');
|
||||
|
||||
server.listen(0, common.mustCall(() => {
|
||||
const req = http.request({
|
||||
port: this.address().port,
|
||||
method: 'GET',
|
||||
port: server.address().port,
|
||||
method: 'POST',
|
||||
path: '/',
|
||||
headers: { 'content-length': buffer.length }
|
||||
}, common.mustCall(function(res) {
|
||||
console.log('Got response');
|
||||
}, common.mustCall((res) => {
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', common.mustCall(function(string) {
|
||||
assert.strictEqual('thanks', string);
|
||||
let data = '';
|
||||
res.on('data', (chunk) => data += chunk);
|
||||
res.on('end', common.mustCall(() => {
|
||||
assert.strictEqual('thanks', data);
|
||||
}));
|
||||
}));
|
||||
req.end(buffer);
|
||||
}));
|
||||
|
||||
|
||||
process.on('exit', function() {
|
||||
assert.strictEqual(bufferSize, measuredSize);
|
||||
});
|
||||
|
@ -20,7 +20,7 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
|
||||
@ -34,31 +34,23 @@ const UTF8_STRING = '南越国是前203年至前111年存在于岭南地区的
|
||||
'采用封建制和郡县制并存的制度,它的建立保证了秦末乱世岭南地区社会秩序的稳定,' +
|
||||
'有效的改善了岭南地区落后的政治、经济现状。';
|
||||
|
||||
const server = http.createServer(function(req, res) {
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf8' });
|
||||
res.end(UTF8_STRING, 'utf8');
|
||||
});
|
||||
server.listen(0, function() {
|
||||
}));
|
||||
server.listen(0, common.mustCall(() => {
|
||||
let data = '';
|
||||
const get = http.get({
|
||||
http.get({
|
||||
path: '/',
|
||||
host: 'localhost',
|
||||
port: this.address().port
|
||||
}, function(x) {
|
||||
port: server.address().port
|
||||
}, common.mustCall((x) => {
|
||||
x.setEncoding('utf8');
|
||||
x.on('data', function(c) { data += c; });
|
||||
x.on('error', function(e) {
|
||||
throw e;
|
||||
});
|
||||
x.on('end', function() {
|
||||
x.on('data', (c) => data += c);
|
||||
x.on('end', common.mustCall(() => {
|
||||
assert.strictEqual('string', typeof data);
|
||||
console.log('here is the response:');
|
||||
assert.strictEqual(UTF8_STRING, data);
|
||||
console.log(data);
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
get.on('error', function(e) { throw e; });
|
||||
get.end();
|
||||
|
||||
});
|
||||
}));
|
||||
})).end();
|
||||
}));
|
||||
|
@ -20,57 +20,35 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const assert = require('assert');
|
||||
const common = require('../common');
|
||||
const http = require('http');
|
||||
const Countdown = require('../common/countdown');
|
||||
|
||||
let clientAborts = 0;
|
||||
const N = 8;
|
||||
|
||||
const server = http.Server(function(req, res) {
|
||||
console.log('Got connection');
|
||||
const countdown = new Countdown(N, common.mustCall(() => server.close()));
|
||||
|
||||
const server = http.Server(common.mustCall((req, res) => {
|
||||
res.writeHead(200);
|
||||
res.write('Working on it...');
|
||||
req.on('aborted', common.mustCall(() => countdown.dec()));
|
||||
}, N));
|
||||
|
||||
// I would expect an error event from req or res that the client aborted
|
||||
// before completing the HTTP request / response cycle, or maybe a new
|
||||
// event like "aborted" or something.
|
||||
req.on('aborted', function() {
|
||||
clientAborts++;
|
||||
console.log(`Got abort ${clientAborts}`);
|
||||
if (clientAborts === N) {
|
||||
console.log('All aborts detected, you win.');
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
server.listen(0, common.mustCall(() => {
|
||||
|
||||
let responses = 0;
|
||||
const N = 8;
|
||||
const requests = [];
|
||||
const requests = [];
|
||||
const reqCountdown = new Countdown(N, common.mustCall(() => {
|
||||
requests.forEach((req) => req.abort());
|
||||
}));
|
||||
|
||||
server.listen(0, function() {
|
||||
console.log('Server listening.');
|
||||
const options = { port: server.address().port };
|
||||
|
||||
for (let i = 0; i < N; i++) {
|
||||
console.log(`Making client ${i}`);
|
||||
const options = { port: this.address().port, path: `/?id=${i}` };
|
||||
const req = http.get(options, function(res) {
|
||||
console.log(`Client response code ${res.statusCode}`);
|
||||
|
||||
res.resume();
|
||||
if (++responses === N) {
|
||||
console.log('All clients connected, destroying.');
|
||||
requests.forEach(function(outReq) {
|
||||
console.log('abort');
|
||||
outReq.abort();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
requests.push(req);
|
||||
options.path = `/?id=${i}`;
|
||||
requests.push(
|
||||
http.get(options, common.mustCall((res) => {
|
||||
res.resume();
|
||||
reqCountdown.dec();
|
||||
})));
|
||||
}
|
||||
});
|
||||
|
||||
process.on('exit', function() {
|
||||
assert.strictEqual(N, clientAborts);
|
||||
});
|
||||
}));
|
||||
|
@ -20,18 +20,19 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const http = require('http');
|
||||
|
||||
const server = http.createServer(function(req, res) {
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.end('Hello');
|
||||
});
|
||||
}));
|
||||
|
||||
server.listen(0, function() {
|
||||
const req = http.get({ port: this.address().port }, function(res) {
|
||||
res.on('data', function(data) {
|
||||
server.listen(0, common.mustCall(() => {
|
||||
const options = { port: server.address().port };
|
||||
const req = http.get(options, common.mustCall((res) => {
|
||||
res.on('data', (data) => {
|
||||
req.abort();
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
}));
|
||||
}));
|
||||
|
@ -20,7 +20,7 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
|
||||
@ -28,23 +28,22 @@ let name;
|
||||
const max = 3;
|
||||
let count = 0;
|
||||
|
||||
const server = http.Server(function(req, res) {
|
||||
const server = http.Server(common.mustCall((req, res) => {
|
||||
if (req.url === '/0') {
|
||||
setTimeout(function() {
|
||||
setTimeout(common.mustCall(() => {
|
||||
res.writeHead(200);
|
||||
res.end('Hello, World!');
|
||||
}, 100);
|
||||
}), 100);
|
||||
} else {
|
||||
res.writeHead(200);
|
||||
res.end('Hello, World!');
|
||||
}
|
||||
});
|
||||
server.listen(0, function() {
|
||||
name = http.globalAgent.getName({ port: this.address().port });
|
||||
for (let i = 0; i < max; ++i) {
|
||||
}, max));
|
||||
server.listen(0, common.mustCall(() => {
|
||||
name = http.globalAgent.getName({ port: server.address().port });
|
||||
for (let i = 0; i < max; ++i)
|
||||
request(i);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
function request(i) {
|
||||
const req = http.get({
|
||||
@ -52,7 +51,7 @@ function request(i) {
|
||||
path: `/${i}`
|
||||
}, function(res) {
|
||||
const socket = req.socket;
|
||||
socket.on('close', function() {
|
||||
socket.on('close', common.mustCall(() => {
|
||||
++count;
|
||||
if (count < max) {
|
||||
assert.strictEqual(http.globalAgent.sockets[name].includes(socket),
|
||||
@ -62,11 +61,7 @@ function request(i) {
|
||||
assert(!http.globalAgent.requests.hasOwnProperty(name));
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
}));
|
||||
res.resume();
|
||||
});
|
||||
}
|
||||
|
||||
process.on('exit', function() {
|
||||
assert.strictEqual(count, max);
|
||||
});
|
||||
|
@ -2,39 +2,28 @@
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
const Countdown = require('../common/countdown');
|
||||
|
||||
const expectedSuccesses = [undefined, null, 'GET', 'post'];
|
||||
let requestCount = 0;
|
||||
const expectedFails = [-1, 1, 0, {}, true, false, [], Symbol()];
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
requestCount++;
|
||||
const countdown =
|
||||
new Countdown(expectedSuccesses.length,
|
||||
common.mustCall(() => server.close()));
|
||||
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.end();
|
||||
countdown.dec();
|
||||
}, expectedSuccesses.length));
|
||||
|
||||
if (expectedSuccesses.length === requestCount) {
|
||||
server.close();
|
||||
}
|
||||
}).listen(0, test);
|
||||
|
||||
function test() {
|
||||
function fail(input) {
|
||||
server.listen(0, common.mustCall(() => {
|
||||
expectedFails.forEach((method) => {
|
||||
assert.throws(() => {
|
||||
http.request({ method: input, path: '/' }, common.mustNotCall());
|
||||
http.request({ method, path: '/' }, common.mustNotCall());
|
||||
}, /^TypeError: Method must be a string$/);
|
||||
}
|
||||
|
||||
fail(-1);
|
||||
fail(1);
|
||||
fail(0);
|
||||
fail({});
|
||||
fail(true);
|
||||
fail(false);
|
||||
fail([]);
|
||||
|
||||
function ok(method) {
|
||||
http.request({ method: method, port: server.address().port }).end();
|
||||
}
|
||||
});
|
||||
|
||||
expectedSuccesses.forEach((method) => {
|
||||
ok(method);
|
||||
http.request({ method, port: server.address().port }).end();
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
@ -20,9 +20,10 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
const Countdown = require('../common/countdown');
|
||||
|
||||
const expectedHeaders = {
|
||||
'DELETE': ['host', 'connection'],
|
||||
@ -35,17 +36,18 @@ const expectedHeaders = {
|
||||
|
||||
const expectedMethods = Object.keys(expectedHeaders);
|
||||
|
||||
let requestCount = 0;
|
||||
const countdown =
|
||||
new Countdown(expectedMethods.length,
|
||||
common.mustCall(() => server.close()));
|
||||
|
||||
const server = http.createServer(function(req, res) {
|
||||
requestCount++;
|
||||
const server = http.createServer(common.mustCall((req, res) => {
|
||||
res.end();
|
||||
|
||||
assert(expectedHeaders.hasOwnProperty(req.method),
|
||||
`${req.method} was an unexpected method`);
|
||||
|
||||
const requestHeaders = Object.keys(req.headers);
|
||||
requestHeaders.forEach(function(header) {
|
||||
requestHeaders.forEach((header) => {
|
||||
assert.strictEqual(
|
||||
expectedHeaders[req.method].includes(header.toLowerCase()),
|
||||
true,
|
||||
@ -59,15 +61,14 @@ const server = http.createServer(function(req, res) {
|
||||
`some headers were missing for method: ${req.method}`
|
||||
);
|
||||
|
||||
if (expectedMethods.length === requestCount)
|
||||
server.close();
|
||||
});
|
||||
countdown.dec();
|
||||
}, expectedMethods.length));
|
||||
|
||||
server.listen(0, function() {
|
||||
expectedMethods.forEach(function(method) {
|
||||
server.listen(0, common.mustCall(() => {
|
||||
expectedMethods.forEach((method) => {
|
||||
http.request({
|
||||
method: method,
|
||||
port: server.address().port
|
||||
}).end();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
@ -20,20 +20,20 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
|
||||
http.createServer(function(req, res) {
|
||||
res.end('ok\n');
|
||||
this.close();
|
||||
}).listen(0, test);
|
||||
|
||||
function test() {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.end('ok');
|
||||
server.close();
|
||||
}).listen(0, common.mustCall(() => {
|
||||
http.request({
|
||||
port: this.address().port,
|
||||
port: server.address().port,
|
||||
encoding: 'utf8'
|
||||
}, function(res) {
|
||||
res.pipe(process.stdout);
|
||||
}).end();
|
||||
}
|
||||
}, common.mustCall((res) => {
|
||||
let data = '';
|
||||
res.on('data', (chunk) => data += chunk);
|
||||
res.on('end', common.mustCall(() => assert.strictEqual(data, 'ok')));
|
||||
})).end();
|
||||
}));
|
||||
|
@ -20,41 +20,33 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const assert = require('assert');
|
||||
|
||||
const common = require('../common');
|
||||
const http = require('http');
|
||||
const net = require('net');
|
||||
const Countdown = require('../common/countdown');
|
||||
|
||||
let connects = 0;
|
||||
let parseErrors = 0;
|
||||
const countdown = new Countdown(2, common.mustCall(() => server.close()));
|
||||
|
||||
const payloads = [
|
||||
'HTTP/1.1 302 Object Moved\r\nContent-Length: 0\r\n\r\nhi world',
|
||||
'bad http = should trigger parse error'
|
||||
];
|
||||
|
||||
// Create a TCP server
|
||||
net.createServer(function(c) {
|
||||
console.log('connection');
|
||||
if (++connects === 1) {
|
||||
c.end('HTTP/1.1 302 Object Moved\r\nContent-Length: 0\r\n\r\nhi world');
|
||||
} else {
|
||||
c.end('bad http - should trigger parse error\r\n');
|
||||
this.close();
|
||||
}
|
||||
}).listen(0, '127.0.0.1', function() {
|
||||
for (let i = 0; i < 2; i++) {
|
||||
http.request({
|
||||
host: '127.0.0.1',
|
||||
port: this.address().port,
|
||||
method: 'GET',
|
||||
path: '/'
|
||||
}).on('error', function(e) {
|
||||
console.log('got error from client');
|
||||
assert.ok(e.message.includes('Parse Error'));
|
||||
assert.strictEqual(e.code, 'HPE_INVALID_CONSTANT');
|
||||
parseErrors++;
|
||||
}).end();
|
||||
}
|
||||
});
|
||||
const server =
|
||||
net.createServer(common.mustCall((c) => c.end(payloads.shift()), 2));
|
||||
|
||||
process.on('exit', function() {
|
||||
assert.strictEqual(connects, 2);
|
||||
assert.strictEqual(parseErrors, 2);
|
||||
});
|
||||
server.listen(0, common.mustCall(() => {
|
||||
for (let i = 0; i < 2; i++) {
|
||||
http.get({
|
||||
port: server.address().port,
|
||||
path: '/'
|
||||
}).on('error', common.mustCall((e) => {
|
||||
common.expectsError({
|
||||
code: 'HPE_INVALID_CONSTANT',
|
||||
message: 'Parse Error'
|
||||
})(e);
|
||||
countdown.dec();
|
||||
}));
|
||||
}
|
||||
}));
|
||||
|
Loading…
x
Reference in New Issue
Block a user