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

概要

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のディレクトリが存在していなかった)