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?
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.
Im trying to make this fixed, but im stuck. Im not very skilled with WSDL, SOAP and making an XML with it. I'll keep getting this error "Operation '' is not defined in the WSDL for this service" Did anyone know how did i get rid of this error? My goal is to get an XML with all the occasions from a car garage and put them in my database.
This is my code:
ini_set('soap.wsdl_cache_enabled', 1);
$options = array(
'soap_version' => SOAP_1_2,
'trace' => true,
'exceptions' => true,
'encoding' => 'UTF-8',
'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP,
'cache_wsdl' => WSDL_CACHE_DISK,
'login' => '****', // <- username here, i got the right one
'password' => '****' // <- same
);
try{
$client = new SoapClient('https://eigenwebsite.doorlinkenvoorraad.nl/v1/leads/deliver.html?wsdl', $options);
//var_dump($client->__getFunctions());
//echo '<br>';
$klant = array(
"key"=>"****", // got the right one
"klantnummer"=>"****", // got the right one
"lead"=>"information_request",
"testmode"=>"dummy"
);
$quote = $client->deliverLead($klant);
}catch(SoapFault $exception){
echo $exception->getMessage();
}
Try changing the SOAP version to 1.1:
'soap_version' => SOAP_1_1,
The web service only supports SOAP 1.1 from the looks of the WSDL, so it is throwing an error when you send it a SOAP 1.2 message.
I've got error: Unable to handle request without a valid action parameter.
I want to just login by SOAP server.
My wsdl is here: https://demo.krd.pl/Siddin/2.1/Import.asmx?WSDL
and my code is like:
$client = new SoapClient('https://demo.krd.pl/Siddin/2.1/Import.asmx?WSDL', array(
'location' => 'https://demo.krd.pl/Siddin/2.1/Import.asmx?WSDL',
'trace' => 1,
'exceptions' => true,
'cache_wsdl' => WSDL_CACHE_NONE,
'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
'soap_version' => SOAP_1_2
));
$auth = new stdClass();
$auth->UserName = 'aaa';
$auth->Password = 'bbb';
$auth = new SoapVar($auth, SOAP_ENC_OBJECT, 'complexType', null, 'LoginRequest', 'types');
$result = $client->login($auth);
die(var_dump($result));
As You can see, I want to invoke method 'login' on this SOAP server with parameter LoginRequest - it's described in wsdl file. How do that?
without a valid action parameter.
This means that your php soap client is not able to make up the needed SOAPAction http header. You WSDL defines for login method this:
soapAction="http://Siddin.ServiceContracts/2006/09/Login"
There are a number of reasons possible for it not to add the header, e.g. this one:
'soap_version' => SOAP_1_2,
Try changing it to
'soap_version' => SOAP_1_1,
In case that doesnt resolve it, i recommend you to start general soap debugging by tracing the message being sent (including http headers) and compare it to a working request that you can set up e.g. using SoapUI https://www.soapui.org/
I'm attempting to run both a PHP SoapClient and a SoapServer (for Magento) behind a proxy, where the only network traffic allowed out is via the proxy server.
I have got this working with the client as so:
$client = new SoapClient('https://www.domain.co.uk/api/v2_soap/?wsdl=1', [
'soap_version' => SOAP_1_1,
'connection_timeout' => 15000,
'proxy_host' => '192.168.x.x',
'proxy_port' => 'xxxx',
'stream_context' => stream_context_create(
[
'ssl' => [
'proxy' => 'tcp://192.168.x.x:xxxx',
'request_fulluri' => true,
],
'http' => [
'proxy' => 'tcp://192.168.x.x:xxxx',
'request_fulluri' => true,
],
]
),
]);
This works as expected - all the traffic is going via the proxy server.
However, with the SoapServer class, I can't work out how to force it to send all outbound traffic via the SoapServer. It appears to be trying to load http://schemas.xmlsoap.org/soap/encoding/ directly form the network, not via the proxy, which is causing the "can't import schema from 'http://schemas.xmlsoap.org/soap/encoding/'" error to be thrown.
I've tried adding a hosts file entry for schemas.xmlsoap.org to 127.0.0.1 and hosting this file locally, but I'm still getting the same issue.
Is there something I'm missing?
Try stream_context_set_default like in file_get_contents:
file_get_contents behind a proxy?
<?php
// Edit the four values below
$PROXY_HOST = "proxy.example.com"; // Proxy server address
$PROXY_PORT = "1234"; // Proxy server port
$PROXY_USER = "LOGIN"; // Username
$PROXY_PASS = "PASSWORD"; // Password
// Username and Password are required only if your proxy server needs basic authentication
$auth = base64_encode("$PROXY_USER:$PROXY_PASS");
stream_context_set_default(
array(
'http' => array(
'proxy' => "tcp://$PROXY_HOST:$PROXY_PORT",
'request_fulluri' => true,
'header' => "Proxy-Authorization: Basic $auth"
// Remove the 'header' option if proxy authentication is not required
)
)
);
//Your SoapServer here
Or try to run server in non-WSDL mode
<?php
$server = new SoapServer(null, array('uri' => "http://localhost/namespace"));
$server->setClass('myClass');
$data = file_get_contents('php://input');
$server->handle($data);
i have a problem with running methods with SOAP. I'm using Apache and PHP.
this is the PHP code:
$opts = array(
'ssl' => array('ciphers'=>'RC4-SHA')
);
ini_set('soap.wsdl_cache_enabled',0);
ini_set('soap.wsdl_cache_ttl',0);
$client = new SoapClient('https://host?wsdl', array (
'stream_context' => stream_context_create($opts),
"trace" => 1,
"exceptions" => 0,
"connection_timeout"=>2000));
var_dump($client->__getFunctions());
$params = array ("key" => "value");
$result = $client->availabeFunction($params);
var_dump($result);
The __getFunctions() It returns me all of the available functions.
Then when i'm trying to call the the available function with parameters.
It returns me a strage error message:
public 'faultstring' => string 'Could not connect to host' (length=25)
public 'faultcode' => string 'HTTP' (length=4)
So i presume it is for some reasons are connecting to through the HTTP, but not through HTTPS.
I've looked up the web, and in some cases they are using a local_cert value with a .pem file.
It it neccecity to have it? Or i'm missing something else?
It's an openssl library bug.
At first try to disable SSL check by adding this params
"stream_context" => stream_context_create(
array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
)
)
)
And next try to not use ?wsdl in location link, try use something like
.wsdl
The solution was much easier as i thoguht it will be:
ini_set('soap.wsdl_cache_enabled',0);
ini_set('soap.wsdl_cache_ttl',0);
$location = 'https://host';
$client = new SoapClient($location . '?wsdl', array (
"trace" => 1,
"exceptions" => 0,
"connection_timeout"=>2000,
"location"=>$location // <- this was the reqiured parameter
));
Everything else is same as before.
This beeing cause by WSDL file configuration, that instead of https URL, it has http.