楽天APIを使うスクリプトを作ろうとしたんだが、LWP::UserAgentでHTTPS通信ができずにハマった。
Illegal instruction (コアダンプ)
コアダンプで終了する状況。
Perlレベルのエラーじゃないのでエラー行番号がでないが、ところどころprintしてリクエスト投げてるとこで死んでることはすぐに判明。
HTTPS通信が原因なことには気づかなかったが、先日も別のスクリプトで同じ症状が出て、forkで全死しないようにして対応したんだが、今回の場合は目的の楽天APIが死んじゃうからそういうわけには行かん。
他に先日作ったgoogleにHTTPSするスクリプトは問題がなく今日も動いてた。
SSL絡みのセキュリティー問題で楽天APIの仕様がLWP::UserAgentのHTTPSでできなくなってるのかな?と推測はできた。
元々の環境は、libwww-perlを入れるとperl-lwp-protocol-httpsのインストールを勧められたと思うんだが、
perl-lwp-protocol-httpsはインストールされてて、それ経由だと思うがperl-net-ssleay、perl-io-socket-sslがインストールされてた。
LWPのHTTPSはperl-net-ssleay以外にperl-crypt-ssleayでも可能なので試しに入れてみたが、
今度は「Crypt-SSLeay can't verify hostnames」でダメ。
それは、
$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'}=0;
か
$ua->ssl_opts( verify_hostname => 0 );
でホストの確認を回避できるのだが、そうするとやっぱ、
Illegal instruction (コアダンプ)
いろいろやってハマったのだが、
$ua->ssl_opts(SSL_version=>'!TLSv12');
で解決できた。
IO::Socket::SSLのSSL通信方式の指定パラメータだが、TLS1.2を無効にする設定かな?
標準では'SSLv23:!SSLv2'になってる模様。
Firefoxでhttps://app.rakuten.co.jp/に接続するとTLS1.2で接続されているようなので、楽天のサーバーは何も指定しないとTLS1.2で応答するが、IO::Socket::SSLのTLS1.2がバグってんのか?
GoogleのhttpsもTLS1.2のようで、こちらはLWPで問題なく接続できているようなんだが・・・
手元のArch Linuxでバグってるんだが、サーバー用に使ってるUbuntu 14.04LTSでは問題が生じてないと思う。