WebDAVってなんだよぉ
Nodeを使った案件で、WebDAVからファイルを取ってくる処理を書かなくてはいけなくなりました。WebDAVなんてFTPを使わないファイルサーバくらいの認識(正しいかは定かではない)しかないのですが、とりあえず動くものができたので共有します。
環境構築
環境はすべてdockerを使用して作成しました。WebDAVのコンテナイメージはこちら。nodeのコンテナはお好きに作成していただいて構いません。
version: '3'
services:
node:
build: .
volumes:
- .:/app
ports:
- 3000:3000
tty: true
environment
- WEBDAV_URL=http://webdav:80
working_dir: /app
webdav:
image: bytemark/webdav
restart: always
ports:
- 80:80
environment:
AUTH_TYPE: Basic
USERNAME: alice
PASSWORD: secret1234
volumes:
- /data:/var/lib/dav/data
※ Qiitaでコードブロックを埋め込むときに、ファイル名をバッククォートの後に書くとファイル名が表示されるんですが、拡張子なしだとファイル名が表示されない。Dockerfileだけだとファイル名が消えてしまうから渋々ドットを付けた。いい方法ないのかね
FROM node:latest
# 非rootユーザじゃないとpermisson errorが出る
# https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#non-root-user
USER node
動くコード
今回使用するライブラリはこちらのwebdav
です。
v5からは開発中ですがESMに対応しているらしく書き方等環境の作り方に注意とのこと。今回は、サポート対象であるv4を利用した書き方を紹介します。
import { AuthType, createClient } from "webdav"
const client = createClient(process.env.WEBDAV_URL, {
// Basic認証の場合は特にAuthTypeの指定はいりません。
username: "alice",
password: "secret1234"
})
client.getDirectoryContents('/').then(console.log)
これで、/var/lib/dav/data
の値がとれます。ここで、環境依存の問題なのか不明ですが、dockerhubの例では /var/lib/dav
にデータを入れてたのですが、私はそれではデータを取得できなかったので /var/lib/dav/data
に入れました。
ちなみに、getDirectoryContents
で指定するパスはコンテナ内のパスではなくて /var/lib/dav/data
がルートになっていることに気を付けてください。私はこれで結構はまりました。。。(WebDAVを知ってる人なら当たり前なのかな?)
追記:Apacheだと var/www/html
がルートになるイメージと同じことだと気づいた
終わりに
今回はnodeでWebDAVからファイルを取得する方法を解説しました。Basic認証以外に、例えばダイジェスト認証のやり方については引用先のサイトを参照してください。