続Gecko エンジンでの Location ヘッダについて
Gecko エンジンでの Location ヘッダについて
http://oshiete1.goo.ne.jp/qa4227374.html
の続きです。
なんだかよく分からない状況になったのでより実際の処理とほぼ同様の
処理を行っているサンプルを用意しました。
# セッション管理
use strict;
use CGI::Session;
&main();
# メイン
sub main {
my $cgi = &getreq();
print "Pragma: no-cache\n";
print "Cache-Control: no-cache\n";
# セッション取得
my $session = &session($cgi);
# セッションが取得できない場合、再取得
if($session == undef) {
# print "Content-type: text/plain\n\n";
# print "CGISESSID=$cgi->{'CGISESSID'}\n";
$session = &session({});
# セッション ID を取得してリダイレクト
my $id = $session->id();
print "Location: ./?CGISESSID=$id\n\n";
exit;
}
my $id = $session->id();
if($cgi->{'CGISESSID'} eq '' || $cgi->{'CGISESSID'} ne $id) {
# print "Content-type: text/plain\n\n";
# print "CGISESSID=$cgi->{'CGISESSID'}\n";
# セッション ID が指定されていないまたは
# セッション ID が異なる場合リダイレクト
print "Location: ./?CGISESSID=$id\n\n";
exit;
}
print "Content-type: text/plain\n\n";
print "CGISESSID=$id\n";
print "OK\n";
exit;
}
# CGI リクエストの取得
sub getreq {
my $cgi = {};
my $query = '';
$query = $ENV{'QUERY_STRING'};
my @args = split(/&/, $query);
foreach my $i (@args) {
my ($name, $val) = split(/=/, $i);
$val =~ tr/+/ /;
$val =~ s/%([0-9a-f]{2})/pack('C', hex($1))/eig;
$name =~ tr/+/ /;
$name =~ s/%([0-9a-f]{2})/pack('C', hex($1))/eig;
$cgi->{$name} = $val;
}
delete($cgi->{''});
return $cgi;
}
# セッション取得
sub session {
my $cgi = shift;
my $dir = { 'Directory' => 'tmp' };
CGI::Session->find(undef, sub {}, $dir);
if($cgi->{'CGISESSID'} eq '') {
my $session = new CGI::Session(undef, undef, $dir);
$session->expire("1h");
return $session;
}
my $session = CGI::Session->load(undef, $cgi->{'CGISESSID'}, $dir);
return ($session == undef || $session->id() eq '') ? undef : $session;
}
こんな感じのCGIで以下のような状況の時にページを更新すると
IE(Trident)/Opera(Presto)及びSafari for Win(WebKit)では
正常に動作するのですがFxやSeaMonkey(Gecko)ではおかしな動作を
します。
1. セッションが切れた時
2. セッションファイルを手動で削除した時
具体的にはセッションが切れたら再度新しいセッションを作成して
リダイレクトをするようにしてあるのですがGeckoでは一度セッションが
切れると更新する度に新しいセッションを作成するようになってしまい
ます。
以前の質問の回答のように Status: 303 See Other ヘッダを出力して
見たのですがやはり効果はないようです。
Cookieは使いたくないのでセッションID(sesid)をCGIリクエストで
送信しているのですがこの方法がまず問題なのでしょうか。
他にも問題のある部分がありましたらご指摘お願いします。