Merge pull request #212 from strongloop/feature/req-pause
Pause the req before checking access
This commit is contained in:
commit
eaa49555a9
|
@ -279,11 +279,16 @@ app.enableAuth = function() {
|
|||
var modelId = modelInstance && modelInstance.id || req.param('id');
|
||||
|
||||
if(Model.checkAccess) {
|
||||
// Pause the request before checking access
|
||||
// See https://github.com/strongloop/loopback-storage-service/issues/7
|
||||
req.pause();
|
||||
Model.checkAccess(
|
||||
req.accessToken,
|
||||
modelId,
|
||||
method.name,
|
||||
function(err, allowed) {
|
||||
// Emit any cached data events that fired while checking access.
|
||||
req.resume();
|
||||
if(err) {
|
||||
console.log(err);
|
||||
next(err);
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
var net = require('net');
|
||||
describe('loopback application', function() {
|
||||
it('pauses request stream during authentication', function(done) {
|
||||
// This test reproduces the issue reported in
|
||||
// https://github.com/strongloop/loopback-storage-service/issues/7
|
||||
var app = loopback();
|
||||
setupAppWithStreamingMethod();
|
||||
|
||||
app.listen(0, function() {
|
||||
sendHttpRequestInOnePacket(
|
||||
this.address().port,
|
||||
'POST /streamers/read HTTP/1.0\n' +
|
||||
'Content-Length: 1\n' +
|
||||
'Content-Type: application/x-custom-octet-stream\n' +
|
||||
'\n' +
|
||||
'X',
|
||||
function(err, res) {
|
||||
if (err) return done(err);
|
||||
expect(res).to.match(/\nX$/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
function setupAppWithStreamingMethod() {
|
||||
app.dataSource('db', {
|
||||
connector: loopback.Memory,
|
||||
defaultForType: 'db'
|
||||
});
|
||||
var db = app.datasources.db;
|
||||
|
||||
loopback.User.attachTo(db);
|
||||
loopback.AccessToken.attachTo(db);
|
||||
loopback.Role.attachTo(db);
|
||||
loopback.ACL.attachTo(db);
|
||||
loopback.User.hasMany(loopback.AccessToken, { as: 'accessTokens' });
|
||||
|
||||
var Streamer = app.model('Streamer', { dataSource: 'db' });
|
||||
Streamer.read = function(req, res, cb) {
|
||||
var body = new Buffer(0);
|
||||
req.on('data', function(chunk) {
|
||||
body += chunk;
|
||||
});
|
||||
req.on('end', function() {
|
||||
res.end(body.toString());
|
||||
// we must not call the callback here
|
||||
// because it will attempt to add response headers
|
||||
});
|
||||
req.once('error', function(err) {
|
||||
cb(err);
|
||||
});
|
||||
};
|
||||
loopback.remoteMethod(Streamer.read, {
|
||||
http: { method: 'post' },
|
||||
accepts: [
|
||||
{ arg: 'req', type: 'Object', http: { source: 'req' } },
|
||||
{ arg: 'res', type: 'Object', http: { source: 'res' } }
|
||||
]
|
||||
});
|
||||
|
||||
app.enableAuth();
|
||||
app.use(loopback.token({ model: app.models.accessToken }));
|
||||
app.use(loopback.rest());
|
||||
}
|
||||
|
||||
function sendHttpRequestInOnePacket(port, reqString, cb) {
|
||||
var socket = net.createConnection(port);
|
||||
var response = new Buffer(0);
|
||||
|
||||
socket.on('data', function(chunk) {
|
||||
response += chunk;
|
||||
});
|
||||
socket.on('end', function() {
|
||||
callCb(null, response.toString());
|
||||
});
|
||||
socket.once('error', function(err) {
|
||||
callCb(err);
|
||||
});
|
||||
|
||||
socket.write(reqString.replace(/\n/g, '\r\n'));
|
||||
|
||||
function callCb(err, res) {
|
||||
if (!cb) return;
|
||||
cb(err, res);
|
||||
cb = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue