Using file_get_contents with basic auth and SSL - php

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;

Related

get request for local ip URL using file_get_contents() is not working

If I call an URL directly on browser, i will get response, but when I try to get contents from this URL using file_get_contents or CURL it returns nothing, get empty page (here am using url start with local ip address .eg :http://192.168.x.xxx/device/reader-config?action=get).
Is there any connection with local ip?
here is my code,
$url = 'http://192.168.x.xxx/device/reader-config?action=get';
$username = 'username';
$password = 'password';
$context = stream_context_create(array('http' =>
array('header' => "Authorization: Basic " . base64_encode("$username:$password"))
));
$rawdata = file_get_contents($url, false, $context);
print_r($rawdata);

PHP : file_get_contents not working properly

I have a html page which sends a get request to php.
This is the code snippet in the php file
<?php
// Create a stream
$opts = array(
'http'=>array(
'method'=>'GET',
)
);
$context = stream_context_create($opts);
//echo("http://services.my511.org/Transit2.0/GetNextDeparturesByStopName.aspx?token={$_GET['token']}&agencyName={$_GET['agency']}&stopName={$_GET['stopname']}");
// Open the file using the HTTP headers set above
$file = file_get_contents("http://services.my511.org/Transit2.0/GetNextDeparturesByStopName.aspx?token={$_GET['token']}&agencyName={$_GET['agency']}&stopName={$_GET['stopname']}", false, $context);
//$file = file_get_contents("http://services.my511.org/Transit2.0/GetNextDeparturesByStopName.aspx?token=123-456-789&agencyName=SF-MUNI&stopName=The%20Embarcadero%20and%20Folsom%20St", false, $context);
echo(json_encode(simplexml_load_string($file)));
?>
Developer Console Output :
Warning: file_get_contents(http://services.my511.org/Transit2.0/GetNextDeparturesByStopName.aspx?token=123-456-789&amp;agencyName=BART&amp;stopName=Powell St. (SF)): failed to open stream: HTTP request failed! HTTP/1.1 400 BAD_REQUEST
As you can see from the developer console output, in the url request sent there are BART&amp;stopName amp;amp; being inserted in the url which I'm not doing. The request fails due to this. Any solution around this?
Try the below code, this will make sure that you're stuff is properly URI encoded.
$params = [
'token' => $_GET['token'],
'agencyName' => $_GET['agency'],
'stopName' => $_GET['stopname']
];
$file = file_get_contents(sprintf("http://services.my511.org/Transit2.0/GetNextDeparturesByStopName.aspx?%s", http_build_query($params));
echo(json_encode(simplexml_load_string($file)));
Try this one:
$data = array('token'=>$_GET['token'],
'stopname'=>$_GET['stopname'],
'agency'=>$_GET['agency'],
);
$url = "http://services.my511.org/Transit2.0/GetNextDeparturesByStopName.aspx?".$data;
$file = file_get_contents($url, false, $context);
echo(json_encode(simplexml_load_string($file)));
Note: I have modified my answer base on your comment.
You can try this way to clean out the url:
<?php
// Create a stream
$opts = array(
'http'=>array(
'method'=>'GET',
)
);
$context = stream_context_create($opts);
$url= "http://services.my511.org/Transit2.0/GetNextDeparturesByStopName.aspx?";
$query = array(
"token" =>$_GET['token'],
"agencyName"=>$_GET['agency'],
"stopName"=>$_GET['stopname']
);
$url = $url.http_build_query($query);
$url = rawurldecode($url);
print_r($url);
$file = file_get_contents($url, false, $context);
echo(json_encode(simplexml_load_string($file)));
?>

Basic authentication with Apache

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.

PHP client side Digest authentication with qop=auth-int

Does anyone know any PHP library for connecting remote servers that use Digest authentication method with qop=auth-int?
Or, if not, now should I build the A2 for the result? It says in RFC 2617 that I need to use an entity body, but what is this? I am just sending a GET request, it does not have any body at all.
Thanks in advance.
I was looking for the answer to your question too, for requests other than GET.
Perheps you could use something like:
$entityBody = file_get_contents('php://input');
I have not tested if it works, but looking at the answer to this question it would make sence to me that it should.
Note that this stream can only be read once [1] so if you need it again elsewhere you should reuse the $entityBody variable.
From my answer of a similar question:
I implemented the client-side Digest Authentication in PHP with cURL recently. Here's the full code:
<?php
error_reporting(E_ALL);
ini_set( 'display_errors','1');
$url = "https://api.example.com/ws.asmx/do";
$username = "username";
$password = "pwd";
$post_data = array(
'fieldname1' => 'value1',
'fieldname2' => 'value2'
);
$options = array(
CURLOPT_URL => $url,
CURLOPT_HEADER => true,
CURLOPT_VERBOSE => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false, // for https
CURLOPT_USERPWD => $username . ":" . $password,
CURLOPT_HTTPAUTH => CURLAUTH_DIGEST,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($post_data)
);
$ch = curl_init();
curl_setopt_array( $ch, $options );
try {
$raw_response = curl_exec( $ch );
// validate CURL status
if(curl_errno($ch))
throw new Exception(curl_error($ch), 500);
// validate HTTP status code (user/password credential issues)
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($status_code != 200)
throw new Exception("Response with Status Code [" . $status_code . "].", 500);
} catch(Exception $ex) {
if ($ch != null) curl_close($ch);
throw new Exception($ex);
}
if ($ch != null) curl_close($ch);
echo "raw response: " . $raw_response;
?>
If you're doing a GET request, you shouldn't need auth-int. If your service requires it, you can assume an empty entity-body (thus you can just do md5("") for this part of the A2 hash).

Twitter Oauth via PHP WITHOUT cURL

My server does not support cURL.
I want to update my status via php.
How to do that without cURL?
Again: WITHOUT CURL!
Here’s how you can tweet without using cURL with PHP.
We have two options-
With stream context
Php function stream_context_create has the magic. It creates and returns a stream context with any options passed.
<?php
set_time_limit(0);
$username = 'username';
$password= 'WHATEVER';
$message='YOUR NEW STATUS';
function tweet($message, $username, $password)
{
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => sprintf("Authorization: Basic %s\r\n", base64_encode($username.':'.$password)).
"Content-type: application/x-www-form-urlencoded\r\n",
'content' => http_build_query(array('status' => $message)),
'timeout' => 5,
),
));
$ret = file_get_contents('http://twitter.com/statuses/update.xml', false, $context);
return false !== $ret;
}
echo tweet($message, $username, $password);
?>
With socket programing
PHP has a very capable socket programming API. These socket functions include almost everything you need for socket-based client-server communication over TCP/IP. fsockopen opens Internet or Unix domain socket connection.
<?php
$username = 'username';
$password= 'WHATEVER';
$message='YOUR NEW STATUS';
$out="POST http://twitter.com/statuses/update.json HTTP/1.1\r\n"
."Host: twitter.com\r\n"
."Authorization: Basic ".base64_encode ("$username:$password")."\r\n"
."Content-type: application/x-www-form-urlencoded\r\n"
."Content-length: ".strlen ("status=$message")."\r\n"
."Connection: Close\r\n\r\n"
."status=$msg";
$fp = fsockopen ('twitter.com', 80);
fwrite ($fp, $out);
fclose ($fp);
?>
Taken from here: http://www.motyar.info/2010/02/update-twitter-status-with-php-nocurl.html
Hope htis helps.
If you need any more help let me know as i am a php programmer myself.
thanks
PK
<?php
/*
* using file_get_contents
*/
$key = '';
$secret = '';
$api_endpoint = 'https://api.twitter.com/1.1/search/tweets.json?q=news'; // endpoint must support "Application-only authentication"
// request token
$basic_credentials = base64_encode($key.':'.$secret);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Authorization: Basic '.$basic_credentials."\r\n".
"Content-type: application/x-www-form-urlencoded;charset=UTF-8\r\n",
'content' => 'grant_type=client_credentials'
)
);
$context = stream_context_create($opts);
// send request
$pre_token = file_get_contents('https://api.twitter.com/oauth2/token', false, $context);
$token = json_decode($pre_token, true);
if (isset($token["token_type"]) && $token["token_type"] == "bearer"){
$opts = array('http' =>
array(
'method' => 'GET',
'header' => 'Authorization: Bearer '.$token["access_token"]
)
);
$context = stream_context_create($opts);
$data = file_get_contents($api_endpoint, false, $context);
print $data;
}
?>
You can do that using the oauth pecl extension. See here for details.
EDIT: you need to install the pecl extension

Categories