mirror of
https://github.com/mosbth/cimage.git
synced 2025-08-01 22:00:31 +02:00
prepare to test fast track cache
This commit is contained in:
231
CFastTrackCache.php
Normal file
231
CFastTrackCache.php
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Enable a fast track cache with a json representation of the image delivery.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CFastTrackCache
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Cache is disabled to start with.
|
||||||
|
*/
|
||||||
|
private $enabled = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to the cache directory.
|
||||||
|
*/
|
||||||
|
private $path;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filename of current cache item.
|
||||||
|
*/
|
||||||
|
private $filename;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container with items to store as cached item.
|
||||||
|
*/
|
||||||
|
private $container;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable cache.
|
||||||
|
*
|
||||||
|
* @param boolean $enable set to true to enable, false to disable
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function enable($enabled)
|
||||||
|
{
|
||||||
|
$this->enabled = $enabled;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the path to the cache dir which must exist.
|
||||||
|
*
|
||||||
|
* @param string $path to the cache dir.
|
||||||
|
*
|
||||||
|
* @throws Exception when $path is not a directory.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setCacheDir($path)
|
||||||
|
{
|
||||||
|
if (!is_dir($path)) {
|
||||||
|
throw new Exception("Cachedir is not a directory.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->path = rtrim($path, "/");
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the filename to store in cache, use the querystring to create that
|
||||||
|
* filename.
|
||||||
|
*
|
||||||
|
* @param array $clear items to clear in $_GET when creating the filename.
|
||||||
|
*
|
||||||
|
* @return string as filename created.
|
||||||
|
*/
|
||||||
|
public function setFilename($clear)
|
||||||
|
{
|
||||||
|
$query = $_GET;
|
||||||
|
|
||||||
|
// Remove parts from querystring that should not be part of filename
|
||||||
|
foreach ($clear as $value) {
|
||||||
|
unset($query[$value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
arsort($query);
|
||||||
|
$queryAsString = http_build_query($query);
|
||||||
|
|
||||||
|
$this->filename = md5($queryAsString);
|
||||||
|
$this->container["query-string"] = $queryAsString;
|
||||||
|
|
||||||
|
return $this->filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add header items.
|
||||||
|
*
|
||||||
|
* @param string $header add this as header.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addHeader($header)
|
||||||
|
{
|
||||||
|
$this->container["header"][] = $header;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add header items on output, these are not output when 304.
|
||||||
|
*
|
||||||
|
* @param string $header add this as header.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addHeaderOnOutput($header)
|
||||||
|
{
|
||||||
|
$this->container["header-output"][] = $header;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set path to source image to.
|
||||||
|
*
|
||||||
|
* @param string $source path to source image file.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setSource($source)
|
||||||
|
{
|
||||||
|
$this->container["source"] = $source;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set last modified of source image, use to check for 304.
|
||||||
|
*
|
||||||
|
* @param string $lastModified
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setLastModified($lastModified)
|
||||||
|
{
|
||||||
|
$this->container["last-modified"] = $lastModified;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get filename of cached item.
|
||||||
|
*
|
||||||
|
* @return string as filename.
|
||||||
|
*/
|
||||||
|
public function getFilename()
|
||||||
|
{
|
||||||
|
return $this->path . "/" . $this->filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write current item to cache.
|
||||||
|
*
|
||||||
|
* @return boolean if cache file was written.
|
||||||
|
*/
|
||||||
|
public function writeToCache()
|
||||||
|
{
|
||||||
|
if (!$this->enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_dir($this->path) && is_writable($this->path)) {
|
||||||
|
$filename = $this->getFilename();
|
||||||
|
return file_put_contents($filename, json_encode($this->container)) !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output current item from cache, if available.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function output()
|
||||||
|
{
|
||||||
|
$filename = $this->getFilename();
|
||||||
|
if (!is_readable($filename)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$item = json_decode(file_get_contents($filename), true);
|
||||||
|
|
||||||
|
if (!is_readable($item["source"])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($item["header"] as $value) {
|
||||||
|
header($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])
|
||||||
|
&& strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) == $item["last-modified"]) {
|
||||||
|
header("HTTP/1.0 304 Not Modified");
|
||||||
|
debug("fast track 304");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($item["header-output"] as $value) {
|
||||||
|
header($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
readfile($item["source"]);
|
||||||
|
debug("fast track 200");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
55
CImage.php
55
CImage.php
@@ -379,6 +379,12 @@ class CImage
|
|||||||
private $useCache = true;
|
private $useCache = true;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the fasttrackCacke to start with, inject an object to enable it.
|
||||||
|
*/
|
||||||
|
private $fastTrackCache = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set whitelist for valid hostnames from where remote source can be
|
* Set whitelist for valid hostnames from where remote source can be
|
||||||
@@ -446,6 +452,25 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject object and use it, must be available as member.
|
||||||
|
*
|
||||||
|
* @param string $property to set as object.
|
||||||
|
* @param object $object to set to property.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function injectDependency($property, $object)
|
||||||
|
{
|
||||||
|
if (!property_exists($this, $property)) {
|
||||||
|
$this->raiseError("Injecting unknown property.");
|
||||||
|
}
|
||||||
|
$this->$property = $object;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set verbose mode.
|
* Set verbose mode.
|
||||||
*
|
*
|
||||||
@@ -2520,7 +2545,7 @@ class CImage
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add HTTP header for putputting together with image.
|
* Add HTTP header for output together with image.
|
||||||
*
|
*
|
||||||
* @param string $type the header type such as "Cache-Control"
|
* @param string $type the header type such as "Cache-Control"
|
||||||
* @param string $value the value to use
|
* @param string $value the value to use
|
||||||
@@ -2571,14 +2596,20 @@ class CImage
|
|||||||
// Get image modification time
|
// Get image modification time
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
$lastModified = filemtime($file);
|
$lastModified = filemtime($file);
|
||||||
$gmdate = gmdate("D, d M Y H:i:s", $lastModified);
|
$lastModifiedFormat = "D, d M Y H:i:s";
|
||||||
|
$gmdate = gmdate($lastModifiedFormat, $lastModified);
|
||||||
|
|
||||||
if (!$this->verbose) {
|
if (!$this->verbose) {
|
||||||
header('Last-Modified: ' . $gmdate . " GMT");
|
$header = "Last-Modified: $gmdate GMT";
|
||||||
|
header($header);
|
||||||
|
$this->fastTrackCache->addHeader($header);
|
||||||
|
$this->fastTrackCache->setLastModified($lastModified);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->HTTPHeader as $key => $val) {
|
foreach ($this->HTTPHeader as $key => $val) {
|
||||||
header("$key: $val");
|
$header = "$key: $val";
|
||||||
|
header($header);
|
||||||
|
$this->fastTrackCache->addHeader($header);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified) {
|
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModified) {
|
||||||
@@ -2590,6 +2621,7 @@ class CImage
|
|||||||
}
|
}
|
||||||
|
|
||||||
header("HTTP/1.0 304 Not Modified");
|
header("HTTP/1.0 304 Not Modified");
|
||||||
|
debug("standard 304");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@@ -2610,9 +2642,18 @@ class CImage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header("Content-type: $mime");
|
$header = "Content-type: $mime";
|
||||||
header("Content-length: $size");
|
header($header);
|
||||||
|
$this->fastTrackCache->addHeaderOnOutput($header);
|
||||||
|
|
||||||
|
$header = "Content-length: $size";
|
||||||
|
header($header);
|
||||||
|
$this->fastTrackCache->addHeaderOnOutput($header);
|
||||||
|
|
||||||
|
$this->fastTrackCache->setSource($file);
|
||||||
|
$this->fastTrackCache->writeToCache();
|
||||||
readfile($file);
|
readfile($file);
|
||||||
|
debug("standard 200");
|
||||||
}
|
}
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
|
0
cache/README.md
vendored
0
cache/README.md
vendored
@@ -14,6 +14,17 @@ $version = "v0.7.12 (2016-06-01)";
|
|||||||
define("CIMAGE_USER_AGENT", "CImage/$version");
|
define("CIMAGE_USER_AGENT", "CImage/$version");
|
||||||
|
|
||||||
|
|
||||||
|
// Include debug functions
|
||||||
|
function debug($msg)
|
||||||
|
{
|
||||||
|
$file = "/tmp/cimage";
|
||||||
|
$msg .= ":" . count(get_included_files());
|
||||||
|
$msg .= ":" . round(memory_get_peak_usage()/1024/1024, 3) . "MB";
|
||||||
|
$msg .= ":" . (string) round((microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']), 6) . "ms";
|
||||||
|
file_put_contents($file, "$msg\n", FILE_APPEND);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display error message.
|
* Display error message.
|
||||||
@@ -348,7 +359,8 @@ if ($autoloader) {
|
|||||||
/**
|
/**
|
||||||
* Create the class for the image.
|
* Create the class for the image.
|
||||||
*/
|
*/
|
||||||
$img = new CImage();
|
$CImage = getConfig('CImage', 'CImage');
|
||||||
|
$img = new $CImage();
|
||||||
$img->setVerbose($verbose || $verboseFile);
|
$img->setVerbose($verbose || $verboseFile);
|
||||||
|
|
||||||
|
|
||||||
@@ -356,12 +368,46 @@ $img->setVerbose($verbose || $verboseFile);
|
|||||||
/**
|
/**
|
||||||
* Get the cachepath from config.
|
* Get the cachepath from config.
|
||||||
*/
|
*/
|
||||||
|
$CCache = getConfig('CCache', 'CCache');
|
||||||
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
$cachePath = getConfig('cache_path', __DIR__ . '/../cache/');
|
||||||
$cache = new CCache();
|
$cache = new $CCache();
|
||||||
$cache->setDir($cachePath);
|
$cache->setDir($cachePath);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* no-cache, nc - skip the cached version and process and create a new version in cache.
|
||||||
|
*/
|
||||||
|
$useCache = getDefined(array('no-cache', 'nc'), false, true);
|
||||||
|
|
||||||
|
verbose("use cache = $useCache");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare fast track cache for swriting cache items.
|
||||||
|
*/
|
||||||
|
$fastTrackCache = "fasttrack";
|
||||||
|
$allowFastTrackCache = getConfig('fast_track_allow', false);
|
||||||
|
|
||||||
|
$CFastTrackCache = getConfig('CFastTrackCache', 'CFastTrackCache');
|
||||||
|
$ftc = new $CFastTrackCache();
|
||||||
|
$ftc->setCacheDir($cache->getPathToSubdir($fastTrackCache))
|
||||||
|
->enable($allowFastTrackCache)
|
||||||
|
->setFilename(array('no-cache', 'nc'));
|
||||||
|
$img->injectDependency("fastTrackCache", $ftc);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load and output images from fast track cache, if items are available
|
||||||
|
* in cache.
|
||||||
|
*/
|
||||||
|
if ($useCache && $allowFastTrackCache) {
|
||||||
|
$ftc->output();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow or disallow remote download of images from other servers.
|
* Allow or disallow remote download of images from other servers.
|
||||||
@@ -707,15 +753,6 @@ verbose("use original = $useOriginal");
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* no-cache, nc - skip the cached version and process and create a new version in cache.
|
|
||||||
*/
|
|
||||||
$useCache = getDefined(array('no-cache', 'nc'), false, true);
|
|
||||||
|
|
||||||
verbose("use cache = $useCache");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* quality, q - set level of quality for jpeg images
|
* quality, q - set level of quality for jpeg images
|
||||||
*/
|
*/
|
||||||
@@ -1082,6 +1119,9 @@ if ($status) {
|
|||||||
$res = $cache->getStatusOfSubdir("srgb");
|
$res = $cache->getStatusOfSubdir("srgb");
|
||||||
$text .= "Cache srgb $res\n";
|
$text .= "Cache srgb $res\n";
|
||||||
|
|
||||||
|
$res = $cache->getStatusOfSubdir($fasttrackCache);
|
||||||
|
$text .= "Cache fasttrack $res\n";
|
||||||
|
|
||||||
$text .= "Alias path writable = " . is_writable($aliasPath) . "\n";
|
$text .= "Alias path writable = " . is_writable($aliasPath) . "\n";
|
||||||
|
|
||||||
$no = extension_loaded('exif') ? null : 'NOT';
|
$no = extension_loaded('exif') ? null : 'NOT';
|
||||||
|
@@ -23,7 +23,7 @@ return array(
|
|||||||
* mode: 'production'
|
* mode: 'production'
|
||||||
*/
|
*/
|
||||||
//'mode' => 'production',
|
//'mode' => 'production',
|
||||||
//'mode' => 'development',
|
'mode' => 'development',
|
||||||
//'mode' => 'strict',
|
//'mode' => 'strict',
|
||||||
|
|
||||||
|
|
||||||
@@ -45,16 +45,42 @@ return array(
|
|||||||
* End all paths with a slash.
|
* End all paths with a slash.
|
||||||
*
|
*
|
||||||
* Default values:
|
* Default values:
|
||||||
* image_path: __DIR__ . '/img/'
|
* image_path: __DIR__ . '/img/'
|
||||||
* cache_path: __DIR__ . '/../cache/'
|
* cache_path: __DIR__ . '/../cache/'
|
||||||
* alias_path: null
|
* alias_path: null
|
||||||
*/
|
*/
|
||||||
'image_path' => __DIR__ . '/img/',
|
'image_path' => __DIR__ . '/img/',
|
||||||
'cache_path' => __DIR__ . '/../cache/',
|
'cache_path' => __DIR__ . '/../cache/',
|
||||||
//'alias_path' => __DIR__ . '/img/alias/',
|
//'alias_path' => __DIR__ . '/img/alias/',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fast track cache. Save a json representation of the image as a
|
||||||
|
* fast track to the cached version of the image. This avoids some
|
||||||
|
* processing and allows for quicker load times of cached images.
|
||||||
|
*
|
||||||
|
* Default values:
|
||||||
|
* fast_track_allow: false
|
||||||
|
*/
|
||||||
|
'fast_track_allow' => true,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class names to use, to ease dependency injection.
|
||||||
|
*
|
||||||
|
* Default values:
|
||||||
|
* CImage: CImage
|
||||||
|
* CCache: CCache
|
||||||
|
* CFastTrackCache: CFastTrackCache
|
||||||
|
*/
|
||||||
|
//'CImage' => 'CImage',
|
||||||
|
//'CCache' => 'CCache',
|
||||||
|
//'CFastTrackCache' => 'CFastTrackCache',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use password to protect from missusage, send &pwd=... or &password=..
|
* Use password to protect from missusage, send &pwd=... or &password=..
|
||||||
* with the request to match the password or set to false to disable.
|
* with the request to match the password or set to false to disable.
|
||||||
|
Reference in New Issue
Block a user