@kyanny's blog

My thoughts, my life. Views/opinions are my own.

DirectorySlash は 301 Moved Permanently でリダイレクトする

http://httpd.apache.org/docs/2.0/mod/mod_dir.html#directoryslash

典型的には、ユーザが末尾のスラッシュ無しでリソースへのリクエストを発行し、 そして、そのリソースがディレクトリを指していた場合、mod_dir は、末尾にスラッシュを付加した上で同じリソースにリダイレクトさせます。

http://httpd.apache.org/docs/2.0/mod/mod_dir.html#directoryslash

リダイレクト時のステータスコードは何なのか気になったので Mac OSX Lion 付属の Apache/2.2.20 (Unix) で試した。

301 Moved Permanently になるようなのでもしステータスコードを変えたかったら mod_rewrite あたりを使う必要がありそう。

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 を明示的に指定するようにした。