The behavior of drupal_http_request() changes, because PHP 7 has changed the defaults regarding the ssl options.

This makes code fail that relies on issuing a http request to a https version of a site, which uses a self-signed certificate.

As this could also be seen as a core limitation / bug instead of a feature, it might be a good idea to make the PHP 7 behavior the default, but allow to turn it off via a variable, especially for local development.

This is the code I use locally to make PHP 7 and a self-signed certificate work:

diff --git a/includes/common.inc b/includes/common.inc
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -820,7 +820,7 @@ function drupal_http_request($url, array $options = array()) {
     'data' => NULL,
     'max_redirects' => 3,
     'timeout' => 30.0,
-    'context' => NULL,
+    'context' => stream_context_create(array('ssl' => ['verify_peer' => FALSE, 'verify_peer_name' => FALSE])),
   );
 
   // Merge the default headers.
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Fabianx created an issue. See original summary.

Fabianx’s picture

Status: Active » Needs review
MegaChriz’s picture

I think the short array syntax shouldn't be used here as Drupal 7 also supports versions of PHP older than 5.4.

I haven't much experience with using drupal_http_request() on https sites yet, so I have no comment on that.

Fabianx’s picture

Issue summary: View changes

Uhm, yes indeed.

DamienMcKenna’s picture

I believe the changes first arose in PHP 5.6: http://php.net/manual/en/migration56.openssl.php

I believe this may be the same issue I described in Backup Migrate: #2498191: Unable to backup to NodeSquirrel using PHP 5.6.9 (on Windows)

hgoto’s picture

I investigated this.

As DamienMcKenna told, the default value of verify_peer seems to be changed in PHP 5.6.

5.6.0 Added peer_fingerprint and verify_peer_name. verify_peer default changed to TRUE.

http://php.net/manual/en/context.ssl.php#refsect1-context.ssl-changelog

The following description is from the php.net.

  • verify_peer: Require verification of SSL certificate used.
  • verify_peer_name: Require verification of peer name.
  • allow_self_signed: Allow self-signed certificates. Requires verify_peer.

The default values of these options are as following.

PHP 5.5:

  • verify_peer: FALSE
  • verify_peer_name: doesn't exist.
  • allow_self_signed: FALSE

PHP 5.6 / PHP 7.0:

  • verify_peer: TRUE
  • verify_peer_name: TRUE
  • allow_self_signed: FALSE (this is same as PHP 5.5)

So, I think the options Fabianx showed in the sample are all we should consider here.

For people who review and think this, the following resources are useful, I believe.

The document of Guzzle might be useful.

Fabianx’s picture

Issue summary: View changes

Hmm, but how would we check that someone did not intentionally set these options.

Maybe we need to make this configurable ... :/

drupal_http_request_ssl_verify_peer => NULL (default behavior), TRUE, FALSE

Tricky ...

Fabianx’s picture

Issue tags: +PHP 5.6
twistor’s picture

Here's a quick stab at this. Curious to see if setting options that don't exist for a PHP version will cause problems.

Status: Needs review » Needs work

The last submitted patch, 9: drupal_http_request-2761345-9.patch, failed testing.

twistor’s picture

Status: Needs work » Needs review
FileSize
1.66 KB

Slightly simpler patch. Not sure what that failure is about.

Status: Needs review » Needs work

The last submitted patch, 11: drupal_http_request-2761345-11.patch, failed testing.

twistor’s picture

Status: Needs work » Needs review
FileSize
1.66 KB

oops.

DamienMcKenna’s picture

Title: PHP 7 - drupal_http_request() behavior changes for SSL using self-signed certs » PHP 5.6, 7 - drupal_http_request() behavior changes for SSL using self-signed certs
DamienMcKenna’s picture

Status: Needs review » Closed (duplicate)
Parent issue: #2656548: Fully support PHP 7.0 in Drupal 7 »
Related issues: +#2656548: Fully support PHP 7.0 in Drupal 7

Closing this in favor of #1081192: Verify peer on HTTPS if cURL available (but be careful of built-in cert bundles in the codebase), which has already been committed to Drupal 8.

Elijah Lynn’s picture

vijayan08’s picture

Hi All,
I have updated the below patch, its working for me, but ssl_verify_peer FALSE is not recommendable

$verify_peer = variable_get('drupal_http_request_ssl_verify_peer', FALSE);

drupal_http_request-2761345-13.patch 1.66 KB
7.x: PHP 5.3 & MySQL 5.5 2,025 pass

Regards,
Vijayan Natarajan