Read an Amazon Cloudfront API Result in PHP - php

I've got a PHP script that submits Invalidation requests to Amazon's Cloudfront via API's.
I can capture the response, but it comes back as text basically looking like this:
HTTP/1.0 201 Created
Content-Type: text/xml
Location: https://cloudfront.amazonaws.com/2012-07-01/distribution/distribution ID/invalidation/invalidation ID
<Invalidation xmlns="http://cloudfront.amazonaws.com/doc/2012-07-01/">
<Id>IDFDVBD632BHDS5</Id>
<Status>InProgress</Status>
<CreateTime>2013-04-16T19:37:58Z</CreateTime>
<InvalidationBatch>
<Paths>
<Items>
<Path>/image1.jpg</Path>
</Items>
</Paths>
<CallerReference>20130416090001</CallerReference>
</InvalidationBatch>
</Invalidation>
I basically just want to grab the status value, and I suppose I could do it via Regex or some string manipulation, but I'm assuming there is a better way to convert the returned data into an object and access it properly.
I tried:
$dom = new DOMDocument();
$dom->loadXML($data);
But $data doesn't work because it literally contains the header portion "HTTP/1.0 201..."
Anyone know the proper way to handle this?

What script are you using? Have you considered using the AWS SDK for PHP (https://github.com/aws/aws-sdk-php)?
Using the AWS SDK for PHP you could do the following:
// Instantiate a CloudFront client
$cloudfront = \Aws\CloudFront\CloudFrontClient::factory(array(
'key' => 'your-aws-access-key-id',
'secret' => 'your-aws-secret-key',
));
// Get the status of an invalidation
$invalidationStatus = $cloudfront->getInvalidation(array(
'DistributionId' => 'your-distribution-id',
'Id' => 'your-invalidation-id',
))->get('Status');

Usually the Http client library should do that, you didn't mention the used one.
Still parsing that response should be simple as:
$dom->loadXML(substr($data, strpos("\n\n", $data)+2))

Got this figured out by doing the following.
$resp = substr($resp, strpos($resp, "\r\n\r\n")+4); // This strips out the header
$outputxml = simplexml_load_string($resp); // Converts it to an object in PHP which can be fed back more easily

Related

Don't pass OAuth in POST variables - PHP OAuth Pecl library

I am working with a third party service that requires me to authenticate through OAuth1 to make requests. I can successfully authenticate and get data back with most of their calls using GET, however some calls they require POST and this is where the problem lies. To authenticate I am using the below:
$oauth = new OAuth(MY_KEY,MY_SECRET);
$oauth->setNonce(rand());
$oauth->setToken('','');
Then for a GET call I am doing something like below:
$array = array(
'partnerId'=>'1234'
);
$call = $oauth->fetch("https://domain.co.uk/api/getInfo/",$array);
$data = $oauth->getLastResponse();
This all works perfectly, and I can print out the $data
However with POST calls:
$oauth = new OAuth(MY_KEY,MY_SECRET);
$oauth->setNonce(rand());
$oauth->setToken('','');
$oauth->enableDebug();
$oauth->setAuthType(OAUTH_AUTH_TYPE_AUTHORIZATION);
$array = array(
'rid' => "$restaurantId",
'datetime' => "$datetime",
'partysize' => $covers,
'timesecurityID' => "$securityId",
'resultskey' => "$resultskey"
);
$call = $oauth->fetch("https://domain.co.uk/api/booking/?pid=1234&st=0",$array,OAUTH_HTTP_METHOD_POST);
$data = $oauth->getLastResponse();
I keep getting the error: Invalid Consumer Signature
Speaking to their tech guy he suggested
Your sbs value indicates that you’re signing with all of the POST
parameters, whereas you only need to sign with the query string. In
this case it would be “pid=1234&st=0”. Unfortunately, I’m not
familiar with the PHP libs and don’t have any recommendations on how
to alter the behavior.
and also mentioned common previous problems with a PHP implementation are:
The PHP HTTP lib will drop the query string once the method is
changed from GET to POST.
The PHP oAuth lib will use the post data
to sign the request rather than the query string or maybe both.
If I dump out the headers I get:
[sbs] => POST&https%3A%2F%2Fdomain.co.uk%2Fapi%2Fbooking%2F&datetime%3D2013-02-21T10%253A30%253A00%26oauth_consumer_key%3DMySiteV3TT%26oauth_nonce%3D1213111151%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1360835965%26oauth_token%3D%26oauth_version%3D1.0%26partysize%3D2%26pid%3D1531%26resultskey%3DfoqgEnYK%25252bIzRd6BV3T8eGQ%25253d%25253d%26rid%3D31852%26st%3D0%26timesecurityID%3D349367809
[headers_sent] => POST /api/booking/?pid=1234&st=0 HTTP/1.1
It looks like it is sending the OAuth data with the rest of the post, I just want this sent in the Authorization header (which it is also sending)
Authorization: OAuth oauth_consumer_key="MySite",oauth_signature_method="HMAC-SHA1",oauth_nonce="1772854358",oauth_timestamp="1360768712",oauth_version="1.0",oauth_token="",oauth_signature="2%2B7xb%2BJ5cdbUDC5UHfsdfsNpFM1pE%3D"
So I think I need to strip the OAuth data from the post request but keep it as a Authorization Header but just can't find the magic way to do that!
I've seen this. In fetch(), try urlencoding your $array and passing it in as a string of the form:
rid=[restaurantId]&datetime=[datetime]&...
Also give the header (final parameter of fetch()):
Content-Type: application/x-www-form-urlencoded

php soap empty output

I'm an experienced PHP programmer but I have actually no clue about SOAP. Now I must use it because my customer needs an automatic generating of DHL batch labels. I need some simple and effective help.
So I send a raw XML request to DHL, I have copied the message from their sample programm but I get always an empty result (no error). My PHP code goes like:
require_once('nusoap/lib/nusoap.php');
$endpoint = "https://test-intraship.dhl.com/intraship.57/jsp/Login_WS.jsp";
$client = new nusoap_client($endpoint, false);
$msg = $client->serializeEnvelope("
<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\"
xmlns:cis=\"http://dhl.de/webservice/cisbase\" xmlns:de=\"http://de.ws.intraship\">
<soap:Header>
<cis:Authentification><cis:user>bzalewski</cis:user>
(...)
");
$result=$client->send($msg, $endpoint);
echo $result;
As said, the message is just copied so it must be OK.
I tried alternatively with another endpoint: http://test-intraship.dhl.com/ws/1_0/ISService/DE.wsdl, but also no result (no error).
Please help.
When using soap_client you do not need to pass raw XML. Instead you look at the WSDL and decide which web service function you want to call, and what parameters it needs. Then you create a soap client object, by passing the wsdl url and whether you want tracing or not (it helps to debug and stuff). Then use this soap client object to call whichever web service function you want to call. If there are parameters needed for the function call, pass them as an array. I have posted a sample code below which uses the WSDL you provided and calls its getVersion function. Note that this function does not need arguments so I am not passing anything. Hope this helps you get started..
<?
$client = new SoapClient('http://test-intraship.dhl.com/ws/1_0/ISService/DE.wsdl', array('trace' => 1));
$res = $client->getVersion();
print_r($res);
?>
This returns following value from the DHL web service:
stdClass Object
(
[Version] => stdClass Object
(
[majorRelease] => 1
[minorRelease] => 0
[build] => 14
)
)
Does the web server respond with a status 200? You said you get an empty response right?
Use this free GUI tool (http://webservicestudio.codeplex.com/) to make webservice call and visualize. You can easily load up the WSDL and start making calls.
By the way working 2 jobs and study is good stuff man! Keep it up.

XML-RPC pinging (google and others)

I am trying to ping (SEO tactic called "ping" is used for new content to get robots index it faster) Google in PHP. Only thing I know is that I need to send my request to following url:
http://blogsearch.google.com/ping/RPC2
Probably I can use PHP XML-RPC functions. I don't know how to format my request and which method to use.
As far as you're concerned to do the XML-RPC request (Example #1).
If you follow the specification of a pingback, it would look like this:
$sourceURI = 'http://example.com/';
$targetURI = 'http://example.com/';
$service = 'http://blogsearch.google.com/ping/RPC2';
$request = xmlrpc_encode_request("pingback.ping", array($sourceURI, $targetURI));
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: text/xml",
'content' => $request
)));
$file = file_get_contents($service, false, $context);
$response = xmlrpc_decode($file);
if ($response && xmlrpc_is_fault($response)) {
trigger_error("xmlrpc: $response[faultString] ($response[faultCode])");
} else {
print_r($response);
}
Which would give you the following output:
Array
(
[flerror] =>
[message] => Thanks for the ping.
)
Generally, if you don't know which method you call, you can also try XML-RPC Introspection - but not all XML-RPC servers offer that.
You asked in a comment:
According to specs, $targetURI should be: "The target of the link on the source site. This SHOULD be a pingback-enabled page". How can I make pingback enabled page, or more important, what is that actually?
A pingback enabled site is a website that announces an XML-RPC pinbback service as well. That's done with the HTMl <link> element in the <head> section. Example:
<link rel="pingback" href="http://hakre.wordpress.com/xmlrpc.php" />
The href points to an XML-RPC endpoint that has the pingback.ping method available.
Or it's done by sending a specifc HTTP response header:
X-Pingback: http://charlie.example.com/pingback/xmlrpc
See pingback-enabled resource.
So if you ping others, others should be able to ping you, too.
Ummm, I think we should use weblogUpdates.ping or weblogUpdates.extendedPing instead of pingback.ping to ping a site about new content.
pingback.ping is for a new link from one site to another, not for new content.
I think you should use weblogUpdates.extendedPing with google blog search, weblogs, Pingomatic and weblogUpdates.ping for other server. I created a ping tool but some server return an error with http and https, i cannot give a bug Online rpc xml ping

PHP Soap - How to remove xsi:type= from XML tag

I'm sending a SOAP request that looks like:
<SOAP-ENV:Body>
<api:GetOrder xsi:type="SOAP-ENC:Struct">
<api_orderId xsi:type="xsd:int">1234</api_orderId>
</api:GetOrder>
</SOAP-ENV:Body>
But needs to look like this (SoapUI generated):
<soapenv:Body>
<api:GetOrder>
<api:orderId>1234</api:orderId>
</api:GetOrder>
</soapenv:Body>
My PHP Code:
$client = $this->getConnection();
$soap_options = array('soapaction' => $config->getValue('soapaction_url') . 'GetOrder');
$obj = new stdClass();
$obj->api_orderId = 59698;
$results = $client->__soapCall('GetOrder', array(new SoapParam($obj, "api:GetOrder")), $soap_options);
2 questions really:
1) How can I remove the "xsi:type" from the request? (If I add xsi:type in to my SoapUI request, I get back a "400 Bad Request"
2) Instead of "api_orderId" I need to send "api:orderId", but I can't name an object with a colon, so do I have to pass the name and value as an array somehow?
Appreciate any help, thank you.
EDIT:
I wasn't able to figure out any other way to send these requests and I essentially ended up doing as Mr.K suggested below.
I wrote a custom class to extend SoapClient. Then overrode the __doRequest method to send my own custom SOAP request.
The only downside is that SOAP no longer returns me an array of objects, so I also had to parse the XML of the SOAP response.
Also I suspect that the performance of doing it this way is a bit slower, but I didn't notice it.
Try with Simple XML parsing, and create the new request as you like.
Read the tag values from Original request, assign those values to a new XML object using parsing. You can create string of XML message and load it as an XML object in PHP.
Just like get it from there, put it inside this..and Send!..

Need help understanding Google Maps API URL?

i am kind of new to API thing, and i need help understanding on what exactly is happening with the below Code.
$address = 'Bhatkal, Karnataka, India';
$requestUrl = 'http://maps.google.com/maps/geo?output=xml&key=aabbcc&oe=utf-8&q='.urlencode($address);
$xml = simplexml_load_file($requestUrl);
i understand that HTTP is capable of sending Request and getting response in return isn't it? what i am unable to understand is the third and last function that is $xml = simplexml_load_file($requestUrl); when i do a print_r($xml) i get an object in return which prints all the object details i got back as response,
how does the function process the
URL?
does it use CURL (i have very less idea about what is CURL).
and where do i look up for Google Maps API URL?
That function does not process the request (nor the URL), only the response, Google processes the URL that, the function just "visit's" it. You can do as well: here. The XML file you see here is ending up in the variable $xml, parsed.
EDIT: the URL in this post is not working too well, because of the key parameter
simplexml_load_file internally uses the fopen wrapper and opens the remote xml that would be produced by the url and then converts into an array for php to easily use.
The response object will help you to extract the data from the response.
Check out the details of Google Maps API

Categories