Rss-Bridge/actions/ConnectivityAction.php

137 lines
3.6 KiB
PHP
Raw Normal View History

action: Add action to check bridge connectivity (#1147) * action: Add action to check bridge connectivity It is currently not simply possible to check if the remote server for a bridge is reachable or not, which means some of the bridges might no longer work because the server is no longer on the internet. In order to find those bridges we can either check each bridge individually (which takes a lot of effort), or use an automated script to do this for us. If a server is no longer reachable it could mean that it is temporarily unavailable, or shutdown permanently. The results of this script will at least help identifying such servers. * [Connectivity] Use Bootstrap container to properly display contents * [Connectivity] Limit connectivity checks to debug mode Connectivity checks take a long time to execute and can require a lot of bandwidth. Therefore, administrators should be able to determine when and who is able to utilize this action. The best way to prevent regular users from accessing this action is by making it available in debug mode only (public servers should never run in debug mode anyway). * [Connectivity] Split implemenation into multiple files * [Connectivity] Make web page responsive to user input * [Connectivity] Make status message sticky * [Connectivity] Add icon to the status message * [contents] Add the ability for getContents to return header information * [Connectivity] Add header information to the reply Json data * [Connectivity] Add new status (blue) for redirected sites Also adds titles to status icons (Successful, Redirected, Inactive, Failed) * [Connectivity] Fix show doesn't work for inactive bridges * [Connectivity] Fix typo * [Connectivity] Catch errors in promise chains * [Connectivity] Allow search by status and update dynamically * [Connectivity] Add a progress bar * [Connectivity] Use bridge factory * [Connectivity] Import Bootstrap v4.3.1 CSS
2019-10-31 22:02:38 +01:00
<?php
/**
* This file is part of RSS-Bridge, a PHP project capable of generating RSS and
* Atom feeds for websites that don't have one.
*
* For the full license information, please view the UNLICENSE file distributed
* with this source code.
*
* @package Core
* @license http://unlicense.org/ UNLICENSE
* @link https://github.com/rss-bridge/rss-bridge
*/
/**
* Checks if the website for a given bridge is reachable.
*
* **Remarks**
* - This action is only available in debug mode.
* - Returns the bridge status as Json-formatted string.
* - Returns an error if the bridge is not whitelisted.
* - Returns a responsive web page that automatically checks all whitelisted
* bridges (using JavaScript) if no bridge is specified.
*/
class ConnectivityAction extends ActionAbstract {
public function execute() {
if(!Debug::isEnabled()) {
returnError('This action is only available in debug mode!');
}
if(!isset($this->userData['bridge'])) {
$this->returnEntryPage();
return;
}
$bridgeName = $this->userData['bridge'];
$this->reportBridgeConnectivity($bridgeName);
}
/**
* Generates a report about the bridge connectivity status and sends it back
* to the user.
*
* The report is generated as Json-formatted string in the format
* {
* "bridge": "<bridge-name>",
* "successful": true/false
* }
*
* @param string $bridgeName Name of the bridge to generate the report for
* @return void
*/
private function reportBridgeConnectivity($bridgeName) {
$bridgeFac = new \BridgeFactory();
$bridgeFac->setWorkingDir(PATH_LIB_BRIDGES);
if(!$bridgeFac->isWhitelisted($bridgeName)) {
header('Content-Type: text/html');
returnServerError('Bridge is not whitelisted!');
}
header('Content-Type: text/json');
$retVal = array(
'bridge' => $bridgeName,
'successful' => false,
'http_code' => 200,
);
$bridge = $bridgeFac->create($bridgeName);
if($bridge === false) {
echo json_encode($retVal);
return;
}
$curl_opts = array(
CURLOPT_CONNECTTIMEOUT => 5
);
try {
$reply = getContents($bridge::URI, array(), $curl_opts, true);
if($reply) {
$retVal['successful'] = true;
if (isset($reply['header'])) {
if (strpos($reply['header'], 'HTTP/1.1 301 Moved Permanently') !== false) {
$retVal['http_code'] = 301;
}
}
}
} catch(Exception $e) {
$retVal['successful'] = false;
}
echo json_encode($retVal);
}
private function returnEntryPage() {
echo <<<EOD
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="static/bootstrap.min.css">
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.6.3/css/all.css"
integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/"
crossorigin="anonymous">
<link rel="stylesheet" href="static/connectivity.css">
<script src="static/connectivity.js" type="text/javascript"></script>
</head>
<body>
<div id="main-content" class="container">
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div id="status-message" class="sticky-top alert alert-primary alert-dismissible fade show" role="alert">
<i id="status-icon" class="fas fa-sync"></i>
<span>...</span>
<button type="button" class="close" data-dismiss="alert" aria-label="Close" onclick="stopConnectivityChecks()">
<span aria-hidden="true">&times;</span>
</button>
</div>
<input type="text" class="form-control" id="search" onkeyup="search()" placeholder="Search for bridge..">
</div>
</body>
</html>
EOD;
}
}