PHP WebDAV server unable to perform PUT method using Windows - php

I'm trying to implement a PHP-based WebDAV server to be able to use it under OS Windows (more precisely Windows 7).
Everything works just fine, except for the PUT method. When I try to upload a file from the filesystem to the WebDAV server the request content-lenght is empty, meaning i can't read the file i want to put in the server.
Here is what I'm receiveng when I drag a file (simple .txt file) using Windows:
[HTTP_USER_AGENT] => Microsoft-WebDAV-MiniRedir/6.1.7601
[HTTP_TRANSLATE] => f
[CONTENT_LENGTH] => 0
[HTTP_VIA] => 1.1 squid.Sole:3128 (squid/2.7.STABLE9), 1.0 squidcache.Proxy6.CCSP:3129 (squid/2.6.STABLE24)
[PATH] => /bin:/usr/bin:/sbin:/usr/sbin
[SERVER_SOFTWARE] => Apache
[SERVER_PORT] => 80
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.0
[REQUEST_METHOD] => PUT
Uploading the same file using a dedicated webdav client, i get a valid response and the file is being uploaded. Here is what I get using CyberDuck client:
[HTTP_EXPECT] => 100-continue
[CONTENT_LENGTH] => 263
[CONTENT_TYPE] => text/plain
[HTTP_CONNECTION] => Keep-Alive
[HTTP_USER_AGENT] => Cyberduck/4.2.1 (9350) (Windows 7/6.1) (x86)
[HTTP_ACCEPT_ENCODING] => gzip,deflate
[PATH] => /bin:/usr/bin:/sbin:/usr/sbin
[SERVER_SOFTWARE] => Apache
[SERVER_PORT] => 80
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.1
[REQUEST_METHOD] => PUT
The CONTENT-LENGTH field changed and the file is online on the server as i should be.
I will post my code fragment here:
$options = Array();
$options["path"] = $this->path;
$options["content_length"] = $_SERVER["CONTENT_LENGTH"];
$options["stream"] = fopen('php://input', 'r');
$stat = $this->PUT($options); // In the PUT method I fopen the destination file in "w"
if ($stat === false) {
$stat = "403 Forbidden";
} else if (is_resource($stat) && get_resource_type($stat) == "stream") {
$stream = $stat;
$stat = $options["new"] ? "201 Created" : "204 No Content";
if (!empty($options["ranges"])) {
if (0 == fseek($stream, $range[0]["start"], SEEK_SET)) {
$length = $range[0]["end"]-$range[0]["start"]+1;
if (!fwrite($stream, fread($options["stream"], $length))) {
$stat = "403 Forbidden";
}
} else {
$stat = "403 Forbidden";
}
}else {
while (!feof($options["stream"])) {
if (false === fwrite($stream, fread($options["stream"], 4096))) { //The fread reads nothing from the stream...
$stat = "403 Forbidden";
break;
}
}
}
fclose($stream);
}
What could I do to solve this issue? is there any thing to set in Windows to make it work or is it just my code who lacks something?

Windows will first create a 0-byte file. After this succeeds it will upload the entire file.

Related

Check URL is an image or not using PHP

I'm trying to check if url is image, so I did use getheader; the getheader is working on localhost but not working on hosting server. I also tried to use getimagesize also it's working on localhost but not working on web hosting server even my php.ini is set to
allow_url_fopen = On
allow_url_include = On
for get_header my code is
$url = "https://hgtvhome.sndimg.com/content/dam/images/hgtv/fullset/2016/2/16/2/Orig-Paul-Schultz_Toybox-Home-kitchen-1.jpg.rend.hgtvcom.616.411.suffix/1455654217545";
$url_headers=get_headers($url, 1);
if(isset($url_headers['Content-Type'])){
$type=strtolower($url_headers['Content-Type']);
$valid_image_type=array();
$valid_image_type['image/png']='';
$valid_image_type['image/jpg']='';
$valid_image_type['image/jpeg']='';
$valid_image_type['image/jpe']='';
$valid_image_type['image/gif']='';
$valid_image_type['image/tif']='';
$valid_image_type['image/tiff']='';
$valid_image_type['image/svg']='';
$valid_image_type['image/ico']='';
$valid_image_type['image/icon']='';
$valid_image_type['image/x-icon']='';
if(isset($valid_image_type[$type])){
echo "Yes it's Images";
}
else
{
echo "no image";
}
}
var_dump of getheader on localhost display
array (size=11)
0 => string 'HTTP/1.0 200 OK' (length=15)
'Content-Type' => string 'image/jpeg' (length=10)
'Server' => string 'Apache' (length=6)
'X-Content-Type-Options' => string 'nosniff' (length=7)
'X-Frame-Options' => string 'SAMEORIGIN' (length=10)
'Content-Length' => string '38885' (length=5)
'Cache-Control' => string 'max-age=2522004' (length=15)
'Expires' => string 'Fri, 03 May 2019 08:55:29 GMT' (length=29)
'Date' => string 'Thu, 04 Apr 2019 04:22:05 GMT' (length=29)
'Connection' => string 'close' (length=5)
'Vary' => string 'User-Agent' (length=10)
But var_dump on web hosting server display
Array
(
[server] => AkamaiGHost, Apache
[content-length] => 0, 2077
[location] => https://www.foodnetwork.com/not-available.html
[cache-control] => max-age=0, max-age=433
[expires] => Thu, 04 Apr 2019 05:16:02 GMT, Thu, 04 Apr 2019 05:23:15 GMT
[date] => Thu, 04 Apr 2019 05:16:02 GMT, Thu, 04 Apr 2019 05:16:02 GMT
[connection] => keep-alive, keep-alive
[vary] => User-Agent, User-Agent, Accept-Encoding
[content-type] => text/html; charset=UTF-8
[access-control-allow-method] => GET
[server-timing] => edge; dur=0, cdn-cache; desc=HIT
[x-akamai-transformed] => 9 - 0 pmb=mRUM,3
[access-control-allow-origin] => *
[content-encoding] => gzip
)
and for getimagesize my code is
if (#getimagesize($url)) {
echo "image exists ";
} else {
echo "image does not exist ";
}
also is working on localhost but not working on web host server the var_dump of #getimagesize($url) is displaying :
bool(false)
As per you comment, You image url is wrong. Is should be : https://hgtvhome.sndimg.com/content/dam/images/hgtv/fullset/2016/2/16/2/Orig-Paul-Schultz_Toybox-Home-kitchen-1.jpg
You should remove image caching and image versioning at the time of checking.
Best solution to check weather file is image or not
Solution 1
if(#is_array(getimagesize($mediapath))){
$image = true;
} else {
$image = false;
}
Solution 2
$allowedTypes = array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF);
$detectedType = exif_imagetype($_FILES['fupload']['tmp_name']);
$error = !in_array($detectedType, $allowedTypes);
Solution 3
$supported_image = array('gif','jpg','jpeg','png','bmp');
$src_file_name = 'https://hgtvhome.sndimg.com/content/dam/images/hgtv/fullset/2016/2/16/2/Orig-Paul-Schultz_Toybox-Home-kitchen-1.jpg';
$ext = strtolower(pathinfo($src_file_name, PATHINFO_EXTENSION));
if (in_array($ext, $supported_image)){
echo "it's image";
}
else {
echo 'not image';
}
You should follow redirect headers (codes 30x)
In this case the image seems 'not available' because the redirect is to a not available page, it seems. Maybe the URL is wrong?
What you should also watch out for: many content providers check at least for a HTTP referrer header or they deny access to images (to make crawling a bit harder). Others check for a previously set cookie. And finally some can use some complex token-based authentication (which I will not get into). But for the first issues and also following redirects, you should use Curl: https://www.php.net/manual/en/book.curl.php
Content-type headers are very often unreliable. I would recommend using the exif image type returned by getimagesize in result index 2, which you seem to be calling anyway.
So to recap: use Curl to set referrer and follow redirects and maybe propagate cookies from a previous referrer page that you might browse, and once you get the content use getimagesize to determine type.
#getimagesize function take much time to respond. use below code for quick respond
function image_urlexists($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ($code == 200); // verifica se recebe "status OK"
}
$url = 'https://www.example.com/static/cs/img/pages/home/security-card-xl.png';
if (image_urlexists($url))
echo "valid Url of image";
else
echo "Not valid url image";

Async Upload Using Curl in PHP - curl_multi_exec()

I'm trying to figure out for days how would it be possible if at all, to upload multiple files parallel using PHP.
given I have a class called Request with 2 methods register() and executeAll():
class Request
{
protected $curlHandlers = [];
protected $curlMultiHandle = null;
public function register($url , $file = [])
{
if (empty($file)) {
return;
}
// Register the curl multihandle only once.
if (is_null($this->curlMultiHandle)) {
$this->curlMultiHandle = curl_multi_init();
}
$curlHandler = curl_init($url);
$options = [
CURLOPT_ENCODING => 'gzip',
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $file,
CURLOPT_USERAGENT => 'Curl',
CURLOPT_HTTPHEADER => [
'Content-Type' => 'multipart/form-data; boundry=-------------'.uniqid()
]
];
curl_setopt_array($curlHandler, $options);
$this->curlHandlers[] = $curlHandler;
curl_multi_add_handle($this->curlMultiHandle, $curlHandler);
}
public function executeAll()
{
$responses = [];
$running = null;
do {
curl_multi_exec($this->curlMultiHandle, $running);
} while ($running > 0);
foreach ($this->curlHandlers as $id => $handle) {
$responses[$id] = curl_multi_getcontent($handle);
curl_multi_remove_handle($this->curlMultiHandle, $handle);
}
curl_multi_close($this->curlMultiHandle);
return $responses;
}
}
$request = new Request;
// For this example I will keep it simple uploading only one file.
// that was posted using a regular HTML form multipart
$resource = $_FILES['file'];
$request->register('http://localhost/upload.php', $resource);
$responses = $request->executeAll(); // outputs an empty subset of array(1) { 0 => array(0) { } }
Problem:
Can't figure out why on upload.php (the script which is my endpoint url on the register method) $_FILES is always an empty array:
upload.php:
<?php
var_dump($_FILES); // outputs an empty array(0) { }
Things I've already tried:
prefixing the data with #, like so:
$options = [
CURLOPT_ENCODING => 'gzip',
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => ['file' => '#'.$file['tmp_name']],
CURLOPT_USERAGENT => 'Curl',
CURLOPT_HTTPHEADER => [
'Content-Type' => 'multipart/form-data; boundry=-------------'.uniqid()
]
];
That unfortunately did not work.
What am I doing wrong ?
how could I get the file resource stored in $_FILES global on the posted script (upload.php) ?
Further Debug Information:
on upload.php print_r the headers I get as response the following:
array(1) {
[0]=>
string(260) "Array
(
[Host] => localhost
[User-Agent] => Curl
[Accept] => */*
[Accept-Encoding] => gzip
[Content-Length] => 1106
[Content-Type] => multipart/form-data; boundary=------------------------966fdfac935d2bba
[Expect] => 100-continue
)
"
}
print_r($_POST) on upload.php gives the following response back:
array(1) {
[0]=>
string(290) "Array
(
[name] => example-1.jpg
[encrypted_name] => Nk9pN21IWExiT2VlNnpHU3JRRkZKZz09.jpg
[type] => image/jpeg
[extension] => jpg
[tmp_name] => C:\xampp\tmp\php77D7.tmp
[error] => 0
[size] => 62473
[encryption] => 1
[success] =>
[errorMessage] =>
)
"
}
I appreciate any answer.
Thanks,
Eden
Can't figure out why on upload.php (the script which is my endpoint url on the register method) $_FILES is always an empty array - your first problem is that you override libcurl's boundary string with your own, but you have curl generate the multipart/form-data body automatically, meaning curl generates another random boundary string, different from your own, in the actual request body, meaning the server won't be able to parse the files. remove the custom boundary string from the headers (curl will insert its own if you don't overwrite it). your second problem is that you're using $_FILES wrong, you need to extract the upload name if you wish to give it to curl, and you need to convert the filenames to CURLFile objects to have curl upload them for you. another problem is that your script will for no good reason use 100% cpu while executing the multi handle, you should add a curl_multi_select to prevent choking an entire cpu core. for how to handle $_FILES, see http://php.net/manual/en/features.file-upload.post-method.php
, for how to use CURLFile, see http://php.net/manual/en/curlfile.construct.php and for how to use curl_multi_select, see http://php.net/manual/en/function.curl-multi-select.php

Why does PHP not process my request?

I have a PHP project in which I have an index.html with a simple form:
<p>Test connection</p>
<form action="Servicios.php" method="post">
<input type='submit' name='Test' value='Test'>
</form>
in Servicios.php Im trying to process it like this
<?php
echo "can you print this";
if($_SERVER["REQUEST_METHOD"]=="POST" )
{
if(!empty($_POST["Test"]))
{
echo "Hello world";
}
}
But it doesn't works, thats because it never evaluates the first if like "true". The first echo at the top does works but if I do an echo to $_SERVER["REQUEST_METHOD"] it doesn't give me anything. I've tried with isset($_POST['Hola']) but I had the same result.
This only happens in the project I have in an internet host. I wrote this exact same code in my local computer using netbeans and xampp and it works perfectly. I have no idea why.
I have the feeling that I'm making some silly mistake but I cant find it.
My host is an Ubuntu server from the ec2 Amazon Web Services.
Edit
this is the output of <?=print_r($_SERVER);?> in Servicios.php
I replaced the parts where my ip is showed with [ip]
Array (
[HTTP_HOST] => [ip]
[HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
[HTTP_ACCEPT_LANGUAGE] => es-MX,es-ES;q=0.9,es;q=0.7,es-AR;q=0.6,es-CL;q=0.4,en-US;q=0.3,en;q=0.1
[HTTP_ACCEPT_ENCODING] => gzip, deflate
[HTTP_REFERER] => http://[ip]/ProyectoPM/
[CONTENT_TYPE] => application/x-www-form-urlencoded
[CONTENT_LENGTH] => 11
[HTTP_CONNECTION] => keep-alive
[HTTP_UPGRADE_INSECURE_REQUESTS] => 1
[PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[SERVER_SIGNATURE] => Apache/2.4.18 (Ubuntu) Server at [ip] Port 80
[SERVER_SOFTWARE] => Apache/2.4.18 (Ubuntu)
[SERVER_NAME] => [ip]
[SERVER_ADDR] => 172.31.43.105
[SERVER_PORT] => 80
[REMOTE_ADDR] => 189.208.87.127
[DOCUMENT_ROOT] => /var/www/html
[REQUEST_SCHEME] => http
[CONTEXT_PREFIX] =>
[CONTEXT_DOCUMENT_ROOT] => /var/www/html
[SERVER_ADMIN] => webmaster#localhost
[SCRIPT_FILENAME] => /var/www/html/ProyectoPM/Servicios.php
[REMOTE_PORT] => 5672
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.1
[REQUEST_METHOD] => POST
[QUERY_STRING] =>
[REQUEST_URI] => /ProyectoPM/Servicios.php
[SCRIPT_NAME] => /ProyectoPM/Servicios.php
[PHP_SELF] => /ProyectoPM/Servicios.php
[REQUEST_TIME_FLOAT] => 1510846404.812
[REQUEST_TIME] => 1510846404 ) 1
This is in the array it returns with <?=var_dump($_SERVER); ?>
["SERVER_PROTOCOL"]=> string(8) "HTTP/1.1"
["REQUEST_METHOD"]=> string(4) "POST"
["QUERY_STRING"]=> string(0) ""
["REQUEST_URI"]=> string(25) "/ProyectoPM/Servicios.php"
["SCRIPT_NAME"]=> string(25) "/ProyectoPM/Servicios.php"
["PHP_SELF"]=> string(25) "/ProyectoPM/Servicios.php"
["REQUEST_TIME_FLOAT"]=> float(1510847672.582)
["REQUEST_TIME"]=> int(1510847672) }
A more important edit
At first I said that a simple echo "can you print this"; worked in the host, now I see that it doesn't either. When I move to Servicios.php in by clicking my button in index.html the browser moves to Servicios.php (it displays it in the url) but it simply doesnt show anything. It only shows something if i delete all the code an put a instrucion like <?=print_r($_SERVER);?> which result I already put above.
if(isset($_POST['Test'])){
echo 'Hello world';
}
This should work. This is checking is button is submitted using POST method. This should be enough check to see if form has been submitted.
You can try this to check if post method
if(strtoupper($_SERVER['REQUEST_METHOD']) === 'POST') {
// if form submitted with post method
// validate request,
// manage post request differently,
// log or don't log request,
// redirect to avoid resubmition on F5 etc
}

Getting error "invalid_client" from Vimeo API on user authentication

I'm attempting to authenticate a user through Vimeo in order to view a list of their videos on the website.
I'm using the Vimeo php library https://github.com/vimeo/vimeo.php with no errors when including it in my code.
I get the authentication URL and am able to navigate to the Allow APP Access page on Vimeo and when I click "Allow" I'm getting the "invalid_client" error on my redirect page, even though they send back a code in the $_GET.
I'm thoroughly confused at this point since I've got the official API library and the APP is set up correctly as far as I can tell. I'm hoping someone might be able to point me in the right direction as to why I'm getting this error and how to fix it!
My Code:
//init Vimeo
require_once("modules/classes/Vimeo/autoload.php");
$lib = new \Vimeo\Vimeo($vimeo_id, $vimeo_secret, $vimeo_access);
if(!isset($_SESSION['vstate'])){
$_SESSION['vstate'] = base64_encode(openssl_random_pseudo_bytes(30));
}
$vimeo_authurl = $lib->buildAuthorizationEndpoint($redirecturi,'public private',$_SESSION['vstate']);
if(isset($_GET['code'])){
echo "Code returned: ".$_GET['code'];
if ($_SESSION['vstate'] != $_GET['state']) {
echo 'Something is wrong. Vimeo sent back a different state than this script was expecting. Please let an administrator know that this has happened.';
}
$tokens = $lib->accessToken($_GET['code'], $redirecturi);
if ($tokens['status'] == 200) {
echo 'Vimeo account successfully connected!';
$_SESSION['access_token'] = $tokens['body']['access_token'];
$lib->setToken($token['body']['access_token']);
} else {
echo 'Sorry, we were unable to connect to your Vimeo account due to the following error:<br/>{'.$tokens['body']['error']."} ".$tokens['body']['error_description'];
}
echo "<br/><br/><pre>";
print_r($tokens);
echo "</pre>";
exit();
}
The print_r($tokens) gives this:
Array
(
[body] => Array
(
[error] => invalid_client
[error_description] => A valid client ID must be provided along with any request made to Vimeo's API
)
[status] => 400
[headers] => Array
(
[Server] => nginx
[Content-Type] => application/json
[Expires] => Fri, 10 Mar 2017 03:11:17 GMT
[Cache-Control] => no-store
[Strict-Transport-Security] => max-age=15552000; includeSubDomains; preload
[Pragma] => no-cache
[X-UA-Compatible] => IE=edge
[X-XSS-Protection] => 1; mode=block
[X-Content-Type-Options] => nosniff
[X-Frame-Options] => sameorigin
[Content-Security-Policy-Report-Only] => default-src https: data: blob: 'unsafe-inline' 'unsafe-eval'; report-uri /_csp
[Accept-Ranges] => bytes
[Via] => 1.1 varnish
[Fastly-Debug-Digest] => 5da2a3ac863afd5f2ad0963779e0dbc4c54c7d97d19f87fd227c5eb8c92bd621
[Content-Length] => 126
[Date] => Fri, 10 Mar 2017 15:11:17 GMT
[Connection] => keep-alive
[X-Served-By] => cache-iad2146-IAD, cache-ord1731-ORD
[X-Cache] => MISS, MISS
[X-Cache-Hits] => 0, 0
[X-Timer] => S1489158677.346607,VS0,VE55
[Vary] => Accept,Vimeo-Client-Id,Accept-Encoding,User-Agent
)
)
So I'm not exactly sure why, but I created a new APP with the same details and this new APP seemed to authenticate fine.
The first APP I was having troubles with I had originally sent a request for Upload Access, but was denied (due to local testing links), so perhaps that was the underlying issue with the "invalid_client" error.

Access Certain Key Value in PHP Array

I am new to PHP and got confused, I wrote a PHP script to log the server environment variables when user make request, and my code looks like this:
<?php
$req_dump = print_r($_SERVER, TRUE);
$fp = fopen('/tmp/request.log', 'a');
fwrite($fp, $req_dump);
fclose($fp);
echo "hello world";
However, the output looks like below:
Array
(
[HTTP_USER_AGENT] => anaconda/13.21.195
[HTTP_HOST] => 10.0.188.97
[HTTP_ACCEPT] => */*
[HTTP_X_ANACONDA_ARCHITECTURE] => x86_64
[HTTP_X_ANACONDA_SYSTEM_RELEASE] => Red Hat Enterprise Linux
[HTTP_X_RHN_PROVISIONING_MAC_0] => eth0 B4:99:BA:07:xx:xx
[HTTP_X_RHN_PROVISIONING_MAC_1] => eth1 B4:99:BA:07:xx:xx
[HTTP_X_RHN_PROVISIONING_MAC_2] => eth2 B4:99:BA:07:xx:xx
[HTTP_X_RHN_PROVISIONING_MAC_3] => eth3 B4:99:BA:07:xx:xx
[HTTP_X_RHN_PROVISIONING_MAC_4] => eth4 00:02:C9:4F:xx:xx
[HTTP_X_RHN_PROVISIONING_MAC_5] => eth5 00:02:C9:4F:xx:xx
[PATH] => /sbin:/usr/sbin:/bin:/usr/bin
[SERVER_SIGNATURE] => <address>Apache/2.2.15 (Red Hat) Server at 10.0.188.97 Port 80</address>
[SERVER_SOFTWARE] => Apache/2.2.15 (Red Hat)
[SERVER_NAME] => 10.0.188.97
[SERVER_ADDR] => 10.0.188.97
[SERVER_PORT] => 80
[REMOTE_ADDR] => 10.0.188.212
[DOCUMENT_ROOT] => /var/www/html
[SERVER_ADMIN] => root#localhost
[SCRIPT_FILENAME] => /var/www/html/ks.php
[REMOTE_PORT] => 59188
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.1
[REQUEST_METHOD] => GET
[QUERY_STRING] =>
[REQUEST_URI] => /ks.php/images/install.img
[SCRIPT_NAME] => /ks.php
[PATH_INFO] => /images/install.img
[PATH_TRANSLATED] => /var/www/html/images/install.img
[PHP_SELF] => /ks.php/images/install.img
[REQUEST_TIME] => 1402439673
)
How I tried to access the array:
FYI, here is the code how I tried to access that array:
# ks.php
<?php
$Table = array(
"00:02:C9:10:aa:bb" => "10.0.188.91",
"00:02:C9:4F:aa:bb" => "10.0.188.92",
"00:02:C9:53:aa:bb" => "10.0.188.93",
"00:02:C9:56:aa:bb" => "10.0.188.94",
"00:02:C9:53:aa:bb" => "10.0.188.95",
"00:02:C9:4E:aa:bb" => "10.0.188.96",
"00:02:C9:5A:aa:bb" => "10.0.188.97",
);
?>
...
%post
...
printf 'DEVICE=eth4 \nIPADDR=<?php echo $Table[$_SERVER["HTTP_X_RHN_PROVISIONING_MAC_4"]]; ?>' > /etc/sysconfig/network-scripts/ifcfg-eth4
service network restart
...
%end
The output doesn't look like straight forward to me. Say I want to get the MAC address of ethernet4, and $_SERVER["HTTP_X_RHN_PROVISIONING_MAC_4"] doesn't work for me.
Can anyone help me explain how to achieve that in PHP?
your $_SERVER['HTTP_X_RHN_PROVISIONING_MAC_4'] output is eth4 00:02:C9:4F:xx:xx which also has a prefix eth4 where as your $Table has 00:02:C9:4F:aa:bb which makes the keys mismatch and actually you are trying to get $Table['eth4 00:02:C9:4F:xx:xx'] which is non existent in your $Table array
Try this:
// We are splitting the mac address by space so that $macAddress contains '00:02:C9:4F:xx:xx' and $eth contains eth4
list($eth,$macAddress) = explode(' ',$_SERVER['HTTP_X_RHN_PROVISIONING_MAC_4']);
// Make sure the value in $macAddress => 00:02:C9:4F:xx:xx is 00:02:C9:4F:aa:bb or change your array accordingly
$Table = array(
"00:02:C9:10:aa:bb" => "10.0.188.91",
"00:02:C9:4F:aa:bb" => "10.0.188.92",
"00:02:C9:53:aa:bb" => "10.0.188.93",
"00:02:C9:56:aa:bb" => "10.0.188.94",
"00:02:C9:53:aa:bb" => "10.0.188.95",
"00:02:C9:4E:aa:bb" => "10.0.188.96",
"00:02:C9:5A:aa:bb" => "10.0.188.97",
);
$finalAddress = $Table[$macAddress];
printf 'DEVICE=eth4 \nIPADDR=<?php echo $finalAddress ; ?>' > /etc/sysconfig/network-scripts/ifcfg-eth4 '
If you just save the array, it becomes like a useless print out. To make it accessible, use json_encode when you save it:
$fp = fopen('/tmp/request.log', 'w');
fwrite($fp, json_encode($_SERVER));
fclose($fp);
Note how I removed the print_r since it’s unnecessary for a task like this. I also changed fopen to overwrite the file using w instead of a so the saved JSON is valid.
Then when you open the file, just use json_decode like this:
$server_variables_json = file_get_contents('/tmp/request.log');
$server_variables = json_decode($server_variables_json , true);
Then $server_variables is an actual array you can act on like this:
if (array_key_exists('HTTP_X_RHN_PROVISIONING_MAC_4', $server_variables)) {
echo $server_variables['HTTP_X_RHN_PROVISIONING_MAC_4'];
}
The if (array_key_exists(…)) is something I put in place to help me debug this locally on my machine since I don’t have HTTP_X_RHN_PROVISIONING_MAC_4 set in my $_SERVER values.
A simple check I did locally to debug this—since I don’t have HTTP_X_RHN_PROVISIONING_MAC_4 in my setup—was just to get the HTTP_HOST like this:
if (array_key_exists('HTTP_HOST', $server_variables)) {
echo $server_variables['HTTP_HOST'];
}
If you want to put the var $_SERVER["HTTP_X_RHN_PROVISIONING_MAC_4"], don't forgot the quotes.
You need to use quotes to identify a non-numeric index:
echo $_SERVER['HTTP_X_RHN_PROVISIONING_MAC_4'];
You can get more basic information from the docs themselves.
Edit: I am not sure what you mean:
<?php
$array=array(
'HTTP_X_RHN_PROVISIONING_MAC_0' => 'eth0 B4:99:BA:07:xx:xx',
'HTTP_X_RHN_PROVISIONING_MAC_1' => 'eth1 B4:99:BA:07:xx:xx',
'HTTP_X_RHN_PROVISIONING_MAC_2' => 'eth2 B4:99:BA:07:xx:xx',
'HTTP_X_RHN_PROVISIONING_MAC_3' => 'eth3 B4:99:BA:07:xx:xx',
'HTTP_X_RHN_PROVISIONING_MAC_4' => 'eth4 00:02:C9:4F:xx:xx',
'HTTP_X_RHN_PROVISIONING_MAC_5' => 'eth5 00:02:C9:4F:xx:xx'
);
echo "Printing just a single element.\r\n";
echo $array['HTTP_X_RHN_PROVISIONING_MAC_4'];
echo "Printing the whole variable:\r\n";
print_r($array);
?>
Outputs the following:
Printing just a single element.
eth4 00:02:C9:4F:xx:xx
Printing the whole variable:
Array
(
[HTTP_X_RHN_PROVISIONING_MAC_0] => eth0 B4:99:BA:07:xx:xx
[HTTP_X_RHN_PROVISIONING_MAC_1] => eth1 B4:99:BA:07:xx:xx
[HTTP_X_RHN_PROVISIONING_MAC_2] => eth2 B4:99:BA:07:xx:xx
[HTTP_X_RHN_PROVISIONING_MAC_3] => eth3 B4:99:BA:07:xx:xx
[HTTP_X_RHN_PROVISIONING_MAC_4] => eth4 00:02:C9:4F:xx:xx
[HTTP_X_RHN_PROVISIONING_MAC_5] => eth5 00:02:C9:4F:xx:xx
)

Categories