I'm working with an api that returns a number of useful variables within the header response, for example with...
Pragma → no-cache
Server → Apache
X-Pages → 1424
... I'd like to use the X-Pages variable to form some further logic. How do I retrieve this variable and use it within my php script?
My api currently call looks like this:
$username = "XXXXXXXX";
$password = "XXXXXXXX";
$remote_url = 'XXXXXXXX';
$headers = array();
$headers[] = "Authorization: Basic " . base64_encode("$username:$password");
$opts = array(
'http'=>array(
'method'=>"GET",
'header' => $headers
)
);
$context = stream_context_create($opts);
$file1 = file_get_contents($remote_url, false, $context);
Thanks,
Matt
You can find the response headers in $http_response_header after making the call to file_get_contents - it'll be automatically populated in the local scope.
Related
I'm attempting a GET request using SSL and basic auth using the file_get_contents function:
$username = "XXXXXXXXXX";
$password = "XXXXXXXXXX";
$url = "https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api";
$context = stream_context_create(array("http" => array("header" => "Authorization: Basic " . base64_encode("$username:$password"))));
$data = file_get_contents($url, false, $context);
echo $data;
Here's the error message I get:
Warning: file_get_contents(https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api): failed to open stream: HTTP request failed! HTTP/1.0 500 Server Error...
I've already confirmed that openssl is enabled:
And we might as well get this out of the way up-front:
Why don't you just use cURL?
I could. But I also want to figure out why file_get_contents isn't working. I like the relative simplicity of file_get_contents. Call me crazy.
Curiosity is a good thing so it's cool to dig this problem without falling back to cURL before fixing this problem.
<?php
$username = "XXXXXXXXXX";
$password = "XXXXXXXXXX";
$url = "https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api";
$context = stream_context_create(array(
"http" => array(
"header" => "Authorization: Basic " . base64_encode("$username:$password"),
"protocol_version" => 1.1, //IMPORTANT IS HERE
)));
$data = file_get_contents($url, false, $context);
echo $data;
The fact is the server does not support HTTP/1.0. So you haven't any problem with SSL/TLS nor with your user agent. It is just the server that support HTTP from 1.1.
As said in the stream_context_create documentation the default protocol_version used in stream_context_create is 1.0. That's why you got an error 500.
EDIT : My bad, don't see this is not curl. Try with this
$username = "XXXXXXXXXX";
$password = "XXXXXXXXXX";
$url = "https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api";
$context = stream_context_create(array(
"http" => array("header" => "Authorization: Basic " . base64_encode("$username:$password")),
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
)));
$data = file_get_contents($url, false, $context);
echo $data;
The Problem
Our GeoServer access is being proxied by a PHP script that handles the authorization/authentication. This works fine for WMS/WFS requests within an OpenLayers map, but not so much when trying to download a zipped-up shapefile the same way: the response ALWAYS returns the request as text.
I know that my URL is correct, because when I take the prepped GeoServer URL and enter credentials manually, I get the desired "Save As" popup:
When running it through the proxy, however, I get no dialog and a bunch of garbage:
The Solution Attempts
Most suggestions I've found point to:
stream_context_create
Setting Content-Disposition in the header
readfile
The Code
URL Prep
Not sure if it matters, but here is how I am preparing the URL to send to GS (and that URL works fine sans proxy, manual credentials):
// Encode geoserver credentials
$auth = base64_encode('username:password');
// Base URL and parameters
$url = 'https://example.com/mygeoserverpath/wfs?';
$query = '';
// Extract arguments
$orig_proxy_url = $_SERVER['REQUEST_URI'];
$orig_query = parse_url($orig_proxy_url, PHP_URL_QUERY);
parse_str($orig_query, $orig_args);
// Loop over arguments, append to base url
foreach ($orig_args as $key => $value) {
if ($key === 'cql_filter') {
$value = rawurlencode($value);
}
$query = $query . '&' . $key . '=' . $value;
}
$url = $url . $query;
Using stream_context_create with Other Stuff
$opts = array(
'http' => array (
'method' => "GET",
'header' => "Authorization: Basic $auth"
. "Content-Description: File Transfer\r\n"
. "Content-Type: application/zip\r\n"
. "Content-disposition: attachment; filename=testing.zip\r\n"
));
$ctx = stream_context_create($opts);
...in conjunction with some other attempts:
// file_get_contents returns text
$output = file_get_contents($url,false,$ctx);
// readfile returns text
readfile($url,false,$ctx);
// fopen/passthru returns text
$fp = fopen($url,'r',0,$ctx);
fpassthru($fp);
exit;
Setting Headers Directly
I could get the Save dialog to appear this way, but it always was an empty zip.
header("Content-Description: File Transfer");
header("Content-Type: application/zip");
header("Content-disposition: attachment; filename=testing.zip");
header("Authorization: Basic $auth");
cURL
Not much to comment on here as I've been saving it as a very last resort.
Now What?
It shouldn't be this difficult considering GS does 99% of the work creating the zipped-up shapefile, but I'm running out of things to try. Any suggestions would be appreciated!
Sounded like this worked:
$opts = array(
'http' => array (
'method' => "GET",
'header' => "Authorization: Basic $auth"
));
header("Content-Disposition: attachment; filename=testing.zip");
$ctx = stream_context_create($opts);
$fp = fopen($url,'r',0,$ctx);
fpassthru($fp);
I have the API request as outlined below which works fine (given the correct replacement of "xxxyyy"!) however I want to perform this call simultaneously with up to 5-10 different remote URLs. In the example below I've shown just 1 remote URL however I have an array of 10,000 urls which I would like to query as quickly as possible, all of which return the same structure in JSON.
After researching the topic I believe this can be done in PHP using Curl Multi, does anyone know if this is true, if so how would I go about this so i can call say 10 at once rather than each one individually?
<?php
$username = "xxxyyyxxxyyyxxxyyyxxxyyy";
$password = "xxxyyyxxxyyyxxxyyyxxxyyyxxxyyyxxxyyyxxxyyyxxxyyy";
$remote_url_1 = 'https://xxxyyyxxxyyyxxxyyyxxxyyy_1.json';
{
$headers = array();
$headers[] = "Authorization: Basic " . base64_encode("$username:$password");
$headers[] = "X-Page:" . $pages;
$opts = array(
'http'=>array(
'method'=>"GET",
'header' => $headers
)
);
$context = stream_context_create($opts);
$file1 = file_get_contents($remote_url, false, $context);
$data = json_decode($file1, true);
$data2 = (array_values($data));
$orderline_id = $data2[0];
$orderline_sale_number = $data2[1];
$orderline_status = $data2[2];
$orderline_notes = $data2[3];
}
}
?>
I need to pass these headers into the $context variable, i tried using putting the values into an array and then passing it into stream_context_create() function but i get http warnings from the file_getcontents function
$prod_id = 4322;
$tnxRef = "RT45635276GHF76783AC";
$mackey = "ADECNH576748GH638NHJ7393MKDSFE73903673";
$agent = $_SERVER['HTTP_USER_AGENT'];
$hash = hash('SHA512', $prod_id.$txnRef.$mackey);
$headers = array(
'http'=>(
'method'=>'GET',
'header'=>'Content: type=application/json \r\n'.
'$agent \r\n'.
'$hash'
)
)
stream_context_create($headers)
$url_returns = file_get_contents("https://test_server.com/test_paydirect/api/v1/gettransaction.json?productid=$prod_id&transactionreference=$txnRef&amount=$amount", false, $context);
$json = json_decode($url_returns, true);
Error:
[function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request`
Thats the error i get, can somebody please help with a definitive example.
You have several errors in your code.
The server returns 400 Bad Request, because your code would result in this incorrect HTTP request:
GET /test_paydirect/api/v1/gettransaction.json?productid=4322&transactionreference=RT45635276GHF76783AC&amount= HTTP/1.1
Host: test_server.com
Content: type=application/json
$agent
$hash
The errors are:
Variable expressions are not evaluated within single quotes
$amount is not set in your code example
The header is Content-Type: and not Content: type=
All headers (agent, hash) must have their corresponding name
Here is an example that should work:
$context = stream_context_create(array(
'http' => array(
'method' => 'GET',
'agent' => $agent,
'header' => "Content-Type: application/json\r\n"
. "X-Api-Signature: $hash"
)
)
);
Please note: X-Api-Signature is just an example - it depends on the API you are using how the API key header is named and how the hash is calculated. You should find this information in the Docs of your API!
I have basic authentication enabled on an Apache server. The server is hosting an API that I implemented and I want to do is call this API from my PHP script. I got as far as figuring out how to create a header:
$user = 'my_name_api';
$pwd = 'xxxxxxxxx';
$auth_string = $user . ':' . $pwd;
$auth_b64 = base64_encode($auth_string);
$header = 'Authorization: Basic ' . $auth_b64;
How do I include the $header in my API calls? I am looking for something other than cURL, and I am NOT using any environments like zend, etc. (saw some example for Zend, etc., but I am not using any of those).
Have you tried fopen / file_get_contents?
Start here: http://php.net/manual/en/function.fopen.php
or here: http://www.php.net/manual/en/function.file-get-contents.php
and let me know how it goes...
airyt
If you don't need SSL or proxy support, you can use file_get_contents() with a stream context. The stream context can contain HTTP headers:
$opts = array
(
'http'=>array
(
'method' => "GET",
'header' => "Authorization: ..."
)
);
$context = stream_context_create($opts);
$file = file_get_contents('http://www.example.com', false, $context);
More on this here.