|
|
'use strict'; |
|
|
|
|
|
var assert = require('assert'); |
|
|
var express = require('express'); |
|
|
var http = require('http'); |
|
|
var startProxyTarget = require('./support/proxyTarget'); |
|
|
var proxy = require('../'); |
|
|
|
|
|
function chunkingProxyServer() { |
|
|
var proxyRouteFn = [{ |
|
|
method: 'get', |
|
|
path: '/stream', |
|
|
fn: function (req, res) { |
|
|
res.write('0'); |
|
|
setTimeout(function () { res.write('1'); }, 100); |
|
|
setTimeout(function () { res.write('2'); }, 200); |
|
|
setTimeout(function () { res.write('3'); }, 300); |
|
|
setTimeout(function () { res.end(); }, 500); |
|
|
} |
|
|
}]; |
|
|
|
|
|
return startProxyTarget(8309, 1000, proxyRouteFn); |
|
|
} |
|
|
|
|
|
function simulateUserRequest() { |
|
|
return new Promise(function (resolve, reject) { |
|
|
var req = http.request({ hostname: 'localhost', port: 8308, path: '/stream' }, function (res) { |
|
|
var chunks = []; |
|
|
res.on('data', function (chunk) { chunks.push(chunk.toString()); }); |
|
|
res.on('end', function () { resolve(chunks); }); |
|
|
}); |
|
|
|
|
|
req.on('error', function (e) { |
|
|
reject('problem with request:', e.message); |
|
|
}); |
|
|
|
|
|
req.end(); |
|
|
}); |
|
|
} |
|
|
|
|
|
function startLocalServer(proxyOptions) { |
|
|
var app = express(); |
|
|
app.get('/stream', proxy('http://localhost:8309', proxyOptions)); |
|
|
return app.listen(8308); |
|
|
} |
|
|
|
|
|
describe('streams / piped requests', function () { |
|
|
this.timeout(3000); |
|
|
|
|
|
var server; |
|
|
var targetServer; |
|
|
|
|
|
beforeEach(function () { |
|
|
targetServer = chunkingProxyServer(); |
|
|
}); |
|
|
|
|
|
afterEach(function () { |
|
|
server.close(); |
|
|
targetServer.close(); |
|
|
}); |
|
|
|
|
|
describe('when streaming options are truthy', function () { |
|
|
var TEST_CASES = [{ |
|
|
name: 'vanilla, no options defined', |
|
|
options: {} |
|
|
}, { |
|
|
name: 'proxyReqOptDecorator is defined', |
|
|
options: { proxyReqOptDecorator: function (reqBuilder) { return reqBuilder; } } |
|
|
}, { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
name: 'proxyReqOptDecorator is a Promise', |
|
|
options: { proxyReqOptDecorator: function (reqBuilder) { return Promise.resolve(reqBuilder); } } |
|
|
}]; |
|
|
|
|
|
TEST_CASES.forEach(function (testCase) { |
|
|
describe(testCase.name, function () { |
|
|
it('chunks are received without any buffering, e.g. before request end', function (done) { |
|
|
server = startLocalServer(testCase.options); |
|
|
simulateUserRequest() |
|
|
.then(function (res) { |
|
|
|
|
|
|
|
|
assert(res instanceof Array, 'res is an Array'); |
|
|
assert.equal(res.length, 4); |
|
|
done(); |
|
|
}) |
|
|
.catch(done); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
|
|
|
describe('when streaming options are falsey', function () { |
|
|
var TEST_CASES = [{ |
|
|
name: 'skipToNextHandler is defined', |
|
|
options: { skipToNextHandlerFilter: function () { return false; } } |
|
|
}]; |
|
|
|
|
|
TEST_CASES.forEach(function (testCase) { |
|
|
describe(testCase.name, function () { |
|
|
it('response arrives in one large chunk', function (done) { |
|
|
server = startLocalServer(testCase.options); |
|
|
|
|
|
simulateUserRequest() |
|
|
.then(function (res) { |
|
|
|
|
|
|
|
|
assert(res instanceof Array); |
|
|
assert.equal(res.length, 1); |
|
|
done(); |
|
|
}) |
|
|
.catch(done); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
|