ext-http
ext-http copied to clipboard
HTTPS does not seem to work on Windows?
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?
btw this is not specific to my test site, the same thing happen for www.google.com
Any insight here @Jan-E @cmb69? Sorry for cold-tagging, but I'm pretty lost on windows issues...
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.
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)
}
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
<?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>";
}
?>
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)
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.
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?
Possibly related: https://stackoverflow.com/questions/61650504/use-of-undefined-constant-curlopt-tcp-fastopen
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)
}
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.
See this issue as well with respect to tcp_fastopen
: https://github.com/curl/curl/issues/3662
Fixed for PHP 8.1 by https://github.com/m6w6/ext-http/commit/86b8a4396d03ad6161ba3d05dd4986521ec7e182
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.
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!
Hi all! I guess this can be closed? Please re-open if I was missing something. Thanks!