[Node.js] node-fetchでBASIC認証をしつつPUTする方法

2 min read

概要

Node.js を使って、BASIC 認証をしつつファイルを PUT する必要に迫られた。

環境

コード

let uploadPath = "distribute/json/";
let filename = "test.json";
let readStream = fs.createReadStream("./hogehoge.json");

readStream.on("open", function () {
  fetch(uploadPath + filename, {
    method: "PUT",
    headers: {
      Authorization:
        "Basic " + new Buffer(`${userID}:${password}`).toString("base64"),
    },
    body: readStream,
  }).then(function (res) {
    console.log("status: ", res.status);
    console.log("statusText: ", res.statusText);
  });
});

fs.createReadStreamでストリームを open し、fetch の body に渡す。BASIC 認証については、Authorization で下記のように指定する。

"Basic " + new Buffer(`${userID}:${password}`).toString("base64");

.catch()でエラーを拾うことができるが、HTTP 通信に関するエラーはthen(function(res){});内で確認できる(404 なども)。

また、fs.createReadStreamの close は自動的にしてくれるようだ。

留意点

HTTP Status で 409 が返ってくる事があった。

409 Conflict - HTTP | MDN
HTTP 409 Conflict はリクエストが現在のサーバーの状態と競合したことを示すステータスコード。

競合は PUT メソッドを使用したリクエストのレスポンスで最も発生しやすい。例えば、サーバーにすでに存在しているファイルよりも古いバージョンのファイルをアップロードした際に 409 の応答が返され、バージョン管理システムの競合が発生する可能性がある。

私の環境では、uploadPathとして指定したディレクトリが存在しておらず、発生していた。(distribute/json/と指定していた場合、jsonのディレクトリが存在していなかった)