How to make a HTTP request to a REST service in PHP? - php

I was wondering if anyone could help me understand how I would go about getting the JSON back using this information? Should I use cURL or fsockopen?
GET /market/10000002/orders/buy/?type=https://api-sisi.testeveonline.com/types/683/ HTTP/1.1
Host: https://api-sisi.testeveonline.com
Authorization: Bearer jKVB8oaN9qboU5kQG4sWSoWxzSUaFkQaUyeisy8jWU3apRfYSgYsKpZGNbLh41xXEzuy-NDBX1FohEdEadaukQ2
Accept: application/vnd.ccp.eve.MarketOrderCollection-v1+json
I have tried doing this, but I have no clue whether or not this is a feasible way of doing it?
$fp = fsockopen("api.eveonline.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET /market/10000002/orders/buy/? type=https://api.eveonline.com/types/683/ HTTP/1.1\r\n";
$out .= "Host: https://api.eveonline.com\r\n";
$out .= "Authorization: Bearer ".auth."\r\n\r\n";
$out .= "Accept: application/vnd.ccp.eve.MarketOrderCollection-v1+json\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
Thanks
EDIT 1:
$opts = array('http' =>
array(
'method' => 'GET',
'header' => "Host: https://api.eveonline.com\r\n".
"Authorization: Bearer ".auth."\r\n".
"Accept: application/vnd.ccp.eve.MarketOrderCollection-v1+json\r\n"
)
);
$context = stream_context_create($opts);
$url = 'https://api.eveonline.com/';
$result = file_get_contents($url, false, $context);
This was my next attempt that I am still working on.

fsockopen is really not a good option for HTTP requests as you have to take care of everything yourself (such as compression, chunking, etc.). cURL sure is an option, but my favourite is just file_get_contents. You need to have allow_url_fopen set to On in the config, but that's not really a security risk and the function itself is very capable.

Related

php curl hanging and infinite loop

i have been working on a scraper tool that rips google search results and then crawls the results websites looking to match specific items.
I'm having an issue with cURL though. I have come accross a site that is causing curl to go into an infinite loop.
website in question.
http://www.darellyelectrical.com/
when i open up my packet sniffer and look through tcp http packets ive found the same request is being sent over and over again.
i can not pinpoint the reason why, I have no trouble with any other websites.
I have tried setting the following curl options
curl_setopt($this->sessions[$key], CURLOPT_TIMEOUT, $timeout);
curl_setopt($this->sessions[$key], CURLOPT_MAXREDIRS, 2);
curl_setopt($this->sessions[$key], CURLOPT_CONNECTTIMEOUT, 1);
be great if someone could test that url with curl and let me know if the issue persists.
thanks
EDIT**
function sck_send()
{
$host = "www.darellyelectrical.com";
$path = "";
$fp = fsockopen($host, 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET /".$path." HTTP/1.1\r\n";
$out .= "Host: ".$host."\r\n";
$out .= "Connection: Close\r\n\r\n";
$data = "";
fwrite($fp, $out);
while (!feof($fp))
{
$data .= fgets($fp, 128);
}
fclose($fp);
echo $data;
}
}
sck_send();
this will produce the loop same as curl.
That server needs the User-Agent header to be included or it does not respond. PHP's curl doesn't set this by default and it wouldn't be included in a socket request unless you specify it. The code below works for me:
<?php
function sck_send() {
$host = "www.darellyelectrical.com";
$path = "";
$fp = fsockopen($host, 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET /".$path." HTTP/1.1\r\n";
$out .= "Host: ".$host."\r\n";
$out .= "User-Agent: Mozilla/5.0 \r\n";
$out .= "Connection: Close\r\n\r\n";
$data = "";
fwrite($fp, $out);
while (!feof($fp)) {
$data .= fgets($fp, 128);
}
fclose($fp);
echo $data;
}
}
sck_send();

how do you enable php to enable to make http calls

After trying all night without any success, this is the code that I have should work but not working:
<?php
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://api.keynote.com/keynote/',
CURLOPT_USERAGENT => 'Codular Sample cURL Request'
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
if(!curl_exec($curl)){
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}
// Close request to clear up some resources
curl_close($curl);
echo $resp;
?>
The error that I am getting is this:
Error: "Failed connect to api.keynote.com:80; No error" - Code: 7
On the server, I can manually bring up this url with any browser without any problems.
How do I make php connec to internet?
The thing is that fsockopen is used for opening socks (i.e connect to the specified port on the specified host/IP).
When you try to open sock to the host "http://google.com" it is like running "ping http://google.com" - you will get an error - as there is no such host "http://"
What you shout do is use http_get or curl
<?php
$response = http_get("http://www.example.com/", array("timeout"=>1), $info);
print_r($info);
?>
or remove the "http://"
<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>

Google cpanel - Retrieving all shared contacts

I don't know if I'm missing something, but I just cant retrieve shared contacts from Google cpanel!?
The auth token is returned by the first request, but the next returns HTTP/1.1 401 Unknown authorization header
Docs:
https://developers.google.com/google-apps/domain-shared-contacts/
Code:
// Authentication
$post_data = array(
'accountType' => 'HOSTED',
'Email' => 'my_email#gmail.com',
'Passwd' => 'password',
'service' => 'cp',
'source' => 'the_source'
);
$post = http_build_query($post_data);
$fp = fsockopen('ssl://www.google.com', 443, $errno, $errstr, 20);
$header = "POST /accounts/ClientLogin HTTP/1.1\\r\n".
"Host: www.google.com\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: ".strlen($post)."\r\n".
"Connection: Close\r\n\r\n".$post;
fwrite($fp, $header);
$auth_response = '';
while($line = fgets($fp)){
$auth_response .= $line;
}
fclose($fp);
list($header, $content) = explode("\r\n\r\n", $auth_response);
preg_match('/\sauth=(.*)\s/i', $content, $matches);
$auth_token = $matches[1];
// Retrieve contacts
$response = '';
$fp = fsockopen('ssl://www.google.com', 443, $errno, $errstr, 20);
$write = "GET /m8/feeds/contacts/my_domain/full HTTP/1.1\r\n".
"Host: www.google.com\r\n".
"Authorization: my_email#gmail.com token=\"$auth_token\"\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n\r\n".
"Connection: Close\r\n\r\n";
fwrite($fp, $write);
while($line = fgets($fp)){
$response .= $line;
}
fclose($fp);
echo $response;
The ClientLogin docs state that auth header should be:
Authorization: GoogleLogin auth=yourAuthToken

How to call RESTful WCF-Service from PHP

I'm trying to send an request to an Self-Hosted WCF-Service with REST in PHP.
I want to send the object to the WCF service as an JSON Object.
I did not get it running yet.
Has anyone an example how to call the service out of PHP?
This is the Operation contract (The method is a POST method):
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
void Method1(AnObject object);
The best working Code in PHP is the following:
$url = "http://localhost:8000/webservice/Method1?object=$object";
$url1 = parse_url($url);
// extract host and path:
$host = $url1['host'];
$path = $url1['path'];
$port = $url1['port'];
// open a socket connection on port 80 - timeout: 30 sec
$fp = fsockopen($host, $port, $errno, $errstr, 30);
if($fp)
{
// send the request headers:
fputs($fp, "POST $path HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-type: application/json \r\n");
fputs($fp, "Content-length: ". strlen($object) ."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $object);
//
// $result = '';
// while(!feof($fp)) {
// // receive the results of the request
// $result .= fgets($fp, 128);
// }
}
else {
return array(
'status' => 'err',
'error' => "$errstr ($errno)"
);
}
// close the socket connection:
fclose($fp);
But this code does not send the object. In Debugging-Mode the Object is "null". I just see, that it enters the method.
I found the solution for my own problem:
$url = "http://localhost:1234/service/PostMethod";
$jsonObject = json_encode($transmitObject);
$options = array(
CURLOPT_HTTPHEADER => array(
"Content-Type:application/json; charset=utf-8",
"Content-Length:".strlen($jsonObject)));
$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 => $jsonObject
);
$ch = curl_init();
curl_setopt_array($ch, ($options + $defaults));
curl_exec($ch);
curl_close($ch);
When you perform a POST on a WCF Rest service the raw request should look as below:
POST http://localhost:8000/webservice/Method1 HTTP 1.1
Content-Type: application/json
Host: localhost
{"object":{"ObjectId":1,"ObjectValue":60}
Assuming your AnObject looks as below:
[DataContract]
public class AnObject
{
[DataMember]
public int ObjectId {get;set;}
[DataMember]
public int ObjectValue {get;set;}
}
From your php code you are trying to send the object as a query string which is not going to work. Rather build your code to add the json string to the http body.
Use some tools like Fiddler or WireShark where you can intercept the request/response and inspect them. You can use them even to test the WCF Rest service by building a raw request.
Find some links that might be helpful:
Create a php Client to invoke a REST Service
php rest api call
I got work "der_chirurg" solution by adding parameter next to $path as below
original:
$url = "http://localhost:8000/webservice/Method1?object=$object";
fputs($fp, "POST $path HTTP/1.1\r\n");
changed to:
fputs($fp, "POST $path**?object=$object** HTTP/1.1\r\n");
and
instead of in the $url
$url = "http://localhost:8000/webservice/Method1
Finally:
url = "http://localhost:8000/webservice/Method1";
$url1 = parse_url($url);
// extract host and path:
$host = $url1['host'];
$path = $url1['path'];
$port = $url1['port'];
// open a socket connection on port 80 - timeout: 30 sec
$fp = fsockopen($host, $port, $errno, $errstr, 30);
if($fp)
{
// send the request headers:
fputs($fp, "POST $path?value=test HTTP/1.1\r\n");
fputs($fp, "Host: $host\r\n");
fputs($fp, "Content-type: application/json \r\n");
fputs($fp, "Content-length: ". strlen($param) ."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
$jsonData = json_encode($object, JSON_PRETTY_PRINT);
$options = array(
'http'=>array(
'method' => "POST",
'ignore_errors' => true,
'content' => $jsonData,
'header' => "Content-Type: application/json\r\n" .
"Content-length: ".strlen($jsonData)."\r\n".
"Expect: 100-continue\r\n" .
"Connection: close"
)
);
$context = stream_context_create($options);
$result = #file_get_contents($requestUrl, false, $context);
Very important is JSON format.

PHP How To Send Raw HTTP Packet

I want to send a raw http packet to a webserver and recieve its response but i cant find out a way to do it. im inexperianced with sockets and every link i find uses sockets to send udp packets. any help would be great.
Take a look at this simple example from the fsockopen manual page:
<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
The connection to the server is established with fsockpen. $out holds the HTTP request that’s then send with frwite. The HTTP response is then read with fgets.
If all you want to do is perform a GET request and receive the body of the response, most of the file functions support using urls:
<?php
$html = file_get_contents('http://google.com');
?>
<?php
$fh = fopen('http://google.com', 'r');
while (!feof($fh)) {
$html .= fread($fh);
}
fclose($fh);
?>
For more than simple GETs, use curl (you have to compile it into php). With curl you can do POST and HEAD requests, as well as set various headers.
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://google.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$html = curl_exec($ch);
?>
cURL is easier than implementing client side HTTP. All you have to do is set a few options and cURL handles the rest.
$curl = curl_init($URL);
curl_setopt_array($curl,
array(
CURLOPT_USERAGENT => 'Mozilla/5.0 (PLAYSTATION 3; 2.00)',
CURLOPT_HTTPAUTH => CURLAUTH_ANY,
CURLOPT_USERPWD => 'User:Password',
CURLOPT_RETURNTRANSFER => True,
CURLOPT_FOLLOWLOCATION => True
// set CURLOPT_HEADER to True if you want headers in the result.
)
);
$result = curl_exec($curl);
If you need to set a header that cURL doesn't support, use the CURLOPT_HTTPHEADER option, passing an array of additional headers. Set CURLOPT_HEADERFUNCTION to a callback if you need to parse headers. Read the docs for curl_setopt for more options.

Categories