mirror of
https://github.com/mosbth/cimage.git
synced 2025-08-05 15:47:30 +02:00
* Using CWhitelist
for checking hotlinking to images, fix #88.
* Added mode for `test` which enables logging verbose mode to file, fix #97.
This commit is contained in:
72
CImage.php
72
CImage.php
@@ -318,6 +318,22 @@ class CImage
|
|||||||
private $useCache = true;
|
private $useCache = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set whitelist for valid hostnames from where remote source can be
|
||||||
|
* downloaded.
|
||||||
|
*/
|
||||||
|
private $remoteHostWhitelist = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do verbose logging to file by setting this to a filename.
|
||||||
|
*/
|
||||||
|
private $verboseFileName = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties, the class is mutable and the method setOptions()
|
* Properties, the class is mutable and the method setOptions()
|
||||||
* decides (partly) what properties are created.
|
* decides (partly) what properties are created.
|
||||||
@@ -418,10 +434,12 @@ class CImage
|
|||||||
$this->allowRemote = $allow;
|
$this->allowRemote = $allow;
|
||||||
$this->remotePattern = is_null($pattern) ? $this->remotePattern : $pattern;
|
$this->remotePattern = is_null($pattern) ? $this->remotePattern : $pattern;
|
||||||
|
|
||||||
$this->log("Set remote download to: "
|
$this->log(
|
||||||
|
"Set remote download to: "
|
||||||
. ($this->allowRemote ? "true" : "false")
|
. ($this->allowRemote ? "true" : "false")
|
||||||
. " using pattern "
|
. " using pattern "
|
||||||
. $this->remotePattern);
|
. $this->remotePattern
|
||||||
|
);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -455,7 +473,10 @@ class CImage
|
|||||||
public function setRemoteHostWhitelist($whitelist = null)
|
public function setRemoteHostWhitelist($whitelist = null)
|
||||||
{
|
{
|
||||||
$this->remoteHostWhitelist = $whitelist;
|
$this->remoteHostWhitelist = $whitelist;
|
||||||
$this->log("Setting remote host whitelist to: " . print_r($this->remoteHostWhitelist, 1));
|
$this->log(
|
||||||
|
"Setting remote host whitelist to: "
|
||||||
|
. (is_null($whitelist) ? "null" : print_r($whitelist, 1))
|
||||||
|
);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,14 +493,18 @@ class CImage
|
|||||||
public function isRemoteSourceOnWhitelist($src)
|
public function isRemoteSourceOnWhitelist($src)
|
||||||
{
|
{
|
||||||
if (is_null($this->remoteHostWhitelist)) {
|
if (is_null($this->remoteHostWhitelist)) {
|
||||||
$allow = true;
|
$this->log("Remote host on whitelist not configured - allowing.");
|
||||||
} else {
|
return true;
|
||||||
$whitelist = new CWhitelist();
|
|
||||||
$hostname = parse_url($src, PHP_URL_HOST);
|
|
||||||
$allow = $whitelist->check($hostname, $this->remoteHostWhitelist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->log("Remote host is on whitelist: " . ($allow ? "true" : "false"));
|
$whitelist = new CWhitelist();
|
||||||
|
$hostname = parse_url($src, PHP_URL_HOST);
|
||||||
|
$allow = $whitelist->check($hostname, $this->remoteHostWhitelist);
|
||||||
|
|
||||||
|
$this->log(
|
||||||
|
"Remote host is on whitelist: "
|
||||||
|
. ($allow ? "true" : "false")
|
||||||
|
);
|
||||||
return $allow;
|
return $allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2253,7 +2278,10 @@ class CImage
|
|||||||
if ($this->verbose) {
|
if ($this->verbose) {
|
||||||
$this->log("Last modified: " . $gmdate . " GMT");
|
$this->log("Last modified: " . $gmdate . " GMT");
|
||||||
$this->verboseOutput();
|
$this->verboseOutput();
|
||||||
exit;
|
|
||||||
|
if (is_null($this->verboseFileName)) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get details on image
|
// Get details on image
|
||||||
@@ -2331,6 +2359,21 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do verbose output to a file.
|
||||||
|
*
|
||||||
|
* @param string $fileName where to write the verbose output.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setVerboseToFile($fileName)
|
||||||
|
{
|
||||||
|
$this->log("Setting verbose output to file.");
|
||||||
|
$this->verboseFileName = $fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do verbose output and print out the log and the actual images.
|
* Do verbose output and print out the log and the actual images.
|
||||||
*
|
*
|
||||||
@@ -2356,10 +2399,17 @@ class CImage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo <<<EOD
|
if (!is_null($this->verboseFileName)) {
|
||||||
|
file_put_contents(
|
||||||
|
$this->verboseFileName,
|
||||||
|
str_replace("<br/>", "\n", $log)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
echo <<<EOD
|
||||||
<h1>CImage Verbose Output</h1>
|
<h1>CImage Verbose Output</h1>
|
||||||
<pre>{$log}</pre>
|
<pre>{$log}</pre>
|
||||||
EOD;
|
EOD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -23,11 +23,11 @@ class CWhitelist
|
|||||||
*/
|
*/
|
||||||
public function set($whitelist = array())
|
public function set($whitelist = array())
|
||||||
{
|
{
|
||||||
if (is_array($whitelist)) {
|
if (!is_array($whitelist)) {
|
||||||
$this->whitelist = $whitelist;
|
|
||||||
} else {
|
|
||||||
throw new Exception("Whitelist is not of a supported format.");
|
throw new Exception("Whitelist is not of a supported format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->whitelist = $whitelist;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@ Revision history
|
|||||||
v0.7.0.x (latest)
|
v0.7.0.x (latest)
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
|
* Added mode for test which enables logging verbose mode to file.
|
||||||
* Improved codestyle and added `phpcs.xml` to start using phpcs to check code style, fix #95.
|
* Improved codestyle and added `phpcs.xml` to start using phpcs to check code style, fix #95.
|
||||||
* Adding `composer.json` for publishing on packagist.
|
* Adding `composer.json` for publishing on packagist.
|
||||||
* Add permalink to setup for comparing images with `webroot/compare/compare.php`, fix #92.
|
* Add permalink to setup for comparing images with `webroot/compare/compare.php`, fix #92.
|
||||||
|
@@ -162,4 +162,19 @@ class CImageRemoteDownloadTest extends \PHPUnit_Framework_TestCase
|
|||||||
$res = $img->isRemoteSourceOnWhitelist("http://$hostname/img.jpg");
|
$res = $img->isRemoteSourceOnWhitelist("http://$hostname/img.jpg");
|
||||||
$this->assertFalse($res, "Should not be a valid hostname on the whitelist: '$hostname'.");
|
$this->assertFalse($res, "Should not be a valid hostname on the whitelist: '$hostname'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function testRemoteHostWhitelistNotConfigured()
|
||||||
|
{
|
||||||
|
$img = new CImage();
|
||||||
|
$res = $img->isRemoteSourceOnWhitelist(null);
|
||||||
|
$this->assertTrue($res, "Should allow when whitelist not configured.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,10 +27,10 @@ function errorPage($msg)
|
|||||||
|
|
||||||
if ($mode == 'development') {
|
if ($mode == 'development') {
|
||||||
die("[img.php] $msg");
|
die("[img.php] $msg");
|
||||||
} else {
|
|
||||||
error_log("[img.php] $msg");
|
|
||||||
die("HTTP/1.0 500 Internal Server Error");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error_log("[img.php] $msg");
|
||||||
|
die("HTTP/1.0 500 Internal Server Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -39,7 +39,13 @@ function errorPage($msg)
|
|||||||
* Custom exception handler.
|
* Custom exception handler.
|
||||||
*/
|
*/
|
||||||
set_exception_handler(function ($exception) {
|
set_exception_handler(function ($exception) {
|
||||||
errorPage("<p><b>img.php: Uncaught exception:</b> <p>" . $exception->getMessage() . "</p><pre>" . $exception->getTraceAsString(), "</pre>");
|
errorPage(
|
||||||
|
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||||
|
. $exception->getMessage()
|
||||||
|
. "</p><pre>"
|
||||||
|
. $exception->getTraceAsString()
|
||||||
|
. "</pre>"
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -111,10 +117,10 @@ function getConfig($key, $default)
|
|||||||
*/
|
*/
|
||||||
function verbose($msg = null)
|
function verbose($msg = null)
|
||||||
{
|
{
|
||||||
global $verbose;
|
global $verbose, $verboseFile;
|
||||||
static $log = array();
|
static $log = array();
|
||||||
|
|
||||||
if (!$verbose) {
|
if (!($verbose || $verboseFile)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,8 +149,10 @@ if (is_file($configFile)) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* verbose, v - do a verbose dump of what happens
|
* verbose, v - do a verbose dump of what happens
|
||||||
|
* vf - do verbose dump to file
|
||||||
*/
|
*/
|
||||||
$verbose = getDefined(array('verbose', 'v'), true, false);
|
$verbose = getDefined(array('verbose', 'v'), true, false);
|
||||||
|
$verboseFile = getDefined('vf', true, false);
|
||||||
verbose("img.php version = $version");
|
verbose("img.php version = $version");
|
||||||
|
|
||||||
|
|
||||||
@@ -170,19 +178,28 @@ if ($mode == 'strict') {
|
|||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
$verbose = false;
|
$verbose = false;
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
} elseif ($mode == 'production') {
|
} elseif ($mode == 'production') {
|
||||||
|
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
$verbose = false;
|
$verbose = false;
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
} elseif ($mode == 'development') {
|
} elseif ($mode == 'development') {
|
||||||
|
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 1);
|
||||||
ini_set('log_errors', 0);
|
ini_set('log_errors', 0);
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
|
} elseif ($mode == 'test') {
|
||||||
|
|
||||||
|
error_reporting(-1);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('log_errors', 0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
errorPage("Unknown mode: $mode");
|
errorPage("Unknown mode: $mode");
|
||||||
@@ -247,23 +264,22 @@ $refererHost = parse_url($referer, PHP_URL_HOST);
|
|||||||
if (!$allowHotlinking) {
|
if (!$allowHotlinking) {
|
||||||
if ($passwordMatch) {
|
if ($passwordMatch) {
|
||||||
; // Always allow when password match
|
; // Always allow when password match
|
||||||
|
verbose("Hotlinking since passwordmatch");
|
||||||
} elseif ($passwordMatch === false) {
|
} elseif ($passwordMatch === false) {
|
||||||
errorPage("Hotlinking/leeching not allowed when password missmatch.");
|
errorPage("Hotlinking/leeching not allowed when password missmatch.");
|
||||||
} elseif (!$referer) {
|
} elseif (!$referer) {
|
||||||
errorPage("Hotlinking/leeching not allowed and referer is missing.");
|
errorPage("Hotlinking/leeching not allowed and referer is missing.");
|
||||||
} elseif (strcmp($serverName, $refererHost) == 0) {
|
} elseif (strcmp($serverName, $refererHost) == 0) {
|
||||||
; // Allow when serverName matches refererHost
|
; // Allow when serverName matches refererHost
|
||||||
|
verbose("Hotlinking disallowed but serverName matches refererHost.");
|
||||||
} elseif (!empty($hotlinkingWhitelist)) {
|
} elseif (!empty($hotlinkingWhitelist)) {
|
||||||
|
$whitelist = new CWhitelist();
|
||||||
|
$allowedByWhitelist = $whitelist->check($refererHost, $hotlinkingWhitelist);
|
||||||
|
|
||||||
$allowedByWhitelist = false;
|
if ($allowedByWhitelist) {
|
||||||
foreach ($hotlinkingWhitelist as $val) {
|
verbose("Hotlinking/leeching allowed by whitelist.");
|
||||||
if (preg_match($val, $refererHost)) {
|
} else {
|
||||||
$allowedByWhitelist = true;
|
errorPage("Hotlinking/leeching not allowed by whitelist. Referer: $referer.");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$allowedByWhitelist) {
|
|
||||||
errorPage("Hotlinking/leeching not allowed by whitelist.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -295,7 +311,7 @@ if ($autoloader) {
|
|||||||
* Create the class for the image.
|
* Create the class for the image.
|
||||||
*/
|
*/
|
||||||
$img = new CImage();
|
$img = new CImage();
|
||||||
$img->setVerbose($verbose);
|
$img->setVerbose($verbose || $verboseFile);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -815,6 +831,13 @@ verbose("alias = $alias");
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cachepath from config.
|
||||||
|
*/
|
||||||
|
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display image if verbose mode
|
* Display image if verbose mode
|
||||||
*/
|
*/
|
||||||
@@ -853,15 +876,17 @@ EOD;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the cachepath from config.
|
* Log verbose details to file
|
||||||
*/
|
*/
|
||||||
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
if ($verboseFile) {
|
||||||
|
$img->setVerboseToFile("$cachePath/log.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load, process and output the image
|
* Load, process and output the image
|
||||||
*/
|
*/
|
||||||
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||||
->setSaveFolder($cachePath)
|
->setSaveFolder($cachePath)
|
||||||
->useCache($useCache)
|
->useCache($useCache)
|
||||||
|
@@ -201,9 +201,12 @@ return array(
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent leeching of images by controlling who can access them from where.
|
* Prevent leeching of images by controlling the hostname of those who
|
||||||
* Default it to allow hotlinking.
|
* can access the images. Default is to allow hotlinking.
|
||||||
* Password apply when hotlinking is disallowed, use password to allow.
|
*
|
||||||
|
* Password apply when hotlinking is disallowed, use password to allow
|
||||||
|
* hotlinking.
|
||||||
|
*
|
||||||
* The whitelist is an array of regexpes for allowed hostnames that can
|
* The whitelist is an array of regexpes for allowed hostnames that can
|
||||||
* hotlink images.
|
* hotlink images.
|
||||||
*
|
*
|
||||||
@@ -214,13 +217,11 @@ return array(
|
|||||||
/*
|
/*
|
||||||
'allow_hotlinking' => false,
|
'allow_hotlinking' => false,
|
||||||
'hotlinking_whitelist' => array(
|
'hotlinking_whitelist' => array(
|
||||||
'#^localhost$#',
|
'^dbwebb\.se$',
|
||||||
'#^dbwebb\.se$#',
|
|
||||||
),
|
),
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create custom shortcuts for more advanced expressions.
|
* Create custom shortcuts for more advanced expressions.
|
||||||
*
|
*
|
||||||
|
147
webroot/imgd.php
147
webroot/imgd.php
@@ -916,6 +916,22 @@ class CImage
|
|||||||
private $useCache = true;
|
private $useCache = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set whitelist for valid hostnames from where remote source can be
|
||||||
|
* downloaded.
|
||||||
|
*/
|
||||||
|
private $remoteHostWhitelist = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do verbose logging to file by setting this to a filename.
|
||||||
|
*/
|
||||||
|
private $verboseFileName = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties, the class is mutable and the method setOptions()
|
* Properties, the class is mutable and the method setOptions()
|
||||||
* decides (partly) what properties are created.
|
* decides (partly) what properties are created.
|
||||||
@@ -1016,10 +1032,12 @@ class CImage
|
|||||||
$this->allowRemote = $allow;
|
$this->allowRemote = $allow;
|
||||||
$this->remotePattern = is_null($pattern) ? $this->remotePattern : $pattern;
|
$this->remotePattern = is_null($pattern) ? $this->remotePattern : $pattern;
|
||||||
|
|
||||||
$this->log("Set remote download to: "
|
$this->log(
|
||||||
|
"Set remote download to: "
|
||||||
. ($this->allowRemote ? "true" : "false")
|
. ($this->allowRemote ? "true" : "false")
|
||||||
. " using pattern "
|
. " using pattern "
|
||||||
. $this->remotePattern);
|
. $this->remotePattern
|
||||||
|
);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -1053,7 +1071,10 @@ class CImage
|
|||||||
public function setRemoteHostWhitelist($whitelist = null)
|
public function setRemoteHostWhitelist($whitelist = null)
|
||||||
{
|
{
|
||||||
$this->remoteHostWhitelist = $whitelist;
|
$this->remoteHostWhitelist = $whitelist;
|
||||||
$this->log("Setting remote host whitelist to: " . print_r($this->remoteHostWhitelist, 1));
|
$this->log(
|
||||||
|
"Setting remote host whitelist to: "
|
||||||
|
. (is_null($whitelist) ? "null" : print_r($whitelist, 1))
|
||||||
|
);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1070,14 +1091,18 @@ class CImage
|
|||||||
public function isRemoteSourceOnWhitelist($src)
|
public function isRemoteSourceOnWhitelist($src)
|
||||||
{
|
{
|
||||||
if (is_null($this->remoteHostWhitelist)) {
|
if (is_null($this->remoteHostWhitelist)) {
|
||||||
$allow = true;
|
$this->log("Remote host on whitelist not configured - allowing.");
|
||||||
} else {
|
return true;
|
||||||
$whitelist = new CWhitelist();
|
|
||||||
$hostname = parse_url($src, PHP_URL_HOST);
|
|
||||||
$allow = $whitelist->check($hostname, $this->remoteHostWhitelist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->log("Remote host is on whitelist: " . ($allow ? "true" : "false"));
|
$whitelist = new CWhitelist();
|
||||||
|
$hostname = parse_url($src, PHP_URL_HOST);
|
||||||
|
$allow = $whitelist->check($hostname, $this->remoteHostWhitelist);
|
||||||
|
|
||||||
|
$this->log(
|
||||||
|
"Remote host is on whitelist: "
|
||||||
|
. ($allow ? "true" : "false")
|
||||||
|
);
|
||||||
return $allow;
|
return $allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2851,7 +2876,10 @@ class CImage
|
|||||||
if ($this->verbose) {
|
if ($this->verbose) {
|
||||||
$this->log("Last modified: " . $gmdate . " GMT");
|
$this->log("Last modified: " . $gmdate . " GMT");
|
||||||
$this->verboseOutput();
|
$this->verboseOutput();
|
||||||
exit;
|
|
||||||
|
if (is_null($this->verboseFileName)) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get details on image
|
// Get details on image
|
||||||
@@ -2929,6 +2957,21 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do verbose output to a file.
|
||||||
|
*
|
||||||
|
* @param string $fileName where to write the verbose output.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setVerboseToFile($fileName)
|
||||||
|
{
|
||||||
|
$this->log("Setting verbose output to file.");
|
||||||
|
$this->verboseFileName = $fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do verbose output and print out the log and the actual images.
|
* Do verbose output and print out the log and the actual images.
|
||||||
*
|
*
|
||||||
@@ -2954,10 +2997,17 @@ class CImage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo <<<EOD
|
if (!is_null($this->verboseFileName)) {
|
||||||
|
file_put_contents(
|
||||||
|
$this->verboseFileName,
|
||||||
|
str_replace("<br/>", "\n", $log)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
echo <<<EOD
|
||||||
<h1>CImage Verbose Output</h1>
|
<h1>CImage Verbose Output</h1>
|
||||||
<pre>{$log}</pre>
|
<pre>{$log}</pre>
|
||||||
EOD;
|
EOD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3002,11 +3052,11 @@ class CWhitelist
|
|||||||
*/
|
*/
|
||||||
public function set($whitelist = array())
|
public function set($whitelist = array())
|
||||||
{
|
{
|
||||||
if (is_array($whitelist)) {
|
if (!is_array($whitelist)) {
|
||||||
$this->whitelist = $whitelist;
|
|
||||||
} else {
|
|
||||||
throw new Exception("Whitelist is not of a supported format.");
|
throw new Exception("Whitelist is not of a supported format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->whitelist = $whitelist;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3070,10 +3120,10 @@ function errorPage($msg)
|
|||||||
|
|
||||||
if ($mode == 'development') {
|
if ($mode == 'development') {
|
||||||
die("[img.php] $msg");
|
die("[img.php] $msg");
|
||||||
} else {
|
|
||||||
error_log("[img.php] $msg");
|
|
||||||
die("HTTP/1.0 500 Internal Server Error");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error_log("[img.php] $msg");
|
||||||
|
die("HTTP/1.0 500 Internal Server Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3082,7 +3132,13 @@ function errorPage($msg)
|
|||||||
* Custom exception handler.
|
* Custom exception handler.
|
||||||
*/
|
*/
|
||||||
set_exception_handler(function ($exception) {
|
set_exception_handler(function ($exception) {
|
||||||
errorPage("<p><b>img.php: Uncaught exception:</b> <p>" . $exception->getMessage() . "</p><pre>" . $exception->getTraceAsString(), "</pre>");
|
errorPage(
|
||||||
|
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||||
|
. $exception->getMessage()
|
||||||
|
. "</p><pre>"
|
||||||
|
. $exception->getTraceAsString()
|
||||||
|
. "</pre>"
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -3154,10 +3210,10 @@ function getConfig($key, $default)
|
|||||||
*/
|
*/
|
||||||
function verbose($msg = null)
|
function verbose($msg = null)
|
||||||
{
|
{
|
||||||
global $verbose;
|
global $verbose, $verboseFile;
|
||||||
static $log = array();
|
static $log = array();
|
||||||
|
|
||||||
if (!$verbose) {
|
if (!($verbose || $verboseFile)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3186,8 +3242,10 @@ if (is_file($configFile)) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* verbose, v - do a verbose dump of what happens
|
* verbose, v - do a verbose dump of what happens
|
||||||
|
* vf - do verbose dump to file
|
||||||
*/
|
*/
|
||||||
$verbose = getDefined(array('verbose', 'v'), true, false);
|
$verbose = getDefined(array('verbose', 'v'), true, false);
|
||||||
|
$verboseFile = getDefined('vf', true, false);
|
||||||
verbose("img.php version = $version");
|
verbose("img.php version = $version");
|
||||||
|
|
||||||
|
|
||||||
@@ -3213,19 +3271,28 @@ if ($mode == 'strict') {
|
|||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
$verbose = false;
|
$verbose = false;
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
} elseif ($mode == 'production') {
|
} elseif ($mode == 'production') {
|
||||||
|
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
$verbose = false;
|
$verbose = false;
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
} elseif ($mode == 'development') {
|
} elseif ($mode == 'development') {
|
||||||
|
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 1);
|
||||||
ini_set('log_errors', 0);
|
ini_set('log_errors', 0);
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
|
} elseif ($mode == 'test') {
|
||||||
|
|
||||||
|
error_reporting(-1);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('log_errors', 0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
errorPage("Unknown mode: $mode");
|
errorPage("Unknown mode: $mode");
|
||||||
@@ -3290,23 +3357,22 @@ $refererHost = parse_url($referer, PHP_URL_HOST);
|
|||||||
if (!$allowHotlinking) {
|
if (!$allowHotlinking) {
|
||||||
if ($passwordMatch) {
|
if ($passwordMatch) {
|
||||||
; // Always allow when password match
|
; // Always allow when password match
|
||||||
|
verbose("Hotlinking since passwordmatch");
|
||||||
} elseif ($passwordMatch === false) {
|
} elseif ($passwordMatch === false) {
|
||||||
errorPage("Hotlinking/leeching not allowed when password missmatch.");
|
errorPage("Hotlinking/leeching not allowed when password missmatch.");
|
||||||
} elseif (!$referer) {
|
} elseif (!$referer) {
|
||||||
errorPage("Hotlinking/leeching not allowed and referer is missing.");
|
errorPage("Hotlinking/leeching not allowed and referer is missing.");
|
||||||
} elseif (strcmp($serverName, $refererHost) == 0) {
|
} elseif (strcmp($serverName, $refererHost) == 0) {
|
||||||
; // Allow when serverName matches refererHost
|
; // Allow when serverName matches refererHost
|
||||||
|
verbose("Hotlinking disallowed but serverName matches refererHost.");
|
||||||
} elseif (!empty($hotlinkingWhitelist)) {
|
} elseif (!empty($hotlinkingWhitelist)) {
|
||||||
|
$whitelist = new CWhitelist();
|
||||||
|
$allowedByWhitelist = $whitelist->check($refererHost, $hotlinkingWhitelist);
|
||||||
|
|
||||||
$allowedByWhitelist = false;
|
if ($allowedByWhitelist) {
|
||||||
foreach ($hotlinkingWhitelist as $val) {
|
verbose("Hotlinking/leeching allowed by whitelist.");
|
||||||
if (preg_match($val, $refererHost)) {
|
} else {
|
||||||
$allowedByWhitelist = true;
|
errorPage("Hotlinking/leeching not allowed by whitelist. Referer: $referer.");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$allowedByWhitelist) {
|
|
||||||
errorPage("Hotlinking/leeching not allowed by whitelist.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -3338,7 +3404,7 @@ if ($autoloader) {
|
|||||||
* Create the class for the image.
|
* Create the class for the image.
|
||||||
*/
|
*/
|
||||||
$img = new CImage();
|
$img = new CImage();
|
||||||
$img->setVerbose($verbose);
|
$img->setVerbose($verbose || $verboseFile);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -3858,6 +3924,13 @@ verbose("alias = $alias");
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cachepath from config.
|
||||||
|
*/
|
||||||
|
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display image if verbose mode
|
* Display image if verbose mode
|
||||||
*/
|
*/
|
||||||
@@ -3896,15 +3969,17 @@ EOD;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the cachepath from config.
|
* Log verbose details to file
|
||||||
*/
|
*/
|
||||||
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
if ($verboseFile) {
|
||||||
|
$img->setVerboseToFile("$cachePath/log.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load, process and output the image
|
* Load, process and output the image
|
||||||
*/
|
*/
|
||||||
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||||
->setSaveFolder($cachePath)
|
->setSaveFolder($cachePath)
|
||||||
->useCache($useCache)
|
->useCache($useCache)
|
||||||
|
147
webroot/imgp.php
147
webroot/imgp.php
@@ -916,6 +916,22 @@ class CImage
|
|||||||
private $useCache = true;
|
private $useCache = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set whitelist for valid hostnames from where remote source can be
|
||||||
|
* downloaded.
|
||||||
|
*/
|
||||||
|
private $remoteHostWhitelist = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do verbose logging to file by setting this to a filename.
|
||||||
|
*/
|
||||||
|
private $verboseFileName = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties, the class is mutable and the method setOptions()
|
* Properties, the class is mutable and the method setOptions()
|
||||||
* decides (partly) what properties are created.
|
* decides (partly) what properties are created.
|
||||||
@@ -1016,10 +1032,12 @@ class CImage
|
|||||||
$this->allowRemote = $allow;
|
$this->allowRemote = $allow;
|
||||||
$this->remotePattern = is_null($pattern) ? $this->remotePattern : $pattern;
|
$this->remotePattern = is_null($pattern) ? $this->remotePattern : $pattern;
|
||||||
|
|
||||||
$this->log("Set remote download to: "
|
$this->log(
|
||||||
|
"Set remote download to: "
|
||||||
. ($this->allowRemote ? "true" : "false")
|
. ($this->allowRemote ? "true" : "false")
|
||||||
. " using pattern "
|
. " using pattern "
|
||||||
. $this->remotePattern);
|
. $this->remotePattern
|
||||||
|
);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -1053,7 +1071,10 @@ class CImage
|
|||||||
public function setRemoteHostWhitelist($whitelist = null)
|
public function setRemoteHostWhitelist($whitelist = null)
|
||||||
{
|
{
|
||||||
$this->remoteHostWhitelist = $whitelist;
|
$this->remoteHostWhitelist = $whitelist;
|
||||||
$this->log("Setting remote host whitelist to: " . print_r($this->remoteHostWhitelist, 1));
|
$this->log(
|
||||||
|
"Setting remote host whitelist to: "
|
||||||
|
. (is_null($whitelist) ? "null" : print_r($whitelist, 1))
|
||||||
|
);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1070,14 +1091,18 @@ class CImage
|
|||||||
public function isRemoteSourceOnWhitelist($src)
|
public function isRemoteSourceOnWhitelist($src)
|
||||||
{
|
{
|
||||||
if (is_null($this->remoteHostWhitelist)) {
|
if (is_null($this->remoteHostWhitelist)) {
|
||||||
$allow = true;
|
$this->log("Remote host on whitelist not configured - allowing.");
|
||||||
} else {
|
return true;
|
||||||
$whitelist = new CWhitelist();
|
|
||||||
$hostname = parse_url($src, PHP_URL_HOST);
|
|
||||||
$allow = $whitelist->check($hostname, $this->remoteHostWhitelist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->log("Remote host is on whitelist: " . ($allow ? "true" : "false"));
|
$whitelist = new CWhitelist();
|
||||||
|
$hostname = parse_url($src, PHP_URL_HOST);
|
||||||
|
$allow = $whitelist->check($hostname, $this->remoteHostWhitelist);
|
||||||
|
|
||||||
|
$this->log(
|
||||||
|
"Remote host is on whitelist: "
|
||||||
|
. ($allow ? "true" : "false")
|
||||||
|
);
|
||||||
return $allow;
|
return $allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2851,7 +2876,10 @@ class CImage
|
|||||||
if ($this->verbose) {
|
if ($this->verbose) {
|
||||||
$this->log("Last modified: " . $gmdate . " GMT");
|
$this->log("Last modified: " . $gmdate . " GMT");
|
||||||
$this->verboseOutput();
|
$this->verboseOutput();
|
||||||
exit;
|
|
||||||
|
if (is_null($this->verboseFileName)) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get details on image
|
// Get details on image
|
||||||
@@ -2929,6 +2957,21 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do verbose output to a file.
|
||||||
|
*
|
||||||
|
* @param string $fileName where to write the verbose output.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setVerboseToFile($fileName)
|
||||||
|
{
|
||||||
|
$this->log("Setting verbose output to file.");
|
||||||
|
$this->verboseFileName = $fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do verbose output and print out the log and the actual images.
|
* Do verbose output and print out the log and the actual images.
|
||||||
*
|
*
|
||||||
@@ -2954,10 +2997,17 @@ class CImage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo <<<EOD
|
if (!is_null($this->verboseFileName)) {
|
||||||
|
file_put_contents(
|
||||||
|
$this->verboseFileName,
|
||||||
|
str_replace("<br/>", "\n", $log)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
echo <<<EOD
|
||||||
<h1>CImage Verbose Output</h1>
|
<h1>CImage Verbose Output</h1>
|
||||||
<pre>{$log}</pre>
|
<pre>{$log}</pre>
|
||||||
EOD;
|
EOD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3002,11 +3052,11 @@ class CWhitelist
|
|||||||
*/
|
*/
|
||||||
public function set($whitelist = array())
|
public function set($whitelist = array())
|
||||||
{
|
{
|
||||||
if (is_array($whitelist)) {
|
if (!is_array($whitelist)) {
|
||||||
$this->whitelist = $whitelist;
|
|
||||||
} else {
|
|
||||||
throw new Exception("Whitelist is not of a supported format.");
|
throw new Exception("Whitelist is not of a supported format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->whitelist = $whitelist;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3070,10 +3120,10 @@ function errorPage($msg)
|
|||||||
|
|
||||||
if ($mode == 'development') {
|
if ($mode == 'development') {
|
||||||
die("[img.php] $msg");
|
die("[img.php] $msg");
|
||||||
} else {
|
|
||||||
error_log("[img.php] $msg");
|
|
||||||
die("HTTP/1.0 500 Internal Server Error");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error_log("[img.php] $msg");
|
||||||
|
die("HTTP/1.0 500 Internal Server Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3082,7 +3132,13 @@ function errorPage($msg)
|
|||||||
* Custom exception handler.
|
* Custom exception handler.
|
||||||
*/
|
*/
|
||||||
set_exception_handler(function ($exception) {
|
set_exception_handler(function ($exception) {
|
||||||
errorPage("<p><b>img.php: Uncaught exception:</b> <p>" . $exception->getMessage() . "</p><pre>" . $exception->getTraceAsString(), "</pre>");
|
errorPage(
|
||||||
|
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||||
|
. $exception->getMessage()
|
||||||
|
. "</p><pre>"
|
||||||
|
. $exception->getTraceAsString()
|
||||||
|
. "</pre>"
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -3154,10 +3210,10 @@ function getConfig($key, $default)
|
|||||||
*/
|
*/
|
||||||
function verbose($msg = null)
|
function verbose($msg = null)
|
||||||
{
|
{
|
||||||
global $verbose;
|
global $verbose, $verboseFile;
|
||||||
static $log = array();
|
static $log = array();
|
||||||
|
|
||||||
if (!$verbose) {
|
if (!($verbose || $verboseFile)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3186,8 +3242,10 @@ if (is_file($configFile)) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* verbose, v - do a verbose dump of what happens
|
* verbose, v - do a verbose dump of what happens
|
||||||
|
* vf - do verbose dump to file
|
||||||
*/
|
*/
|
||||||
$verbose = getDefined(array('verbose', 'v'), true, false);
|
$verbose = getDefined(array('verbose', 'v'), true, false);
|
||||||
|
$verboseFile = getDefined('vf', true, false);
|
||||||
verbose("img.php version = $version");
|
verbose("img.php version = $version");
|
||||||
|
|
||||||
|
|
||||||
@@ -3213,19 +3271,28 @@ if ($mode == 'strict') {
|
|||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
$verbose = false;
|
$verbose = false;
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
} elseif ($mode == 'production') {
|
} elseif ($mode == 'production') {
|
||||||
|
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
$verbose = false;
|
$verbose = false;
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
} elseif ($mode == 'development') {
|
} elseif ($mode == 'development') {
|
||||||
|
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 1);
|
||||||
ini_set('log_errors', 0);
|
ini_set('log_errors', 0);
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
|
} elseif ($mode == 'test') {
|
||||||
|
|
||||||
|
error_reporting(-1);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('log_errors', 0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
errorPage("Unknown mode: $mode");
|
errorPage("Unknown mode: $mode");
|
||||||
@@ -3290,23 +3357,22 @@ $refererHost = parse_url($referer, PHP_URL_HOST);
|
|||||||
if (!$allowHotlinking) {
|
if (!$allowHotlinking) {
|
||||||
if ($passwordMatch) {
|
if ($passwordMatch) {
|
||||||
; // Always allow when password match
|
; // Always allow when password match
|
||||||
|
verbose("Hotlinking since passwordmatch");
|
||||||
} elseif ($passwordMatch === false) {
|
} elseif ($passwordMatch === false) {
|
||||||
errorPage("Hotlinking/leeching not allowed when password missmatch.");
|
errorPage("Hotlinking/leeching not allowed when password missmatch.");
|
||||||
} elseif (!$referer) {
|
} elseif (!$referer) {
|
||||||
errorPage("Hotlinking/leeching not allowed and referer is missing.");
|
errorPage("Hotlinking/leeching not allowed and referer is missing.");
|
||||||
} elseif (strcmp($serverName, $refererHost) == 0) {
|
} elseif (strcmp($serverName, $refererHost) == 0) {
|
||||||
; // Allow when serverName matches refererHost
|
; // Allow when serverName matches refererHost
|
||||||
|
verbose("Hotlinking disallowed but serverName matches refererHost.");
|
||||||
} elseif (!empty($hotlinkingWhitelist)) {
|
} elseif (!empty($hotlinkingWhitelist)) {
|
||||||
|
$whitelist = new CWhitelist();
|
||||||
|
$allowedByWhitelist = $whitelist->check($refererHost, $hotlinkingWhitelist);
|
||||||
|
|
||||||
$allowedByWhitelist = false;
|
if ($allowedByWhitelist) {
|
||||||
foreach ($hotlinkingWhitelist as $val) {
|
verbose("Hotlinking/leeching allowed by whitelist.");
|
||||||
if (preg_match($val, $refererHost)) {
|
} else {
|
||||||
$allowedByWhitelist = true;
|
errorPage("Hotlinking/leeching not allowed by whitelist. Referer: $referer.");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$allowedByWhitelist) {
|
|
||||||
errorPage("Hotlinking/leeching not allowed by whitelist.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -3338,7 +3404,7 @@ if ($autoloader) {
|
|||||||
* Create the class for the image.
|
* Create the class for the image.
|
||||||
*/
|
*/
|
||||||
$img = new CImage();
|
$img = new CImage();
|
||||||
$img->setVerbose($verbose);
|
$img->setVerbose($verbose || $verboseFile);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -3858,6 +3924,13 @@ verbose("alias = $alias");
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cachepath from config.
|
||||||
|
*/
|
||||||
|
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display image if verbose mode
|
* Display image if verbose mode
|
||||||
*/
|
*/
|
||||||
@@ -3896,15 +3969,17 @@ EOD;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the cachepath from config.
|
* Log verbose details to file
|
||||||
*/
|
*/
|
||||||
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
if ($verboseFile) {
|
||||||
|
$img->setVerboseToFile("$cachePath/log.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load, process and output the image
|
* Load, process and output the image
|
||||||
*/
|
*/
|
||||||
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||||
->setSaveFolder($cachePath)
|
->setSaveFolder($cachePath)
|
||||||
->useCache($useCache)
|
->useCache($useCache)
|
||||||
|
147
webroot/imgs.php
147
webroot/imgs.php
@@ -916,6 +916,22 @@ class CImage
|
|||||||
private $useCache = true;
|
private $useCache = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set whitelist for valid hostnames from where remote source can be
|
||||||
|
* downloaded.
|
||||||
|
*/
|
||||||
|
private $remoteHostWhitelist = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do verbose logging to file by setting this to a filename.
|
||||||
|
*/
|
||||||
|
private $verboseFileName = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties, the class is mutable and the method setOptions()
|
* Properties, the class is mutable and the method setOptions()
|
||||||
* decides (partly) what properties are created.
|
* decides (partly) what properties are created.
|
||||||
@@ -1016,10 +1032,12 @@ class CImage
|
|||||||
$this->allowRemote = $allow;
|
$this->allowRemote = $allow;
|
||||||
$this->remotePattern = is_null($pattern) ? $this->remotePattern : $pattern;
|
$this->remotePattern = is_null($pattern) ? $this->remotePattern : $pattern;
|
||||||
|
|
||||||
$this->log("Set remote download to: "
|
$this->log(
|
||||||
|
"Set remote download to: "
|
||||||
. ($this->allowRemote ? "true" : "false")
|
. ($this->allowRemote ? "true" : "false")
|
||||||
. " using pattern "
|
. " using pattern "
|
||||||
. $this->remotePattern);
|
. $this->remotePattern
|
||||||
|
);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -1053,7 +1071,10 @@ class CImage
|
|||||||
public function setRemoteHostWhitelist($whitelist = null)
|
public function setRemoteHostWhitelist($whitelist = null)
|
||||||
{
|
{
|
||||||
$this->remoteHostWhitelist = $whitelist;
|
$this->remoteHostWhitelist = $whitelist;
|
||||||
$this->log("Setting remote host whitelist to: " . print_r($this->remoteHostWhitelist, 1));
|
$this->log(
|
||||||
|
"Setting remote host whitelist to: "
|
||||||
|
. (is_null($whitelist) ? "null" : print_r($whitelist, 1))
|
||||||
|
);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1070,14 +1091,18 @@ class CImage
|
|||||||
public function isRemoteSourceOnWhitelist($src)
|
public function isRemoteSourceOnWhitelist($src)
|
||||||
{
|
{
|
||||||
if (is_null($this->remoteHostWhitelist)) {
|
if (is_null($this->remoteHostWhitelist)) {
|
||||||
$allow = true;
|
$this->log("Remote host on whitelist not configured - allowing.");
|
||||||
} else {
|
return true;
|
||||||
$whitelist = new CWhitelist();
|
|
||||||
$hostname = parse_url($src, PHP_URL_HOST);
|
|
||||||
$allow = $whitelist->check($hostname, $this->remoteHostWhitelist);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->log("Remote host is on whitelist: " . ($allow ? "true" : "false"));
|
$whitelist = new CWhitelist();
|
||||||
|
$hostname = parse_url($src, PHP_URL_HOST);
|
||||||
|
$allow = $whitelist->check($hostname, $this->remoteHostWhitelist);
|
||||||
|
|
||||||
|
$this->log(
|
||||||
|
"Remote host is on whitelist: "
|
||||||
|
. ($allow ? "true" : "false")
|
||||||
|
);
|
||||||
return $allow;
|
return $allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2851,7 +2876,10 @@ class CImage
|
|||||||
if ($this->verbose) {
|
if ($this->verbose) {
|
||||||
$this->log("Last modified: " . $gmdate . " GMT");
|
$this->log("Last modified: " . $gmdate . " GMT");
|
||||||
$this->verboseOutput();
|
$this->verboseOutput();
|
||||||
exit;
|
|
||||||
|
if (is_null($this->verboseFileName)) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get details on image
|
// Get details on image
|
||||||
@@ -2929,6 +2957,21 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do verbose output to a file.
|
||||||
|
*
|
||||||
|
* @param string $fileName where to write the verbose output.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setVerboseToFile($fileName)
|
||||||
|
{
|
||||||
|
$this->log("Setting verbose output to file.");
|
||||||
|
$this->verboseFileName = $fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do verbose output and print out the log and the actual images.
|
* Do verbose output and print out the log and the actual images.
|
||||||
*
|
*
|
||||||
@@ -2954,10 +2997,17 @@ class CImage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo <<<EOD
|
if (!is_null($this->verboseFileName)) {
|
||||||
|
file_put_contents(
|
||||||
|
$this->verboseFileName,
|
||||||
|
str_replace("<br/>", "\n", $log)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
echo <<<EOD
|
||||||
<h1>CImage Verbose Output</h1>
|
<h1>CImage Verbose Output</h1>
|
||||||
<pre>{$log}</pre>
|
<pre>{$log}</pre>
|
||||||
EOD;
|
EOD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3002,11 +3052,11 @@ class CWhitelist
|
|||||||
*/
|
*/
|
||||||
public function set($whitelist = array())
|
public function set($whitelist = array())
|
||||||
{
|
{
|
||||||
if (is_array($whitelist)) {
|
if (!is_array($whitelist)) {
|
||||||
$this->whitelist = $whitelist;
|
|
||||||
} else {
|
|
||||||
throw new Exception("Whitelist is not of a supported format.");
|
throw new Exception("Whitelist is not of a supported format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->whitelist = $whitelist;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3070,10 +3120,10 @@ function errorPage($msg)
|
|||||||
|
|
||||||
if ($mode == 'development') {
|
if ($mode == 'development') {
|
||||||
die("[img.php] $msg");
|
die("[img.php] $msg");
|
||||||
} else {
|
|
||||||
error_log("[img.php] $msg");
|
|
||||||
die("HTTP/1.0 500 Internal Server Error");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error_log("[img.php] $msg");
|
||||||
|
die("HTTP/1.0 500 Internal Server Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3082,7 +3132,13 @@ function errorPage($msg)
|
|||||||
* Custom exception handler.
|
* Custom exception handler.
|
||||||
*/
|
*/
|
||||||
set_exception_handler(function ($exception) {
|
set_exception_handler(function ($exception) {
|
||||||
errorPage("<p><b>img.php: Uncaught exception:</b> <p>" . $exception->getMessage() . "</p><pre>" . $exception->getTraceAsString(), "</pre>");
|
errorPage(
|
||||||
|
"<p><b>img.php: Uncaught exception:</b> <p>"
|
||||||
|
. $exception->getMessage()
|
||||||
|
. "</p><pre>"
|
||||||
|
. $exception->getTraceAsString()
|
||||||
|
. "</pre>"
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -3154,10 +3210,10 @@ function getConfig($key, $default)
|
|||||||
*/
|
*/
|
||||||
function verbose($msg = null)
|
function verbose($msg = null)
|
||||||
{
|
{
|
||||||
global $verbose;
|
global $verbose, $verboseFile;
|
||||||
static $log = array();
|
static $log = array();
|
||||||
|
|
||||||
if (!$verbose) {
|
if (!($verbose || $verboseFile)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3186,8 +3242,10 @@ if (is_file($configFile)) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* verbose, v - do a verbose dump of what happens
|
* verbose, v - do a verbose dump of what happens
|
||||||
|
* vf - do verbose dump to file
|
||||||
*/
|
*/
|
||||||
$verbose = getDefined(array('verbose', 'v'), true, false);
|
$verbose = getDefined(array('verbose', 'v'), true, false);
|
||||||
|
$verboseFile = getDefined('vf', true, false);
|
||||||
verbose("img.php version = $version");
|
verbose("img.php version = $version");
|
||||||
|
|
||||||
|
|
||||||
@@ -3213,19 +3271,28 @@ if ($mode == 'strict') {
|
|||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
$verbose = false;
|
$verbose = false;
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
} elseif ($mode == 'production') {
|
} elseif ($mode == 'production') {
|
||||||
|
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
ini_set('display_errors', 0);
|
ini_set('display_errors', 0);
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
$verbose = false;
|
$verbose = false;
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
} elseif ($mode == 'development') {
|
} elseif ($mode == 'development') {
|
||||||
|
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
ini_set('display_errors', 1);
|
ini_set('display_errors', 1);
|
||||||
ini_set('log_errors', 0);
|
ini_set('log_errors', 0);
|
||||||
|
$verboseFile = false;
|
||||||
|
|
||||||
|
} elseif ($mode == 'test') {
|
||||||
|
|
||||||
|
error_reporting(-1);
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
ini_set('log_errors', 0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
errorPage("Unknown mode: $mode");
|
errorPage("Unknown mode: $mode");
|
||||||
@@ -3290,23 +3357,22 @@ $refererHost = parse_url($referer, PHP_URL_HOST);
|
|||||||
if (!$allowHotlinking) {
|
if (!$allowHotlinking) {
|
||||||
if ($passwordMatch) {
|
if ($passwordMatch) {
|
||||||
; // Always allow when password match
|
; // Always allow when password match
|
||||||
|
verbose("Hotlinking since passwordmatch");
|
||||||
} elseif ($passwordMatch === false) {
|
} elseif ($passwordMatch === false) {
|
||||||
errorPage("Hotlinking/leeching not allowed when password missmatch.");
|
errorPage("Hotlinking/leeching not allowed when password missmatch.");
|
||||||
} elseif (!$referer) {
|
} elseif (!$referer) {
|
||||||
errorPage("Hotlinking/leeching not allowed and referer is missing.");
|
errorPage("Hotlinking/leeching not allowed and referer is missing.");
|
||||||
} elseif (strcmp($serverName, $refererHost) == 0) {
|
} elseif (strcmp($serverName, $refererHost) == 0) {
|
||||||
; // Allow when serverName matches refererHost
|
; // Allow when serverName matches refererHost
|
||||||
|
verbose("Hotlinking disallowed but serverName matches refererHost.");
|
||||||
} elseif (!empty($hotlinkingWhitelist)) {
|
} elseif (!empty($hotlinkingWhitelist)) {
|
||||||
|
$whitelist = new CWhitelist();
|
||||||
|
$allowedByWhitelist = $whitelist->check($refererHost, $hotlinkingWhitelist);
|
||||||
|
|
||||||
$allowedByWhitelist = false;
|
if ($allowedByWhitelist) {
|
||||||
foreach ($hotlinkingWhitelist as $val) {
|
verbose("Hotlinking/leeching allowed by whitelist.");
|
||||||
if (preg_match($val, $refererHost)) {
|
} else {
|
||||||
$allowedByWhitelist = true;
|
errorPage("Hotlinking/leeching not allowed by whitelist. Referer: $referer.");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$allowedByWhitelist) {
|
|
||||||
errorPage("Hotlinking/leeching not allowed by whitelist.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -3338,7 +3404,7 @@ if ($autoloader) {
|
|||||||
* Create the class for the image.
|
* Create the class for the image.
|
||||||
*/
|
*/
|
||||||
$img = new CImage();
|
$img = new CImage();
|
||||||
$img->setVerbose($verbose);
|
$img->setVerbose($verbose || $verboseFile);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -3858,6 +3924,13 @@ verbose("alias = $alias");
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cachepath from config.
|
||||||
|
*/
|
||||||
|
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display image if verbose mode
|
* Display image if verbose mode
|
||||||
*/
|
*/
|
||||||
@@ -3896,15 +3969,17 @@ EOD;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the cachepath from config.
|
* Log verbose details to file
|
||||||
*/
|
*/
|
||||||
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
if ($verboseFile) {
|
||||||
|
$img->setVerboseToFile("$cachePath/log.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load, process and output the image
|
* Load, process and output the image
|
||||||
*/
|
*/
|
||||||
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
$img->log("Incoming arguments: " . print_r(verbose(), 1))
|
||||||
->setSaveFolder($cachePath)
|
->setSaveFolder($cachePath)
|
||||||
->useCache($useCache)
|
->useCache($useCache)
|
||||||
|
Reference in New Issue
Block a user