?iť?
Current Path : /home/scgforma/www/cloud/3rdparty/sabre/dav/lib/DAV/ |
Current File : /home/scgforma/www/cloud/3rdparty/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php |
<?php namespace Sabre\DAV; use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; use Sabre\HTTP\URLUtil; /** * Temporary File Filter Plugin * * The purpose of this filter is to intercept some of the garbage files * operation systems and applications tend to generate when mounting * a WebDAV share as a disk. * * It will intercept these files and place them in a separate directory. * these files are not deleted automatically, so it is advisable to * delete these after they are not accessed for 24 hours. * * Currently it supports: * * OS/X style resource forks and .DS_Store * * desktop.ini and Thumbs.db (windows) * * .*.swp (vim temporary files) * * .dat.* (smultron temporary files) * * Additional patterns can be added, by adding on to the * temporaryFilePatterns property. * * @copyright Copyright (C) fruux GmbH (https://fruux.com/) * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ class TemporaryFileFilterPlugin extends ServerPlugin { /** * This is the list of patterns we intercept. * If new patterns are added, they must be valid patterns for preg_match. * * @var array */ public $temporaryFilePatterns = [ '/^\._(.*)$/', // OS/X resource forks '/^.DS_Store$/', // OS/X custom folder settings '/^desktop.ini$/', // Windows custom folder settings '/^Thumbs.db$/', // Windows thumbnail cache '/^.(.*).swp$/', // ViM temporary files '/^\.dat(.*)$/', // Smultron seems to create these '/^~lock.(.*)#$/', // Windows 7 lockfiles ]; /** * A reference to the main Server class * * @var \Sabre\DAV\Server */ protected $server; /** * This is the directory where this plugin * will store it's files. * * @var string */ private $dataDir; /** * Creates the plugin. * * Make sure you specify a directory for your files. If you don't, we * will use PHP's directory for session-storage instead, and you might * not want that. * * @param string|null $dataDir */ function __construct($dataDir = null) { if (!$dataDir) $dataDir = ini_get('session.save_path') . '/sabredav/'; if (!is_dir($dataDir)) mkdir($dataDir); $this->dataDir = $dataDir; } /** * Initialize the plugin * * This is called automatically be the Server class after this plugin is * added with Sabre\DAV\Server::addPlugin() * * @param Server $server * @return void */ function initialize(Server $server) { $this->server = $server; $server->on('beforeMethod', [$this, 'beforeMethod']); $server->on('beforeCreateFile', [$this, 'beforeCreateFile']); } /** * This method is called before any HTTP method handler * * This method intercepts any GET, DELETE, PUT and PROPFIND calls to * filenames that are known to match the 'temporary file' regex. * * @param RequestInterface $request * @param ResponseInterface $response * @return bool */ function beforeMethod(RequestInterface $request, ResponseInterface $response) { if (!$tempLocation = $this->isTempFile($request->getPath())) return; switch ($request->getMethod()) { case 'GET' : return $this->httpGet($request, $response, $tempLocation); case 'PUT' : return $this->httpPut($request, $response, $tempLocation); case 'PROPFIND' : return $this->httpPropfind($request, $response, $tempLocation); case 'DELETE' : return $this->httpDelete($request, $response, $tempLocation); } return; } /** * This method is invoked if some subsystem creates a new file. * * This is used to deal with HTTP LOCK requests which create a new * file. * * @param string $uri * @param resource $data * @param ICollection $parent * @param bool $modified Should be set to true, if this event handler * changed &$data. * @return bool */ function beforeCreateFile($uri, $data, ICollection $parent, $modified) { if ($tempPath = $this->isTempFile($uri)) { $hR = $this->server->httpResponse; $hR->setHeader('X-Sabre-Temp', 'true'); file_put_contents($tempPath, $data); return false; } return; } /** * This method will check if the url matches the temporary file pattern * if it does, it will return an path based on $this->dataDir for the * temporary file storage. * * @param string $path * @return bool|string */ protected function isTempFile($path) { // We're only interested in the basename. list(, $tempPath) = URLUtil::splitPath($path); foreach ($this->temporaryFilePatterns as $tempFile) { if (preg_match($tempFile, $tempPath)) { return $this->getDataDir() . '/sabredav_' . md5($path) . '.tempfile'; } } return false; } /** * This method handles the GET method for temporary files. * If the file doesn't exist, it will return false which will kick in * the regular system for the GET method. * * @param RequestInterface $request * @param ResponseInterface $hR * @param string $tempLocation * @return bool */ function httpGet(RequestInterface $request, ResponseInterface $hR, $tempLocation) { if (!file_exists($tempLocation)) return; $hR->setHeader('Content-Type', 'application/octet-stream'); $hR->setHeader('Content-Length', filesize($tempLocation)); $hR->setHeader('X-Sabre-Temp', 'true'); $hR->setStatus(200); $hR->setBody(fopen($tempLocation, 'r')); return false; } /** * This method handles the PUT method. * * @param RequestInterface $request * @param ResponseInterface $hR * @param string $tempLocation * @return bool */ function httpPut(RequestInterface $request, ResponseInterface $hR, $tempLocation) { $hR->setHeader('X-Sabre-Temp', 'true'); $newFile = !file_exists($tempLocation); if (!$newFile && ($this->server->httpRequest->getHeader('If-None-Match'))) { throw new Exception\PreconditionFailed('The resource already exists, and an If-None-Match header was supplied'); } file_put_contents($tempLocation, $this->server->httpRequest->getBody()); $hR->setStatus($newFile ? 201 : 200); return false; } /** * This method handles the DELETE method. * * If the file didn't exist, it will return false, which will make the * standard HTTP DELETE handler kick in. * * @param RequestInterface $request * @param ResponseInterface $hR * @param string $tempLocation * @return bool */ function httpDelete(RequestInterface $request, ResponseInterface $hR, $tempLocation) { if (!file_exists($tempLocation)) return; unlink($tempLocation); $hR->setHeader('X-Sabre-Temp', 'true'); $hR->setStatus(204); return false; } /** * This method handles the PROPFIND method. * * It's a very lazy method, it won't bother checking the request body * for which properties were requested, and just sends back a default * set of properties. * * @param RequestInterface $request * @param ResponseInterface $hR * @param string $tempLocation * @return bool */ function httpPropfind(RequestInterface $request, ResponseInterface $hR, $tempLocation) { if (!file_exists($tempLocation)) return; $hR->setHeader('X-Sabre-Temp', 'true'); $hR->setStatus(207); $hR->setHeader('Content-Type', 'application/xml; charset=utf-8'); $properties = [ 'href' => $request->getPath(), 200 => [ '{DAV:}getlastmodified' => new Xml\Property\GetLastModified(filemtime($tempLocation)), '{DAV:}getcontentlength' => filesize($tempLocation), '{DAV:}resourcetype' => new Xml\Property\ResourceType(null), '{' . Server::NS_SABREDAV . '}tempFile' => true, ], ]; $data = $this->server->generateMultiStatus([$properties]); $hR->setBody($data); return false; } /** * This method returns the directory where the temporary files should be stored. * * @return string */ protected function getDataDir() { return $this->dataDir; } }