I have googled and looked here in stackoverflow but I have not found a solution to my specific problem. I keep getting the error
SOAP-ERROR: Parsing WSDL: Couldnt load from "https://sampleurl.com/MerchantQueryService.asmx?WSDL" : failed to load external entity "https://sampleurl.com/MerchantQueryService.asmx?WSDL"
I am trying to use a SOAP API with a URL like
https://sampleurl.com/MerchantQueryService.asmx?WSDL
I am running MAMP on my localhost and using godaddy shared hosting, I have tried on both with the wsdl file can be found here
http://clemdemo.com/test.wsdl
In PHP I use the code below
error_reporting(-1);
ini_set('display_errors', 'On');
ini_set('soap.wsdl_cache_enabled', 0);
echo "<pre>";
try {
$url = "https://sampleurl.com/MerchantQueryService.asmx?WSDL ";
$headers = [
'Host: sampleurl.com',
'Connection: Keep-Alive',
'User-Agent: PHP-SOAP/5.3.29',
'Content-Type: text/xml; charset=utf-8',
'SOAPAction: "RequestTransaction"',
'Content-Length: 409'];
$rq = [
"userName" => "username_here",
"passWord" => "password_here",
"referenceId" => "3455566694",
"msisdn" => "346774313"];
try {
$cient = new SoapClient($url,
[
'soap_version' => SOAP_1_2,
'exceptions' => 1,
'cache_wsdl' => WSDL_CACHE_NONE,
'trace' => 1,
'stream_context' => stream_context_create(array('http' => array('header' => $headers)))
]);
print_r($cient);
} catch (SoapFault $e) {
echo "\nFault Code: ".$e->faultcode;
echo "\nFault String: ".$e->faultstring;
}
On my MAMP localhost i have SOAP,openssl and curl.
ALSO, I tried using (sending request) to the API with an online WSDL http://wsdlbrowser.com it WORKS but on code using PHP it fails
It often happens that providers neglect their SSL certificates and hence the sites and services end up having an invalid certificates - I suspect this is the case here.
Disabling the certificate validation as described by Kaii here or even better get your provider to fix their certificate.
Your code could/should then be something like:
$url = "https://sampleurl.com/MerchantQueryService.asmx?WSDL ";
$context = stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
));
$rq = ["userName" => "username_here",
"passWord" => "password_here",
"referenceId" => "3455566694",
"msisdn" => "346774313"];
$service = new SoapClient($url, array('stream_context' => $context));
$service->RequestTransaction($rq);
The error message appears to say that your app is not able to read our WSDL. Try opening a browser from the same machine on which your app is running and see if you can access the WSDL address at https://sampleurl.com/MerchantQueryService.asmx?WSDL.
If not - you have a network/firewall/Anti Virus problem. (in case)
If you can access this address from a browser - is your app still experiencing this problem? then check any app that could be hindering your firewall.(Anti virus are most probable cause)
If you use docker there is a chance you get error because of OpenSSL default security level. Even if you disable verify and allow self-signed in SoapClient options.
Try out to lower seclevel in /etc/ssl/openssl.cnf from DEFAULT#SECLEVEL=2 to
DEFAULT#SECLEVEL=1
Or just add into Dockerfile
RUN sed -i "s|DEFAULT#SECLEVEL=2|DEFAULT#SECLEVEL=1|g" /etc/ssl/openssl.cnf
By: https://github.com/dotnet/runtime/issues/30667#issuecomment-566482876
You can verify it by run on container
curl -A 'cURL User Agent' -4 https://ewus.nfz.gov.pl/ws-broker-server-ewus/services/Auth?wsdl
Better diagnostics can be performed with: libxml_get_last_error();
Could have cached a bad response, set 'cache_wsdl' => WSDL_CACHE_NONE when initating the object
if you skip cache, and get this in your libxml error:
LibXMLError Object
(
[level] => 1
[code] => 1549
[column] => 0
[message] => failed to load external entity "URL"
[file] =>
[line] => 0
)
With no description on Ubuntu, then its not pulling the file period. You just got hit with the Ubuntu update. Wave them the bronx salute and reboot.
Related
I hope this question won't be marked as duplicate as I read many related questions and answers on the site: although I tried most of the suggestions out there I still couldn't resolve my problem.
My codebase : (I left comments on purpose to give an idea of what I have been trying so far, based on my browsing)
try {
$opts = array(
//~mrossw 'http' => array(
//~mrossw 'user_agent' => 'PHPSoapClient'
//~mrossw ),
//~mrossw 'socket' => array('bindto' => '158.69.189.149')
'socket' => array('bindto' => '127.0.0.1')
//~mrossw ,
//~mrossw 'ssl' => [
//~mrossw 'verify_peer' => true,
//~mrossw 'verify_peer_name' => true,
//~mrossw 'allow_self_signed' => true
//~mrossw ]
);
$context = stream_context_create($opts);
$client = new SoapClient("https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones/OpFooBarBlahReqABCS?wsdl",
//~mrossw $client = new SoapClient($doc_root.'OpCotizadorVehiculoExtReqABCS.xml',
array(
'location' => "https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones/OpFooBarBlahReqABCS?wsdl",
'uri' => "https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones",
// Stuff for development.
'trace' => 1,
'exceptions' => true,
'keep_alive' => true,
'connection_timeout' => 120,
'stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE,
'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | SOAP_COMPRESSION_DEFLATE,
//~mrossw 'local_cert' => $certRequest_param['sslcertfile'],
//~mrossw 'login'=>'username',
//~mrossw 'password' => 'password'
)
);
} catch (Exception $e) {
echo \"<h2>Exception Error!</h2>\";
echo $e->getMessage();
// print_r($e);
}
The WS provider has an dev environment on port xxxx and a prod env on port yyyy. Hostname and path request are the same.
SoapClient instanciation and operation call work perfect in dev env.
When i change the port to fetch against prod env I get the following error:
SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones/OpFooBarBlahReqABCS?wsdl' : failed to load external entity "https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones/OpFooBarBlahReqABCS?wsdl"
Provider says my public web server's IP is correctly set as allowed in their firewall. It looks right because when I tried to run the code from a different server with different IP and it fails with the same error in both dev and prod env.
When I run that code from a server inside a private network, it works in both
environment ! I don't know much about security, but this sounds to me like a security breach. I mention it here though, in case it can give a clue. I guess this is because this server has a private ip and the provider's firewall don't filter it.
When I go to https://ws_provider_hostname:xxxx/foo/bar/blah/Operaciones/OpFooBarBlahReqABCS?wsdl in my PC browser i get the correct wsdl's xml.
Do you have an idea of what can prevent the code to work form my public web server ?
Or maybe what else can I check ?
For example I couldn't find a way to check the ws server's http response code from outside my browser.
I could neither get a curl request form bash to return the wsdl xml, but that should be another question maybe.
Also let me know if i can provide any other relevant test or data.
I have installed WAMP 3.0.4 and am trying to write a PHP script that connects to an external HTTPS web service. But this returns the error:
Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
I have written a short script that demonstrates the issue:
<?php
$auth = base64_encode('username:password');
$aContext = array(
'http' => array(
'proxy' => 'tcp://proxyip:proxyport',
'request_fulluri' => true,
'header' => 'Proxy-Authorization: Basic $auth'
),
'SSL' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
'cafile' => 'C:/wamp/certificates/cacert.pem'
)
);
$cxContext = stream_context_create($aContext);
$sFile = file_get_contents("https://www.google.com", False, $cxContext);
echo $sFile;
?>
It is a requirement to use a proxy server.
As can be seen, I have tried installing a root certificates bundle and also adding verify_peer to false (not that I would do that in production) but still I receive this error.
As can be clearly seen from the above, I am something of an Apache / WAMP novice. Can someone perhaps explain what I am missing?
If you want to disable the verification of the SSL connection you can use:
'verify_peer' => false
And inside your code:
<?php
$auth = base64_encode('username:password');
$aContext = array(
'http' => array(
'proxy' => 'tcp://proxyip:proxyport',
'request_fulluri' => true,
'header' => "Proxy-Authorization: Basic $auth"
),
'ssl' => array(
'verify_peer' => false,
),
);
$cxContext = stream_context_create($aContext);
$sFile = file_get_contents("https://www.google.com", False, $cxContext);
echo $sFile;
?>
However note that this means that no-one is guarantee you that the data you get is authentic (since the ssl certificate is NOT verified).
If you want to verify the certificate, you should use the root certificates as in your question, however, you said you work with WAMP so the path to your cafile should be something like:
"cafile" => "c:/wamp/certificates/cacert.pem",
More important - you said nothing regarding the proxy in your question. Is it something that you need or is it something you found somewhere and just trying to use?
If you don't need the proxy just remove if from your request.
While on MAMP on macOS, simply restarting MAMP server solved this issue for me.
Currently i'm trying to build a little PHP - Soap Connector, which worked pretty good so far. But when i'm deploying my little script to my server, it won't work anymore and i have no clue, why.
I'm connecting in 2 different ways (by curling the SOAP WSDL Scheme, and saving it temporary in the script location, and creating from that a new SOAP Client, and creating a SOAP Client directly by using the SOAP WSDL Scheme URL):
$opts = array(
'http'=>array(
'user_agent' => 'PHP Soap Client'
)
);
$context = stream_context_create($opts);
// SOAP 1.2 client
$params = array (
'encoding' => 'UTF-8',
'verifypeer' => false,
'verifyhost' => false,
'soap_version' => SOAP_1_2,
'trace' => 1,
'exceptions' => 1,
'connection_timeout' => 30,
);
$curlStuff = curl_init($soapURL);
curl_setopt($curlStuff,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curlStuff,CURLOPT_FOLLOWLOCATION,true);
curl_setopt($curlStuff,CURLOPT_TIMEOUT,30);
$response = curl_exec($curlStuff);
$info = curl_getinfo($curlStuff);
if($response) {
file_put_contents("./tempSoapScheme.wsdl", $response);
}
$soapClient = new SoapClient(
'./tempSoapScheme.wsdl',
array(
'trace' => 1,
'stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE
)
);
$soapClientTwo = new SoapClient(
$soapURL,
array(
'trace' => 1,
'stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE
)
);
$result = $soapClient->myLoginMethod(
array(
'username' => 'my#email.example',
'password' => 'password'
)
);
As i said earlier - on my local machine it works like a charm, and everything is fine. The param "soapURL", which is not inside the script, is just the https path to my SOAP WSDL Scheme.
I've tried different options inside "$params" array, other curl setopt settings, but i can't make it work.
The response from both SoapClients:
SOAP-ERROR: Parsing WSDL: Couldn't load from '<MyURL>' : failed to load external entity "<MyURL>", which is pretty uncommon, because the CURL could save everything.
Do you have any suggestions for me?
EDIT - forgot the most important thing:
- The server, which should execute the script, has very strong firewall restrictions, and the SOAP URL Scheme is on another server (not the same). And i guess, that is the point, why it won't work, but i receive an answer from the Scheme by executing CURL.. So it's just SOAP?
Using the php Soapclient I got the exception:
Uncaught SoapFault exception: [HTTP] Proxy Authentication Required
But when using a web browser with the same proxy set up, without specifying any credentials for that proxy, I can connect getting a XML response.
The system department ensures that there is no need for authenticate. Also I'm using the SoapUI just configuring the proxy for testing porpouses, without credentials again, and I can call the methods in the WS.
Why is the php SoapClient throwing that exception? Here is the code I'm using...
$this->client = new SoapClient( null, array(
'location' => 'http://www.xxxxx.dev',
'uri' => self::URI,
'proxy_host' => self::PROXY_HOST,
'proxy_port' => self::PROXY_PORT,
) );
Following solve the exception
$this->client = SoapClient( self::URL , array(
'proxy_host' => self::PROXY_HOST,
'proxy_port' => self::PROXY_PORT,
'authentication' => SOAP_AUTHENTICATION_BASIC,
'stream_context' => stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => false
)
))
));
Misunderstood with the documentation, "URI of the WSDL file or NULL if working in non-WSDL mode" and I was expecting first parameter as a file, not an URL. In some of the attempts I already tried but forgetting to set up the stream context with the SSL parameter to skip peer verification. ( probably SOAP_AUTHENTICATION_BASIC isn't necessary )
Hope it helps someone
I have two servers : one is used for development and can access to the WEB easily but another one for production which can access to the WEB only using a proxy.
I would like to call a SOAP WEB service from my production server.
So following is the code (the URLs are fake):
$url = 'https://www.webservice.com/soap.php';
$wsdl = 'https://www.webservice.com/soap.php?wsdl';
$client = new SoapClient
(
$wsdl,
array
(
'location' => $url,
'proxy_host' => 'www.myproxy.com',
'proxy_port' => 8080,
)
);
$namespace = 'urn:mynamespace';
$header = array
(
'header1' => 'H1',
'header2' => 'H2',
'header3' => 'H3',
);
$client->__setSoapHeaders(new SoapHeader($namespace, 'myHeader', $header));
$params = array
(
'param1' => 'val1',
'param2' => 'val2',
'param3' => 'val3',
);
$result = $client->method($params);
I run it from my development server and I get the expected result.
Now I run it from my production server and I get :
PHP Warning: SoapClient::SoapClient(https://www.webservice.com/soap.php?wsdl): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request
PHP Warning: SoapClient::SoapClient(): I/O warning : failed to load external entity "https://www.webservice.com/soap.php?wsdl" in /home/benji/test.php on line 20
PHP Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://www.webservice.com/soap.php?wsdl' : failed to load external entity "https://www.webservice.com/soap.php?wsdl"
When I wget the wsdl from the production server, it's working:
$ https_proxy=www.myproxy.com wget https://www.webservice.com/soap.php?wsdl
--2013-02-22 10:57:40-- https://www.webservice.com/soap.php?wsdl
Resolving www.myproxy.com... 10.0.0.125
Connecting to www.myproxy.com|10.0.0.125|:8080... connected.
Proxy request sent, awaiting response... 200 OK
Length: unspecified [text/xml]
Saving to: `soap.php?wsdl'
[ <=> ] 9 010 --.-K/s in 0,009s
2013-02-22 10:57:40 (980 KB/s) - `soap.php?wsdl' saved [9010]
The following solution solved the described problem for me:
create a new stream context where you also specify your proxy information
for the stream context set option SNI_enabled to false
pass the stream context as new parameter in the options array to the soapclient
$context = stream_context_create(
array(
'ssl' => array(
'SNI_enabled' => false
),
'http' => array(
'proxy' => 'tcp://yourproxy.com:9999'
)
)
);
$soapOptions = array(
'stream_context' => $context
);
$soapClient = new SoapClient( 'wsdl.path', $soapOptions );