PHP SOAP client over IPv4

2k Views Asked by At

I have a PHP client that needs to connect to a SOAP server:

$client = new \SoapClient('url_to_wsdl.wsdl', [
                'local_cert' => 'path_to_certificate.pem', 
                'connection_timeout ' => 300,
                'trace' => 1,
            ]);

$params = [];
$response = $client->executeAFunction($params);

But the SOAP client can't connect to the host: SoapFault "Could not connect to host" (it actually can't load the wsdl file either, but I mocked that by using a local copy of the file).

I came to the point where I figured out the Soap client cannot connect to the host because it seemingly uses IPv6 by default (I got to this point because of this answer on SO).

What have I done so far:

  • I already disabled IPv6 on my server (ubuntu), but that didn't change anything to the SOAP client.
  • I double-checked the reachability of websites over both IPv4 and IPv6 via the servers terminal

    $ curl -6 http://v6.testmyipv6.com/
    curl: (6) Could not resolve host: v6.testmyipv6.com
    
    $ curl -4 http://v4.testmyipv6.com/
    <html>
    <head>
    <title>IPv6 Test and Dual-Stack Test For Network Connectivity</title>
    ...
    
    # the above commands are true for all urls I tested
    

My actual question is: how can I tell the Soap client to connect to the host using IPv4 instead of using IPv6?

2

There are 2 best solutions below

0
On BEST ANSWER

A SOAP request is a socket connection, so you can use socket_context options. Use stream_context_create() to bind your request to a specified IP.

stream_context_create(['socket' => ['bindto' => '123.123.123.123:0']]);

Set 0 for port number so PHP will set this automatically.

0
On

Rather than binding to a specific IPv4 IP address, you can also substitute the IP address with 0:

stream_context_create(['socket' => ['bindto' => '0:0']]);

A full example of forcing IPv4 for a SoapClient might be:

$opts = array(
    'http' => array(
        'user_agent' => 'Your/UserAgent'
    ),
    'socket' => ['bindto' => '0:0']
);
$context = stream_context_create($opts);

$soapClientOptions = array(
    'stream_context' => $context,
    'trace' => true,
);
$client = new SoapClient($wsdlUrl, $soapClientOptions);