AN HTTPD ゲストブック/コメント集(2005年2月16日15:46)


ちりりん♪ ちりりん♪ 2005/02/23 10:46

>いとさん
IE6とNC4.78で正常動作確認できました。
本当にありがとうございました。
というか私の調べ方が中途半端だったようで恥ずかしいです(^_^;
Cで組んでるからperlのソースはあんまり関係ないかなという思い込みがありました。
また、ブラウザのバージョンやローカルかネットかによって動作が違ったりしたので
そちらのほうにばかり目が行っておりました。
勉強になりました。


いと gfh05223@nifty.com 2005/02/22 21:56

ちりりん♪さん

いつの頃からか分かりませんが、KENTさんのところの ASKA BBSが
Locationを使った二重投稿防止対策をするようになっていますね。

このCGIを使えば動作検証ができます。ちょっと試してみたところでは、
427行目の "?" がポイントのようです。
 print "Location: $location?\n\n";

最初のリクエストの methodは POSTですが、"?" があるとリダイレクト後は
ブラウザに関わらず必ず GETになるようです。このときには Location: の
後の空白はあってもなくても動作は同じです。

一方、"?" がないと Location: の後の空白の有無で(IE6の)動作が変わります。
空白有のときはこの上と同じですが、空白無のときは二回連続 POSTになります。
Netscape7.2は "?" なしでもリダイレクト後は空白に無関係に GET になります。

Location行を解釈して次のリクエストを出しているのは、Webサーバではなく
ブラウザですから、空白の有無が影響するのはどうも IE6のバグではないか
という気がするのですが。

結論として URLの最後に "?" を付けるのが解決策になるのではないかと思います。
NC4.78でも "?" があれば問題なさそうです。

上記の話とは直接関係ありませんが、ASKAユーザの人は 137行目の $locationを
以下のように設定しておけばいいかと思います。
 $location = "http://$ENV{HTTP_HOST}"."$ENV{SCRIPT_NAME}";


ちりりん♪ ちりりん♪ 2005/02/21 14:40

>eternallyさん
お手数をお掛けして申し訳ありませんでした。
確かにご指摘のページではコロンのあとにスペース空いてますね。
実は以前私もそのページも見たような気がするのですが(^_^;
Cのソースプログラム上でのスペースと同じように
意味のないものとして無視してしまっていたのがそもそも誤りのようですね。

>いとさん
詳細な解説ありがとうございます。
やはりRFCを避けて通るわけには行かないようですね。
#英語が苦手とか言ってる場合じゃないですねこれは(^_^;

確認できた範囲での動作結果です。@Win2K
1.コロンの後にスペースを入れない
 1-1.ローカル環境
  1-1-a.IE6 「ページを表示できません。」
  1-1-b.NC4.78 「ドキュメントにデータが含まれていません」
 1-2.LAN環境(自宅の別PCから)
  1-2-a.IE6 正常のように見えるがPOSTを繰り返している(※)
  1-2-b.NC4.78 「ドキュメントにデータが含まれていません」
2.コロンの後にスペースを入れた
 2-1.ローカル環境
  2-1-a.IE6 正常に動作。
  2-1-b.NC4.78 「ドキュメントにデータが含まれていません」
 2-2.LAN環境(自宅の別PCから)
  同上
・会社からテストしてみましたが結果はLAN環境の場合と同じでした。

※1-2-a.はcgiの二重書き込みチェック(同一データの連続書き込みのチェック)に
 かかって見た目は正常に表示されますが、実際はPOSTになっていますので
 ブラウザのリロードボタンを押すともう一度POSTしに行きます。

これはサーバの動作というよりはブラウザ側の実装によるもの(?)のような気が。
なんだか微妙なのでcgiへの実装についてはもう少し悩んでみます。
長々と失礼致しました。
&ありがとうございました。>eternallyさん、いとさん


いと gfh05223@nifty.com 2005/02/20 11:24

ちりりん♪さん、eternallyさん

インターネットに関する技術の標準は RFCに定められているので
探すならそこでしょうね。ちょっと検索してみると RFC2068(HTTP/1.1)、
RFC1945(HTTP/1.0)がみつかりました。
 http://www.w3.org/Protocols/rfc2068/rfc2068
 http://www.w3.org/Protocols/rfc1945/rfc1945

RFC2068の日本語訳は以下。
 http://www.mars.dti.ne.jp/~torao/rfc/rfc2068-ja.html

関係するのは以下の辺りでしょうか。
4.2 Message Headers
Each header field consists of a name followed by a colon (":") and the field value. Field names are case-insensitive. The field value may be preceded by any amount of LWS, though a single SP is preferred.
message-header = field-name ":" [ field-value ] CRLF
field-value = *( field-content | LWS )

私には以下のような意味に思えるのですが。
メッセージヘッダは最初に field-name(Content-Type, Location など)があり、
コロン、field value が続き、行の終わりは CRLF(carriage return + linefeed)。

field value は最初に LWSがいくつあってもよい。
LWSというのは少なくとも一つのSP(スペース)または HT(タブ)のこと。
LWSはゼロ個でもよい(field-value の * の前後に数字がついていないので)が
SP(スペース)一つが望ましい。
(継続行の説明も書かれているがここでは直接関係ないので省略)

ということで
Location: の後にスペースはなくてもよいし、いくつスペースがあってもよいが
スペース一つが好ましい。
ということではないかと思います。

実際 AN HTTPDで試してみると、スペースはあってもなくても動いています。

> Location:http://127.0.0.1/cgi-bin/chiribbs.cgi

127.0.0.1というのはクライアント機のことですから、サーバ機自身からの
アクセスなら動作しますが、他機からアクセスしたときはだめでしょう。

127.0.0.1を他からアクセス可能なホスト名/IPアドレスにすればいいかと思いますが。


eternally 2005/02/20 01:27

あんまり特定のサイトってないんですよね・・・。
どちらかというとその場限りで検索しちゃうことが多いので。
Googleで「ヘッダ CGI 書式 一覧」で検索したところ以下のものが出てきました。
http://www.rfs.jp/sitebuilder/perl/03/03.html
それとコマンドプロンプトでもそうですけど半角スペースで区切ってコマンドを認識させることが多いと思います。
本当のことは知りませんがヘッダの場合もその流れなのかなと。


ちりりん♪ ちりりん♪ 2005/02/19 16:42

>eternally様
Location:とurlの間にスペースを入れて確認したところうまく行きました。
まだローカル環境のみでの確認ですので週明け早々にでも外部から
(とはいってもおそらく会社から(^_^;)アクセスして確認してみます。

googleで「locationヘッダ 書式」と検索して調べていたのですが
「間にスペース」について言及しているところが見つけられませんでした。
ヘッダの書式等くわしいところをご存知でしたらご教示頂けないでしょうか。
#ってこれはちょっとずうずうしすぎるか(^_^;

どうもありがとうございました。


eternally 2005/02/18 01:39

>ちりりん♪さん
Location: http://127.0.0.1/cgi-bin/chiribbs.cgi\n\n
間にスペースを入れるぐらいしか間違っていると思われるような箇所は見つけられませんね・・・。
これで一度やってみてもらえますか?


ちりりん♪ ちりりん♪ 2005/02/16 15:46

はじめまして。
Cでexe形式のcgi作成を勉強中のちりりん♪と申します。
現在掲示板cgiを作成中でLocationヘッダについてちょっと質問させて頂きたいのですが
こちらでよろしいでしょうか?

掲示板の二重投稿を回避する方法について調べていたのですが
POSTでのデータ更新が正常に終了した場合に
Locationヘッダを発行してcgiをもう一度呼び出すようにすると
cgiはGETで呼び出されるので大丈夫、
という記述をWeb上でみかけてそのつもりでいたのですが間違っているのでしょうか(^_^;

anhttpを使用して実際に実行してみると、
>>> s=368: Wed Feb 16 15:03:13 2005 >>>
HTTP/1.1 302 Found
MIME-Version: 1.0
Server: AnWeb/1.42n
Date: Wed, 16 Feb 2005 06:03:13 GMT
Transfer-Encoding: chunked
Expires: -1
Pragma: no-cache
Cache-control: no-cache
Last-Modified: Wed, 16 Feb 2005 06:03:13 GMT
>>> s=368: Wed Feb 16 15:03:13 2005 >>>
Set-Cookie: ※cookieはちょっと長いので略します
Location:http://127.0.0.1/cgi-bin/chiribbs.cgi

>>> s=368: Wed Feb 16 15:03:13 2005 >>>
0

IEでは「ページを表示できません。」
NC4.78(古いですが(^_^;)では「ドキュメントにデータが含まれていません」
になります。
---
常識的な「そんなのムリ」というような話でしたら申し訳ありません。
Locationヘッダを利用した二重投稿よけの方法がありましたらご教示お願い致します。
それともmetaタグでrefreshを使用するのがよい(というか普通)でしょうか?