如何在node.js上进行一些authentication后避免请求stream丢失的数据?

请求stream如何与node.js(express或restify)一起工作?

当试图将audio,mpeg或其他二进制文件上载到服务器的客户端时,请求应该是服务器上的可读stream。 我们可以使用request.pipe()将其传入另一个stream,例如从请求中获取文件,然后使用knox将file upload到amazon s3。

当我使用asynchronous身份validation方法时,部分stream式数据正在丢失,并且长度与传输的content-length头部不再匹配。 有什么办法可以避免这种行为? 请求stream的数据只存储在内存中还是node.js将数据存储在某个本地临时文件夹中?

 var express = require('express'), app = express(), passport = require('passport'), BasicStrategy = require('passport-http').BasicStrategy; var users = [ { id: 1, username: 'bob', password: 'secret', email: 'bob@example.com' } , { id: 2, username: 'joe', password: 'birthday', email: 'joe@example.com' } ]; function findByUsername(username, fn) { for (var i = 0, len = users.length; i < len; i++) { var user = users[i]; if (user.username === username) { return fn(null, user); } } return fn(null, null); } passport.use(new BasicStrategy( function(username, password, done) { process.nextTick(function () { findByUsername(username, function(err, user) { if (err) { return done(err); } if (!user) { return done(null, false); } if (user.password != password) { return done(null, false); } return done(null, user); }) }); })); app.configure(function() { app.use(express.logger()); app.use(passport.initialize()); app.use(app.router); }); app.post('/upload', passport.authenticate('basic', { session: false }), function(req, res, next) { var dataLength = 0; req.on('data', function(chunk) { console.log('loading'); dataLength += chunk.length; }).on('end', function() { console.log('load end'); console.log('contentLength: %s', req.headers['content-length']); console.log('dataLength: : %s', dataLength); res.send(200); }); }); app.listen(8080, function() { console.log('server is running'); }); 

让我们看看,从哪里开始:

  • 是的,请求是一个ReadStream,它会发出data事件。
  • stream中的第一个数据块存储在内存中,没有临时文件。

您遇到的一般问题是,您需要捕获req发出的数据,并在身份validation完成后重新发射它。 Connect提供助手为您完成此操作。 它看起来像护照-http目前不使用它们。

如果你安装暂停模块,它可以为你处理。

尝试这样的事情:

 var pause = require('pause'); // Create our own middleware constructor. var bufferedAuthenticate = function(){ // Set up standard authenticate handler passing arguments through. var authMiddleware = passport.authenticate.apply(passport, arguments); // Pass our own middleware instead that wraps passport-http. return function(req, res, next){ // Pause the request before authenticating. var obj = pause(req); authMiddleware(req, res, function(err){ next(err); // Emit any cached data events that fired while authenticating. obj.resume(); }); }; }; app.post('/upload', bufferedAuthenticate('basic', { session: false }), function(req, res, next) { var dataLength = 0; req.on('data', function(chunk) { console.log('loading'); dataLength += chunk.length; }).on('end', function() { console.log('load end'); console.log('contentLength: %s', req.headers['content-length']); console.log('dataLength: : %s', dataLength); res.send(200); }); } );