ext-http icon indicating copy to clipboard operation
ext-http copied to clipboard

HTTPS does not seem to work on Windows?

Open optyfr opened this issue 2 years ago • 16 comments

I get

http\Exception\RuntimeException: http\Client::send(): SSL peer certificate or SSH remote key was not OK; SSL certificate problem: unable to get local issuer certificate (https://test.compodata.eu/) in D:\Referentiel\LSReferentielPreProd\test2.php:6
Stack trace:
#0 D:\Referentiel\LSReferentielPreProd\test2.php(6): http\Client->send()
#1 {main}

The code is

try {
	$client = new \http\Client();
	$client->setSslOptions(['cainfo'=>'c:\php\extras\ssl\cacert.pem',"verifypeer"=>false]);
	$client->enqueue(new \http\Client\Request("GET", "https://test.compodata.eu"));
	$client->send();
	echo "pecl_http success :<br>";
} catch (Exception $e) {
	echo "pecl_http FAIL :<pre>$e</pre>";
}

It does not seem to take into account SSL options, the line setSSLOptions does nothing, and setOptions is not better I tried using PHP 8.0 NTS x64 using 4.2.0 and 4.0.0 without success (4.1.0 did not load) I tried using PHP 7.4 NTS x64 using 3.2.4 and 3.2.3 but the extension did not load at all (with no error using php -m)

by the way I directly tried the same site using curl extension and an initialized cainfo, and it worked fine on the same server/php

did I miss something?

optyfr avatar Oct 06 '21 09:10 optyfr

btw this is not specific to my test site, the same thing happen for www.google.com

optyfr avatar Oct 06 '21 09:10 optyfr

Any insight here @Jan-E @cmb69? Sorry for cold-tagging, but I'm pretty lost on windows issues...

m6w6 avatar Oct 21 '21 15:10 m6w6

I tried using PHP 7.4 NTS x64 using 3.2.4 and 3.2.3 but the extension did not load at all (with no error using php -m)

For PECL/http 3 you need to load PECL/propro and PECL/raphf as well, and you likely need an outdated ICU (3.2.4 needs icuuc65.dll; you can use deplister.exe to check for such missing dependencies). It was probably a bad idea to upgrade ICU during the stable branch. It's probably necessary to re-build PECL/http, but that may break some older setups. :(

Wrt. to the issue at hand: I can reproduce that (current cacert.pem from curl, and without any certfile, what should fallback to Windows cert store). I get the following notice in advance:

PHP Notice:  http\Client::enqueue(): Could not set option tcp_fastopen (An unknown option was passed in to libcurl) in C:\php\php-8.0.8-nts-Win32-vs16-x64\test.php on line 6

I guess that is unrelated, though.

cmb69 avatar Oct 21 '21 15:10 cmb69

Works with my version of PHP 7.4.25 NTS x64. See https://phpdev.toolsforresearch.com/php-7.4.25-nts-Win32-vc15-x64.htm https://phpdev.toolsforresearch.com/php-7.4.25-nts-Win32-vc15-x64.zip

More info: https://www.apachelounge.com/viewtopic.php?t=6359

pecl_http success :
object(http\Client)#1 (4) {
  ["observers":"http\Client":private]=>
  object(SplObjectStorage)#2 (1) {
    ["storage":"SplObjectStorage":private]=>
    array(0) {
    }
  }
  ["options":protected]=>
  array(1) {
    ["ssl"]=>
    array(2) {
      ["cainfo"]=>
      string(20) "c:\phpdev\cacert.pem"
      ["verifypeer"]=>
      bool(false)
    }
  }
  ["history":protected]=>
  NULL
  ["recordHistory"]=>
  bool(false)
}

Jan-E avatar Oct 21 '21 17:10 Jan-E

Loads OK with a lot of extensions:

[PHP Modules]
apc
apcu
bcmath
calendar
Core
ctype
curl
date
dom
ereg
ffmpeg
filter
gd
hash
http
iconv
intl
json
libxml
mbstring
mcrypt
mysql
mysqli
mysqlnd
openssl
pcre
PDO
pdo_mysql
Phar
propro
raphf
readline
Reflection
session
SimpleXML
soap
SPL
standard
tokenizer
uploadprogress
wddx
xml
xmlreader
xmlwriter
Zend OPcache
zip
zlib

[Zend Modules]
Zend OPcache

Jan-E avatar Oct 21 '21 18:10 Jan-E

<?php
try {
	$client = new \http\Client();
	$client->setSslOptions(['cainfo'=>'c:\phpdev\cacert.pem',"verifypeer"=>false]);
	$client->enqueue(new \http\Client\Request("GET", "https://google.com"));
	$client->send();
	echo "pecl_http success :\n";
	var_dump($client);
} catch (Exception $e) {
	echo "pecl_http FAIL :<pre>$e</pre>";
}
?>

Jan-E avatar Oct 21 '21 18:10 Jan-E

For php 7.4 and pecl_http 3.2.4 ir 3.2.3 I confirm that I used raphf and propro with no luck. btw my primary target is php 8 I ended up using directly curl which worked fine (and I even wrote a small abstraction layer compatible with pecl_http 1.x old methods)

optyfr avatar Oct 21 '21 19:10 optyfr

I triggered new builds of PECL/http 3.2.4 and these are using the proper ICU, but they still don't load. I'll have a closer look on Monday.

cmb69 avatar Oct 21 '21 20:10 cmb69

Bug reproduced for PHP 8.0 x64 and PHP 8.1 x64. I seem to have success by removing these 3 lines. On git HEAD for PHP 8.1:

diff --git a/src/php_http_client_curl.c b/src/php_http_client_curl.c
index daadf69..094447c 100644
--- a/src/php_http_client_curl.c
+++ b/src/php_http_client_curl.c
@@ -1485,9 +1485,6 @@ static void php_http_curle_options_init(php_http_options_t *registry)
 		Z_LVAL(opt->defval) = 60;
 	}
 #endif
-#if PHP_HTTP_CURL_VERSION(7,49,0)
-	php_http_option_register(registry, ZEND_STRL("tcp_fastopen"), CURLOPT_TCP_FASTOPEN, _IS_BOOL);
-#endif
 
 	/* ssl */
 	if (PHP_HTTP_CURL_FEATURE(CURL_VERSION_SSL)) {

Recompiling all PHP 8.0 and 8.1 x64 now. @cmb69 Can you try this as well?

Jan-E avatar Oct 22 '21 00:10 Jan-E

Possibly related: https://stackoverflow.com/questions/61650504/use-of-undefined-constant-curlopt-tcp-fastopen

Jan-E avatar Oct 22 '21 00:10 Jan-E

With https://phpdev.toolsforresearch.com/php-8.0.12-nts-Win32-vs16-x64.htm https://phpdev.toolsforresearch.com/php-8.0.12-nts-Win32-vs16-x64.zip

D:\phpdev\php80nts.x64>php -v
PHP 8.0.12 (cli) (built: Oct 22 2021 02:44:08) ( NTS Visual C++ 2019 x64 )
Copyright (c) The PHP Group
Zend Engine v4.0.12, Copyright (c) Zend Technologies

D:\phpdev\php80nts.x64>php ..\http-https.php
pecl_http success :
object(http\Client)#1 (4) {
  ["observers":"http\Client":private]=>
  object(SplObjectStorage)#2 (1) {
    ["storage":"SplObjectStorage":private]=>
    array(0) {
    }
  }
  ["options":protected]=>
  array(1) {
    ["ssl"]=>
    array(2) {
      ["cainfo"]=>
      string(20) "c:\phpdev\cacert.pem"
      ["verifypeer"]=>
      bool(false)
    }
  }
  ["history":protected]=>
  NULL
  ["recordHistory"]=>
  bool(false)
}

Jan-E avatar Oct 22 '21 01:10 Jan-E

https://github.com/curl/curl/blob/823d3ab855c55e26d595cfda1a13814baa0f684c/docs/TODO#L389-L393

1.24 TCP Fast Open for windows

 libcurl supports the CURLOPT_TCP_FASTOPEN option since 7.49.0 for Linux and
 Mac OS. Windows supports TCP Fast Open starting with Windows 10, version 1607
 and we should add support for it.

Jan-E avatar Oct 22 '21 01:10 Jan-E

See this issue as well with respect to tcp_fastopen: https://github.com/curl/curl/issues/3662

Jan-E avatar Oct 22 '21 07:10 Jan-E

Fixed for PHP 8.1 by https://github.com/m6w6/ext-http/commit/86b8a4396d03ad6161ba3d05dd4986521ec7e182

Jan-E avatar Oct 22 '21 12:10 Jan-E

I can confirm that 86b8a4396d03ad6161ba3d05dd4986521ec7e182 solves the reported issue, but it doesn't look like a proper fix for the actual problem; why would failing to set an unsupported option break the request? A plain cURL request works as expected:

$curl = curl_init("https://google.com");
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_TCP_FASTOPEN, true);
curl_exec($curl);

Particularly, it doesn't look right that the return value of php_http_options_apply() is not checked: https://github.com/m6w6/ext-http/blob/86b8a4396d03ad6161ba3d05dd4986521ec7e182/src/php_http_client_curl.c#L2210 So if the function fails on the first unsupported option, further options may not be set, but possibly the request may succeed.

cmb69 avatar Oct 25 '21 17:10 cmb69

I can confirm that 86b8a43 solves the reported issue, but it doesn't look like a proper fix for the actual problem; why would failing to set an unsupported option break the request?

Awesome work up, thank you all!

Particularly, it doesn't look right that the return value of php_http_options_apply() is not checked:

https://github.com/m6w6/ext-http/blob/86b8a4396d03ad6161ba3d05dd4986521ec7e182/src/php_http_client_curl.c#L2210

So if the function fails on the first unsupported option, further options may not be set, but possibly the request may succeed.

Duh, good find – I'll look into that!

m6w6 avatar Oct 26 '21 10:10 m6w6

Hi all! I guess this can be closed? Please re-open if I was missing something. Thanks!

m6w6 avatar Mar 09 '23 08:03 m6w6