在node.js上进行一些身份验证后如何避免请求流丢失的数据? [英] How to avoid the data of request stream loss after doing some authentication on node.js?

查看:146
本文介绍了在node.js上进行一些身份验证后如何避免请求流丢失的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请求流如何与node.js一起使用(快速或重新定义)?

How do request streams works with node.js (express or restify) ?

当尝试将音频,mpeg或其他二进制文件上传到服务器,请求应该是服务器上的可读流。我们可以使用 request.pipe()来管理另一个流,例如从请求获取文件,然后使用knox将文件上传到amazon s3。

When a client who tries to upload an audio, mpeg or other binary file to the server, the request should be a Readable Stream on the server. that we could pipe into another stream using request.pipe() to for example get the file from the request, and then upload the file to amazon s3 using knox.

当我使用异步认证方法时,部分流数据丢失,长度与发送的 content-length 标题了。有什么办法可以避免这种行为吗?
请求流的数据仅存储在内存中,否则node.js将数据存储在某些本地临时文件夹中?

When I'm using an asynchronous authentication method part of the streamed data is being lost and the length doesn't match with the transmitted content-length header anymore. Is there any way to avoid this behavior? Is the data of request stream stored only in memory or does node.js store the data in some local temp folder?

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');
});


推荐答案

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

Lets see, where to begin:


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

  • Yes, the request is a ReadStream that will emit data events as you said.
  • The first chunk of data in the stream is stored in memory, there are no temporary files.

您遇到的一般问题是,您需要捕获从 req 发出的数据,并在验证完成后重新发出。 Connect为您提供帮助。看来护照 - http目前不使用它们。

The general issue you are running into is that you need to capture the data emitted from the req and re-emit it once the authentication is completed. Connect provides helpers to do this for you. It looks like passport-http doesn't currently use them.

如果您安装暂停模块,它可以处理这个。

If you install the pause module it can handle this for you.

尝试这样的东西:

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);
        }); 
    }
);

这篇关于在node.js上进行一些身份验证后如何避免请求流丢失的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆