File size: 4.14Kb
<?php
/**
* Class to wrap around the xf-http stream handler
*/
class XenForo_HttpStream
{
/**
* File pointer
*
* @var resource
*/
protected $_resource;
/**
* Stream URI passed in
*
* @var string
*/
protected $_path;
/**
* Length of file written
*
* @var int
*/
protected $_length = 0;
/**
* Maximum size of file (in bytes) allowed to be cached.
* Files larger than this will not be retrieved or served.
*
* @var int
*/
protected static $_maxSize = 0;
/**
* Max time in seconds to allow reading for
*
* @var int
*/
protected static $_maxReadTime = 10;
/**
* True if registered as wrapper
*
* @var bool
*/
protected static $_registered = false;
/**
* Array of meta data related to the request (including error, etc)
*
* @var array
*/
protected static $_metadata = array();
public function stream_cast($castAs)
{
return $this->_resource;
}
public function stream_close()
{
fclose($this->_resource);
}
public function stream_eof()
{
return feof($this->_resource);
}
public function stream_flush()
{
return fflush($this->_resource);
}
public function stream_open($path, $mode, $options, &$opened_path)
{
$filePath = self::getTempFile($path);
self::$_metadata[$path] = array(
'length' => 0,
'image' => null,
'start' => microtime(true)
);
$fileDir = dirname($filePath);
if (!XenForo_Helper_File::createDirectory($fileDir, true))
{
return false;
}
$this->_path = $path;
$this->_resource = fopen($filePath, $mode, false);
return (bool)$this->_resource;
}
public function stream_read($count)
{
return fread($this->_resource, $count);
}
public function stream_seek($offset, $whence)
{
return fseek($this->_resource, $offset, $whence);
}
public function stream_stat()
{
return fstat($this->_resource);
}
public function stream_tell()
{
return ftell($this->_resource);
}
public function stream_truncate($size)
{
return ftruncate($this->_resource, $size);
}
public function stream_write($data)
{
if (!empty(self::$_metadata[$this->_path]['error']))
{
return false;
}
$addLength = strlen($data);
if (self::$_maxSize && $this->_length + $addLength > self::$_maxSize)
{
self::$_metadata[$this->_path]['error'] = 'too_large';
return false;
}
$success = fwrite($this->_resource, $data);
if ($success)
{
$this->_length += $addLength;
self::$_metadata[$this->_path]['length'] = $this->_length;
}
if (!empty(self::$_metadata[$this->_path]['start']))
{
$spent = microtime(true) - self::$_metadata[$this->_path]['start'];
if ($spent > self::$_maxReadTime)
{
self::$_metadata[$this->_path]['error'] = 'too_slow';
return false;
}
}
return $success;
}
public function unlink($path)
{
return unlink(self::getTempFile($path));
}
public function url_stat($path, $flags)
{
$statPath = self::getTempFile($path);
return ($flags & STREAM_URL_STAT_QUIET ? @stat($statPath) : stat($statPath));
}
/**
* Gets the path to the written file for a stream URI
*
* @param string $path
*
* @return string
*/
public static function getTempFile($path)
{
$path = preg_replace('#^[a-z0-9_-]+://#i', '', $path);
return XenForo_Helper_File::getTempDir() . '/' . strtr($path, '/\\.', '---') . '.temp';
}
/**
* Gets the metadata for a path
*
* @param string $path
*
* @return null|array
*/
public static function getMetaData($path)
{
if (!isset(self::$_metadata[$path]))
{
return null;
}
return self::$_metadata[$path];
}
/**
* Registers the xf-http stream wrapper
*/
public static function register()
{
if (self::$_registered)
{
return;
}
stream_wrapper_register('xf-http', __CLASS__);
self::$_registered = true;
}
/**
* @param integer $size
*/
public static function setMaxSize($size)
{
self::$_maxSize = intval($size);
}
/**
* @return int
*/
public static function getMaxSize()
{
return self::$_maxSize;
}
}