HttpWebRequestとオレオレ証明書2007年10月10日 02時42分05秒

まずは1発目。

いま抱えてる仕事が月末納期で、そろそろ詰めの段階にきているのだが、本番系のサーバに暫定でオレオレ証明書を入れてSSL通信を始めた。

基本はWebアプリなのだが、印刷周りだけはWebじゃ如何ともしがたいため、C#で印刷アプリも作っていて、認証と基本情報の取得にWebアプリとHttpWebRequestで通信を行っているのだが、これがいきなりハマった。「リモート サーバーとの信頼関係を確立できませんでした」というやつだ。

証明書のインストールが必要かと思い、IEでアクセスして証明書のインストールを行ったが状況が改善しない。IEで表示される警告をよくよく読んでみると、どうやら(証明書の発行元が確認できないのはもちろんだが)証明書そのものが通信しているサーバ向けではなく、他のサイト向けとして発行されているとのことだ。

で、もう少し調べてみたら、MicrosoftのKBで「PRB:「 System.Net.WebException」 基になる接続は、閉じられました。 「リモート サーバーとの信頼関係は確立できる」でした。 .NET Framework をアップグレードすると、エラー メッセージ」なんてのが見つかった。

機械翻訳なので少々アレだが、

他のシナリオは、存在します。 たとえば、外部クライアント versus 内部的に一部のネットワークが別の名前解決方式を使用します。証明書が(www.adatum.com)などパブリック URL とイントラネット アプリケーションでサーバーに発行される場合に、内部ドメインネーム システム DNS サーバーは、(www.internal.corporate.adatum.com)など同じサーバーの別の名前を指定します。 この SSL での Web サービスの要求は、失敗することがあります。 この変更は、 SSL を使用する Web サービスのセキュリティを強化するのが行われます。
なんてことが書いてあり、どうやらそのものズバリくさい。

なので、このページに掲載されていたサンプルにあるように、「サーバが送りつけてきた証明書を無条件に信頼するICertificatePolicyを実装し、ServicePointManagerに設定する」という、なんともアレな回避策で無事(?)回避することができた。

ま、リリース時はちゃんとした証明書を発行してもらう(つか、手続き中)ので問題ないんだけども、なんだかなぁ、というお話でした。

fgetcsvでハマってみたり2007年10月10日 02時43分46秒

ハマりネタ2発目。今度はPHP。

普段は自分の開発PC(WinXP)上のApache+PHPで開発を行っているのだが、試験用のデータを登録するため、本番系のサーバで動作させてみた。

今回動作させたのが、CSVファイルのアップロードなのだが、かなり不可思議な現象に見舞われた。

アップしたCSVのデータのうち、マルチバイトの文字が欠落するのだ。それも全部が全部ではなく、二重引用符や丸括弧で囲っているデータは大丈夫で、それ以外の文字が落ちるという現象だ。

たとえば、

注文ID(消さないでください),注文日,...
なんてデータをfgetcsv()で読み込んで行ごとにprint_r()してみると、
Array(
    [0] => ID(消さないでください),
    [1] =>
     :
     :
)
のように、最初のフィールドでは「注文ID(消さないでください)」の「注文」部分のみが欠落、次のフィールドではすべての文字(すべてマルチバイト文字)が欠落、といった感じで、どうもシングルバイト文字が出現するまで無視されているような感じになるのだ。

fgetcsv()で読み込む前に、アップロードしたファイルを一括して文字コードを変更し、それを読み込む処理をしているのだが、文字コード変換後のファイルをfile_get_contents()でダンプしてみると、特に文字化けもしていない。

print_r()の結果を見たところ、フィールドの区切りも誤認識しているわけではないし、さらに、自分の開発PC上ではまったく同じコード・同じデータで問題が発生していない。もうどうなってるやらさっぱり

と、泣きそうな気持ちで必死に調べたところ、「[PHP-dev 1206] Re: PHP5のfgetcsv()関数について」と、大いに関係ありそうな記事が見つかった。

この記事によると、

PHP 5.0 の fgetcsv() はロケールの設定に依存します。
とのこと。さらにこのスレッドの先を見てみると、
少々乱暴ですが、 setlocale(LC_ALL, 'ja_JP.UTF-8'); で、UTF-8のCSVファイルについてはfgetcsv()は希望通りに動作しました。
とあったので、試してみたら、これビンゴ。多分PHP.INIの設定の違いだったのかなぁ。

一瞬自前でCSVデコードせにゃならんかと思って結構鬱になったりならなかったりだったが、なんにしても解決策(というか回避策?)が見つかってほっとした。ちとバッドノウハウくさい気もするが。PHP.INIを見直しておくかなぁ。