php soap client with a local wsdl call - php

I´m a newbie to soap in php, so I apologize if I´m not precise in my description.
I have working soap clients consuming wsdl´s in a providers remote server (eg www.remoteaddress.com/wsdl/webservice.wsdl). I was wondering if I could speed up that first wsdl call (before getting it into de cache) by downloading that wsdl from the remote server and uploading it locally to the same folder that contains the php that makes the call.
php.net says...
$client = new SoapClient(null, array('location' => "http://localhost/soap.php",
'uri' => "http://test-uri/",
'style' => SOAP_DOCUMENT,
'use' => SOAP_LITERAL));
So, questions please...does the location always have to be an http address or can a local apache server address be used (so as to reference a folder on a higher level than the public_html)? or in other words how do I reference in "location" the folder containing the the local uploaded wsdl? Would this speed things up, and if the local wsdl is in a public directory in my local server, does that pose some sort of security risk? Tried some combinations with the localhost above but none worked...
Thanks in advance for your help,
Pablo

Related

Could not construct ApplicationDefaultCredentials with Recaptcha Enterprise

I'm getting a "Could not construct ApplicationDefaultCredentials" from Google Recaptcha Enterprise, but only on our remote server. I've tried everything I can think of to isolate the issue, but I've had no luck.
I have two Recaptcha Enterprise keys: One for testing, and one for prod.
The testing key works fine on localhost. I've tried both the testing and prod key on our staging server, but I keep getting the same error.
Could not construct ApplicationDefaultCredentials
Things I've checked:
The key is successfully requesting tokens (I can see them in the form)
The service account .json credentials are being picked up correctly (I've tried outputting the contents to ensure they can be read)
The domains are correctly configured and allowed (Google helpfully lets you know if this isn't the case)
The Project ID is also correctly being picked up and sent
Basically all the values are present (project ID, site ID, service account details) and the domain is allowed, but as soon as it's on the remote staging server, it is failing to create credentials.
I'm struggling to figure out what the difference could be.
public static function createRecaptchaAssessment(
string $siteKey, // Present
string $token, // Present
string $projectId // Present
): Assessment {
$options = [
'keyFile' => config('services.google.app_credentials'), // Present
'projectID' => $projectId
];
$client = new RecaptchaEnterpriseServiceClient($options); // <-- Throws exception for ApplicationDefaultCredentials not being able to be created
...
Things to consider: The staging server is hosted on an elasticbeanstalk.com subdomain, and the site is password protected with .htpasswd. I know sometimes elasticbeanstalk.com is blacklisted because it is a blanket domain, but we're only specifying the subdomain and there's no "This domain is not allowed" message from Google. And there shouldn't be any inbound connections being blocked by .htapasswd that I'm aware of.
I've tried creating a new Service Account, just incase there was something configured incorrectly (it has Recaptcha Enterprise Agent permissions) but nothing changed.
Any ideas on how else I could debug this would be gratefully appreciated. (Note: This is a PHP/Laravel 9 project hosted on AWS Elastic Beanstalk, but I don't think that's a factor.)
Key takeaway: The ApplicationDefaultCredentials error is almost certainly related to the Service Account .json not being picked up by your application.
Full version: So apparently I took some poor advice from another SO answer which suggested you could pass the path to the Service Account credentials .json file through the following array:
$options = [
'keyFile' => config('services.app_credentials'), // DON'T DO THIS
'projectID' => $projectId
];
I spent a long time looking through the Google library only to discover that neither array keys are used. Actually what happens is this:
If the library isn't passed a path to the Service Account credentials .json file, it then looks for an environment variable called GOOGLE_APPLICATION_CREDENTIALS.
If you have this ENV and your environment supports it, that's actually what it is going on. (Which is why you might find that it works locally, but not remotely, as I did.)
When you deploy Laravel remotely, all the .env variables are cached and so not available through getenv()... meaning the library is not able to find GOOGLE_APPLICATION_CREDENTIALS even if you have it included in your .env.
The solution is to add the path through an array key credentials:
$options = [
'credentials' => config('services.app_credentials')
];
$client = new RecaptchaEnterpriseServiceClient($options);
Now it works perfectly.

Uploading files from my app to Softlayer's Object Storage using Gaufrette

I'm building a web application that allows to upload many types of files, some of them very big. Backend is built using Symfony (v3.1 in fact, but I don't think this matters for the issue) and I am using Gaufrette Bundle to interact with the filesystem. I found it a great solution, since it allows me to easily switch between local storage and cloud object storage depending on the file type and size.
However, I don't manage to make it work with Softlayer Object Storage. It has many built in wrappers, one of them for OpenStack based clouds (e.g. Rackspace or Softlayer) and the documentation seems very comprehensive, but I can't successfully connect to Softlayer API.
I have tried both integration within the Symfony Bundle and using the libraries directly in my classes and none of them works, below the latter:
public function uploadFromUrl($url)
{
$connection = new OpenStack(
'https://fra02.objectstorage.softlayer.net/auth/v1.0/',
array(
'username' => 'myuser',
'password' => 'mykey'
)
);
dump($connection);
$objectStore = $connection->objectStoreService('cloudFiles', 'fra02', 'publicURL');
$adapter = new OpenCloudAdapter(
$objectStore,
'mycontainer'
);
$filesystem = new Filesystem($adapter);
$filename = pathinfo($url, PATHINFO_FILENAME);
$filesystem->write($filename, file_get_contents($url));
return $filename;
}
And the error I am getting:
Client error response
[status code] 400
[reason phrase] Bad Request
[url] https://fra02.objectstorage.softlayer.net/auth/v1.0/tokens
I suspect the problem is related to a bad formatting of the curl the library is doing internally, but I have no way to find out what are the parameters it is passing and whether they match with Softlayer API. I have tried both OpenStack and Rackspace examples shown in Gaufrette documentation with no luck
I tried to reproduce your issue but I couldn't (I didn't have success to connect with the Object Storage). Anyway, it seems the same issue from the following forum (see below), because you are using php opencloud library:
Connecting to softlayer object storage using openstack API library
php-opencloud
I would recommend to use: SoftLayer Object Storage PHP Client, I hope it helps with your requirements

SoapClient fails to load WSDL where SoapUI has no issue

At my office I can connect directly to the relevant soap servers and my code works as it should.
However - because of security - it is not allowed that VPN connections (from home) access the SOAP servers. So I have to resort to using an SSH tunnel over a jump-station.
Because the WSDL files contain absolute urls I can't use the "location" to change this, it won't load the WSDL. Therefor I've resolved to adding entries to the hosts files mapping that server name to 127.0.0.1 and and SSH tunnel to our jumpstation forwarding the correct ports.
This allows me to use the original WSDL without modification. I just have to comment out the hosts entries when at the office.
Via SoapUI everything works. I can load the WSDL, it fully parses it (it has a lot of includes - big corporate soap service) and I can launch SOAP requests that get answered correctly.
However, if I do the same via the php SoapClient (running against an apache on localhost) it throws an exception:
SOAP-ERROR: Parsing Schema: can't import schema from 'http://wsdl.service.addres:port/wsdlUri?SCHEMA%2Fsoa.osb.model%2Fsrc%...'
(I've replaced the server and the rest of the request because its not relevant.)
If I take that entire URL and paste it into my browser it results in an WSDL-XML.
The PHP code to load create the SoapClient is as simple as this:
$options =
[
'trace' => 1,
'exception' => 1,
];
$wsdl = '/path/to/local/wsdlfile.xml';
$client = new \SoapClient($wsdl, $options);
Anyone have a clue where to look? I can't think of anything to try anymore.
I know for sure that my PHP is setup correctly (as the code has been working for months at the office and nothing was changed here). Is PHP doing DNS resolving differently and somehow getting another (or no) IP for that corporate server perhaps?

Zend Soap Server with wsdl - 403 Forbidden

I'm working on a project with ZF in windows environment (using wamp) trying to develop a web service (wsdl definition) with the Soap library of Zend.
Everything works as expected at localhost, the URI http://localhost/mySite/webService/Server.php?wsdl returns a good definition of the service and it can be consumed. But the same using an IP like, let's say http://192.168.1.20/mySite/webService/Server.php?wsdl doesn't seem to be available. I get the error:
Forbidden
You don't have permission to access /mySite/webService/Server.php on this server.
I did the test using http://192.168.0.20/mySite/public/ and it works fine. I get the standard "Welcome to the Zend Framework!" because I haven't changed it yet (it even works using my public IP). In the same project I have some controllers/actions and they fail the same way.
I think the problem could be related with the httpd.conf file, but I don't really know how to handle it. Or maybe the .htaccess on this project?
Has somebody a clue?
Thanks.
Try without cache in your client:
$options['cache_wsdl'] = WSDL_CACHE_NONE:
$uri = http://192.168.1.20/mySite/webService/Server.php?wsdl;
$client = new Zend_Soap_Client($uri, $options);

Set up Google API on ZF2/PHP - Cannot connect to server

I am trying to connect to the google API from a localhost, but keep on receiving an exception (key changed - in text below).
Warning: file_get_contents(compress.zlib://https://www.googleapis.com/books/v1/volumes?q=Henry+David+Thoreau&filter=free-ebooks&key=bItatTTTTT7amAHYSaROTTTTTbtttuuuuuuuu) [function.file-get-contents]: failed to open stream: operation failed in C:\zendProject\zf2\vendor\google\apiclient\src\Google\IO\Stream.php on line 115
The code I am using in my browser comes straight from the API Guide and reads:
$client = new \Google_Client();
$client->setApplicationName("rent");
$service = new \Google_Service_Books($client);
$optParams = array('filter' => 'free-ebooks');
$results = $service->volumes->listVolumes('Henry David Thoreau', $optParams);
I think my problems relate to the config file, and that fact I am working off the localhost development server.
'Google_Auth_OAuth2' => array(
'application_name' => 'www.example.com',
'client_id' => '4498xxxxx061-3333xxxx9pjcpkbqhoxxxxxxxxxxx.apps.googleusercontent.com',
'client_secret' => '8xxxxxxxxx333xxxxxxxxx',
'redirect_uri' => 'http://localhost',
'developer_key' => 'AxxxxxxzBjpxxxxxaxxxxxxZxxx1xxxxx',
In the new developer console I have created a new client ID for the project and inserted the "Client_id", "Client_secret", etc.
I have also enabled the relevant APIs for Calenders and Books.
I have tested my API key on the URL I found for google fonts - so I am sure I have the right developer key.
I suspect the issue may be around the local host in uri fields, what do I need to put in here?
Does anyone know what I am doing wrong.
UPDATE: I found a post that suggested getting the HTTP response code here:
The response from the server is 304 - not sure if this helps
UPDATE: #Carlos Roubles - was correct I was using the incorrect version. Just in case anyone else runs into this issue - the composer information on the google website appears to be incorrect.
I previously used "google/apiclient": "1.0." this appears in the google documentation. I have now tried "google/apiclient": "1." and this seems to have fixed the problem.
Thats a problem with file_get_contents rather that with the api.
Most people changes file_get_contents to CURL for accesing remote files.
Anyways, i was checking the library and i cannot find any call to file_get_contents in all the stream.php file
https://github.com/google/google-api-php-client/blob/master/src/Google/IO/Stream.php
and in line 115, what we have is a commented line, so what comes to my mind is that yu are not using the last version of the library. Also, i see that in this version they make the request with fopen.
So you can try to update it, and probably this fixes the issue

Categories