Select Git revision
-
Hahn Axel (hahn) authoredHahn Axel (hahn) authored
redirect.admin.class.php 6.80 KiB
<?php
require_once 'redirect.class.php';
/**
* ----------------------------------------------------------------------
* _____ __ __ _ _____ _ _ _
* |_ _| \/ | | | __ \ | (_) | |
* | | | \ / | | | |__) |___ __| |_ _ __ ___ ___| |_
* | | | |\/| | | | _ // _ \/ _` | | '__/ _ \/ __| __|
* _| |_| | | | |____ | | \ \ __/ (_| | | | | __/ (__| |_
* |_____|_| |_|______| |_| \_\___|\__,_|_|_| \___|\___|\__|
*
* ----------------------------------------------------------------------
* Loads a config json from outside webroot and makes a 3xx redirect
* if the definition exists
* ----------------------------------------------------------------------
* 2020-05-11 v1.4 ah rewrite as class
* 2022-02-03 v1.5 ah add method isEnabled
* 2022-05-23 v1.6 ah add http head check+render output;
* 2022-05-31 v1.7 ah optical changes
*/
/**
* Description of redirect
*
* @author axel
*/
class redirectadmin extends redirect {
protected function _getCurlOptions(){
$aReturn=array(
CURLOPT_HEADER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERAGENT => strip_tags($this->sAbout),
CURLOPT_VERBOSE => false,
CURLOPT_ENCODING => 'gzip, deflate', // to fetch encoding
CURLOPT_HTTPHEADER => array(
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language: en',
'DNT: 1',
),
// TODO: this is unsafe .. better: let the user configure it
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 5,
);
return $aReturn;
}
/**
* make a single http(s) get request and return the response body
* @param string $url url to fetch
* @param boolean $bHeaderOnly optional: true=make HEAD request; default: false (=GET)
* @return string
*/
public function httpGet($url, $bHeaderOnly = false) {
$ch = curl_init($url);
foreach ($this->_getCurlOptions() as $sCurlOption=>$sCurlValue){
curl_setopt($ch, $sCurlOption, $sCurlValue);
}
if ($bHeaderOnly) {
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
}
$res = curl_exec($ch);
curl_close($ch);
return ($res);
}
public function renderHttpResponseHeader($sHeader){
$sReturn=$sHeader;
if(!$sReturn){
$sReturn='<pre><span class="status status-error">Request failed. </span><br>'
.'No data... no response.<br>'
.'Maybe ... '
.'<ul>'
.'<li>the nostname does not exist ... </li>'
.'<li>or there is a network problem ... or </li>'
.'<li>the webservice on the target system does not run.</li>'
.'</ul>'
.'</pre>'
;
} else {
$sReturn=preg_replace('/(HTTP.*)\\r/', '</pre><pre><strong>$1</strong>', $sReturn);
$sReturn=preg_replace('/(HTTP.*200.*)/', '<span class="status status-ok">$1</span>', $sReturn);
$sReturn=preg_replace('/(HTTP.*30.*)/', '<span class="status status-redirect">$1</span>', $sReturn);
$sReturn=preg_replace('/(HTTP.*40.*)/', '<span class="status status-error">$1</span>', $sReturn);
$sReturn=preg_replace('/(HTTP.*50.*)/', '<span class="status status-error">$1</span>', $sReturn);
$sReturn=preg_replace('/\ ([1-5][0-9][0-9])\ /', ' <span class="statuscode">$1</span> ', $sReturn);
$sReturn=preg_replace('/(x-debug-.*)\\r/i', '<span class="debug">$1</span>', $sReturn);
$sReturn=preg_replace('/(location:.*)\\r/i', '<span class="location">$1</span>', $sReturn);
$sReturn.='</pre>';
preg_match_all('/(HTTP\/.*)/i', $sReturn, $aTmp);
// $sReturn.=print_r($aTmp, 1);
$iHops=(count($aTmp[0])-1);
$sReturn=($iHops>0
? 'Found hops: <strong>'.$iHops.'</strong>'
.($iHops>1 ? ' <span class="warning"> ⚠️ Verify your redirect to skip unneeded hops.</span>' : '' ).'<br><br>'
: ''
).$sReturn
;
}
return $sReturn;
}
/**
* check if admin is enabled
* @return bool
*/
public function isEnabled(){
$sFile2Enable=__DIR__ . '/'.basename(__FILE__).'_enabled.txt';
return file_exists($sFile2Enable);
}
/**
* get ip address of a given hostname as ip (string) or false
* @return string|bool
*/
protected function _getIp($sHostname){
$sIp=gethostbyname($sHostname);
return $sIp===$sHostname ? false : $sIp;
}
/**
* get an array with all config entries in all json files
* including some error checking
* @return array
*/
public function getHosts(){
$aReturn = array();
$aErrors = array();
foreach(glob($this->sConfigDir . '/redirects_*.json') as $sFilename){
$sMyHost= str_replace(array('redirects_', '.json'), array('',''), basename($sFilename));
$aReturn[$sMyHost]=array(
'type'=>'config',
'file'=>$sFilename,
'ip'=> $this->_getIp($sMyHost),
'aliases'=>array(),
'redirects'=>json_decode(file_get_contents($sFilename), 1),
);
if (!$aReturn[$sMyHost]['ip']){
$aErrors[]=basename($sFilename).': The hostname was not found in DNS: '.$sMyHost;
}
}
$aAliases=$this->_getAliases();
foreach($aAliases as $sAlias=>$sConfig){
if(isset($aReturn[$sAlias])){
$aErrors[]="alias.json: A configuration for alias [$sAlias] is useless. There exists a file redirects_{$sAlias}.json (which has priority).";
} else {
if(!isset($aReturn[$sConfig])){
$aErrors[]="alias.json: [$sAlias] points to a non existing host [$sConfig] - a file redirects_$sConfig.yml does not exist.";
} else {
$aReturn[$sConfig]['aliases'][]=$sAlias;
$aReturn[$sAlias]=array(
'type'=>'alias',
'target'=>$sConfig,
'ip'=> $this->_getIp($sAlias),
);
if (!$aReturn[$sAlias]['ip']){
$aErrors[]='alias.json: The hostname was not found in DNS: '.$sAlias;
}
}
}
}
$aReturn['_errors']=$aErrors;
ksort($aReturn);
return $aReturn;
}
}