1

Node.js/Restify で作成している RESTful API を介して Amazon S3 バケットにデータをアップロードする方法を見つけようとしています。基本的な概念はすべて機能していると思いますが、POST リクエストの本文に接続しようとすると、問題が発生します。単純に文字列を S3 に渡すようにコールバック関数を設定すると、問題なく動作し、適切な S3 バケットにファイルが作成されます。

function postPoint(req, res, next) {

  var point = [
    { "x": "0.12" },
    { "y": "0.32" }
  ];

  var params = { Bucket: 'myBucket', Key: 'myKey', Body: JSON.stringify(point) };

  s3.client.putObject(params, function (perr, pres) {
    if (perr) {
        console.log("Error uploading data: ", perr);
    } else {
        console.log("Successfully uploaded data to myBucket/myKey");
    }
  });

  res.send(200);
  return next();
}

server.post('/point', postPoint);

明らかに、最終的にリクエストの本文からリクエストをストリーミング/パイプする必要があります。私がする必要があるのは、単にパラメーターの本体を要求ストリームに切り替えることだけだと思いました。

function postPoint(req, res, next) {

  var params = { Bucket: 'myBucket', Key: 'myKey', Body: req };

  s3.client.putObject(params, function (perr, pres) {
    if (perr) {
        console.log("Error uploading data: ", perr);
    } else {
        console.log("Successfully uploaded data to myBucket/myKey");
    }
  });

  res.send(200);
  return next();
}

しかし、それにより、次のようなログ メッセージが表示されることになります。「データのアップロード中にエラーが発生しました: [TypeError: パスは文字列である必要があります]」。最終的には、送信されるデータが非常に大きくなる可能性があるため、結果をパイプできるようにしたいので (前の例で本体がメモリに格納されているかどうかはわかりません)、このようなものが機能する可能性があると考えました。 :

function postPoint(req, res, next) {

  var params = { Bucket: 'myBucket', Key: 'myKey', Body: req };

  req.pipe(s3.client.putObject(params));

  res.send(200);
  return next();
}

うまく機能するGET関数で同様のことを行ったので:( s3.client.getObject(params).createReadStream().pipe(res);)。しかし、それもうまくいきませんでした。

この時点で少し途方に暮れているので、ガイダンスをいただければ幸いです。

4

1 に答える 1

3

そのため、AWS 開発者フォーラムに投稿した後、ようやく答えを見つけました。Content-Length ヘッダーが S3 リクエストにないことがわかりました。Loren@AWSはそれを非常にうまくまとめています。

オブジェクトを S3 にアップロードするには、Content-Length を指定する必要があります。通常、SDK は Buffer および String データ (または .length プロパティを持つ任意のオブジェクト) からコンテンツを推測できます。また、ファイル ストリームに対してファイル長を取得するための特別な検出機能があります。残念ながら、SDK が任意のストリームの長さを把握する方法はないため、HTTP ストリームなどを渡す場合は、コンテンツの長さを自分で手動で指定する必要があります。

提案された解決策は、http.IncomingMessage オブジェクトのヘッダーからコンテンツの長さを単純に渡すことでした。

var params = {
  Bucket: 'bucket', Key: 'key', Body: req,
  ContentLength: parseInt(req.headers['content-length'], 10)
};
s3.putObject(params, ...);

スレッド全体を読みたい人は、ここからアクセスできます。

于 2013-06-21T11:08:28.687 に答える