4

リクエストストリームはnode.js(expressまたはrestify)でどのように機能しますか?

オーディオ、mpeg、またはその他のバイナリファイルをサーバーにアップロードしようとするクライアントの場合、要求はサーバー上の読み取り可能なストリームである必要があります。request.pipe()たとえば、リクエストからファイルを取得し、knoxを使用してファイルをamazon s3にアップロードするために、別のストリームにパイプすることができます。

content-length非同期認証方式を使用していると、ストリーミングされたデータの一部が失われ、長さが送信されたヘッダーと一致しなくなります。この動作を回避する方法はありますか?リクエストストリームのデータはメモリにのみ保存されますか、それとも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');
});
4

1 に答える 1

4

見てみましょう、どこから始めましょう:

  • dataはい、リクエストは、あなたが言ったようにイベントを発行するReadStreamです。
  • ストリームの最初のデータチャンクはメモリに保存され、一時ファイルはありません。

発生している一般的な問題は、から送信されたデータをキャプチャしreq、認証が完了したら再送信する必要があることです。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);
        }); 
    }
);
于 2012-11-16T08:45:24.753 に答える