Subscribed unsubscribe Subscribe Subscribe

@kyanny's blog

Write down what I learnt. Opinions are my own.

WebDav Depth Header と Net::HTTP#delete

WebDav の規格で Depth というヘッダがあり、 DELETE メソッドの挙動をコントロールできる。 0, 1, Infinity のいずれかの値をとり、 0 ならば対象のリソース自身を、 1 ならば対象のリソースとそれの直下のリソースを、 Infinity ならば対象のリソース以下のパスの全てのリソースを、それぞれ削除する。

nginx で特定のパス以下のみ WebDav を有効にして DELETE リクエストを受け付けていたら、リソースの削除ができずエラーログに "XXXX (TODO: あとで正確なエラーログに修正する)" と出ていた。調べた結果 Ruby の Net::HTTP#delete メソッドを呼び出したとき初期値で Depth: Infinity というヘッダが付与されていた。

https://github.com/ruby/ruby/blob/trunk/lib/net/http.rb#L1160

    # Sends a DELETE request to the +path+ and gets a response,
    # as an HTTPResponse object.
    def delete(path, initheader = {'Depth' => 'Infinity'})
      request(Delete.new(path, initheader))
    end

delete の呼び出し時に {'Depth' => '0'} を渡したら DELETE が成功する。 nginx は Depth: Infinity はダメなのか?と思ってエラーメッセージをよーくみると 0 or 'infinity' とある。もしやと思って {'Depth' => 'infinity'} としたらこれも成功する。どうやら nginx が case sensitive なせいでうまく動いてなかったらしい。何かの間違いで上位パスを指定してしまって全部消されても困るので、 Depth: 0 を明示的に指定するようにした。