状況
getimagesize()で外部サイトから画像のサイズ情報を取得する処理、急に特定のサイトでエラーがでるようになりました。
[PHP] E_WARNING: getimagesize() [function.getimagesize]: SSL operation failed with code 1. OpenSSL Error messages: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
最初は画像取得先のサーバーがssl化したかな?と思いましたが、もともとhttpsでアクセスしにいってたので、
どうやらそのせいじゃないっぽいです。
SSLとTLS
OpenSSLには、SSLとTLSという2つのバージョンがあるんですね。(そんなことも知らなかった)
セキュリティの懸念から、現在では一般的にSSL3.0プロトコルの利用は非推奨とされているため、多くのウェブサイトではSSL3.0の利用を終了し、TLS1.2などより安全性が高いバージョンのプロトコルが使われるように設定されています。
https://www.symantec.com/ja/jp/page.jsp?id=ssl-tls
なるほど…
チェック
SSL3.0を指定して画像取得→error
$ curl https://test.com/image01.jpg --sslv3 --head
curl: (35) SSL connect error
tls1.0を指定して画像取得→OK
$ curl https://test.com/image01.jpg --tlsv1.0 --head
HTTP/1.1 200 OK
やはり、画像取得先のサーバーでSSL3.0を禁止したみたいです。
解決策
PHPのバージョンが高ければいろいろやりようはあるみたいですけど、
今回はPHP5.2 だったため、getimagesize()はあきらめてcurlを使うことにしました。
こんなかんじで
$ch = curl_init($image_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
$data = curl_exec($ch);
curl_close($ch);
if( @file_put_contents($localpath ,$data) ){
list( $w, $h ) = @getimagesize( $localpath );
$ret = array( 'w' => $w, 'h' => $h );
}
curlであれば特別な設定はなくても画像取得できました。
画像を一回ローカルに保存してから画像サイズを取得しています。