0

busboy で Express を使用して、Node.js 4.x でファイルのアップロードを実現しようとしています。ファイルをアップロードして Azure Blob Storage に保存することは既に可能です。

いいえ、Azure に保存する前にファイルの種類を確認し、無効なファイルを拒否したいと思います。

マジックナンバーを使って検証したいと思います。const fileType = require('file-type');ファイルの種類を決定するものを見つけまし た。

今、私はこの作業をできるだけ効率的にしようとしていますが、ここで苦労しています。ファイル ストリームを Azure に直接パイプしたいのです。しかしその前に、ストリームから最初の 5 バイトをファイル タイプ別に処理されるバッファに読み込む必要があります。

ストリームから読み取ってから紺碧にパイプすることは確かに機能しません。いくつかの調査の後、ファイルを 2 つの PassThrough ストリームにパイプすることで解決策を見つけました。しかし今、私はこれらの 2 つのストリームを正しく処理するのに苦労しています。

const fileType = require('file-type');
const pass = require('stream').PassThrough;

//...

req.busboy.on('file', function (fieldname, file, filename) {
   console.log("Uploading: " + filename);
   var b = new pass;
   var c = new pass;
   file.pipe(b);
   file.pipe(c);


   var type = null;
   b.on('readable', function() {
      b.pause();
      if(type === null) {
         var chunk = b.read(5);
         type = fileType(chunk) || false;
         b.end();
      }
   });

   b.on('finish', function() {
      if(type && ['jpg', 'png', 'gif'].indexOf(type.ext) !== -1) {
         var blobStream = blobSvc.createWriteStreamToBlockBlob(storageName,
            blobName,
            function (error) {
               if (error) console.log('blob upload error', error);
               else console.log('blob upload complete')
            });
         c.pipe(blobStream);
      }
      else {
         console.error("Rejected file of type " + type);
      }
   });

});

この解決策は機能する場合があります。また、「終了後の書き込み」エラーが発生する場合もあります。また、ストリームが適切に閉じられていないと思います。通常、リクエストの後、エクスプレスはコンソールに次のようなログを記録するためです。

POST /path - - ms - -

しかし、このログ メッセージは、おそらく何らかのタイムアウトが原因で、「blob のアップロードが完了」してから 30 秒から 60 秒後に表示されます。

これを修正する方法はありますか?

4

1 に答える 1

2

ミックスにストリームを追加する必要はありません。消費された部分だけunshift()をストリームに戻します。例えば:

const fileType = require('file-type');
req.busboy.on('file', function (fieldname, file, filename) {
  function readFirstBytes() {
    var chunk = file.read(5);
    if (!chunk)
      return file.once('readable', readFirstBytes);
    var type = fileType(chunk);
    if (type.ext === 'jpg' || type.ext === 'png' || type.ext === 'gif') {
      const blobStream = blobSvc.createWriteStreamToBlockBlob(
        storageName,
        blobName,
        function (error) {
          if (error)
            console.log('blob upload error', error);
          else
            console.log('blob upload complete');
        }
      );
      file.unshift(chunk);
      file.pipe(blobStream);
    } else {
      console.error('Rejected file of type ' + type);
      file.resume(); // Drain file stream to continue processing form
    }
  }

  readFirstBytes();
});
于 2015-11-28T18:33:18.077 に答える