GET と POST, Apache1.3系 と Apache2.X系

HTTPで何かのコンテンツを取得するのは普通 GET だけれど、

POST /path/to/file.html HTTP/1.0(改行)
(改行)

こんなことをやるとどうなるか、という話。

POSTメソッドというのは、情報をサーバに送りつけるためのメソッドであって、コンテンツを取得するための物ではない。なので、POST本来の意味において、上記枠内のようなリクエストは不正であると言わざるをえない。何にも情報を送ってないからね。204 No Content なんていうHTTPステータスコードが、"コンテンツはないよ"なのに、204 なのは純粋にPOSTが情報を送るためのメソッドである証拠と言えましょう(2で始まるステータスコードはオッケーの証)。この話のネタ元の人によると、これは「エラーになった」とのこと。エラーってどんなだろう?と思ってかるくテストしてみたら、これがわりと面白かったので掲載。

Apache 1.3系の場合

POST /index.html HTTP/1.0

HTTP/1.1 405 Method Not Allowed
Date: Thu, 28 Jul 2005 07:19:42 GMT
Server: Apache
Allow: GET, HEAD, OPTIONS, TRACE
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
(以下、405のエラードキュメント)

なるほど、405 Method Not Allowed だ。

Apache2.X系の場合

POST /index.html HTTP/1.0

HTTP/1.1 200 OK
Date: Thu, 28 Jul 2005 07:21:44 GMT
Server: Apache
Last-Modified: Sat, 24 May 2003 00:07:20 GMT
ETag: "554009-1ef-c2d35e00"
Accept-Ranges: bytes
Content-Length: 495
Connection: close
Content-Type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
(以下、普通に index.htmlの内容)

あらま、GET と同じ扱いだ。ちなみにちょっと前に出た2.1系でも同じだった。

まとめ

Apache 1.3系と 2.X系ではやっぱり違うことがわかった。

Apache1.3系がなぜ Method Not Allowed にするかと言うと、(ソース読んでないけど)POSTメソッドを取り扱う=ポストされた情報を取り扱うことが出来るリソースへのアクセス、という前提になっているからだと思う。
つまり、ポストされた情報を取り扱うことが出来るリソース=何らかのハンドラが割当られたリソース、これが必要なのでしょう。
だから、AddHandler cgi-script .cgi のように、ハンドラが割り当てられたリソースでないと、POSTをエラーにするんだろうな、と。今や知る人も少なく多分に前時代的な imagemap もPOSTを受付られる気がしますよ。AddHandler imap-file .map ですよ。おりゃ面倒だから試しません。

ではなぜ、Apache2.X系では問題ないのか。これは、Apacheのリクエストハンドリングの方法が根本的に変わったから、でしょう。詳しいことは俺は知らないけど、たぶんそういうこと。

で、なんでまたこんな話なのかというと。

又聞きなのでいい加減な記述になるけれど、なんでも携帯ブラウザの中には、Location: で飛ばした先へのリクエストメソッドを、前のメソッドと同じにする奴がいるんだそうですよ。
POSTメソッドで叩いたCGIの結果がLocation:ヘッダで飛ばすようになっている時に、飛んだ先へのリクエストメソッドを前と同じPOSTにしてしまうために、飛ばし先がhtmlだったりすると、前述のように405 Method Not Allowed になってしまうんだそうで。(この情報は何も調べていないので鵜呑みにしないこと)。

と、いうのが発端なのでした。