Making POST request to web serivce - php

Simply put, I need to make a POST request to a web service using a php script. The problem is that the php version on the server is 4.4.x and curl is disabled. Any ideas how I can make the call and read the response?

You can use fopen and stream_context_create, as per the example on the stream_context_create page:
$context = stream_context_create(array(
'http' => array (
'method' => 'GET'
)
));
$fp = fopen ('http://www.example.com', 'r', $context);
$text = '';
while (!feof($fp)) {
$text .= fread($fp, 8192);
}
fclose($fp);
Also, see HTTP context options and Socket context options to see the options you can set.

you could basically use socket (fsockopen) and fputs like this :
$port = 80;
$server = "domain.com";
$valuesInPost = 'param=value&ahah=ohoho';
$lengthOfThePost = strlen($valuesInPost);
if($fsock = fsockopen($server, $port, $errno, $errstr)){
fputs($fsock, "POST /path/to/resource HTTP/1.1 \r\n");
fputs($fsock,"Host: $server \r\n");
fputs($fsock,"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13 \r\n");
fputs($fsock,"Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3 \r\n");
fputs($fsock,"Keep-Alive: 115 \r\n");
fputs($fsock,"Connection: keep-alive\r\n");
fputs($fsock,"Referer: http://refererYou.want\r\n");
fputs($fsock,"Content-Type: application/x-www-form-urlencoded\r\n");
fputs($fsock,"Content-Length: $lengthOfThePost\r\n\r\n");
fputs($fsock,"$valuesInPost\r\n\r\n");
$pcontent = "";
// results
while (!feof($fsock))
$pcontent .= fgets($fsock, 1024);
// echoes response
echo $pcontent;
}
There might be some syntax errors due to like rewriting.
Note you can use the port you want.

Do you have access to PEAR http_request?

Related

Why doesnt work the fsockopen if my server called the file?

I need little help..
We have a test code which use fsockopen. Code:
<?php
//require_once "../common.php";
$url = "https://xxxxx/xxxx/fsockopen_called_file.php";
$close = true;
echo "<pre>";
error_log("\n\n");
trigger_error("1. fsockopen url meghivasa: ".$url);
$result = call_url($url, $close);
trigger_error("2. eredmény: ".var_export($result, true)."\n\n");
function call_url($url, $close = TRUE) {
$user_agent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36";
$parts = parse_url($url);
if (#$parts["scheme"] === "https" && (!#$parts["port"] || $parts["port"] == 80)) {
$parts["port"] = 443;
$parts["scheme"] = "ssl";
}
$out = "GET ".$parts["path"]." HTTP/1.1\r\n";
$out.= "Host: ".$parts["host"]."\r\n";
$out.= "User-Agent: ".$user_agent."\r\n";
$out.= "Content-Length: 0\r\n";
if ($close) { $out.= "Connection: Close\r\n"; }
$out.= "\r\n";
$fsock_url = ($parts["scheme"] !== "http"? ($parts["scheme"]."://") : "").$parts["host"];
$fp = fsockopen($fsock_url, isset($parts["port"])? $parts["port"] : 80, $errno, $errstr, 30);
fwrite($fp, $out);
$result = "";
//Ha a kapcsolatot lezárjuk, akkor nem várjuk meg a választ.
if (!$close) {
while (!feof($fp)) {
$result .= fgets($fp, 128);
}
}
fclose($fp);
if (is_bool($fp) && !$fp && !$errno) {
//Az fsockopen false értékkel tért vissza, és nincs az errno változóban hibakód.
$errno = 1;
$errstr = "Nem lehetett a szerverhez kapcsolódni: ".$url." => ".$fsock_url;
}
return ["errno" => $errno, "errstr" => $errstr, "result" => $result];
}
My problem is that the file(fsockopen_called_file.php) that the code calls does not appear in the access log.
accesslog:
x.x.x.x - [19/Jun/2022:20:20:32 +0200] "GET /xxx/fsockopen.php HTTP/1.1" 200 4890 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36"
Thats it. fsockopen_called_file.php file doesnt apper. It's like doesnt work.
Server info:
Ubuntu 20.04
Apache 2.4.54-1+ubuntu20.04.1+deb.sury.org+1
Php7.4 1:7.4.30-1+ubuntu20.04.1+deb.sury.org+1
I tried this options:
-firewall off
-I build same server same options and its worked
Does anyone have any ideas that can help me?
Thanks,
Balee

Making http request using pure PHP

I was trying to make my php code send http request with its own (I don't want to use external libraries like CURL for now),but I can't find the right tag or I don't know how to use $_POST for this purpose. Any help please
If it's a GET request, using file_get_contents, maybe you can try something like this:
<?php
$test = file_get_contents("http://example.com/");
var_dump($test);
?>
If it's a POST request, using fsock, maybe you can try something like this:
<?php
$domain = 'dummy.restapiexample.com';
$fp = fsockopen($domain, 80);
$vars = array(
'name' => 'test',
'salary' => '123',
'age' => '23'
);
$content = http_build_query($vars);
fwrite($fp, "POST /api/v1/create HTTP/1.1\r\n");
fwrite($fp, "Host: $domain\r\n");
fwrite($fp, "Content-Type: application/json\r\n");
fwrite($fp, "Content-Length: ".strlen($content)."\r\n");
fwrite($fp, "Connection: close\r\n");
fwrite($fp, "\r\n");
fwrite($fp, $content);
header('Content-type: text/plain');
while (!feof($fp)) {
echo fgets($fp, 1024);
}
?>

Use Proxy With fsockopen

I have a Pagerank checking script that i'd like to add proxies to. I usually use Curl so im not sure exactly how to go about making the request through a proxy. I want the request to pick a random proxy from the $proxies array and use that for the request. Can anyone walk me through how this is done using this script. Thanks in advance.
$proxyauth = "username:password";
$proxies = array(
"proxy1",
"proxy2",
"proxy3",
"proxy4",
"proxy5",
"proxy6",
"proxy7",
"proxy8",
"proxy9",
"proxy10"
);
function check($page){
// Open a socket to the toolbarqueries address, used by Google Toolbar
$socket = fsockopen("toolbarqueries.google.com", 80, $errno, $errstr, 30);
// If a connection can be established
if($socket) {
// Prep socket headers
$out = "GET /tbr?client=navclient-auto&ch=".$this->checkHash($this->createHash($page))
."&features=Rank&q=info:".$page."&num=100&filter=0 HTTP/1.1\r\n";
$out .= "Host: toolbarqueries.google.com\r\n";
$out .= "User-Agent: Mozilla/4.0 (compatible; GoogleToolbar 2.0.114-big; Windows XP 5.1)\r\n";
$out .= "Connection: Close\r\n\r\n";
// Write settings to the socket
fwrite($socket, $out);
// When a response is received...
$result = "";
while(!feof($socket)) {
$data = fgets($socket, 128);
$pos = strpos($data, "Rank_");
if($pos !== false){
$pagerank = substr($data, $pos + 9);
$result += $pagerank;
}
}
// Close the connection
fclose($socket);
// Return the rank!
return $result;
}
}
With fsockopen, instead of toolbarqueries.google.com you connect to the selected proxy. Then you send a complete URL with the GET request:
$socket = fsockopen("proxy5", 80, $errno, $errstr, 30);
...
$out = "GET http://toolbarqueries.google.com/tbr?client=..."
You can still send the Host header, but you don't need it.

Why can I not download files from some sites like this?

This is my php source code:
<?php
$path = '/images/one.jpg';
$imm = 'http://www.allamoda.eu/wp-content/uploads/2012/05/calzedonia_290x435.jpg';
if( $content = file_get_contents($imm) ){
file_put_contents($path, $content);
echo "Yes";
}else{
echo "No";
}
?>
and I get this error:
Warning: file_get_contents(http://www.allamoda.eu/wp-content/uploads/2012/05/calzedonia_290x435.jpg) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden in /opt/lampp/htdocs/test/down.php on line 4
No
Why ?
There are some headers expected by the server(especially Accept and User-Agent). Use the stream_context -argument of file_get_contents() to provide them:
<?php
$path = '/images/one.jpg';
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Accept:image/png,image/*;q=0.8,*/*;q=0.5 \r\n".
"Host: www.allamoda.eu\r\n" .
"User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20100101 Firefox/12.0\r\n"
)
);
$context = stream_context_create($opts);
$imm = 'http://www.allamoda.eu/wp-content/uploads/2012/05/calzedonia_290x435.jpg';
if( $content = file_get_contents($imm,false,$context) ){
file_put_contents($path, $content);
echo "Yes";
}else{
echo "No";
}
?>
You are not allowed to download this file, the server allamoda.eu says (HTTP 403).
Nothing wrong with the code. The server simply is not letting you (either you have too much requests to it, or it just blocks all scripts scraping it).
You're not allowed to open the file directly. But you can try to fetch it's content by using sockets:
function getRemoteFile($url)
{
// get the host name and url path
$parsedUrl = parse_url($url);
$host = $parsedUrl['host'];
if (isset($parsedUrl['path'])) {
$path = $parsedUrl['path'];
} else {
// the url is pointing to the host like http://www.mysite.com
$path = '/';
}
if (isset($parsedUrl['query'])) {
$path .= '?' . $parsedUrl['query'];
}
if (isset($parsedUrl['port'])) {
$port = $parsedUrl['port'];
} else {
// most sites use port 80
$port = '80';
}
$timeout = 10;
$response = '';
// connect to the remote server
$fp = #fsockopen($host, '80', $errno, $errstr, $timeout );
if( !$fp ) {
echo "Cannot retrieve $url";
} else {
// send the necessary headers to get the file
fputs($fp, "GET $path HTTP/1.0\r\n" .
"Host: $host\r\n" .
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3\r\n" .
"Accept: */*\r\n" .
"Accept-Language: en-us,en;q=0.5\r\n" .
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" .
"Keep-Alive: 300\r\n" .
"Connection: keep-alive\r\n" .
"Referer: http://$host\r\n\r\n");
// retrieve the response from the remote server
while ( $line = fread( $fp, 4096 ) ) {
$response .= $line;
}
fclose( $fp );
// strip the headers
$pos = strpos($response, "\r\n\r\n");
$response = substr($response, $pos + 4);
}
// return the file content
return $response;
}
Example:
$content = getRemoteFile('http://www.allamoda.eu/wp-content/uploads/2012/05/calzedonia_290x435.jpg');
Source

How do you detect a website visitor's country (Specifically, US or not)?

I need to show different links for US and non-US visitors to my site. This is for convenience only, so I am not looking for a super-high degree of accuracy, and security or spoofing are not a concern.
I know there are geotargeting services and lists, but this seems like overkill since I only need to determine (roughly) if the person is in the US or not.
I was thinking about using JavaScript to get the user's timezone, but this appears to only give the offset, so users in Canada, Mexico, and South America would have the same value as people in the US.
Are there any other bits of information available either in JavaScript, or PHP, short of grabbing the IP address and doing a lookup, to determine this?
There are some free services out there that let you make country and ip-based geolocalization from the client-side.
I've used the wipmania free JSONP service, it's really simple to use:
<script type="text/javascript">
// plain JavaScript example
function jsonpCallback(data) {
alert('Latitude: ' + data.latitude +
'\nLongitude: ' + data.longitude +
'\nCountry: ' + data.address.country);
}
</script>
<script src="http://api.wipmania.com/jsonp?callback=jsonpCallback"
type="text/javascript"></script>
Or if you use a framework that supports JSONP, like jQuery you can:
// jQuery example
$.getJSON('http://api.wipmania.com/jsonp?callback=?', function (data) {
alert('Latitude: ' + data.latitude +
'\nLongitude: ' + data.longitude +
'\nCountry: ' + data.address.country);
});
Check the above snippet running here.
The best indicator is probably the HTTP Accept-Language header. It will look something like below in the HTTP request:
GET / HTTP/1.1
Accept: */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; .NET CLR 3.5.30729; MDDC; OfficeLiveConnector.1.4; OfficeLivePatch.0.0; .NET CLR 3.0.30729)
Accept-Encoding: gzip, deflate
Host: www.google.com
Connection: Keep-Alive
You should be able to retrieve this in PHP using the following:
<?php
echo $_SERVER['HTTP_ACCEPT_LANGUAGE'];
?>
I would say that geotargetting is the only method that's even remotely reliable. But there are also cases where it doesn't help at all. I keep getting to sites that think I'm in France because my company's backbone is there and all Internet traffic goes through it.
The HTTP Accept Header is not enough to determine the user locale. It only tells you what the user selected as their language, which may have nothing to do with where they are. More on this here.
Wipmania.com & PHP
<?php
$site_name = "www.your-site-name.com";
function getUserCountry() {
$fp = fsockopen("api.wipmania.com", 80, $errno, $errstr, 5);
if (!$fp) {
// API is currently down, return as "Unknown" :(
return "XX";
} else {
$out = "GET /".$_SERVER['REMOTE_ADDR']."?".$site_name." HTTP/1.1\r\n";
$out .= "Host: api.wipmania.com\r\n";
$out .= "Typ: php\r\n";
$out .= "Ver: 1.0\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
$country = fgets($fp, 3);
}
fclose($fp);
return $country;
}
}
?>
#rostislav
or using cURL:
public function __construct($site_name) {
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml"));
curl_setopt($ch, CURLOPT_URL, "http://api.wipmania.com".$_SERVER['REMOTE_ADDR']."?".$site_name);
curl_setopt($ch, CURLOPT_HEADER, 0);
// grab URL and pass it to the browser
$response = curl_exec($ch);
$info = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if (($response === false) || ($info !== 200)) {
throw new Exception('HTTP Error calling Wipmania API - HTTP Status: ' . $info . ' - cURL Erorr: ' . curl_error($ch));
} elseif (curl_errno($ch) > 0) {
throw new Exception('HTTP Error calling Wipmania API - cURL Error: ' . curl_error($ch));
}
$this->country = $response;
// close cURL resource, and free up system resources
curl_close($ch);
}
Simply we can use Hostip API
<?php $country_code = file_get_contents("http://api.hostip.info/country.php"); <br/>if($country_code == "US"){ echo "You Are USA"; } <br/>else{ echo "You Are Not USA";} ?>
All Country codes are here..
http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
My solution, easy and small, in this example i test Canada region from language fr-CA or en-CA
if( preg_match( "/^[a-z]{2}\-(ca)/i", $_SERVER[ "HTTP_ACCEPT_LANGUAGE" ] ) ){
$region = "Canada";
}
Depending on which countries you want to distinguish, time zones can be a very easy way to achieve it - and I assume it's quite reliable as most people will have the clocks on their computers set right. (Though of course there are many countries you can't distinguish using this technique).
Here's a really simple example of how to do it:
http://unmissabletokyo.com/country-detector

Categories