file_get_contents() with POST method shows as GET? - php

Using Google App Engine, when calling my API using POST method, it shows as GET - why?
This is my code:
function call_api($client_id, $client_secret, $data) {
$api_url = 'http://myapp.com/api.php';
$options = array(
'http' => array(
'header' => "Authorization: Basic " . Base64_encode("$client_id:$client_secret") . "\r\nContent-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
$context = stream_context_create($options);
$result = file_get_contents($api_url, false, $context);
return $result;
}
The first line of api.php is:
echo "<pre>"; print_r($_SERVER); echo "</pre>";
And within that output, I see:
[REQUEST_METHOD] => GET
How/why could this be happening?
It's also worth mentioning that the method shows as POST when testing this code on GAE's SDK.

I worked it out and I need to answer my own question because it's a doozy!!
Whilst the url is http $api_url = 'http://myapp.com/api.php';, as per everything else, the GAE app.yaml file serves all scripts as https as per:
- url: /(.+\.php)$
script: \1
secure: always
This means that the page that calls my function above is https so the api call doesn't like the request because of Cross-orgin source sharing.
The solution was to simply change the $api_url to be https.

Related

Adding cookie header causes request to hang

I'm working on a class project where we need to make use of php to write a website. We're told that we should write separate pages that we query for information along with a php session for keeping variables. I have successfully gotten a session started but when I try to make a request and I add a header for the session, the request stalls and doesn't complete. Below is the code that I'm using.
function GetDataV2(string $URL, string $method, array $postPayload)
{
$sessID = $_COOKIE['PHPSESSID'];
$cookieString = "Cookie: PHPSESSID=$sessID";
$options = array(
'http' => array(
'header' => array('Content-Type: application/x-www-form-urlencoded', 'Accept: application/json', $cookieString),
'method' => 'POST',
'content' => http_build_query($postPayload)
)
);
$context = stream_context_create($options);
return file_get_contents($URL, false, $context);
}
Any help is appreciated since I cannot seem to figure out what is causing the request to just hang. Unfortunately php is required for the project otherwise I wouldn't use it at all.
After doing more extensive searching, I needed to add session_write_close() before executing the call to release the session file before the other page could modify it.

PHP file_get_contents() is ignoring the request body when making a GET request

I am trying to make a simple HTTP GET request to query Elasticsearch. The Elasticsearch syntax allow the use of a request body in a GET request to add addition query options. I am using the PHP function file_get_contents() to make the GET request.
The problem is that file_get_contents() seems to be ignoring the body of the request when making a GET request yet it works fine when using a POST request instead.
How can I get file_get_contents() to process the body of the GET request correctly?
The code I am using is shown below.
Note that :
I want to use file_get_contents() to do this, NOT php cURL, php Request2, or the elasticsearch-php library
I would like to keep this as a GET request, changing it to a POST request instead is not what I am after
Thanks in advance!
$url = "example-elasticsearch-url-here.com/index/_search";
$body=<<<EOD
{
"_source": ["email"],
"size":10,
"query":{
"match_all" : {}
}
}
EOD;
$contextData = array (
'method' => 'GET',
'header' => "Content-Type: application/json\r\n".
'ssl'=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
),
'content'=> $body
);
$context = stream_context_create (array ( 'https' => $contextData ));
try {
$result = file_get_contents ($url,false,$context);
} catch (Exception $e) {
$result = false;
}
echo $result;
Does it work, if you use http instead of https as key name in $context?

Reddit Api endpoint returns 302 found

I'm using CakePHP and I've already got a access token and a refresh token for the Reddit API, when I make a get request to a endpoint like '/subreddits/popular.json' it works and returns json. My problem is when I make a get request to /subreddits/mine/subscriber.json I get the following response:
302 Found
The resource was found at https://www.reddit.com/subreddits/login.json?dest=https%3A%2F%2Foauth.reddit.com%2Freddits%2Fmine%2Fsubscriber.json%3Fcount%3D100%26limit%3D100; you should be redirected automatically. "
Why is json not returned? or have I missed something the code used to send a get request is:
$endpoint = $this->ENDPOINT_OAUTH . '/subreddits/mine/subscriber.json';
$options = array(
'header' => array(
'Authorization' => $accessToken,
'Accept' => 'application/json',
'Content-Type' => 'application/json; charset=UTF-8'
)
);
$results = $HttpSocket->get($endpoint, $data, $options);
print_r('<pre>');
var_dump($results);
print_r('</pre>');
EDIT: if I add to my options array 'redirect' => true then it redirects to the 302 found url and then returns a 200 ok response but with no data
EDIT 2: After adding the 'redirect' => true I then removed the ':' from in front of Bearer TOKEN and it works
To get it working I needed to add redirect => true to my options parameter so that it sent the second GET request.
When setting my access token it was set like this:
$accessToken = 'Bearer: ' . $accessToken;
When I removed the ':' from the front of Bearer it then worked and returns the results

NodeJitsu PHP Curl Json API - Restart an application

I have problem with use NodeJitsu API in PHP curl...
I want make php file which will be restart my application.
Here is NodeJistu API: https://www.nodejitsu.com/documentation/api/#restart-an-application
But i don't realy now how i can use it in php. Can you help me?
They use a simple REST API. You'll need to send an empty HTTP POST request to the url named in the docs. A request body isn't required for the restart action.
I don't have an account for testing there, but following their documentation it could look like this:
/* Login credentials */
$user = 'user';
$pass = 'secret';
/* Application id */
$application = 'foo';
/* Base url */
$baseUrl = 'https://www.nodejitsu.com';
// Create a context for the following HTTP request
$context = stream_context_create(
'http' => array(
'method' => 'POST',
'header' => 'Authorization: Basic '
. base64_encode("$user:$pass")
)
);
// Execute the HTTP request to restart the application
$url = "$baseUrl/apps/$user/$application/restart";
$response = file_get_contents($url, false, $context);
// Dump response
var_dump(json_decode($response));
You can use file_get_contents(), curl isn't required.

Connecting Nav Web Service in php

I am trying to connect the Nav Web Services in Php (followed by this Blog).
but it's returning an error:
SOAP-ERROR: Parsing WSDL: Couldn't load from
'http://NavIP.com:7047/DynamicsNAV/WS/SystemService' : Start tag
expected, '<' not found.
Could you tell me where I went wrong?
thanks in advance..
my code is:
//client.php
<?php
require_once("NTLMStream.php");
require_once("NTLMSoapClient.php");
try
{
// we unregister the current HTTP wrapper
stream_wrapper_unregister('http');
// we register the new HTTP wrapper
stream_wrapper_register('http', 'NTLMStream') or die("Failed to register protocol");
// Initialize Soap Client
$baseURL = 'http://NavIp.Com:7047/DynamicsNAVPMS/WS/';
$client = new NTLMSoapClient($baseURL.'SystemService');
// Find the first Company in the Companies
$result = $client->Companies();
$companies = $result->return_value;
echo "Companies:<br>";
if (is_array($companies)) {
foreach($companies as $company) {
echo "$company<br>";
}
$cur = $companies[0];
}
else {
echo "$companies<br>";
$cur = $companies;
}
}
catch(Exception $ex)
{
echo $ex->getMessage();
}
?>
I am dealing with the exact same problem, but have not found a solution because they all come back to this same script. Your problem is that you are getting no result back because of a 401 error code (could not authenticate), which is exactly I where I am stuck as well. The script ends up using CURL to connect, but somehow that fails.
Use this
$client = new NTLMSoapClient(null, $baseURL.'SystemService');
You are wrongly providing baseURL which is being taken as WSDL location. In your code, seems like you are trying to provide the service endpoint. Try that.
You could also use a packet sniffer like 'Wireshark' to see what response you are getting. The expected response is an xml, which seems like it is not returning. Maybe it is returning a 401 unauthorized? That's not an XML response, that also could be a cause.
Also, where is define('USERPWD','user:pass'); in your code? Didn't you use authentication? I have a strong feeling you just need to define it. Make sure you define the 'domain' part in the username field if you are using a domain. So, 'domain\user:pass'.
This post is good: http://blogs.msdn.com/b/freddyk/archive/2010/01/19/connecting-to-nav-web-services-from-php.aspx
Instead of using NTLM, try using Basic Authentication which is quite straight forward and then use cURL. It is easy peasy. See code below for a simple implementation. You can use SOAP or ODATA
You should also use a Chrome extension known as Wizdler
See sample code below for a Basic implementation
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://navdynamicsip.com:port/WebService/WS/COMPANY NAME/Page/webservice",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_POSTFIELDS =>"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\">\n<Body>\n<Read xmlns=\"urn:microsoft-dynamics-schemas/page/webservice\"></Read>\n</Body>\n</Envelope>",
CURLOPT_HTTPHEADER => array(
"Content-Type: text/xml; charset=utf-8",
"SoapAction: urn:microsoft-dynamics-schemas/page/webservice",
"Authorization: Basic " .base64_encode('username:password')
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

Categories