お仕事: 2009年7月アーカイブ

色々事情があって、OpenPNE の「メッセージを送る」画面でメッセージ送信をすると、OpenPNE のユーザのメールアドレスに直接メールを送信する機能を Perl で実装した。

OpenPNE ではメールアドレスは暗号化されているので、OpenPNE のソースを元に、以下のような復号化スクリプトを書いて復号を行った。

#!/usr/local/bin/php
<?php
    $address = $argv[1];
    define('ENCRYPT_KEY', 'hogehoge_key');
    $path ="/www/lib/include";
    set_include_path(get_include_path() . PATH_SEPARATOR . $path);
    include_once 'Crypt/Blowfish.php';
    $blowfish = new Crypt_Blowfish(ENCRYPT_KEY);
    $address = base64_decode($address);
    $address = $blowfish->decrypt($address);
    echo $address;
?>

で、不思議なことに、hogehoge3@exsample.co.jp宛のメールアドレスにはメールが届くのに、hoge@exsample.co.jp宛には届かない。
どちらも、ちゃんと存在しているメールアドレスなのにだ。

原因は、復号されたメールアドレスにあった。
どうも、上記のスクリプトで復号すると、24バイト以下のメールアドレスの後ろに 0x00 のコード(NULL)がセットされてた・・・

一応、後ろにスペースがセットされてたらやだなと思って、Perl 側で、

$address =~ s/\s//g;

な置換はかけてたんだけど、NULL値は \s じゃ引っかからんのね・・・

ということで、

$address =~ s/[\x00]//g;

として不要な NULL値を削ってやったら、問題なくメールが届くようになった。

ああ、ほんまに、ラピッドサイトサーバは maillog が見れないんで駄目駄目サーバだ。
独自のシステムを動かしたい企業は、月数千円の金をケチるのはやめて、WebARENA とかを使うべきである。(・・・て話は、この間もしたな(^^;)

今、「サイト全体で OpenPNE の cookie を参照したいのだが」を書いたばかりだけど・・・

うまくいきました・・・
やっぱ、俺のやり方で間違ってなかったのだ。俺、天才。
どうも、古いクッキー情報(path に OPENPNE_URL を指定したもの)が残っていたために、うまくいかなかったようだ。

一応、InternetExplorer7 で、[ツール]→[インターネットオプション]で Cookie の削除もしたのだが、どうもちゃんと消えてなかったようで・・・他に IE7 のウィンドウが開いていたせいか???
全ての IE7 を一旦閉じて、もう一度チャレンジしたら上手くいった。(^^;

これで、CGI から PHPSESSID が取れるので、OpenPNE の認証が終わっているかどうかの判断が出来る。

ばっちり!
う~ん・・・

OpenPNE(OpenPNE-2.12.11)の cookie 情報をサイト全体で参照したいのだが、なかなかうまくいかん。

例えば、OpenPNE の URL(OPENPNE_URL)を、http://exsample.jp/AAA/ とする。
で、http://exsample.jp/BBB/ の下で動いている CGI から cookie を参照したいわけだ。

ソースを見ると、OPENPNE_URL を cookie の path にセットしているようなので、grep で cookie_path の編集をしているソースを見つけて、以下のような修正をしてみた。

◇webapp/init.inc の 106行目
ini_set('session.cookie_path', $url['path']);
  ↓
ini_set('session.cookie_path', '/');

◇webapp/lib/OpenPNE/Auth.php の 86行目
            $this->cookie_path = $url['path'];
        ↓
            $this->cookie_path = '/';

o_public_invite.php と、o_regist_prof.php については、init.inc でセットした session.cookie_path を参照しているだけのようなので何もせず。

しかし、この状態でログインを行うと正しく認証されないようで、すぐにログイン画面に戻ってしまう。

Auth.php の修正箇所を元に戻せば、ログイン出来るようになる。
(が、当然のことながら、サイト全体に cookie は有効にならない)

む~・・・取りあえず、OpenPNE 公式SNS で質問をさせていただこう。
某ホスティングサイト上でシステムの開発をしているんだが、そのサーバには許せないことに、Perl モジュールの Jcode.pm が入っていない。

root 権限もくれないので、普通に make 出来ないし。
なので、展開したファイルを手動でコピーして使ってたんだが、それだと UTF-8 の変換で問題があるんだよねえ。

その辺の原因を追及する時間がもったいなかったので、IN/OUT のデータも、Perl のソースも全て UTF-8 にして、変換が必要ないようにしてたんだけど、どうしてもメール送信しなくちゃいけなくなって。
メールも Unicode のままでも良いんだけど、俺の使ってる AL-Mail が Unicode のメールが読めないんでねえ。(笑)

ということで、Jcode.pm を使って変換することにしたんだけど、いやぁ、ハマった、ハマった。(^^;

変換時にエラーが出る対応で、Jcode/_Classic.pm を修正しちゃったもんだから(「Unicode 変換時の Jcode のエラー」に書いたように、これは誤った対処方法)、その後、エラーが出ないのに、何で正しく UTF-8 がらみの変換が出来ないのか悩むことに・・・(^^;

これで、丸一日無駄にしちゃった。(^^;

最後には、nkf 使って、

    my $str    = join '', @_;
    my $tmp    = (time) . $$ . '.txt';
    open(NKF, ">$tmp");
    print NKF $str;
    close(NKF);
    $str    = `cat $tmp|/usr/local/bin/nkf -j`;
    unlink $tmp;
    return($str);

みたいな関数作って対応してたんだけど、さすがに美しくないので・・・(^^;
結局、ユーザ環境に Jcode.pm を make install することにした。

% perl Makefile.PL INSTALLDIRS=site INSTALLSITELIB=/usr/home/hoge/www/cgi-bin
% make
% make install

でOK。
make install の時に、(一般ユーザの書込権限の無いディレクトリに書き込もうとするので)perllocal.pod のインストールで失敗するが、Jcode.pm の実行には影響無い。
もちろん、perllocal.pod をユーザ環境にインストールするよう設定出来るが、ま、インストールしなくても困んないので、今回はこれでヨシ。

これで、Jcode/Unicode.pm が作られるので、「Unicode 変換時の Jcode のエラー」に書いたように、Jcode/Unicode/NoXS.pm を修正する必要は無い。

この時に、必ず @INC に含まれるディレクトリをインストール先にすること。(でないと、Perl スクリプトの頭で、いちいちインストール先を @INC に加える処理が必要になるけえ)
なので、俺は、cgi-bin の直下にインストールした。(. ディレクトリは @INC に含まれているからね)

ああ。root 権限くれるホスティングサービスだったら、こんな苦労しなくていいのにな。
Perl で作った独自システムを動かしたい会社は、月々数千円の金を惜しまず、WebARENA とか使えばええのだ。いや、マジで。
う~む、何か、Jcode.pm を使って、EUC から UTF-8 に変換しようとすると、

Undefined subroutine &Jcode::_Classic::euc_utf8 called at lib/Jcode/_Classic.pm line 255.

てなエラーが出てしまう。

サイトによっては「Perl のバージョンが古いせい」とか訳の分からない説明をしてるところもあるけど、実際にはそんな単純な話ではない。

この原因は、ちゃんと Jcode.pm のインストール時に make; make install をして Unicode.pm を作成していないから。
なので、本来なら make して、Unicode.pm を作ってやるのが一番だが、ホスティング環境によっては SSH 接続等でのシェル使用を許してなくて(FTP のみ可とかで) make 出来ないケースもあるしな。

解決策として、

Jcode/_Classic.pm の 255行目付近を、

sub utf8{
    load_module("Jcode::Unicode");
    euc_utf8(${$_[0]->[0]});
}
    ↓
sub utf8{
    load_module("Jcode::Unicode");
    Jcode::euc_utf8(${$_[0]->[0]});
}

と変更し、Jcode::Unicode(Unocode.pm)の euc_utf8 ではなく、Unicode/NoXS.pm 内の Jcode::euc_utf8 を呼ぶようにしてやると書いているサイトもあるが嘘。
これだと、確かにエラーで落ちることはなくなるが、UTF-8 がらみの変換が正しく行われない。

UTF-8 がらみの変換、

$str    = Jcode->new($str, 'utf8')->h2z->jis;

とか

$str    = Jcode->new($str, 'utf8')->h2z->euc;

が正しく行われるようにするには、Jcode/Unicode/NoXS.pm を以下のように編集する。

% diff NoXS.pm NoXS.pm_org
56c56
< sub Jcode::_Classic::ucs2_euc{
---
> sub Jcode::ucs2_euc{
71c71
< sub Jcode::_Classic::euc_ucs2{
---
> sub Jcode::euc_ucs2{
87c87
< sub Jcode::_Classic::euc_utf8{
---
> sub Jcode::euc_utf8{
90,91c90,91
<     &Jcode::_Classic::euc_ucs2($r_str);
<     &Jcode::_Classic::ucs2_utf8($r_str);
---
>     &Jcode::euc_ucs2($r_str);
>     &Jcode::ucs2_utf8($r_str);
94c94
< sub Jcode::_Classic::utf8_euc{
---
> sub Jcode::utf8_euc{
97,98c97,98
<     &Jcode::_Classic::utf8_ucs2($r_str);
<     &Jcode::_Classic::ucs2_euc($r_str);
---
>     &Jcode::utf8_ucs2($r_str);
>     &Jcode::ucs2_euc($r_str);
101c101
< sub Jcode::_Classic::ucs2_utf8{
---
> sub Jcode::ucs2_utf8{
124c124
< sub Jcode::_Classic::utf8_ucs2{
---
> sub Jcode::utf8_ucs2{

これでバッチリ!
Jcode/_Classic.pm の編集はしちゃあいかんぜ。

このアーカイブについて

このページには、2009年7月以降に書かれたブログ記事のうちお仕事カテゴリに属しているものが含まれています。

前のアーカイブはお仕事: 2009年6月です。

次のアーカイブはお仕事: 2009年9月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。


月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら