I can't seem to connect to a https endpoint with a SoapClient
. As my wget returns a handshake failure
, I suspect that is the cause.
How can I do a SOAP request to this server with PHP
?
I'm trying to connect to a SOAP server (https). It doesn't have client certificate authentication, so the connection should be pretty straightforward, but sadly it isn't.
The problem is that I keep getting Could not connect to host
messages.
The connection method I'm using is working for another server and I've verified that I'm setting the location for this server correctly (changed it to a server I control, and I'm getting response there). I suspect the problem is with the https/ssl connection to the server.
Soapclient
based on a wsdl I have locally. wget
to connect to it (see below)
Unable to establish SSL connection.There are a lot of topics about "no connection!", but there is obviously a lot of "my router was bad, I made a typo in the address etc" going on. I did try these settings that were suggested multiple times, but more as a "cut'n'paste" solution to be sure It didn't work" then out of real reasoning. Some comments from me added
Creating a stream_context
for the wsdl options. I have tried
$context = stream_context_create(
array(
'ssl' => array(
'verify_peer' => false, //default
'allow_self_signed' => true, //needs verify peer, tried that
'ciphers'=>"SHA1", // quite random.
),
'https' => array(
'curl_verify_ssl_peer' => false,
'curl_verify_ssl_host' => false
)
)
);
$options['stream_context'] = $context;
(first only the ssl
options with verify_peer
and allow_self_signed
. Then I added the https
array, then finally I added the ciphers
key to ssl
.)
I found a reference to this bug, but 1) I'm not getting that warning, 2) it seems to be proxy-related and 3) My version shouldn't have the bug anymore. I'm running php 5.3.10
When I try to wget the url, I get:
wget https://[[servername]]/SOAP
Resolving [[servername]] ([[servername]])... xxx.xxx.xxx.xxx
Connecting to [[servername]]([[servername]])|xxx.xxx.xxx.xxx|:443... connected.
OpenSSL: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
If I try to connect with openssl, I get this:
$ openssl s_client -connect [[server]]:443 -state
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:unknown state
SSL3 alert read:fatal:handshake failure
SSL_connect:error in unknown state
3074463944:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:724:
but if I force ssl3, I get an expected result
$ openssl s_client -ssl3 -connect [[server]]:443 -state
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:SSLv3 read server hello A
**happy certificate stuff. this is good**
Protocol : SSLv3
Cipher : DHE-RSA-AES256-SHA
**more happy certificate stuff. **
I have tried to add the curl-wrapper from this question with ssl_version set to 3 (as this seems to work on the openssl
command above). That wrapper does discard some of the parameters, so I'm not sure how complete this would be. Further, I still get a handshake error, unless I explicitly set checking to false. If I do that (see below), I get an empty response.
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);
As said above, I suspect the ssl handshake, but I have no clue how to fix it. I don't suspect issues with the wsdl or the client-creation, as the connection does work with another wsdl, the same wsdl with a different location set etc. It is purely this (https) endpoint that's giving me headaches.
Just as the test above with the curl wrapper I tried sending a minimal soap envelope as @halfwarr seemed to suggest in the comments. Als returns an empty response.
So with above it seems that I do have a method to squeeze an http 204
out of the server, but that's hardly success. But it could be a second problem? Not sure.
I am supposing that I need to try and force the ssl3, but I have no idea how (and this could be the wrong path as well so I'm trying to not have an XY problem here :)
Interesting. Try adding this:
wget https://[[SERVER]]/soap/ —post-file=request.xml —header=”Content-Type: text/xml” -O response.xml
This will save the result as a file named response.xml.
The latest version PHP 5.5.3 will allow you to set the SSL Version. I've seen others that have been able to use a stream_context but, I was unable to get that work as well.
As a work around and fail safe, I used a catch to grab the soap envelope request (similar to what you tested above):
$xml = $client->__getLastRequest()
and send via curl:
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
That's allowing me to at least move forward.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With