Zend_Http_Clientのバグ?その3

前回

久しぶりにZend_Http_Client、というかPHPネタ。前回やってたことの続きなのでZend_Http_Clientのバージョンは古い。先日1.0が出たので修正されているかもしれない。

その1「cookieヘッダのセパレータがセミコロンだけのため、一部システムでうまくcookieが扱われない」

Zend_Http_Clientの例

Cookie: a=hoge;b=hoge2;c=hoge3

Firefox等の例

Cookie: a=hoge; b=hoge2; c=hoge3

のように出力される。一部のシステム、ぶっちゃけサイボウズではスペースがないと2個目以降のcookieが上手くわたってない模様。RFC的にどっちがどうなのかまでは調べてない。

対策としてはCookie.phpのZend_Http_Cookie::__toString()を変更。

変更前: return $this->name . '=' . urlencode($this->value) . ';';
変更後: return $this->name . '=' . urlencode($this->value) . '; ';

その2「GET/POSTパラメータに同一名の引数を渡すと勝手に[]がついてしまう」

こういうパラメータを渡したい場合。

a=1&a=2&a=3

HTMLでいうと、

<select name="a" multiple="multiple">
<option value="1">a</option>
<option value="2">a</option>
<option value="3">a</option>
</select>

これをGET/POSTしたとき、Zend_Http_Clientではこうなってしまう。

a%5B%5D=1&a%5B%5D=2&a%5B%5D=3

%5B%5Dってのはアンエスケープすると[]。つまりこうなる。

a[]=1&a[]=2&a[]=3

再現コードはこんな感じ。

$client = new Zend_Http_Client('http://example.com/hoge.php');
$param = array('a' => array('12', '14', '19'));
$client->setParameterPost($param);
$client->request(Zend_Http_Client::POST);

これじゃブラウザと動作が違っちゃうでしょ(゜Д゜)ゴルァ!!というお話。

原因はZend_Http_Client内部で使われてる標準関数(PHP5以降)のhttp_build_query()の動作がそうだから。

対策としてはZend_Http_Client::_buildHttpQuery()という関数をでっちあげて、http_build_query()の代わりにそっちを使うように変更。本来はZend_Http_Clientクラスを派生するなどすべき。

protected function _buildHttpQuery($formdata, $name = null)
{
    if(!is_array($formdata)){
        return '';
    }
    $query = array();

    foreach($formdata as $key => $value){
        if(is_null($name)){
            $tmp = urlencode($key) . '=';
        }else{
            $tmp = urlencode($name) . '=';
        }

        if(is_array($value)){
            $tmp = $this->_buildHttpQuery($value, $key);
        }else{
            $tmp .= urlencode($value);
        }
        array_push($query, $tmp);
    }
    return implode('&', $query);
}

修正したソースのバージョンはこれ

@version    $Id: Client.php 3834 2007-03-09 05:12:52Z bkarwin $
@version    $Id: Cookie.php 3834 2007-03-09 05:12:52Z bkarwin $
最終更新時刻: 2008年10月31日

[dddav] dddav 0.0.10.0リリース

dddav - GUIのWebDAVクライアント for Windows

仕様変更

  • OpenSSLを動的リンクから静的リンクに変更。ssleay32.dllおよびlibeay32.dllは必要なくなりました。
最終更新時刻: 2008年11月11日

muninをインストール / PostgreSQLでActiveDirectory認証

muninをインストール

Redhat Linux Enterprise Linux 4にmuninをインストール。

まずはrrdtoolに必要なライブラリをインストール。

# up2date libart_lgpl-devel
# up2date libpng-devel
# up2date freetype-devel

rrdtool本体をインストール

# tar xvfz rrdtool-1.2.23.tar.gz
# cd rrdtool-1.2.23
# ./configure
# make
# make install

perl用のRRDモジュールとライブラリをインストール。RRDs.pmのコピー先は自身なし。

# ln -s /usr/local/rrdtool-1.2.23/lib/perl/5.8.5/i386-linux-thread-multi/auto/RRDs/RRDs.so /usr/lib/
# cp /usr/local/src/rrdtool-1.2.23/bindings/perl-shared/RRDs.pm \
     /usr/local/rrdtool-1.2.23/lib/perl/5.8.5/i386-linux-thread-multi/

mumin用ユーザとグループを作成。

# groupadd -g 4949 munin
# useradd -u 4949 -g munin -m -s/sbin/nologin munin

必要なperlモジュールをインストール。

# cpan install Time::HiRes
# cpan install HTML::Template
# cpan install Net::SNMP

muminクライアントをインストール。

# tar zxvf munin_1.2.5.tar.gz
# cd munin-1.2.5
# make install-main

muminノードをインストール。今回はクライアント/ノードが同一のマシン。

# cpan install Net::Server::Fork
# make install-node install-node-plugins
# /opt/munin/sbin/munin-node-configure --shell | sh
# cp dists/redhat/munin-node.rc /etc/init.d/munin-node
# echo '*/5 * * * * munin /opt/munin/bin/munin-cron 2>&1' > /etc/cron.d/munin

Apacheの設定。

/usr/local/apache2/conf/httpd.conf
---
ExtendedStatus On

<VirtualHost *:80>
    (...中略...)
    <Location /server-status>
        SetHandler server-status
        Order Deny,Allow
        Deny from all
        Allow from 127.0.0.1
    </Location>

    Alias /munin/ "/opt/munin/var/www/"
    (...中略...)
</VirtualHost>
---

Apacheの設定を反映。

# /etc/init.d/apache restart

参考サイト

PostgreSQLでActiveDirectory認証

PostgreSQLでActiveDirectory認証するためのメモ。

技術的には8.2.0から対応しているLDAP認証を使った。ActiveDirectoryのパスワードを使ってPostgreSQLにアクセスできる。

PostgreSQLに--with-ldapオプションを付けて再コンパイルする。--with-pam/--with-krb5はAD認証だけなら必要ないが、後でPAMとKerberos認証も試したいのでも付けておく。

make distclean
./configure --with-pam --with-ldap --with-krb5
make
make install

pg_hba.confに下記のように記述。

host all all 192.168.1.0/24 ldap "ldap://ad.example.net/dc=example,dc=net"

接続ユーザは「hoge@example.net」のようになる。このユーザはPostgreSQLにも存在している必要があるため、登録しておく。

createuser hoge@example.net

あとはクライアントから接続する。Windows経由でODBC接続と、psqlコマンドを使ったリモート接続で確認。

PostgreSQLサーバを192.168.1.2と仮定すると下記のような感じで接続できる。

psql -h 192.168.1.2 -U hoge@example.net template0

あとがき

  • PAM経由でLDAP認証する方法もあるが失敗した。
  • どうせActiveDirectory使うならKerberos認証使えばSSO(シングルサインオン)みたいなことができると思う。

参考文書

最終更新時刻: 2008年07月15日

WindowsにApache2.2とPHP5をインストールする手順

用意したファイル

  • apache_2.2.4-win32-x86-no_ssl.msi
  • php-5.2.3-Win32.zip
  • pecl-5.2.3-Win32.zip

peclは必須ではなく、別途拡張ライブラリが欲しい場合に用意する。今回はphp_ssh2.dllを使用する為用意。

Apacheのインストール

apache_2.2.4-win32-x86-no_ssl.msiはインストーラなので手順通り。

IEでhttp://localhostにアクセスして正常に起動していることを確認する。

PHPのインストール

php-5.2.3-Win32.zipを展開。今回はc:\usr\local\phpに展開。

この時点でApacheに組み込んでみて正常に連携することを確認する。まずはhttpd.confを編集。

httpd.confはデフォルトでは「Apacheのインストールフォルダ\conf」にある。

# 下記を追加
LoadModule php5_module E:/usr/local/php/php5apache2_2.dll
AddType application/x-httpd-php .php

「Apacheのインストールフォルダ\htdocs\phpinfo.php」を作成。

<?php phpinfo();

http://localhost/phpinfo.php」にアクセスしてみてphpinfo()が表示されれば正常に連携している。Apacheの起動に失敗する場合、イベントログを確認する。

PEARをインストールするため「go-pear.bat」を実行。

「%Systemroot%」フォルダにc:\usr\local\phpから以下のファイルをコピー

  • php.ini(元ファイル名はphp.ini-distもしくはphp.ini-recommended)
  • ssleay32.dllとlibeay32.dll(php_ldap.dll/php_ssh2.dll等で必要)

次にphp.iniを編集。

extension_dir = "E:\usr\local\php\ext"
extension=php_ldap.dll
extension=php_mbstring.dll
extension=php_ssh2.dll

ちなみに通例として、magic_quotes_gpcをOffにしたり昔はregister_globalsをOffにしたり(現在はデフォルトでOff)にする。ただし自分の場合「.htaccessで設定できる項目は.htaccessでやる」というポリシーなのでphp.iniは極力編集しない。

.htaccessで設定する場合、こんな感じ。

php_value session.gc_probability 30
php_value session.use_trans_sid 0
php_flag  magic_quotes_gpc Off
php_flag  register_globals Off
php_flag  mbstring.encoding_translation Off
php_value mbstring.internal_encoding "UTF-8"
php_value mbstring.http_input "UTF-8"
php_flag  short_open_tag Off
php_value pcre.backtrack_limit 300000

最後にApacheをリスタートして設定を反映。

Apache2.2とPHP5のエラーが文字化けする。

httpd.exe: Syntax error on line 115 of
C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf:
Cannot load E:/usr/local/php/php5apache2.dll into server:
\x8ew\x92\xe8\x82\xb3\x82\xea\x82\xbd\x83\x82\x83W\x83\x85\x81[\x83\x8b\x82\xaa\x8c\xa9

上記エラーはイベントログに残されたApache2.2のログ。実際は一行。

エラーが出力された原因はhttpd.confの記述ミスで、115行目にこう書いていた。

LoadModule php5_module E:/usr/local/php/php5apache2.dll

今回使っているのはApache2.2なのでphp5apache2_2.dllと記述すべき。

見ればわかるとおり(?)Shift-JISのコードが16進で出力されているので、バイナリエディタなどで変換してやれば内容がわかる。

今回だと「指定されたファイルが見つかりません」だったと思う。

それからもうひとつ、PHP5がApache2.2経由で出力するerror_logにも同じように文字化けが。

PHP Warning:  PHP Startup: Unable to load dynamic library
'E:\\usr\\local\\php\\ext\\php_ldap.dll' -
\x8ew\x92\xe8\x82\xb3\x82\xea\x82\xbd\x83\x82\x83W\x83\x85\x81[
\x83\x8b\x82\xaa\x8c\xa9\x82\xc2\x82\xa9\x82\xe8\x82\xdc\x82\xb9
\x82\xf1\x81B\r\n in Unknown on line 0

こちらも実際は一行。

ちなみにエラーが出力された原因はphp_ldap.dllに必要なssleay32.dllとlibeay32.dllを%SystemRoot%にコピーし忘れたため上記DLLがロードできなかったことによるエラー。

なんだけど、出力されているエラーは「指定されたファイルが見つかりません」。このエラーだけ見ると「'E:\\usr\\local\\php\\ext\\php_ldap.dll'が見つからなかった」と間違えて読み取ってしまいそう。

余談ではあるけど、上記エラーはphp_ssh2.dllについても同様のエラーが出力されていたし、libmysql.dllを%SystemRoot%にコピーせずにphp_mysql.dllをロードしようとした場合にも発生するらしい。

WindowsのPHPで拡張モジュールのエラーが出てる場合は、依存するDLLが%SystemRoot%等に存在するかどうか確認すべき。

最終更新時刻: 2009年09月30日

たまにはプライベートな話題

「マニアックすぎる」「意味がわからん」

このブログに対する、僕を知る人からの印象。確信犯ですけどね!(゜∀゜)

特に最近、プライベートな話題はmixi、マニアックな話題はココ。とはっきりわけてるのでなおさらです。

昔は飲みにいったこともここに書いてたんですけどね。そういう今日も飲んでるわけですが。

とはいえココしか見てない人は過半数を超える勢いなのでたまにはプライベートな話題を書いておきます。

英会話

英会話始めました。今のレベルは、飲み屋で「ウォータープリーズ」とか言っちゃうレベルです。

水泳

用意だけはしてるものの、行けてるのは隔週1回くらい。ゴルフの練習よりは優先度低め。

ゴルフ

相変わらず本コース未経験。ショートコース一回。練習は週一。ストレス発散にちょうどイイ。

プログラミング

人生は「仕事、遊び(趣味)、ライフワーク」の三本柱があるとバランスいいな、と思い始める今日この頃。家族ができたりしたら、比率は変わると思うけど。

プログラミングはライフワークです。

カメラ

人物撮りに目覚めそう。しかし、いかんせん「センスがない」。

カメラに限らず、「センスは経験で補える」が持論。「センスと経験(努力といってもイイ)を積んでる人」のレベルまではいけなくとも、「センスだけの人」とは素人さんから見たら変わらないレベルにはなれるんじゃないかと思う。

ちなみに、自分のプログラミングスキルを客観的に見ると「センスがない」。でも経験だけでも何とかなります。高望みしなければ。

あー、あと「実力の無さは機械(レンズ)でカバー」。

その他

  • 車にキャリアを付けようかどうしようか悩み中。
  • スライド本棚をもう一本購入しようか迷い中。
  • 去年の夏以来のゲーム(逆転裁判)。
最終更新時刻: 2008年06月10日

[dddav] dddav 0.0.10.1/0.0.10.2リリース / 他のWebDAVクライアント紹介(1)

dddav 0.0.10.1/0.0.10.2リリース

dddav - GUIのWebDAVクライアント for Windows

申し訳ないですが、バグ修正の為のリリースです。

0.0.10.1の変更内容

バグ修正

  • webdav.dllのメモリリークを修正。

0.0.10.2の変更内容

バグ修正

  • スレッドの終了時にOpenSSLのクリーンナップ処理(ERR_remove_state(0))を追加。
  • OpenSSLのメモリリークを回避するため、OpenSSLのコンパイルオプション(-DOPENSSL_NO_COMP)を追加。

他のWebDAVクライアント紹介(1)

dddav以外のWebDAVクライアント。

TeamFileクライアント

TeamFile(チームファイル) WebDAVファイルサーバ -

クライアントはフリーウェアです。

CarotDAV

麗の小屋 - ソフトウェア -

.NETで実装されてます。

WebFolders

ダウンロードの詳細 : Web フォルダのソフトウェア更新プログラム: KB907306

Windows標準のWebDAVフォルダ機能の修正ファイルが公開されています。でも日本語版はファイルが古い(ファイル名がWebfldrs-KB892211-JPN.exeとなっている)ような?

最終更新時刻: 2009年02月01日

RAW画像をPhotoshopで現像して保存すると色褪せる

完成

撮影機材:EOS Kiss Digital N EF50mm F1.8 II

EOS Kiss Digital Nで撮影したRAW画像(*.CS2)をPhotoshop CS2で現像してjpg保存(Web用に保存...でも同じ)すると色あせた(薄く)ようになってしまう。

↓これがプレビューした際の色。

プレビューした画像

↓これがそのまま保存した色。色あせてしまっている。

普通に保存した画像

原因はカラープロファイルで、対策は「編集」の「プロファイル変換」でsRGBあたりに変換してやること。そうするとプレビューどおりの色で保存できた。

トリミングしてカラーを調整して完成したのが最初の写真。

写真は名駅「座座はなれ」にて友人撮影。

最終更新時刻: 2008年10月19日