Make a HTTPS request through PHP and get response - php

I want to make HTTPS request through PHP to a server and get the response.
something similar to this ruby code
http = Net::HTTP.new("www.example.com", 443)
http.use_ssl = true
path = "uri"
resp, data = http.get(path, nil)
Thanks

this might work, give it a shot.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
// Set so curl_exec returns the result instead of outputting it.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Get the response and close the channel.
$response = curl_exec($ch);
curl_close($ch);
for more info, check
http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/

To open HTTPS stream I could only work it out using both HTTP and SSL context options…
Thus something like:
<?php
$postdata = http_build_query(
array(
'var1' => 'some content',
'var2' => 'doh'
)
);
$opts = array(
'ssl' => array(
'verify_peer' => false,
'verify_peername' => false
// Instead ideally use
// 'cafile' => 'path Certificate Authority file on local filesystem'
),
'http' => array(
'method' => 'POST',
'header' =>
'Content-type: application/x-www-form-urlencoded'."\r\n".
''
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents('https://example.com/submit.php', false, $context);
// A Good friend
var_dump($http_response_header);
?>

The Zend Framework has a nice component called Zend_Http_Client which is perfect for this kind of transaction.
Under the hood it uses curl to make requests, but you'll find Zend_Http_Client has a much nicer interface to work with and is easier to configure when you want to add custom headers or work with responses.
If all you want to do is retrieve the page contents with minimal work, you may be able to do the following, depending on your server's configuration:
$data = file_get_contents('https://www.example.com/');

Example how to use HttpRequest to post data and receive the response:
<?php
//set up variables
$theData = '<?xml version="1.0"?>
<note>
<to>my brother</to>
<from>me</from>
<heading>hello</heading>
<body>this is my body</body>
</note>';
$url = 'http://www.example.com';
$credentials = 'user#example.com:password';
$header_array = array('Expect' => '',
'From' => 'User A');
$ssl_array = array('version' => SSL_VERSION_SSLv3);
$options = array(headers => $header_array,
httpauth => $credentials,
httpauthtype => HTTP_AUTH_BASIC,
protocol => HTTP_VERSION_1_1,
ssl => $ssl_array);
//create the httprequest object
$httpRequest_OBJ = new httpRequest($url, HTTP_METH_POST, $options);
//add the content type
$httpRequest_OBJ->setContentType = 'Content-Type: text/xml';
//add the raw post data
$httpRequest_OBJ->setRawPostData ($theData);
//send the http request
$result = $httpRequest_OBJ->send();
//print out the result
echo "<pre>"; print_r($result); echo "</pre>";
?>

There are 2 examples, GET and POST methods, but they both require the HttpRequest library to be included.
If you don't have the HttpRequest library included, kindly check this answer on how to include it: HttpRequest not found in php
GET example:
<?php
$r = new HttpRequest('http://example.com/feed.rss', HttpRequest::METH_GET);
$r->setOptions(array('lastmodified' => filemtime('local.rss')));
$r->addQueryData(array('category' => 3));
try {
$r->send();
if ($r->getResponseCode() == 200) {
file_put_contents('local.rss', $r->getResponseBody());
}
} catch (HttpException $ex) {
echo $ex;
}
?>
Post Example
<?php
$r = new HttpRequest('http://example.com/form.php', HttpRequest::METH_POST);
$r->setOptions(array('cookies' => array('lang' => 'de')));
$r->addPostFields(array('user' => 'mike', 'pass' => 's3c|r3t'));
$r->addPostFile('image', 'profile.jpg', 'image/jpeg');
try {
echo $r->send()->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>

Related

My page won't answer the Messenger call

I'm developing some code that answers via Facebook Messenger and I use this piece of code to handle the answer and answer back:
if(isset($_REQUEST['hub_verify_token'])) {
if ($_REQUEST['hub_verify_token'] === A::VERIFY_TOKEN) {
echo $_REQUEST['hub_challenge'];
exit;
}
}
$input = json_decode(file_get_contents('php://input'), TRUE);
$sender_id = $input['entry'][0]['messaging'][0]['sender']['id'];
$message_text = $input['entry'][0]['messaging'][0]['message']['text'];
$fb_handler = new FBHandler($sender_id);
/*$to_send = array(
'recipient' => array('id' => $sender_id ),
'message' => array('text' => "Hi" )
);*/
$to_send = $fb_handler->talk($message_text);
$ch = curl_init('https://graph.facebook.com/v2.6/me/messages?access_token='.A::ACCESS_TOKEN);
curl_setopt_array($ch, array(
CURLOPT_POSTFIELDS => json_encode($to_send),
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HTTPHEADER => array('Content-Type: application/json')
));
$response = curl_exec($ch);
error_log($response['error']);
curl_close($ch);
What I don't understand is why the commented $to_send works but the non-commented not, because the code in the A class is correct, it composes correctly the array.
So I came up with an idea and I'm asking you if it's correct (because I found nothing in the Facebook Developers documentation): is it possible that the array that will be sent to Messenger has to be composed in the same set of instructions?
I know it sounds ridiculous, but I dunno what else to think.
Also I noticed that error_log doesn't work: nothing has been written in the php_errorlog file. What's happening?

Recaptcha missing-input-response

I have a problem with google reCaptcha.
Here is my php code:
$secret = 'SECRET_KEY';
$response = $_POST['g-recaptcha-respone'];
$remoteip = $_SERVER['REMOTE_ADDR'];
$url = "https://www.google.com/recaptcha/api/siteverify?secret=$secret&response=$response&remoteip=$remoteip";
$result_json = file_get_contents($url);
$resulting = json_decode($result_json, true);
print_r($resulting);
if($resulting['success']) {
//Success
}
input of print_r is: Array ( [success] => [error-codes] => Array ( [0] => missing-input-response ) )
How to solve this problem?
Thanks for answers
Please note : g-recaptcha-respone != g-recaptcha-response
Google reCatcha API you might need to specify additional parameters to the file_get_contents function call, setting the context options specifically for SSL (If site has SSL).
// If submitted check response
if ($_POST["g-recaptcha-response"]) {
// Input data
$secret = 'SECRET_KEY';
$response = $_POST['g-recaptcha-response'];
$remoteip = $_SERVER['REMOTE_ADDR'];
$url = "https://www.google.com/recaptcha/api/siteverify";
$post_data = http_build_query(
array(
'secret' => $secret,
'response' => $response,
'remoteip' => $remoteip
)
);
$options=array(
// If site has SSL then
'ssl'=>array(
// In my case its /etc/ssl/certs/cacert.pem
'cafile' => '/path/to/cacert.pem',
'verify_peer' => true,
'verify_peer_name' => true,
),
'http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $post_data
)
);
$context = stream_context_create( $options );
$result_json = file_get_contents( $url, false, $context );
$resulting = json_decode($result_json, true);
if($resulting['success']) {
//Success
} else {
// action for no response
}
At least on ubuntu - If site has SSL
cd /usr/local/share/ca-certificates
sudo curl http://curl.haxx.se/ca/cacert.pem -o cacert.crt
sudo update-ca-certificates
sudo update-ca-certificates –fresh
and your cafile and path will be
capath=/etc/ssl/certs/
cafile=/etc/ssl/certs/cacert.pem
In my case I needed to add two extra parameters ('', '&') in this call:
http_build_query(array(
'secret' => $secret,
'response' => $response,
'remoteip' => $remoteip
), '', '&');
This error happened to me because I had two instances of the ReCaptcha element on my page (one for mobile views, one for desktop). As soon as I removed one of them this error stopped.
I'm not able to comment so I'm going to answer here. I copied my code which works perfectly and btw $_POST['g-recaptcha-respone'], are you sure your inputs name is g-recaptcha-respone?
$secret = 'SECRET-KEY';
$response = $_POST['g-recaptcha-response'];
$ip = $_SERVER['REMOTE_ADDR'];
$dav = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$response."&remoteip=".$ip);
$res = json_decode($dav,true);
if ($res['success']) {
die(json_encode(0));
} else {
die(json_encode(1));
}
Just a note on this, you should be sending all your params via POST not GET (see https://developers.google.com/recaptcha/docs/verify#api_request). Use something like cURL to help make the request.

Call JSON API with params in PHP (with example)

Formerly i used XML way to get data from external API. Now, internal company policy orders to use JSON to communicate with API. I know what data i should send in request and how data i'll get back but i have no idea how to call with API by JSON.
My PHP server is localhost.
Let JSON API be located https://api.example.com/service-api and i'm sure it works fine.
Request
{"action":"authorization", "args":{"username":"firstname#dev.com","password":"qpujy676"}}
Callback
{"status":"OK", "token":"8hsa77hh687y3sbdha7ah3dajknfa93"}
I found example but i dont know what is Http_client(), what is it role and what it will do.
$http = new Http_Client();
$http->setUri('https://api.example.com/service-api');
$postdata = array(
'action' => 'authorization',
'args' => array(
'username' => 'firstname#dev.com',
'password' => 'qpujy676',
)
);
if (CRYPT_KEY_API) { //if encrypted data
$postdata ['rand'] = md5(time() . rand(2303, 85500));
$postdata = json_encode($postdata);
$postdata = Crypt::encrypt($postdata);
} else {
$postdata = json_encode($postdata);
}
$http->setRawData($postdata, 'application/json');
$response = $http->request(POST);
if ($response->isSuccessful()) {
$responseData = $response->getBody();
if (CRYPT_KEY_API) { //if encrypted data
$responseData = Crypt::decrypt($responseData);
}
$results = json_decode($responseData, true);
} else {
$error_message = "<p>Error</p>\n";
$error_message .= "HTTP Status: " . $response->getStatus() . "\n";
$error_message .= "HTTP Headers:\n";
$responseHeaders = $response->getHeaders();
foreach ($responseHeaders as $responseHeaderName => $responseHeaderValue) {
$error_message .= "$responseHeaderName: $responseHeaderValue\n";
}
throw new Exception($error_message);
}
Practically i need only exemplary http_client class to solve my problem :-) Especially
setRawData($postdata, 'application/json')
request(POST)
getBody()
I creared method autorization_test(), that supposedly should response with external API. Supposedly, because it output is:
Warning:
file_get_contents(https://api.example.com/service-api):
failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in
C:\xampp\htdocs\prestashop1611\modules\miniwa\miniwa.php on line 180
Error
public function authorization_test()
{
$domain = MINIWA_DOMAIN;
$username = 'tester#user.com';
$password = '12345';
$postData = array(
'action' => 'authorization',
'args' => array(
'domain' => $domain,
'username' => $username,
'password' => $password,
),
);
$postData = json_encode($postData);
//$postData = Crypt::encrypt($postData);
$context = stream_context_create(array(
'http' => array(
// http://www.php.net/manual/en/context.http.php
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => $postData,
)
));
// Send the request
$response = file_get_contents('https://api.example.com/service-api', FALSE, $context);
// Check for errors
if($response === FALSE){
die('Error');
}
//$response= Crypt::decrypt($response);
// Decode the response
$responseData = json_decode($response, TRUE);
// send the output data to view
$smarty->assign(array(
'json_decoded_output' => $responseData,
));
return $smarty;
Why there's no positive output?
Here you have whole documentation:
https://pear.php.net/manual/en/package.http.http-client.http-client-summary.php
API was disabled, now is OK, code is right.

POST call does not work correctly

I am currently working on a project and trying to do a POST call. The API documentation says the following
POST https://jawbone.com/nudge/api/v.1.1/users/#me/mood HTTP/1.1
Host: jawbone.com
Content-Type: application/x-www-form-urlencoded
title=MoodTest&sub_type=2
My code is:
$url = "http://jawbone.com/nudge/api/v.1.1/users/#me/mood";
$data = array('title' => 'moodTest', 'sub_type' => 2);
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded",
'method' => 'POST',
'content' => http_build_query($data)
),
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
title and sub_type are needed for changing the specific data.
I get the following error:
Warning: file_get_contents(http://...#me/mood): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in C:\wamp\www\main.php on line 53
Call Stack
# Time Memory Function Location
1 0.0028 265776 {main}( ) ..\main.php:0
2 0.9006 268584 postMood( ) ..\main.php:15
3 0.9007 271680 file_get_contents ( ) ..\main.php:53
What am I doing wrong?
You're issue seems to be that you are not authenticated.
If you open this request:
https://jawbone.com/nudge/api/v.1.1/users/#me/mood?title=asd&sub_type=2
on your browser, you will see the details of the error. If you check the headers in the response, you see that the status code is "404 Not Found".
I would suggest you to check the documentation of the API about how to authenticate or maybe switch to a supported API version (as the message of the response is "Unsupported API version 1.1, unless called with an OAuth header").
use javascript:
function getJson() {
var xhr = new XMLHttpRequest();
xhr.open("get", "https://jawbone.com/nudge/api/v.1.1/users/#me/mood", true);
xhr.onload = function(){
var response = JSON.parse(xhr.responseText);
}
xhr.send(null);
}
The best way in php to POST is to use curl (http://php.net/manual/ru/function.curl-exec.php)
so in your case you can use example (http://php.net/manual/ru/function.curl-exec.php#98628) :
function curl_post($url, array $post = NULL, array $options = array())
{
$defaults = array(
CURLOPT_POST => 1,
CURLOPT_HEADER => 0,
CURLOPT_URL => $url,
CURLOPT_FRESH_CONNECT => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FORBID_REUSE => 1,
CURLOPT_TIMEOUT => 4,
CURLOPT_POSTFIELDS => http_build_query($post)
);
$ch = curl_init();
curl_setopt_array($ch, ($options + $defaults));
if( ! $result = curl_exec($ch))
{
trigger_error(curl_error($ch));
}
curl_close($ch);
return $result;
}
$url = "http://jawbone.com/nudge/api/v.1.1/users/#me/mood";
$data = array('title' => 'moodTest', 'sub_type' => 2);
$result = curl_post($url, $data);

Can file_get_contents() return HTML on 4xx?

I need to send a POST request from PHP to a remote HTTPS address, which returns a JSON.
I've used the following code:
//$url = ...
$data = array('username' => $username, 'password' => $passwort);
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
),
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
However at the last line the function fails with a failed to open stream: HTTP request failed! HTTP/1.1 403 FORBIDDEN error.
The server also sends an explanation in HTML format, but I have no idea how to access it through file_get_contents. Help?
EDIT: I will use cURL instead.
As far as I know it is not possible. But if you use an HTTP client like Guzzle you will be able to perform this request very easy and handle errors gracefully. Also Guzzle uses cURL under the hood so you don't have to deal with it directly!
Send your POST request like this:
$client = new GuzzleHttp\Client();
$response = $client->post($url, [
'body' => [
'username' => $username,
'password' => $password
]
]);
echo $response->getStatusCode(); // 200
echo $response->getHeader('content-type'); // 'application/json; charset=utf8'
echo $response->getBody(); // {"type":"User"...'
var_export($response->json()); // Outputs the JSON decoded data
Because you are placing the username and password in the body array it will automatically be url encoded!
You will be able to deal with errors in an OO way and get the body of the 4xx response if the response exists:
try {
$client->get('https://github.com/_abc_123_404');
} catch (RequestException $e) {
echo $e->getRequest();
if ($e->hasResponse()) {
echo $e->getResponse();
}
}
See the documentation for more information.

Categories