CGI プログラム用の標準的な Perl モジュール。 Perl 5.005 から標準 Perl ライブラリに含まれるようになった。
header メソッドに対して、charset オプションが使えるようになったのは 2.57 から。 2.57 以降 (Perl 5.6.1 以降)は charset オプションに 'UTF-8' 等を指定すると、Cotent-Type ヘッダ に charset が追加されるようになる。
2.56 以前 (Perl 5.6 以前)は charset オプションの処理がないので、type オプションを 'text/html; charset=UTF-8' のように指定する必要がある。
Perl バージョン | CGI.pm |
5.004 | 2.36 |
5.00405 | 2.42 |
5.005 | 2.42 |
5.005_03 | 2.46 |
5.005_04 | 2.46 |
5.6.0 | 2.56 |
5.6.1 | 2.752 |
5.6.2 | 2.752 |
5.7.3 | 2.80 |
5.8.0 | 2.81 |
5.8.1 | 3.00 |
5.8.2 | 3.00 |
5.8.3 | 3.01 |
5.8.4 | 3.04 |
5.8.5 | 3.05 |
5.8.6 | 3.05 |
5.8.7 | 3.10 |
5.8.8 | 3.15 |
5.009 | 3.00 |
5.009001 | 3.04 |
5.009002 | 3.07 |
5.009003 | 3.15_01 |
WiKickerベースの日記システム実装に合わせて、Wiki の方も tDiaryテーマ互換モードを実装しておく。
div の追加、class の変更など。 当然ではあるが表示要素が異なるので tDiaryのテーマの要素にうまくマッピングできないものが出てくるな。 どうしたものか。 できるだけ、近そうなものにはマッピングしてみたが。
補助用に複数の外部スタイシートを指定できるようにもしておく。 新し目のCGI.pm だと
start_html(-style => {-src => [ 'a.css', 'b.css' ]})
のように直接複数指定できるのだが、古いやつだと駄目。-head の方に Link({-rel => 'stylesheet'...}) で複数指定する必要あり。
簡単なユーザ認証のある、iモード向けデータ入力CGI プログラムを作成。
当初ホスティングサービスのサーバ上に置くつもりだったので CGI.pm だけでちまちまと書いてみた。データは hidden で持ち歩けばいいかと思ったが、コーディングしているうちにiモード端末の制約などもあって面倒になってきた。
ということで融通のきくサーバを前提として CGI::Session を利用するように作成変更。セッションオブジェクトにデータを置くようにしたら、急に楽になった。 やっぱり hidden は無理があるな。
手元の WiKicker (や DiKicker) で、「C++」という文字列を含む URI にアクセスしたらエラー。
Nested quantifiers in regex; marked by <-- HERE in m//C++ <-- HERE .html$/ at (eval 27) line 7.
正規表現の一部として使う時には \Q...\E していたと思ったが抜けがあったか。 とコードをチェックしてみたが、それっぽいところなし。 そもそも、Perl 5.005_03 だと問題おきていないし。
確認したら CGI.pm の url() の中でのエラーだった。 quotemeta されていない。
Perl 5.8.8 に含まれている CGI.pm 3.15 で問題を確認。3.17 までは駄目で、3.19 以降だと \Q...\E するように修正されている (3.18 は CPAN にないので不明)。
標準 Perl ライブラリのバグを踏んだか……。 標準 Perl ライブラリのアップグレードはなにかと面倒なので、システム要件にはしたくはないんだよねぇ。
などがある。 Apache を使うのがより実際の環境に近いテストができるのだが、通常動いている Apache を使って make test でテストできるようにするとすると「どこに配置するか」などの問題がでてくる。
となればいっその事、自分(一般ユーザ)で専用に Apache を起動した方が良さそうだ。 httpd.conf を用意するのが面倒だが、highperformance.conf 等をみる限り実はそれほど必須の設定は多くないようである。
ということで Debian GNU/Linux sid の Apache (2.0.55-4) で必要な設定は何か試してみた。少なくとも以下の設定は書いておく必要があるようだ。
# httpd.conf for Debian GNU/Linux Apache 2.0.55-4 Listen 9100 ServerRoot . DocumentRoot /home/naney/htdocs ErrorLog error_log TypesConfig /etc/mime.types PidFile apache2.pid
これを httpd.conf として保存して、
/usr/sbin/apache2ctl -f httpd.conf
で起動すればアクセスできるようになる。
/usr/sbin/apache2ctl -f httpd.conf -k stop
で停止。
ServerRoot は起動時の -d オプションでも指定できるのだが、httpd.conf に書いておかないとうまく起動してくれなかった (-X を一緒に指定してデバッグモードにする場合は ServerRoot 無しに -d 指定だけでも動く)。
CGI プログラムを動くようにするとすると例えば次のような感じ。
# httpd.conf for Debian GNU/Linux Apache 2.0.55-4 Listen 9100 ServerRoot . DocumentRoot /home/naney/htdocs ErrorLog error_log TypesConfig /etc/mime.types PidFile apache2.pid LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so Options +ExecCGI AddHandler cgi-script .cgi
ディストリビューション独自のパッケージングなどに対応するように、多少泥臭く環境検出する必要があるが、なんとか make test から呼べそうだな。
最近は WWW::Mechanize::CGI がお気に入りなのだが、2つ以上の CGI プログラムにまたがるようなアプリケーションのテストには向かなさそうなので、今度この方法でも試してみたい。
Twitter をいろいろ遊んでみて「やはり携帯電話から更新できないと」と思えてきた。
携帯電話からメールを送る事で Twitter にアップデートをかけてくれるゲートウェイを設置できれば一番いいのだけれど、そのようなメールアドレスを作る場所が今はない(さすがに会社のサーバはまずい)。
ということでiモードから更新をかけられるように短い CGI プログラムを書くことにした。 CPAN には Net::Twitter という Perl モジュールがあるのだが、JSON::Any (と JSON::XS / JSON / JSON::DWIW / JSON::Syck のどれか) が必要で、ちょっと大げさなので今回は使用は見送り。 普通に CGI.pm と LWP::UserAgent で書いた。
#!/usr/bin/perl -w use 5.005_03; use strict; use CGI qw(-no_xhtml); use Jcode; use LWP::UserAgent; my $query = CGI->new; my $user_name = $query->param('u'); my $password = $query->param('p'); my $status = $query->param('s'); $user_name = '' unless defined $user_name; $password = '' unless defined $password; $status = '' unless defined $status; my $message = ''; if ($user_name ne '' && $password ne '' && $status ne '') { my $ua = LWP::UserAgent->new; Jcode::convert(\$status, 'utf8', 'sjis'); $ua->credentials('twitter.com:80', 'Twitter API', $user_name, $password); my $request = $ua->post('http://twitter.com/statuses/update.json', {status => $status . ' '}); if ($request->is_success) { $message = '<p>OK</p>'; } } print $query->header(-type => 'text/html', -charset => ''); print '<html><head><title>Twitter update</title></title><body>'; print '<form method="post" action="twitter">'; print 'ユーザ名:', $query->textfield('u'), '<br>'; print 'パスワード:', $query->password_field('p'), '<br>'; print 'ステータス:', $query->textfield('s'), '<br>'; print '<input type="submit">'; print '</form>'; print $message; print '</body></html>';
とりあえずこれで、iモードから送信できることを確認。 パスワードの入力が面倒だけれども、サーバ側に書いておくのも嫌なので毎回送ることにした。FOMA 端末側には定型文として保存しておく以外にいい手はないのかな。
最初うまく送れなくてなんだろうと思ったが、あきやん氏の「Twitterで日本語を入力する方法 (akiyan.com)」の記事にある
といった日本語を入力する際の注意点がらみだったようである。 とりあえず CGI プログラムの方で最後に必ずいわゆる半角空白を追加するようにしておいた。
文字数チェックとか Twitter API の返り値チェックとか、改善すべきところはいろいろあるけれど、自分用にはまずこれでいいかな。
気が向いた時に外出先から更新かけます。
2002年10月19日から開発を始めてしばらく公開・運用をしていた WikiEngine だけれど最近は WikiEngine そのものは使っていなくて、今はそのコードをベースに作った日記システム の DiKicker 部分しか使っていない。DiKicker の方は自分自身で今後も使っていくんだけれど、さすがにいろいろ古いのでそろそろ大改修しようかなと。基盤部分的には
などをして今後も使っていけるようにしたい。既に使っていないアプリケーションとしての WikiEngine 部分は移行させていく手間をかける必要はないと思うので、コードを削除していくことにした。WikiForum 立てるなら既にいろいろ他の選択肢があるしね。
CVS での管理もやめて Git 管理に変更。最後の公開 tarball を展開して git init して最初のコミットとし、その後に変更した作業ディレクトリを Git 側の作業ツリーに上乗せしていったんコミット。あらためて最後の公開コードの上に差分を積んでいくつもり。
ぼっち Slack チームをタイムライン型ノートにするの、やってみたら便利で重宝している。
普段から Google Chrome で Slack のページを開いておけば PC で作業中にサクっとメモできる。ただ、人に見られるのはちょっとな雑記が並んだ Slack チャネルページを開きっぱなしにしておきたくない時は気を使わなければならないのが嫌。
ということで Slack チャネルページを開かないで投稿できるようにしてみることにした。
Google Chrome はいつも開いているのでアドレスバー(オムニボックス)からさくっと投稿できるようにするのがいいかな。Google Chrome の拡張とか書いたことが無いのでとりあえずパラメータで送られてきたテキストを webhook で Slack に投稿するだけのスクリプトを Web サイトに置いてそれを呼ぶだけにしよう。
サーバ側はとりあえずレガシーだけれど CGI.pm で。Google Chrome 側は「検索エンジンの管理」で「キーワード」を「note」に、URL に「http://www.example.com/note?text=%s」みたいな感じ設定。
これでアドレスバーで
note メモしたいテキスト
と入力すれば Slack の #notebook チャネルに投稿される。
use warnings; use strict; use utf8; use Encode; use CGI; use LWP::UserAgent; use JSON; my $slack_channel = '#notebook'; my $username = 'myname'; my $webhook = 'https://hooks.slack.com/...'; my $query = CGI->new; my $text = $query->param('text'); LWP::UserAgent->new->post( $webhook, { payload => JSON::encode_json( { channel => $slack_channel, username => $username, text => decode_utf8($text) } ) } ) if defined $text && $text ne ''; print $query->redirect('https://www.google.co.jp/');
昨日ラピッドSSLを申し込んで TLS 1.0 接続できるようになったので、ここからはコンテンツ側の対応です。
nDiki (DiKicker) はかなり昔に作ったので CGI.pm を使っています。CGI.pm の url メソッドで絶対 URL を取得して permalink の生成などをしています。ここでさくらのレンタルサーバでは HTTPS 用の Apache はプロキシとしてとして動いていることもあり https://www.naney.org/diki でアクセスすると CGI.pm の url メソッドが https://naney.org:80/diki を返してしまうようになってしまいました。
ここはいったん設定ファイルでスクリプトの URL を明示的に設定できるようにして対応しました。
http スキームで書かれた内部リンクは順次 https に修正します。結構な量があるのでおいおいという感じです。画像などのリソースを http で指定しているところは優先して対応した方が良いですね。
外部サイトのプロフィールなどで htts スキームで書いたリンクなども順次修正です。こちらもおいおいという感じで。
Naney (なにい) です。株式会社MIXIで SNS 事業の部長をしています。
※本サイトの内容は個人的見解であり所属組織とは関係ありません。