Rss-Bridge/index.php

279 lines
8.3 KiB
PHP
Raw Normal View History

<?php
/*
TODO :
2013-08-11 13:30:41 +02:00
- factorize the annotation system
2016-09-10 21:01:02 +02:00
- factorize to adapter : Format, Bridge, Cache(actually code is almost the same)
2013-08-11 13:30:41 +02:00
- implement annotation cache for entrance page
- Cache : I think logic must be change as least to avoid to reconvert object from json in FileCache case.
- add namespace to avoid futur problem ?
- see FIXME mentions in the code
- implement header('X-Cached-Version: '.date(DATE_ATOM, filemtime($cachefile)));
*/
// Defines the minimum required PHP version for RSS-Bridge
define('PHP_VERSION_REQUIRED', '5.6.0');
//define('PROXY_URL', 'tcp://192.168.0.0:28');
// Set to true if you allow users to disable proxy usage for specific bridges
2016-09-10 21:01:02 +02:00
define('PROXY_BYBRIDGE', false);
// Comment this line or keep PROXY_NAME empty to display PROXY_URL instead
2016-09-10 21:01:02 +02:00
define('PROXY_NAME', 'Hidden Proxy Name');
2013-08-11 13:30:41 +02:00
date_default_timezone_set('UTC');
error_reporting(0);
2016-10-08 16:21:00 +02:00
// Specify directory for cached files (using FileCache)
define('CACHE_DIR', __DIR__ . '/cache');
// Specify path for whitelist file
define('WHITELIST_FILE', __DIR__ . '/whitelist.txt');
/*
Create a file named 'DEBUG' for enabling debug mode.
For further security, you may put whitelisted IP addresses
2016-09-10 21:01:02 +02:00
in the 'DEBUG' file, one IP per line. Empty file allows anyone(!).
Debugging allows displaying PHP error messages and bypasses the cache: this can allow a malicious
client to retrieve data about your server and hammer a provider throught your rss-bridge instance.
*/
if(file_exists('DEBUG')) {
2016-09-10 21:01:02 +02:00
$debug_enabled = true;
$debug_whitelist = trim(file_get_contents('DEBUG'));
if(strlen($debug_whitelist) > 0) {
2016-09-10 21:01:02 +02:00
$debug_enabled = false;
foreach(explode("\n", $debug_whitelist) as $allowed_ip) {
if(trim($allowed_ip) === $_SERVER['REMOTE_ADDR']) {
2016-09-10 21:01:02 +02:00
$debug_enabled = true;
break;
}
}
}
if($debug_enabled) {
2016-09-10 21:01:02 +02:00
ini_set('display_errors', '1');
error_reporting(E_ALL);
define('DEBUG', true);
2016-09-10 21:01:02 +02:00
}
}
2015-12-04 10:19:05 +01:00
require_once __DIR__ . '/lib/RssBridge.php';
// Check PHP version
if(version_compare(PHP_VERSION, PHP_VERSION_REQUIRED) === -1)
die('RSS-Bridge requires at least PHP version ' . PHP_VERSION_REQUIRED . '!');
// extensions check
2016-09-10 21:01:02 +02:00
if(!extension_loaded('openssl'))
die('"openssl" extension not loaded. Please check "php.ini"');
if(!extension_loaded('libxml'))
die('"libxml" extension not loaded. Please check "php.ini"');
// configuration checks
if(ini_get('allow_url_fopen') !== "1")
die('"allow_url_fopen" is not set to "1". Please check "php.ini');
// Check cache folder permissions (write permissions required)
if(!is_writable(CACHE_DIR))
die('RSS-Bridge does not have write permissions for ' . CACHE_DIR . '!');
// Check whitelist file permissions (only in DEBUG mode)
if(!file_exists('./whitelist.txt') && !is_writable('./'))
die('RSS-Bridge does not have write permissions for ' . WHITELIST_FILE . '!');
2014-05-14 21:34:07 +02:00
// FIXME : beta test UA spoofing, please report any blacklisting by PHP-fopen-unfriendly websites
2017-03-09 23:27:14 +01:00
$userAgent = 'Mozilla/5.0(X11; Linux x86_64; rv:30.0)';
$userAgent .= ' Gecko/20121202 Firefox/30.0(rss-bridge/0.1;';
$userAgent .= '+https://github.com/RSS-Bridge/rss-bridge)';
ini_set('user_agent', $userAgent);
2014-05-25 19:56:59 +02:00
// default whitelist
$whitelist_default = array(
"BandcampBridge",
"CryptomeBridge",
"DansTonChatBridge",
"DuckDuckGoBridge",
"FacebookBridge",
2014-05-25 19:56:59 +02:00
"FlickrExploreBridge",
2014-07-20 17:43:29 +02:00
"GooglePlusPostBridge",
2014-05-25 19:56:59 +02:00
"GoogleSearchBridge",
"IdenticaBridge",
"InstagramBridge",
"OpenClassroomsBridge",
"PinterestBridge",
"ScmbBridge",
"TwitterBridge",
"WikipediaBridge",
2014-05-25 19:56:59 +02:00
"YoutubeBridge");
2016-09-10 21:01:02 +02:00
try {
Bridge::setDir(__DIR__ . '/bridges/');
Format::setDir(__DIR__ . '/formats/');
Cache::setDir(__DIR__ . '/caches/');
if(!file_exists(WHITELIST_FILE)) {
$whitelist_selection = $whitelist_default;
$whitelist_write = implode("\n", $whitelist_default);
file_put_contents(WHITELIST_FILE, $whitelist_write);
} else {
$whitelist_file_content = file_get_contents(WHITELIST_FILE);
if($whitelist_file_content != "*\n") {
$whitelist_selection = explode("\n", $whitelist_file_content);
} else {
$whitelist_selection = Bridge::listBridges();
}
}
2016-09-10 21:01:02 +02:00
$action = filter_input(INPUT_GET, 'action');
$bridge = filter_input(INPUT_GET, 'bridge');
if($action === 'display' && !empty($bridge)) {
2016-09-10 21:01:02 +02:00
// DEPRECATED: 'nameBridge' scheme is replaced by 'name' in bridge parameter values
// this is to keep compatibility until futher complete removal
if(($pos = strpos($bridge, 'Bridge')) === (strlen($bridge) - strlen('Bridge'))) {
2016-09-10 21:01:02 +02:00
$bridge = substr($bridge, 0, $pos);
}
$format = filter_input(INPUT_GET, 'format');
2016-09-10 21:01:02 +02:00
// DEPRECATED: 'nameFormat' scheme is replaced by 'name' in format parameter values
// this is to keep compatibility until futher complete removal
if(($pos = strpos($format, 'Format')) === (strlen($format) - strlen('Format'))) {
2016-09-10 21:01:02 +02:00
$format = substr($format, 0, $pos);
}
// whitelist control
if(!Bridge::isWhitelisted($whitelist_selection, $bridge)) {
2016-09-10 21:01:02 +02:00
throw new \HttpException('This bridge is not whitelisted', 401);
die;
}
// Data retrieval
$bridge = Bridge::create($bridge);
2016-09-10 21:01:02 +02:00
$noproxy = filter_input(INPUT_GET, '_noproxy', FILTER_VALIDATE_BOOLEAN);
if(defined('PROXY_URL') && PROXY_BYBRIDGE && $noproxy) {
2017-02-14 17:28:07 +01:00
define('NOPROXY', true);
}
2016-09-10 21:01:02 +02:00
$params = $_GET;
// Initialize cache
$cache = Cache::create('FileCache');
2016-10-08 16:21:00 +02:00
$cache->setPath(CACHE_DIR);
$cache->purgeCache(86400); // 24 hours
$cache->setParameters($params);
unset($params['action']);
unset($params['bridge']);
unset($params['format']);
unset($params['_noproxy']);
// Load cache & data
try {
$bridge->setCache($cache);
$bridge->setDatas($params);
} catch(Exception $e) {
header('HTTP/1.1 ' . $e->getCode() . ' ' . Http::getMessageForCode($e->getCode()));
header('Content-Type: text/html');
die(buildBridgeException($e, $bridge));
}
2016-09-10 21:01:02 +02:00
// Data transformation
try {
$format = Format::create($format);
$format->setItems($bridge->getItems());
$format->setExtraInfos($bridge->getExtraInfos());
$format->display();
} catch(Exception $e) {
header('HTTP/1.1 ' . $e->getCode() . ' ' . Http::getMessageForCode($e->getCode()));
header('Content-Type: text/html');
die(buildTransformException($e, $bridge));
2016-09-10 21:01:02 +02:00
}
2016-09-10 21:01:02 +02:00
die;
}
} catch(HttpException $e) {
2016-09-10 21:01:02 +02:00
header('HTTP/1.1 ' . $e->getCode() . ' ' . Http::getMessageForCode($e->getCode()));
header('Content-Type: text/plain');
die($e->getMessage());
} catch(\Exception $e) {
2016-09-10 21:01:02 +02:00
die($e->getMessage());
}
2013-08-11 13:30:41 +02:00
$formats = Format::searchInformation();
?>
<!DOCTYPE html>
<html lang="en">
<head>
2016-09-10 21:01:02 +02:00
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Rss-bridge" />
<title>RSS-Bridge</title>
<link href="static/style.css" rel="stylesheet">
<script src="static/search.js"></script>
<noscript>
<style>
.searchbar {
display: none;
}
</style>
</noscript>
</head>
2013-08-11 13:30:41 +02:00
<body onload="search()">
2016-10-02 18:43:20 +02:00
<?php
$status = '';
if(defined('DEBUG') && DEBUG === true) {
2016-10-02 18:43:20 +02:00
$status .= 'debug mode active';
}
2013-08-11 13:30:41 +02:00
2016-10-02 18:43:20 +02:00
echo <<<EOD
2016-09-10 21:01:02 +02:00
<header>
<h1>RSS-Bridge</h1>
<h2>·Reconnecting the Web·</h2>
2016-10-02 18:43:20 +02:00
<p class="status">{$status}</p>
2016-09-10 21:01:02 +02:00
</header>
<section class="searchbar">
<h3>Search</h3>
<input type="text" name="searchfield"
id="searchfield" placeholder="Enter the bridge you want to search for"
onchange="search()" onkeyup="search()">
</section>
2016-10-02 18:43:20 +02:00
EOD;
2016-09-10 21:01:02 +02:00
$activeFoundBridgeCount = 0;
$showInactive = filter_input(INPUT_GET, 'show_inactive', FILTER_VALIDATE_BOOLEAN);
2014-07-20 17:11:11 +02:00
$inactiveBridges = '';
$bridgeList = Bridge::listBridges();
foreach($bridgeList as $bridgeName) {
if(Bridge::isWhitelisted($whitelist_selection, $bridgeName)) {
echo displayBridgeCard($bridgeName, $formats);
2016-09-10 21:01:02 +02:00
$activeFoundBridgeCount++;
} elseif($showInactive) {
2014-07-20 17:11:11 +02:00
// inactive bridges
$inactiveBridges .= displayBridgeCard($bridgeName, $formats, false) . PHP_EOL;
2014-07-20 17:11:11 +02:00
}
}
2016-08-02 22:16:43 +02:00
echo $inactiveBridges;
2014-07-20 16:49:53 +02:00
?>
<section class="footer">
2017-08-03 20:51:59 +02:00
<a href="https://github.com/RSS-Bridge/rss-bridge">RSS-Bridge 2017-08-03 ~ Public Domain</a><br />
2016-08-02 22:16:43 +02:00
<?= $activeFoundBridgeCount; ?>/<?= count($bridgeList) ?> active bridges. <br />
2016-09-10 21:01:02 +02:00
<?php
if($activeFoundBridgeCount !== count($bridgeList)) {
2016-09-10 21:01:02 +02:00
// FIXME: This should be done in pure CSS
if(!$showInactive)
echo '<a href="?show_inactive=1"><button class="small">Show inactive bridges</button></a><br />';
else
echo '<a href="?show_inactive=0"><button class="small">Hide inactive bridges</button></a><br />';
}
?>
</section>
</body>
2014-05-14 21:34:07 +02:00
</html>