【WordPress】httpsサイトに対するwp_remote_requestが正しく動作しない場合に確認すること

WordPressには外部サイトの情報を取得するためのメソッドがいくつか用意されています。

  • wp_remote_request
  • wp_remote_get
  • wp_remote_post
  • wp_remote_head

これらは内部的にcURLまたはfsockopenを使用しており、cURLが優先されます。

simplicityのフォーラムでも報告があったのですが、環境によってcURLでエラーになる場合があります。

Simplicityの特徴 › フォーラム › Simplicity2に関する話題何でも › 「エントリーカード全体をリンク化」で外部カードのタイトルが外に追い出される このトピックには
Simplicityの特徴 › フォーラム › Simplicity2に関する話題何でも › 「Internet Archive」への外部リンクブログカードが正常に表示されなくなった こ
スポンサーリンク

症状

wp_remote_getなどでECC系の暗号化スイートのみが許可されたSSLサーバーにアクセスした場合に「SSL connect error」になり、正しくページを取得できません。

例えばCloudFlareの提供しているUniversal SSLはECC系の暗号化スイートのみを扱っているようなので、これを使用しているhttpsのウェブページはwp_remote_getなどで取得することができません。

SSL on Paid Plans Our SSL certificates on paid plans (Pro, Business and Enterprise) will work with all desktop browsers, so if you are worried about compatibili...

Simpicityの独自キャッシュのブログカードではwp_remote_getを使用しているため、正しくブログカードが表示されなくなります。

原因

バージョン7.36.0までのlibcurlでは使用する暗号化ライブラリがNSSの場合にECC系の暗号化スイートが標準で無効化されています。

そのためlibcurlのバージョンが7.36.0未満SSLライブラリにNSSが使用されている場合、上記の症状が現れます。

redhat6のRPM版curlでNSSを使用するように修正されているため、CentOS6.xなどの環境では通常のインストールによって、上記不具合が起こるバージョンがインストールされる場合があるようです。

モバイルサイトのキャリア通信にて、ユーザー認証の部分でcurlを使っているが アプリサーバーのOSをCentOS5から6へ上げ

cURLのバージョンを確かめる

sshで以下のコマンドを実行します。

以下のようにバージョンが表示されます。

7.19.4

7.19.7

7.40.0

上記3つの環境では真ん中のみ症状が現れます。

解決方法

WordPress4.5.3以下で使える方法

使用する暗号化スイートをPHPから指定することが可能です。

「CURLOPT_SSL_CIPHER_LIST」オプションで使用する暗号化スイートを設定します。

上のページでも説明がありますが、NSSの場合にこのオプションで暗号化スイートを設定すると、設定したものだけが使用されるようになります。

したがってより多くの環境で動作させるためにはできるだけ多くを設定して上げる必要があります。

暗号化スイートのリストは以下のページを参考にしています。

上記の動作をcurl_initで取得した$handleに対して行います。

WordPress4.5.3以下では「http_api_curl」アクションをフックすることでそれを実現することが可能です。

以下のコードを子テーマのfunctions.phpなどに記述します。

ここで説明する内容は直接本番環境で行わないほうが無難です。
一度ローカル環境で確かめた上で反映を行うなどの手順を踏んでください。
PHP5.3以上で動作します。

WordPress4.6以上の場合

WordPress4.6でHTTP APIに内部的に大きな変更がされ「http_api_curl」アクションが使用できなくなったため上記方法はできなくなりました。

For WordPress 4.6, the HTTP API (wp_remote_request() and family) have undergone a large internal change. Rather than using a WordPress-specific HTTP library, Wo...

下のチケットでも挙げられているようにWordPress4.6の仕様ではcurl_exec実行前に割り込める手段がありませんがバージョンアップで対応される可能性はあります。

現時点では少しトリッキーな方法をとることで自分の環境では対応することができました。

リクエストで使用するのは「cURL」か「fsockopen」ですが、通常は「cURL」が優先されます。

以下のコードで無理やり「fsockopen」を優先させることが可能になります。

ここで説明する内容は直接本番環境で行わないほうが無難です。
一度ローカル環境で確かめた上で反映を行うなどの手順を踏んでください。
PHP5.3以上で動作します。

cURLをバージョンアップ

先に挙げた不具合が起こる条件に合わないバージョンに更新することで問題は解決します。

その他設定値に関して

simplicityのフォーラムで少し話題になっていた設定値に関して

sslverify

引数 ‘sslverify’ は WordPress 2.8 から導入され、SSL 証明が有効か否か (自己署名されたものではなく、リクエストされたサイトに対するもの) をチェックし、無効であった場合はリクエストを拒否します。HTTPS をリクエストするときに、そのサイトが自己署名されたものか、充分に信頼出来るサイトである場合は、false にセットします。

引用によるとsslverifyは自己証明書によるSSLかどうかのチェックを行う設定です。

自己証明書のページにブラウザでアクセスした場合、画像のような表示になります。

https_error

逆に言うとこのような表示にならないページであれば自己証明書ではありません。

上の引用でfalseにするときの説明がありますが、それは例えば自分のサイトにcURLでアクセスする場合など絶対に自己証明書のチェックが必要ないとわかっている場合に、そのチェックを省くことで少しでも高速化を図っているものだと考えます。

したがってsslverifyは基本的にはtrueにしておくべきだと考えます。

user-agent

wp_remote_getなどでデフォルトで設定される値は以下です。

トピック内で$_SERVER[‘HTTP_USER_AGENT’]を設定するとうまくとれるという書き込みがありました。

bot拒否の目的でユーザーエージェントにWordPressを含む場合に拒否するなどの設定がされている場合があるので、この設定はよい修正だと考えられます。

しかしSimplicityを使用していないあるサイトAからwp_remote_getでまだキャッシュされていないブログカードを含む自分のサイトのページにアクセスされた場合、そのページのブログカード生成時のwp_remote_getで設定する$_SERVER[‘HTTP_USER_AGENT’]の値はサイトAが発行したものになるため、WordPressのデフォルトのuser-agentになります。

稀なケースですがその場合はWordPressのデフォルトのユーザーエージェントを拒否するサイトのブログカードが正しく生成されません。

解決方法としては、一般的なブラウザのユーザーエージェントを設定しておくことが考えられます。

以下はSimplicityのブログカード取得用のwp_remote_getのユーザーエージェントをクロームのユーザーエージェントに設定するサンプルコードです。

ここで説明する内容は直接本番環境で行わないほうが無難です。
一度ローカル環境で確かめた上で反映を行うなどの手順を踏んでください。
PHP5.3以上で動作します。

まとめ

同じような内容をSimplicityのフォーラムに投稿したのですが、テーマレベルで対応すべきことなのかは微妙なところです。

フォーラムにはできるだけテーマのみに影響するようなコードを書いたのですが、それ以外のプラグインなどでもwp_remote_getなどが使用され、同様の問題が発生している場合があります。

cURLの設定値を変更するプラグインはあるようですが、これはWordPress4.6で廃止された「http_api_curl」を使用しているため、今は意味がありません。

Allows configuration of cURL connection options.

できればWordPress本体で対応されればよいのですが。

もしhttpsのサイトのデータの取得がうまくいかない方がいらっしゃいましたら参考にしてみてください。

追記(2016.9.14)

WordPress4.6以上で「http_api_curl」アクションが使用できない問題は、フックの仕方は変わるようですがWordPress4.7で対応されるようです。

追記(2016.10.7)

上記の対応はv4.6.2に前倒しになるようです。

スポンサーリンク

シェアする

フォローする