2009/09/23(Wed)UTF-8な文字列をsubstrする

2009/09/23 5:10 Languages::Perl
ずいぶん以前からPerlで物を書くときには、文字コードをUTF-8にし、use utf8をしないで書いている。
で、その際、substrなどで文字列を切り出したいとすると、UTF-8は1文字あたりの長さが可変長であるため、入力文字列によっては変な文字が切り出されてしまうことになる。
これを正しく切り出すときに色々調べてみたメモ。

続きを読む

2008/09/17(Wed)Set-Cookieのpathについて

2008/09/17 18:22 Languages::Perl
Kerosoft@webのアナウンスをRSS配信するため、ウェブにコンパネを作っていた時、セッション管理用にCookieを使ったのだが、その時のメモ。

設定するとき

Set-Cookieのときのpathには注意しなくてはならない。
スクリプトの設置位置が、http://path-to-server/hogehoge.cgiだった場合、
Set-Cookie: CGISESSID=60b725f10c9c85c70d97880dfe8191b3; expires=Wed, 17-Sep-2008 21:16:22 GMT;
などとすると、デフォルトではその階層以下全てのディレクトリに対してCookieを送信してしまうので、ユーザー領域/~User/にも送ってしまうことになる。これは非常にまずい。

調べてみると、スクリプトを置く位置を自分以外がアクセスできないよう、/~hoge/以下に動かして、path=/~hoge/;とすれば安全と書いてあったが、今回のようにルートディレクトリに置きたい場合はどうするか。


結果的にいえば、こんな感じでいいようだ。
Set-Cookie: CGISESSID=60b725f10c9c85c70d97880dfe8191b3; expires=Wed, 17-Sep-2008 21:16:22 GMT; path=/hogehoge.cgi;
こうすれば、/hogehoge.cgi以下にはCookieが送られ、それ以外のアクセス(たとえば、/favicon.icoや/~user/hoge.htmlなど)へは送信されない。
このpathには、ディレクトリを指定するというような書き方をしているページが多々あったので、使い方を誤っているのかもしれないが、試した限りでは意図した動作をしているのでいいことにしようか…。
なお、別のユーザーが、/hogehoge.cgi/*等に対してアクセス権限を持っているとしたら意味がないので注意。そんなことはないと思うが。
ちなみに、/hogehoge.cgi部分は、$ENV{'SCRIPT_NAME'}で良いと思う。

削除のとき

削除する場合はexpiresに過去の値、たとえばThu, 01-Jan-1970 00:00:00 GMTを指定するが、これに関しても、pathを設定せねばならない。
Set-Cookie: CGISESSID=; expires=Thu, 01-Jan-1970 00:00:00 GMT; path=/hogehoge.cgi;
指定しない場合は、削除されない
ここに10分ほどハマってしまった……。

2008/07/31(Thu)adiaryのカウンタについて

2008/07/31 1:00 Languages::Perl
このModus Operandiがお世話になっているadiaryというBlog Systemはカウンタ機能を標準で持っていないので、3か月前くらいに自分で作ったのだが、たまたま友人から「ページビューが1増えたり2増えたりしてるぞ?」と報告をもらって色々調べてみた。


仕様としては、自分でPerl Moduleを一個作って/lib/Satsuki/に入れ、diary.user.skel/_sidebar.htmlのSystem Infoのとこにloadpmと値参照を加えるだけ。

とまぁ、そこまではいいのだが、やっぱりページビューを測るとなんかおかしい。
最初は自分の書き方が悪いのかと思ったのだが、どう考えてもforやwhileなどの繰り替えしを通らない部分に、カウント値の1upのコードを書いているので、おかしい……と悩んだ挙句、_sidebar.htmlが複数回呼ばれることがあるという結論に至った。

adiaryの中身をあまり詳しく見たわけではないのでよく分からないけど、1回しか呼ばれない場合と、2回呼ばれる場合がある模様。

そもそもカウンタはimgタグで対応してくれというのが作者の思惑なのかはわからないけど、とりあえずテキストカウンタにこだわりたいので現状のスタイルを保持して正しくカウントするには……と考え、PageViewの方はtime関数の戻り値が1以上ずれない限りカウントアップしないようにすることで対応した。
(ほんとは$$とかで対応しようかと思ったけど、speedy_backendが立ち上がりっぱなしなので、この手が使えない)

というわけで、同一時刻に複数からアクセスしても逆に1増えない、という状況になってしまったが、致し方ない。
細かい統計はGoogle Analyticsで見るか……。

原因が分かった 2008/07/31

開発者のnabe様から的確なコメントをいただき、一発で原因が分かりました。ありがとうございます。
どうやらブラウザが勝手に読みに行くfavicon.icoや存在しないRSSファイルを憶測で読みに行く時の404 Not Found画面でカウントアップしている感じでした。
<@ifexec(v.load_days, begin)>
<$c=loadpm("SimpleCounter")>
<@c.counter>
<$end>
404の"記事がありません"のメッセージ文を参考に、上記のように書き換えたことで、意図する動作になったかな。