Magento SOAP API: wsdl soap:address location incorrect - api

I'm trying to connect to a Magento instance using the SOAP API v2, and although I can see the wsdl when I visit http://www.domain.loc/api/v2_soap?type=soap&wsdl=1 in my browser, I am unable to execute the login() call, an error is always thrown.
Code:
$options = array(
'trace' => 1,
'cache_wsdl' => WSDL_CACHE_NONE,
//'location' => 'http://www.domain.loc/index.php/api/v2_soap?wsdl=1',
'soap_version' => SOAP_1_2,
'connection_timeout' => 120,
'exception' => 0,
'encoding' => 'utf-8',
);
try {
$client = new soapClient('http://www.domain.loc/api/v2_soap?type=soap&wsdl=1', $options);
$client->login('username', 'password');
//$result = $client->catalogProductList($sessionId);
//$result = $client->call($session, 'catalog_product.list');
var_dump($client);
} catch (SoapFault $e) {
var_dump($e);
}
Which yields "SoapFault: looks like we got no XML document"
When I uncomment the location option I get "SoapFault: Wrong Version"
When I view the wsdl file, I see the soap:address location set as
<port name="Mage_Api_Model_Server_HandlerPort" binding="typens:Mage_Api_Model_Server_HandlerBinding">
<soap:address location="http://www.domain.loc/index.php/?SID=7o7mn7iiu9tr8u1b9163r305d4dp1l1jrcn1hmnr34utgnhgb6i0&type=soap"/>
Which seems incorrect as it is the URL to the homepage, with the SID and a query param.
Magento version EE1.14
Things I have tried:
Disable local modules - no change
Using Zend_Soap_Client - no change
Various different URL configurations - tried everything under the
sun, no change
Using SOAP v1 - same results
Tried using this on a remote instance instead of my local - same
result
Checked phpinfo - yes SOAP is installed
Tried debugging - When I turn on Xdebug and run my test script it
seems to prevent the script from even running. Browser just
indicates loading forever
Tried to uncomment line in .htaccess to rewrite RewriteRule
^api/([a-z][0-9a-z_]+)/?$api.php?type=$1 [QSA,L] - No change
(yes mod rewrite is on and working)
Tried fetching wsdl and saving locally and passing it into SOAP
client constructor - no change
Anyone know how to troubleshoot this? I see several threads with these errors, but either unanswered or have tried their solution and it did not work in this case. Why is my location in the wsdl incorrect? Any help at all would be appreciated. Thanks!

Related

php-curl times out when calling a php on the same domain

I do have a very strange problem where I cannot find any way for debugging. I have a server running Arch Linux, Apache 2.4 and PHP versions 7.4, 8.0 and recent 8.1 as php-fpm. All PHP configurations are identically (modules and configs). But 8.1 has a very strange behaviour regarding php-curl.
I install this php (curltest.php) on my server:
<?php
// this was the originally intended code:
// define ('HTTP_URL', 'https://'.$_SERVER['HTTP_HOST'].'/curltest.php?test=1');
// this doeas not work, too:
define ('HTTP_URL', 'https://'.$_SERVER['HTTP_HOST'].'/any_php_script.php');
// all commented following lines are for testing if $_GET is the cause
// if (empty($_GET['test'])) {
$curlHandle = curl_init();
$fp = fopen('/tmp/error.txt', 'w+');
curl_setopt_array($curlHandle, array(
CURLOPT_URL => HTTP_URL,
CURLOPT_VERBOSE => true,
CURLOPT_STDERR => $fp,
CURLOPT_FAILONERROR => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 5,
CURLOPT_RETURNTRANSFER => true
));
$response = curl_exec($curlHandle);
if (curl_errno($curlHandle)) {
$response = 'Curl error: ' . curl_error($curlHandle);
}
curl_close($curlHandle);
//} else {
$response = 'Erfolg';
//}
echo $response;
The script works perfectly if I run it with PHP 7.4 and 8.0. If I use PHP8.1 I get a "timeout" - no response, nothing in the logs. I dug a bit deeper and tested with calling a text or html file instead of the script itself: this works flawlessly. If I call another php on the same domain the issue pops up again. But if I call a php on the same server but a different domain it works! So the problem only exists:
when using PHP 8.1 (8.1.13-1)
calling a php script which resides on the same domain as my testscript
So it cannot be a dns issue (calling text or html files is working). And it cannot be a problem that I cannot access php via a php-curl: using different domain (on the same server running the same php version) is also working. Any hint for debugging this is welcome.
As already stated I tested with different file types and different domains (on the same server using the same php version). I increased php log level and activated curl to be verbose writing STDERR to file output without success.
You are getting a timeout because you are running in an endless loop. It looks like in that one setup the $_GET variable is not populated and so the if condition always evaluates to true, opening another curl request.
The reason for this can be a misconfiguration of variables_order (php.ini) or FPM parameters (sometimes in a file like fastcgiparams or fastcgi_param params in nginx).
You can verify this by putting a small message after opening the error log:
fwrite($fp, 'Opening socket ' . (string)$curlHandle . PHP_EOL);
Make sure you got G in ini_get('variables_order');

Use Selenium automation using perl

I am in a requirement to download multiple files (from a private/internal network) on daily basis.
For which I intended to use selenium with perl to daily download the files from respective locations. I am very new to this domain and need your help.
As a sample program, i am trying to simply connect google.com but it is not getting connected.
my $sel = WWW::Selenium->new( host => "localhost",
port => 80,
browser => "*iexplore",
browser_url => "http://www.google.com",
);
$sel->start;
$sel->open("http://www.google.com");
$sel->type("q", "hello world");
$sel->click("btnG");
$sel->wait_for_page_to_load(5000);
print $sel->get_title;
$sel->stop;
ERROR - > Error requesting http://localhost:4444/selenium-server/driver/:
500 Can't connect to localhost:4444 (Bad address)
i changed the port to 80 and then i get error as:
Error requesting http://localhost:80/selenium-server/driver/:
404 Not Found
Any inputs would be highly appreciated.

angular2 call remote rest api [duplicate]

I'm making an Ajax.request to a remote PHP server in a Sencha Touch 2 application (wrapped in PhoneGap).
The response from the server is the following:
XMLHttpRequest cannot load http://nqatalog.negroesquisso.pt/login.php. Origin http://localhost:8888 is not allowed by Access-Control-Allow-Origin.
How can I fix this problem?
I wrote an article on this issue a while back, Cross Domain AJAX.
The easiest way to handle this if you have control of the responding server is to add a response header for:
Access-Control-Allow-Origin: *
This will allow cross-domain Ajax. In PHP, you'll want to modify the response like so:
<?php header('Access-Control-Allow-Origin: *'); ?>
You can just put the Header set Access-Control-Allow-Origin * setting in the Apache configuration or htaccess file.
It should be noted that this effectively disables CORS protection, which very likely exposes your users to attack. If you don't know that you specifically need to use a wildcard, you should not use it, and instead you should whitelist your specific domain:
<?php header('Access-Control-Allow-Origin: http://example.com') ?>
If you don't have control of the server, you can simply add this argument to your Chrome launcher: --disable-web-security.
Note that I wouldn't use this for normal "web surfing". For reference, see this post: Disable same origin policy in Chrome.
One you use Phonegap to actually build the application and load it onto the device, this won't be an issue.
If you're using Apache just add:
<ifModule mod_headers.c>
Header set Access-Control-Allow-Origin: *
</ifModule>
in your configuration. This will cause all responses from your webserver to be accessible from any other site on the internet. If you intend to only allow services on your host to be used by a specific server you can replace the * with the URL of the originating server:
Header set Access-Control-Allow-Origin: http://my.origin.host
If you have an ASP.NET / ASP.NET MVC application, you can include this header via the Web.config file:
<system.webServer>
...
<httpProtocol>
<customHeaders>
<!-- Enable Cross Domain AJAX calls -->
<remove name="Access-Control-Allow-Origin" />
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
This was the first question/answer that popped up for me when trying to solve the same problem using ASP.NET MVC as the source of my data. I realize this doesn't solve the PHP question, but it is related enough to be valuable.
I am using ASP.NET MVC. The blog post from Greg Brant worked for me. Ultimately, you create an attribute, [HttpHeaderAttribute("Access-Control-Allow-Origin", "*")], that you are able to add to controller actions.
For example:
public class HttpHeaderAttribute : ActionFilterAttribute
{
public string Name { get; set; }
public string Value { get; set; }
public HttpHeaderAttribute(string name, string value)
{
Name = name;
Value = value;
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
filterContext.HttpContext.Response.AppendHeader(Name, Value);
base.OnResultExecuted(filterContext);
}
}
And then using it with:
[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
public ActionResult MyVeryAvailableAction(string id)
{
return Json( "Some public result" );
}
As Matt Mombrea is correct for the server side, you might run into another problem which is whitelisting rejection.
You have to configure your phonegap.plist. (I am using a old version of phonegap)
For cordova, there might be some changes in the naming and directory. But the steps should be mostly the same.
First select Supporting files > PhoneGap.plist
then under "ExternalHosts"
Add a entry, with a value of perhaps "http://nqatalog.negroesquisso.pt"
I am using * for debugging purposes only.
This might be handy for anyone who needs to an exception for both 'www' and 'non-www' versions of a referrer:
$referrer = $_SERVER['HTTP_REFERER'];
$parts = parse_url($referrer);
$domain = $parts['host'];
if($domain == 'google.com')
{
header('Access-Control-Allow-Origin: http://google.com');
}
else if($domain == 'www.google.com')
{
header('Access-Control-Allow-Origin: http://www.google.com');
}
If you're writing a Chrome Extension and get this error, then be sure you have added the API's base URL to your manifest.json's permissions block, example:
"permissions": [
"https://itunes.apple.com/"
]
I will give you a simple solution for this one. In my case I don't have access to a server. In that case you can change the security policy in your Google Chrome browser to allow Access-Control-Allow-Origin. This is very simple:
Create a Chrome browser shortcut
Right click short cut icon -> Properties -> Shortcut -> Target
Simple paste in "C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security.
The location may differ. Now open Chrome by clicking on that shortcut.
I've run into this a few times when working with various APIs. Often a quick fix is to add "&callback=?" to the end of a string. Sometimes the ampersand has to be a character code, and sometimes a "?": "?callback=?" (see Forecast.io API Usage with jQuery)
This is because of same-origin policy. See more at Mozilla Developer Network or Wikipedia.
Basically, in your example, you to need load the http://nqatalog.negroesquisso.pt/login.php page only from nqatalog.negroesquisso.pt, not localhost.
if you're under apache, just add an .htaccess file to your directory with this content:
Header set Access-Control-Allow-Origin: *
Header set Access-Control-Allow-Headers: content-type
Header set Access-Control-Allow-Methods: *
In Ruby on Rails, you can do in a controller:
headers['Access-Control-Allow-Origin'] = '*'
If you get this in Angular.js, then make sure you escape your port number like this:
var Project = $resource(
'http://localhost\\:5648/api/...', {'a':'b'}, {
update: { method: 'PUT' }
}
);
See here for more info on it.
You may make it work without modifiying the server by making the broswer including the header Access-Control-Allow-Origin: * in the HTTP OPTIONS' responses.
In Chrome, use this extension. If you are on Mozilla check this answer.
We also have same problem with phonegap application tested in chrome.
One windows machine we use below batch file everyday before Opening Chrome.
Remember before running this you need to clean all instance of chrome from task manager or you can select chrome to not to run in background.
BATCH: (use cmd)
cd D:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security
In Ruby Sinatra
response['Access-Control-Allow-Origin'] = '*'
for everyone or
response['Access-Control-Allow-Origin'] = 'http://yourdomain.name'
When you receive the request you can
var origin = (req.headers.origin || "*");
than when you have to response go with something like that:
res.writeHead(
206,
{
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Origin': origin,
}
);

How can I push a page from one MediaWiki to another SSL based wiki with self signed certificate using the Push extension?

https://www.mediawiki.org/wiki/Extension:Push
is an extension that will let you push pages from one MediaWiki toanother.
As documented in
https://www.mediawiki.org/wiki/Topic:Saza08eh1dcygs3c
I had trouble getting this to work with target Mediawikis that use SSL and self signed certificates.
Push would choke up with the message: Dateitransfer fehlgeschlagen: Authentifizierung auf https:///api.php ist fehlgeschlagen.
The issue is now solved and I am adding this question to make the solution available for Stackoverflow users to find.
First as outlined in https://www.mediawiki.org/wiki/Topic:Saza08eh1dcygs3c
https://github.com/BITPlan/Push/commit/cf393a32423bd8ae07af50a5587f847f20cfb9b9
has a commit with a few extra lines for error handling. The resulting message is:
Authentication at .../mediawiki/api.php(http-curl-error:SSL certificate problem: unable to get local issuer certificate) failed.
This is a major improvement in handling such situations - especially the debugging works better.
So the natural attempt to add:
ini_set("openssl.cafile","BITPlanValidCerts.pem")
ini-set("curl.cainfo","BITPlanValidCerts.pem")
didn't work - you have to set these in the php.ini file. A curl https:// test then works. But still no go with Mediawiki and the push extension.
https://github.com/BITPlan/Push/commit/3f68dd36a65ff6ad8c68df807c2c32311073dae4
fixes the issue by adding the curl.cainfo php ini setting to the curl options
getHttpRequest( $target,
array(
array(
'postData' => $requestData,
'postData' => $requestData,
'method' => 'POST',
'method' => 'POST',
- 'timeout' => 'default'
+ 'timeout' => 'default',
+ 'caInfo' => ini_get('curl.cainfo')
)
)
);
);
The same fix might also apply to similar situations where the upgrade advice:
https://www.mediawiki.org/wiki/Manual:Extension_support/1.17/ExtUpgrading
has been followed. MWHttpRequest will handle the caInfo option if it is supplied see https://doc.wikimedia.org/mediawiki-core/master/php/HttpFunctions_8php_source.html

logstash and centralised redis problems

I'm trying to get logstash working in a centralised setup using the docs as an example:
http://logstash.net/docs/1.2.2/tutorials/getting-started-centralized
I've got logstash (as indexer), redis, elasticsearch and standalone kibana3 running on my web server. I then need to run logstash as an agent on another server to collect apache logs and send them to the web server via redis. The number of agents will increase and the logs will vary, but for now I just want to get this working!
I need everything to run as a service so that all is well after reboots etc. All servers are running Ubuntu.
For all logstash instances (indexer and agent), I'm using the following init script (Ubuntu version, second gist):
https://gist.github.com/shadabahmed/5486949#file-logstash-ubuntu
For running redis as a service, I followed the instructions here:
http://redis.io/topics/quickstart (Installing redis more properly)
Elasticsearch is also running as a service.
On the web server, running redis-cli returns PONG correctly. Navigating to the correct Elasticsearch URL returns the correct JSON response. Navigating to the Kibana3 url gives me the dashboard, but no data. UFW is set to allow the redis port (at the moment from everywhere).
On the web server, my logstash.conf is:
input {
file {
path => "/var/log/apache2/access.log"
type => "apache-access"
sincedb_path => "/etc/logstash/.sincedb"
}
redis {
host => "127.0.0.1"
data_type => "list"
key => "logstash"
codec => json
}
}
filter {
grok {
type => "apache-access"
pattern => "%{COMBINEDAPACHELOG}"
}
}
output {
elasticsearch {
embedded => true
}
statsd {
# Count one hit every event by response
increment => "apache.response.%{response}"
}
}
From the agent server, I can telnet successfully to the web server IP and redis port. logstash is running. The logstash.conf file is:
input {
file {
path => "/var/log/apache2/shift.access.log"
type => "apache"
sincedb_path => "/etc/logstash/since_db"
}
stdin {
type => "example"
}
}
filter {
if [type] == "apache" {
grok {
pattern => "%{COMBINEDAPACHELOG}"
}
}
}
output {
stdout { codec => rubydebug }
redis { host => ["xx.xx.xx.xx"] data_type => "list" key => "logstash" }
}
If I comment out the stdin and stdout lines, I still don't get a result. The logstash logs do not give me any connection errors - only warnings about the deprecated grok settings format.
I have also tried running logstash from the command line (making sure to stop the demonised service first). The apache log file is correctly outputted in the terminal, so I know that logstash is accessing the log correctly. And I can write random strings and they are output in the correct logstash format.
The redis logs on the web server show no sign of trouble......
The frustrating thing is that this has worked once. One message from stdin made it all the way through to elastic search. That was this morning just after getting everything setup. Since then, I have had no luck and I have no idea why!
Any tips/pointers gratefully received... Solving my problem will stop me tearing out more of my hair which will also make my wife happy......
UPDATE
Rather than filling the comments....
Thanks to #Vor and #rutter, I've confirmed that the user running logstash can read/write to the logstash.log file.
I've run the agent with -vv and the logs are populated with e.g.:
{:timestamp=>"2013-12-12T06:27:59.754000+0100", :message=>"config LogStash::Outputs::Redis/#host = [\"XX.XX.XX.XX\"]", :level=>:debug, :file=>"/opt/logstash/logstash.jar!/logstash/config/mixin.rb", :line=>"104"}
I then input random text into the terminal and get stdout results. However, I do not see anything in the logs until AFTER terminating the logstash agent. After the agent is terminated, I get lines like these in the logstash.log:
{:timestamp=>"2013-12-12T06:27:59.835000+0100", :message=>"Pipeline started", :level=>:info, :file=>"/opt/logstash/logstash.jar!/logstash/pipeline.rb", :line=>"69"}
{:timestamp=>"2013-12-12T06:29:22.429000+0100", :message=>"output received", :event=>#<LogStash::Event:0x77962b4d #cancelled=false, #data={"message"=>"test", "#timestamp"=>"2013-12-12T05:29:22.420Z", "#version"=>"1", "type"=>"example", "host"=>"Ubuntu-1204-precise-64-minimal"}>, :level=>:info, :file=>"(eval)", :line=>"16"}
{:timestamp=>"2013-12-12T06:29:22.461000+0100", :level=>:debug, :host=>"XX.XX.XX.XX", :port=>6379, :timeout=>5, :db=>0, :file=>"/opt/logstash/logstash.jar!/logstash/outputs/redis.rb", :line=>"230"}
But while I do get messages in stdout, I get nothing in redis on the other server. I can however telnet to the correct port on the other server, and I get "ping/PONG" in telnet, so redis on the other server is working..... And there are no errors etc in the redis logs.
It looks to me very much like the redis plugin on the logstash shipper agent is not working as expected, but for the life of me, I can't see where the breakdown is coming from.....