<?php /** * ---------------------------------------------------------------------- * _____ __ __ _ _____ _ _ _ * |_ _| \/ | | | __ \ | (_) | | * | | | \ / | | | |__) |___ __| |_ _ __ ___ ___| |_ * | | | |\/| | | | _ // _ \/ _` | | '__/ _ \/ __| __| * _| |_| | | | |____ | | \ \ __/ (_| | | | | __/ (__| |_ * |_____|_| |_|______| |_| \_\___|\__,_|_|_| \___|\___|\__| * * ---------------------------------------------------------------------- * admin: list all defined redirections * ---------------------------------------------------------------------- * 2022-02-03 v0.1 <axel.hahn@iml.unibe.ch> initial version * 2022-05-31 v0.2 <axel.hahn@iml.unibe.ch> optical changes; use debugredirect=1 if url is a local domain * 2023-08-28 v1.0 <axel.hahn@unibe.ch> Welcome message if there is no config yet * ---------------------------------------------------------------------- */ require_once '../classes/redirect.admin.class.php'; $oR=new redirectadmin(); $sHtml=''; $sErrors=''; $aIco=[ 'h1'=>'⏩', 'h2_head'=>'✔️', 'h2_err'=>'🔔', 'h2_config'=>'🛠️', 'h2_file'=>'📄', 'ip_ok'=>'🟢', 'ip_warn'=>'🟠', 'ip_err'=>'❗', 'type_config'=>'🔷', 'type_alias'=>'◻️', 'url'=>'🌐', 'welcome'=>'🪄', ]; // ---------------------------------------------------------------------- // FUNCTIONS // ---------------------------------------------------------------------- function getId($sDomain){ return 'id_'.md5($sDomain); } // ---------------------------------------------------------------------- // MAIN // ---------------------------------------------------------------------- if (!$oR->isEnabled()){ $sHtml.='<div class="content"> <h3>Nothing to see here.</h3> <div class="error"> The Admin interface is disabled. </div> </div>'; } else { // ---------- return content for ajax requests // ---------- TEST URL $sUrl=(isset($_GET['url']) && $_GET['url']) ? $_GET['url'] : ''; if ($sUrl){ $sResult=$oR->httpGet($sUrl,1); echo '<h2>Response of a http HEAD request to '.$aIco['url'].' <a href="'.$sUrl.'">'.$sUrl.'</a></h2>' . $oR->renderHttpResponseHeader($sResult, 1) ; return true; } # ---------- return content for ajax requests $sCfgfile=(isset($_GET['cfgfile']) && $_GET['cfgfile']) ? $_GET['cfgfile'] : ''; if($sCfgfile){ $sFilename=__DIR__.'/../../config/'.$sCfgfile; echo '<h2>'.$aIco['h2_file'].' File: '.htmlentities($sCfgfile).'</h2>' . (file_exists($sFilename) ? '<pre>'. file_get_contents($sFilename).'</pre>' : '<div class="error">ERROR: config file was not found.</div>' ) ; exit(0); } $sMyIp=gethostbyname($_SERVER['SERVER_NAME']); if(!$sMyIp){ $sErrors.='<li>Ip address of current host ['.$_SERVER['SERVER_NAME'].'] was not found.</li>'; } // ---------- GET CONFIG DATA $aHosts=$oR->getHosts(); // ---------- SHOW ERRORS if(count($aHosts['_errors'])) { $sErrors.= '<li>' . implode('</li><li>', $aHosts['_errors']).'</li>'; } unset($aHosts['_errors']); // ---------- LOOP OVER ALL ENTRIES $sTable=''; foreach($aHosts as $sHost => $aCfg){ $sTdFirst='<tr class="cfgtype-'.$aCfg['type'].'">' .'<td>' .'<span style="display: none">'.$sHost.'</span>' .$aIco['type_'.$aCfg['type']] .' <a href="?url=http://'.$sHost.'/' .($aCfg['ip']===$sMyIp ? '?debugredirect=1' : '' ) .'" title="click to test http://'.$sHost.'/" onclick="showInOverlay(this); return false;">'.$sHost.'</a></td>' .'<td>' .($aCfg['ip'] ? ($aCfg['ip']===$sMyIp ? '<span title="">'.$aIco['ip_ok'].' '.$aCfg['ip']. '</span>' : '<span title="Warning: this is not the ip address of the current host ('.$sMyIp.')">'.$aIco['ip_warn'].' '.$aCfg['ip']. '</span>' ) : '<span class="error">'.$aIco['ip_err'].' ERROR: unknown host</span>') .'</td>' .'<td>' .($aCfg['type']=="config" ? '<a href="?cfgfile=redirects_'.$sHost.'.json" onclick="showInOverlay(this); return false;" title="show config for host '.$sHost.'">'.$aCfg['type'].'</a> ' : '<a href="?cfgfile=redirects_'.$aCfg['target'].'.json" onclick="showInOverlay(this); return false;" title="show config for alias '.$sHost.' pointing to host '.$aCfg['target'].'">'.$aCfg['type'].'</a> ' ) . '</td>' ; /* if(!$aCfg['ip']){ $sErrors.='<li>Host was not found in DNS: '.$sHost.'</li>'; } */ if (isset($aCfg['redirects'])){ $iCount=0; foreach(['direct', 'regex'] as $sType){ if (count($aCfg['redirects'][$sType])){ foreach($aCfg['redirects'][$sType] as $sFrom=>$aTo){ $iCount++; $sTable.=$sTdFirst .'<td class="type-'.$sType.'">'.$sType.'</td>' .'<td class="type-'.$sType.'">' .($sType == 'direct' ? '<a href="?url=http://'.$sHost.'/'.$sFrom.'" title="click to test http://'.$sHost.'/'.$sFrom.'" onclick="showInOverlay(this); return false;">/'.$sFrom.'</a>' : $sFrom ) .'</td>' .'<td class="http-'.$aTo['code'].'">'.$aTo['code'].'</td>' .'<td>'.$aIco['url'].' <a href="?url='.$aTo['target'].'" title="click to test '.$aTo['target'].'" onclick="showInOverlay(this); return false;">'.$aTo['target'].'</a></td>' .'</tr>'; } } } } else { // type = alias // $sHtml.='<tr>'.$sTdFirst.'<td></td><td></td><td></td><td>'.(isset($aCfg['target']) ? 'see config for <a href="#'.getId($aCfg['target']).'">'.$aCfg['target'].'</a>' : '').'</td></tr>'; $sTable.=$sTdFirst.'<td></td><td></td><td></td><td>'.(isset($aCfg['target']) ? 'see config for <em>'.$aCfg['target'].'</em>' : '').'</td></tr>'; } } $sTable=''; $sTable=$sTable ? '<table class="mydatatable"><thead> <tr> <th>Host</th> <th>Ip address</th> <th>Setup</th> <th>Type</th> <th>From</th> <th>Code</th> <th>Target</th> </tr> </thead><tbody>'.$sTable.'</tbody></table></div>' . '<br><br>' .'<div class="content legend">' . '<strong>Legend</strong>:<br>' . '<table><tbody>' .'<tr>' . '<td colspan="2"><br>Icons:</td>' .'</tr>' .'<tr>' . '<td>' . $aIco['type_config'].' Domain with config entries<br>' . $aIco['type_alias'].' Alias pointng to the config of another domain<br>' . $aIco['url'].' clickable url to show result of a http head request<br>' . '</td>' . '<td>' . $aIco['ip_ok'].' Domain is on the same ip like the redirect tool.<br>' . $aIco['ip_warn'].' Domain is on another domain (= the config from here does not work because redirect is handled on another system)<br>' . $aIco['ip_err'].' Hostname was not found in DNS<br>' . '</td>' . '</tr>' .'<tr>' . '<td colspan="2"><br>Redirect status codes:</td>' .'<tr>' . '<td colspan="2">' . '301 Moved Permanently - The address is outdated! However, the new address of the resource is still being forwarded.<br>' . '307 Temporary Redirect - The URL is currently being redirected temporarily (method is retained) - but the old address remains valid.<br>' . '308 Permanent Redirect - The address is outdated! The new address of the resource is forwarded with the same method.<br>' . '</td>' .'</tr>' .'</tbody></table>' .'</div>' : '<h3>'.$aIco['welcome'].' Welcome!</h3> <p> Thank you for the installation!<br> Now is a good moment to create your first config. </p> <ul> <li>Go to the directory ./config/</li> <li>Watch the *.dist files - make a copy of them to *.json (without .dist)</li> <li>Relaod this page</li> </ul> <p> See the <a href="'.$oR->urlDocs.'Configuration.html" target="_blank">Docs</a> for details. </p> ' ; $sHtml.=' <!-- <h2>'.$aIco['h2_head'].' Http head tester</h2> <div class="content"> <form> '.$aIco['url'].' <input type="text" name="url" size="100" value="'.$sUrl.'" placeholder="Enter url or click a link in the table below."/> <button>Http HEAD</button> </form> </div> <br> --> <h2>'.$aIco['h2_config'].' Domains and their redirects</h2> <div class="content">' /* .'<h2>Config array</h2> <pre>'.print_r($aHosts, 1).'</pre>' */ .$sTable ; $sErrors = $sErrors ? '<h2>'.$aIco['h2_err'].' Found errors</h2>' .'<div class="content">' .'<ol class="error">' .$sErrors .'</ol>' .'</div>' : '' ; $sHtml.='<footer><a href="'.$oR->urlRepo.'">Source</a> | <a href="'.$oR->urlDocs.'">Docs</a></footer>' ; } // ---------- OUTPUT ?><!doctype html> <html> <head> <title>Redirects</title> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.11.4/datatables.min.css"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.11.4/datatables.min.js"></script> <link rel="stylesheet" href="main.css"> </head> <body> <h1><?php echo $aIco['h1']?> <a href="?">Redirects :: admin</a></h1> <?php echo $sErrors . $sHtml; ?> <div id="divoverlay" class="overlay" onclick="this.style.display='none';"></div> <script type="text/javascript" src="functions.js"></script> <script> </script> </body> </html>