httpsでfgets()した場合に「SSL: fatal protocol error」が出る
presented by 役に立つかもしれないBlog
MicrosoftのIISサーバーとの通信中に「function.fgets: SSL: fatal protocol error ...」のエラーメッセージが出る場合があります。 その原因と対策方法について。
IISとの通信中に発生することがある
毎回ではないですが、たまにIISがSSLの標準に準拠せずデータ送信終了してしまうために、PHPはデータの終わりをちゃんと認識することができず、エラーを出してしまいます。
より具体的にはIISは「close_notify」を送らないで終了してしまうのだそうです。 むむ、思わぬ所に地雷が...
「close_notify」とは、データの送信側が「これでデータ終了です」ということを受信側に知らせるために発行するTLSハンドシェイクプロトコルに定義されているAlertプロトコルの一種です。 (参考データ)
ちなみに、このエラーはfile_get_contents()でも発生することがあります(情報元(英語))。
エラー回避法
解決ではなくエラーの回避方法ですが、error_reportingのレベルを下げて、警告レベルまでは表示しないようにすると良いでしょう。 多くの人はこれで回避しています。
php.ini で設定する場合
...(前略)... error_reporting = E_ALL ^ E_WARNING
phpプログラム途中で設定する場合
...(前略)... error_reporting(E_ALL ^ E_WARNING);
phpプログラム中に一瞬だけ変える場合
この場合は現在のエラーレベルを退避させておいてから設定します。 実行後は再度もとのエラーレベルに設定します。
$fp = fopen("https://~", "r");
if (!$fp) {
return "";
} else {
$nowlevel = error_reporting();
error_reporting(E_ALL ^ E_WARNING);
$data = '';
while (!feof($fp)) {
$data = fgets($fp, 4096);
}
fclose($fp);
error_reporting($nowlevel);
return $data;
}
エラー解決法?
こちらは実際にテストしたわけではなく、PHPのオンラインマニュアルにあった情報です。
PHP4.3.7以降ではfopen()やfile_get_contents()ではなく、fsockopen()を利用してファイルポインタを取得することで、IISが出すエラーの処理を受けてコントロールできるようです。
fsockopen()を使うと、受信したデータが正しいものかどうかは受信者側で判断するようになっているためです。
ただ、この「close_notify」をどうやって受信側が特定するのかについてはどこにも書かれていません。
このページに関連のある記事はこちら
- プログラマーが「『超』入門 失敗の本質」を読んでみた。
- 勝手に英文をツイートされてしまうハッキング事例が多数発生中!
- mkdirでディレクトリに「0777」が設定できない場合の解決法
- エラー解消:Fatal error: Call to undefined function spl_autoload_register
- PHPの開発環境(IDE)でベストなのはどれ?
- PHPでMovableTypeのエントリーDBをSQL検索する方法
- EC-CUBEで好きな時にログを出力する方法
- PowerPointでPDF書き出し時のテキストが消える問題と解決法
- PHPでMovableType5のデータベースにアクセスする方法
- さくらのVPSのPHP+MySQLを最新のものにアップデート。
- MySQL(innoDB)でリレーション設定時に「インデックスは設定されていません」エラー



はじめまして。
@をつけるだけでも良い?