diff options
Diffstat (limited to '3rdparty/Sabre/DAV')
90 files changed, 582 insertions, 141 deletions
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php index 1e89b84f9a1..1e89b84f9a1 100755..100644 --- a/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php +++ b/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php index 9833928b976..9833928b976 100755..100644 --- a/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php +++ b/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php diff --git a/3rdparty/Sabre/DAV/Auth/Backend/Apache.php b/3rdparty/Sabre/DAV/Auth/Backend/Apache.php index d4294ea4d86..d4294ea4d86 100755..100644 --- a/3rdparty/Sabre/DAV/Auth/Backend/Apache.php +++ b/3rdparty/Sabre/DAV/Auth/Backend/Apache.php diff --git a/3rdparty/Sabre/DAV/Auth/Backend/File.php b/3rdparty/Sabre/DAV/Auth/Backend/File.php index de308d64a67..de308d64a67 100755..100644 --- a/3rdparty/Sabre/DAV/Auth/Backend/File.php +++ b/3rdparty/Sabre/DAV/Auth/Backend/File.php diff --git a/3rdparty/Sabre/DAV/Auth/Backend/PDO.php b/3rdparty/Sabre/DAV/Auth/Backend/PDO.php index eac18a23fbb..eac18a23fbb 100755..100644 --- a/3rdparty/Sabre/DAV/Auth/Backend/PDO.php +++ b/3rdparty/Sabre/DAV/Auth/Backend/PDO.php diff --git a/3rdparty/Sabre/DAV/Auth/IBackend.php b/3rdparty/Sabre/DAV/Auth/IBackend.php index 5be5d1bc93d..5be5d1bc93d 100755..100644 --- a/3rdparty/Sabre/DAV/Auth/IBackend.php +++ b/3rdparty/Sabre/DAV/Auth/IBackend.php diff --git a/3rdparty/Sabre/DAV/Auth/Plugin.php b/3rdparty/Sabre/DAV/Auth/Plugin.php index 55a4e391674..55a4e391674 100755..100644 --- a/3rdparty/Sabre/DAV/Auth/Plugin.php +++ b/3rdparty/Sabre/DAV/Auth/Plugin.php diff --git a/3rdparty/Sabre/DAV/Browser/GuessContentType.php b/3rdparty/Sabre/DAV/Browser/GuessContentType.php index b6c00d461cb..b6c00d461cb 100755..100644 --- a/3rdparty/Sabre/DAV/Browser/GuessContentType.php +++ b/3rdparty/Sabre/DAV/Browser/GuessContentType.php diff --git a/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php b/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php index 15884887641..15884887641 100755..100644 --- a/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php +++ b/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php diff --git a/3rdparty/Sabre/DAV/Browser/Plugin.php b/3rdparty/Sabre/DAV/Browser/Plugin.php index 09bbdd2ae02..b6440ab6340 100755..100644 --- a/3rdparty/Sabre/DAV/Browser/Plugin.php +++ b/3rdparty/Sabre/DAV/Browser/Plugin.php @@ -338,7 +338,7 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin { $icon = ''; if ($this->enableAssets) { - $node = $parent->getChild($name); + $node = $this->server->tree->getNodeForPath(($path?$path.'/':'') . $name); foreach(array_reverse($this->iconMap) as $class=>$iconName) { if ($node instanceof $class) { diff --git a/3rdparty/Sabre/DAV/Browser/assets/favicon.ico b/3rdparty/Sabre/DAV/Browser/assets/favicon.ico Binary files differindex 2b2c10a22cc..2b2c10a22cc 100755..100644 --- a/3rdparty/Sabre/DAV/Browser/assets/favicon.ico +++ b/3rdparty/Sabre/DAV/Browser/assets/favicon.ico diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png b/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png Binary files differindex c9acc84172d..c9acc84172d 100755..100644 --- a/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png +++ b/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png b/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png Binary files differindex 3ecd6a800a0..3ecd6a800a0 100755..100644 --- a/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png +++ b/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/card.png b/3rdparty/Sabre/DAV/Browser/assets/icons/card.png Binary files differindex 2ce954866d8..2ce954866d8 100755..100644 --- a/3rdparty/Sabre/DAV/Browser/assets/icons/card.png +++ b/3rdparty/Sabre/DAV/Browser/assets/icons/card.png diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png b/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png Binary files differindex 156fa64fd50..156fa64fd50 100755..100644 --- a/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png +++ b/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/file.png b/3rdparty/Sabre/DAV/Browser/assets/icons/file.png Binary files differindex 3b98551cec3..3b98551cec3 100755..100644 --- a/3rdparty/Sabre/DAV/Browser/assets/icons/file.png +++ b/3rdparty/Sabre/DAV/Browser/assets/icons/file.png diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png b/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png Binary files differindex 156fa64fd50..156fa64fd50 100755..100644 --- a/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png +++ b/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png b/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png Binary files differindex f8988f828e6..f8988f828e6 100755..100644 --- a/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png +++ b/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png diff --git a/3rdparty/Sabre/DAV/Client.php b/3rdparty/Sabre/DAV/Client.php index 9a428765e90..9d9f4c96b02 100755..100644 --- a/3rdparty/Sabre/DAV/Client.php +++ b/3rdparty/Sabre/DAV/Client.php @@ -16,12 +16,25 @@ */ class Sabre_DAV_Client { + /** + * The propertyMap is a key-value array. + * + * If you use the propertyMap, any {DAV:}multistatus responses with the + * proeprties listed in this array, will automatically be mapped to a + * respective class. + * + * The {DAV:}resourcetype property is automatically added. This maps to + * Sabre_DAV_Property_ResourceType + * + * @var array + */ public $propertyMap = array(); protected $baseUri; protected $userName; protected $password; protected $proxy; + protected $trustedCertificates; /** * Basic authentication @@ -88,6 +101,18 @@ class Sabre_DAV_Client { } /** + * Add trusted root certificates to the webdav client. + * + * The parameter certificates should be a absulute path to a file + * which contains all trusted certificates + * + * @param string $certificates + */ + public function addTrustedCertificates($certificates) { + $this->trustedCertificates = $certificates; + } + + /** * Does a PROPFIND request * * The list of requested properties must be specified as an array, in clark @@ -143,13 +168,13 @@ class Sabre_DAV_Client { if ($depth===0) { reset($result); $result = current($result); - return $result[200]; + return isset($result[200])?$result[200]:array(); } $newResult = array(); foreach($result as $href => $statusList) { - $newResult[$href] = $statusList[200]; + $newResult[$href] = isset($statusList[200])?$statusList[200]:array(); } @@ -279,6 +304,10 @@ class Sabre_DAV_Client { CURLOPT_MAXREDIRS => 5, ); + if($this->trustedCertificates) { + $curlSettings[CURLOPT_CAINFO] = $this->trustedCertificates; + } + switch ($method) { case 'HEAD' : @@ -363,10 +392,30 @@ class Sabre_DAV_Client { if ($response['statusCode']>=400) { switch ($response['statusCode']) { + case 400 : + throw new Sabre_DAV_Exception_BadRequest('Bad request'); + case 401 : + throw new Sabre_DAV_Exception_NotAuthenticated('Not authenticated'); + case 402 : + throw new Sabre_DAV_Exception_PaymentRequired('Payment required'); + case 403 : + throw new Sabre_DAV_Exception_Forbidden('Forbidden'); case 404: - throw new Sabre_DAV_Exception_NotFound('Resource ' . $url . ' not found.'); - break; - + throw new Sabre_DAV_Exception_NotFound('Resource not found.'); + case 405 : + throw new Sabre_DAV_Exception_MethodNotAllowed('Method not allowed'); + case 409 : + throw new Sabre_DAV_Exception_Conflict('Conflict'); + case 412 : + throw new Sabre_DAV_Exception_PreconditionFailed('Precondition failed'); + case 416 : + throw new Sabre_DAV_Exception_RequestedRangeNotSatisfiable('Requested Range Not Satisfiable'); + case 500 : + throw new Sabre_DAV_Exception('Internal server error'); + case 501 : + throw new Sabre_DAV_Exception_NotImplemented('Not Implemented'); + case 507 : + throw new Sabre_DAV_Exception_InsufficientStorage('Insufficient storage'); default: throw new Sabre_DAV_Exception('HTTP error response. (errorcode ' . $response['statusCode'] . ')'); } @@ -386,6 +435,7 @@ class Sabre_DAV_Client { * @param array $settings * @return array */ + // @codeCoverageIgnoreStart protected function curlRequest($url, $settings) { $curl = curl_init($url); @@ -399,6 +449,7 @@ class Sabre_DAV_Client { ); } + // @codeCoverageIgnoreEnd /** * Returns the full url based on the given url (which may be relative). All @@ -453,19 +504,17 @@ class Sabre_DAV_Client { */ public function parseMultiStatus($body) { - $body = Sabre_DAV_XMLUtil::convertDAVNamespace($body); - $responseXML = simplexml_load_string($body, null, LIBXML_NOBLANKS | LIBXML_NOCDATA); if ($responseXML===false) { throw new InvalidArgumentException('The passed data is not valid XML'); } - $responseXML->registerXPathNamespace('d', 'urn:DAV'); + $responseXML->registerXPathNamespace('d', 'DAV:'); $propResult = array(); foreach($responseXML->xpath('d:response') as $response) { - $response->registerXPathNamespace('d', 'urn:DAV'); + $response->registerXPathNamespace('d', 'DAV:'); $href = $response->xpath('d:href'); $href = (string)$href[0]; @@ -473,7 +522,7 @@ class Sabre_DAV_Client { foreach($response->xpath('d:propstat') as $propStat) { - $propStat->registerXPathNamespace('d', 'urn:DAV'); + $propStat->registerXPathNamespace('d', 'DAV:'); $status = $propStat->xpath('d:status'); list($httpVersion, $statusCode, $message) = explode(' ', (string)$status[0],3); diff --git a/3rdparty/Sabre/DAV/Collection.php b/3rdparty/Sabre/DAV/Collection.php index 776c22531b2..c7648a8a52d 100755..100644 --- a/3rdparty/Sabre/DAV/Collection.php +++ b/3rdparty/Sabre/DAV/Collection.php @@ -17,9 +17,13 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_ /** * Returns a child object, by its name. * - * This method makes use of the getChildren method to grab all the child nodes, and compares the name. + * This method makes use of the getChildren method to grab all the child + * nodes, and compares the name. * Generally its wise to override this, as this can usually be optimized * + * This method must throw Sabre_DAV_Exception_NotFound if the node does not + * exist. + * * @param string $name * @throws Sabre_DAV_Exception_NotFound * @return Sabre_DAV_INode diff --git a/3rdparty/Sabre/DAV/Directory.php b/3rdparty/Sabre/DAV/Directory.php deleted file mode 100755 index 6db8febc02e..00000000000 --- a/3rdparty/Sabre/DAV/Directory.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php - -/** - * Directory class - * - * This class is now deprecated in favor of the Sabre_DAV_Collection class. - * - * @package Sabre - * @subpackage DAV - * @deprecated Use Sabre_DAV_Collection instead - * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) - * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License - */ -abstract class Sabre_DAV_Directory extends Sabre_DAV_Collection { -} - diff --git a/3rdparty/Sabre/DAV/Exception.php b/3rdparty/Sabre/DAV/Exception.php index a2cd6cf5820..a2cd6cf5820 100755..100644 --- a/3rdparty/Sabre/DAV/Exception.php +++ b/3rdparty/Sabre/DAV/Exception.php diff --git a/3rdparty/Sabre/DAV/Exception/BadRequest.php b/3rdparty/Sabre/DAV/Exception/BadRequest.php index b198648a754..b198648a754 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/BadRequest.php +++ b/3rdparty/Sabre/DAV/Exception/BadRequest.php diff --git a/3rdparty/Sabre/DAV/Exception/Conflict.php b/3rdparty/Sabre/DAV/Exception/Conflict.php index 6b0bd1fad73..6b0bd1fad73 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/Conflict.php +++ b/3rdparty/Sabre/DAV/Exception/Conflict.php diff --git a/3rdparty/Sabre/DAV/Exception/ConflictingLock.php b/3rdparty/Sabre/DAV/Exception/ConflictingLock.php index 6121868e69e..6121868e69e 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/ConflictingLock.php +++ b/3rdparty/Sabre/DAV/Exception/ConflictingLock.php diff --git a/3rdparty/Sabre/DAV/Exception/FileNotFound.php b/3rdparty/Sabre/DAV/Exception/FileNotFound.php index d76e400c93b..d76e400c93b 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/FileNotFound.php +++ b/3rdparty/Sabre/DAV/Exception/FileNotFound.php diff --git a/3rdparty/Sabre/DAV/Exception/Forbidden.php b/3rdparty/Sabre/DAV/Exception/Forbidden.php index 20b1056e31b..20b1056e31b 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/Forbidden.php +++ b/3rdparty/Sabre/DAV/Exception/Forbidden.php diff --git a/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php b/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php index 1a15089b0a3..1a15089b0a3 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php +++ b/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php diff --git a/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php b/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php index 2230f1d0811..2230f1d0811 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php +++ b/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php diff --git a/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php b/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php index 80ab7aff65a..80ab7aff65a 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php +++ b/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php diff --git a/3rdparty/Sabre/DAV/Exception/Locked.php b/3rdparty/Sabre/DAV/Exception/Locked.php index 976365ac1f8..976365ac1f8 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/Locked.php +++ b/3rdparty/Sabre/DAV/Exception/Locked.php diff --git a/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php b/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php index 31875751505..31875751505 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php +++ b/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php diff --git a/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php b/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php index 87ca624429f..87ca624429f 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php +++ b/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php diff --git a/3rdparty/Sabre/DAV/Exception/NotFound.php b/3rdparty/Sabre/DAV/Exception/NotFound.php index 2b9da560d23..2b9da560d23 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/NotFound.php +++ b/3rdparty/Sabre/DAV/Exception/NotFound.php diff --git a/3rdparty/Sabre/DAV/Exception/NotImplemented.php b/3rdparty/Sabre/DAV/Exception/NotImplemented.php index d017a19f559..d017a19f559 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/NotImplemented.php +++ b/3rdparty/Sabre/DAV/Exception/NotImplemented.php diff --git a/3rdparty/Sabre/DAV/Exception/PaymentRequired.php b/3rdparty/Sabre/DAV/Exception/PaymentRequired.php index 4982f45a4b5..4982f45a4b5 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/PaymentRequired.php +++ b/3rdparty/Sabre/DAV/Exception/PaymentRequired.php diff --git a/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php b/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php index 213e9c52317..213e9c52317 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php +++ b/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php diff --git a/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php b/3rdparty/Sabre/DAV/Exception/ReportNotSupported.php index e86800f3038..a2906865f8e 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php +++ b/3rdparty/Sabre/DAV/Exception/ReportNotSupported.php @@ -1,7 +1,7 @@ <?php /** - * ReportNotImplemented + * ReportNotSupported * * This exception is thrown when the client requested an unknown report through the REPORT method * @@ -11,7 +11,7 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Sabre_DAV_Exception_ReportNotImplemented extends Sabre_DAV_Exception_NotImplemented { +class Sabre_DAV_Exception_ReportNotSupported extends Sabre_DAV_Exception_Forbidden { /** * This method allows the exception to include additional information into the WebDAV error response diff --git a/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php b/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php index 29ee3654a7e..29ee3654a7e 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php +++ b/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php diff --git a/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php b/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php index 9a4693b21a8..9a4693b21a8 100755..100644 --- a/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php +++ b/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php diff --git a/3rdparty/Sabre/DAV/FS/Directory.php b/3rdparty/Sabre/DAV/FS/Directory.php index 3af2d755583..72fec744d0f 100755..100644 --- a/3rdparty/Sabre/DAV/FS/Directory.php +++ b/3rdparty/Sabre/DAV/FS/Directory.php @@ -17,7 +17,7 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol * Data will either be supplied as a stream resource, or in certain cases * as a string. Keep in mind that you may have to support either. * - * After succesful creation of the file, you may choose to return the ETag + * After successful creation of the file, you may choose to return the ETag * of the new file here. * * The returned ETag must be surrounded by double-quotes (The quotes should @@ -58,6 +58,9 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol /** * Returns a specific child node, referenced by its name * + * This method must throw Sabre_DAV_Exception_NotFound if the node does not + * exist. + * * @param string $name * @throws Sabre_DAV_Exception_NotFound * @return Sabre_DAV_INode diff --git a/3rdparty/Sabre/DAV/FS/File.php b/3rdparty/Sabre/DAV/FS/File.php index 6a8039fe303..6a8039fe303 100755..100644 --- a/3rdparty/Sabre/DAV/FS/File.php +++ b/3rdparty/Sabre/DAV/FS/File.php diff --git a/3rdparty/Sabre/DAV/FS/Node.php b/3rdparty/Sabre/DAV/FS/Node.php index 1283e9d0fdc..1283e9d0fdc 100755..100644 --- a/3rdparty/Sabre/DAV/FS/Node.php +++ b/3rdparty/Sabre/DAV/FS/Node.php diff --git a/3rdparty/Sabre/DAV/FSExt/Directory.php b/3rdparty/Sabre/DAV/FSExt/Directory.php index 540057183b3..70dfdc2c3b5 100755..100644 --- a/3rdparty/Sabre/DAV/FSExt/Directory.php +++ b/3rdparty/Sabre/DAV/FSExt/Directory.php @@ -17,7 +17,7 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA * Data will either be supplied as a stream resource, or in certain cases * as a string. Keep in mind that you may have to support either. * - * After succesful creation of the file, you may choose to return the ETag + * After successful creation of the file, you may choose to return the ETag * of the new file here. * * The returned ETag must be surrounded by double-quotes (The quotes should @@ -64,6 +64,9 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA /** * Returns a specific child node, referenced by its name * + * This method must throw Sabre_DAV_Exception_NotFound if the node does not + * exist. + * * @param string $name * @throws Sabre_DAV_Exception_NotFound * @return Sabre_DAV_INode diff --git a/3rdparty/Sabre/DAV/FSExt/File.php b/3rdparty/Sabre/DAV/FSExt/File.php index b93ce5aee21..590fb808e61 100755..100644 --- a/3rdparty/Sabre/DAV/FSExt/File.php +++ b/3rdparty/Sabre/DAV/FSExt/File.php @@ -9,15 +9,15 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFile { +class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_PartialUpdate_IFile { /** * Updates the data * * data is a readable stream resource. * - * @param resource $data - * @return void + * @param resource|string $data + * @return string */ public function put($data) { @@ -27,9 +27,33 @@ class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFi } /** + * Updates the data at a given offset + * + * The data argument is a readable stream resource. + * The offset argument is a 0-based offset where the data should be + * written. + * + * param resource|string $data + * @return void + */ + public function putRange($data, $offset) { + + $f = fopen($this->path, 'c'); + fseek($f,$offset-1); + if (is_string($data)) { + fwrite($f, $data); + } else { + stream_copy_to_stream($data,$f); + } + fclose($f); + return '"' . md5_file($this->path) . '"'; + + } + + /** * Returns the data * - * @return string + * @return resource */ public function get() { diff --git a/3rdparty/Sabre/DAV/FSExt/Node.php b/3rdparty/Sabre/DAV/FSExt/Node.php index 68ca06beb7e..68ca06beb7e 100755..100644 --- a/3rdparty/Sabre/DAV/FSExt/Node.php +++ b/3rdparty/Sabre/DAV/FSExt/Node.php diff --git a/3rdparty/Sabre/DAV/File.php b/3rdparty/Sabre/DAV/File.php index 3126bd8d364..3126bd8d364 100755..100644 --- a/3rdparty/Sabre/DAV/File.php +++ b/3rdparty/Sabre/DAV/File.php diff --git a/3rdparty/Sabre/DAV/ICollection.php b/3rdparty/Sabre/DAV/ICollection.php index 4626038a66e..94431a0c496 100755..100644 --- a/3rdparty/Sabre/DAV/ICollection.php +++ b/3rdparty/Sabre/DAV/ICollection.php @@ -19,7 +19,7 @@ interface Sabre_DAV_ICollection extends Sabre_DAV_INode { * Data will either be supplied as a stream resource, or in certain cases * as a string. Keep in mind that you may have to support either. * - * After succesful creation of the file, you may choose to return the ETag + * After successful creation of the file, you may choose to return the ETag * of the new file here. * * The returned ETag must be surrounded by double-quotes (The quotes should @@ -50,6 +50,9 @@ interface Sabre_DAV_ICollection extends Sabre_DAV_INode { /** * Returns a specific child node, referenced by its name * + * This method must throw Sabre_DAV_Exception_NotFound if the node does not + * exist. + * * @param string $name * @return Sabre_DAV_INode */ diff --git a/3rdparty/Sabre/DAV/IExtendedCollection.php b/3rdparty/Sabre/DAV/IExtendedCollection.php index 6ec345f9a62..6ec345f9a62 100755..100644 --- a/3rdparty/Sabre/DAV/IExtendedCollection.php +++ b/3rdparty/Sabre/DAV/IExtendedCollection.php diff --git a/3rdparty/Sabre/DAV/IFile.php b/3rdparty/Sabre/DAV/IFile.php index 478f822ae71..1eca8986a5c 100755..100644 --- a/3rdparty/Sabre/DAV/IFile.php +++ b/3rdparty/Sabre/DAV/IFile.php @@ -51,7 +51,7 @@ interface Sabre_DAV_IFile extends Sabre_DAV_INode { * * If null is returned, we'll assume application/octet-stream * - * @return void + * @return string|null */ function getContentType(); diff --git a/3rdparty/Sabre/DAV/INode.php b/3rdparty/Sabre/DAV/INode.php index c57d3923105..c57d3923105 100755..100644 --- a/3rdparty/Sabre/DAV/INode.php +++ b/3rdparty/Sabre/DAV/INode.php diff --git a/3rdparty/Sabre/DAV/IProperties.php b/3rdparty/Sabre/DAV/IProperties.php index 38eaab16dad..38eaab16dad 100755..100644 --- a/3rdparty/Sabre/DAV/IProperties.php +++ b/3rdparty/Sabre/DAV/IProperties.php diff --git a/3rdparty/Sabre/DAV/IQuota.php b/3rdparty/Sabre/DAV/IQuota.php index 3fe4c4eced4..3fe4c4eced4 100755..100644 --- a/3rdparty/Sabre/DAV/IQuota.php +++ b/3rdparty/Sabre/DAV/IQuota.php diff --git a/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php b/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php index 127e643a2b9..127e643a2b9 100755..100644 --- a/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php +++ b/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php diff --git a/3rdparty/Sabre/DAV/Locks/Backend/FS.php b/3rdparty/Sabre/DAV/Locks/Backend/FS.php index 02cab87fc82..02cab87fc82 100755..100644 --- a/3rdparty/Sabre/DAV/Locks/Backend/FS.php +++ b/3rdparty/Sabre/DAV/Locks/Backend/FS.php diff --git a/3rdparty/Sabre/DAV/Locks/Backend/File.php b/3rdparty/Sabre/DAV/Locks/Backend/File.php index c33f963514b..c33f963514b 100755..100644 --- a/3rdparty/Sabre/DAV/Locks/Backend/File.php +++ b/3rdparty/Sabre/DAV/Locks/Backend/File.php diff --git a/3rdparty/Sabre/DAV/Locks/Backend/PDO.php b/3rdparty/Sabre/DAV/Locks/Backend/PDO.php index acce80638ec..acce80638ec 100755..100644 --- a/3rdparty/Sabre/DAV/Locks/Backend/PDO.php +++ b/3rdparty/Sabre/DAV/Locks/Backend/PDO.php diff --git a/3rdparty/Sabre/DAV/Locks/LockInfo.php b/3rdparty/Sabre/DAV/Locks/LockInfo.php index 9df014a4281..9df014a4281 100755..100644 --- a/3rdparty/Sabre/DAV/Locks/LockInfo.php +++ b/3rdparty/Sabre/DAV/Locks/LockInfo.php diff --git a/3rdparty/Sabre/DAV/Locks/Plugin.php b/3rdparty/Sabre/DAV/Locks/Plugin.php index 035b3a63863..957ac506a9c 100755..100644 --- a/3rdparty/Sabre/DAV/Locks/Plugin.php +++ b/3rdparty/Sabre/DAV/Locks/Plugin.php @@ -152,6 +152,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin { case 'MKCOL' : case 'PROPPATCH' : case 'PUT' : + case 'PATCH' : $lastLock = null; if (!$this->validateLock($uri,$lastLock)) throw new Sabre_DAV_Exception_Locked($lastLock); diff --git a/3rdparty/Sabre/DAV/Mount/Plugin.php b/3rdparty/Sabre/DAV/Mount/Plugin.php index b37a90ae993..b37a90ae993 100755..100644 --- a/3rdparty/Sabre/DAV/Mount/Plugin.php +++ b/3rdparty/Sabre/DAV/Mount/Plugin.php diff --git a/3rdparty/Sabre/DAV/Node.php b/3rdparty/Sabre/DAV/Node.php index 070b7176afd..3b95dfec2fa 100755..100644 --- a/3rdparty/Sabre/DAV/Node.php +++ b/3rdparty/Sabre/DAV/Node.php @@ -27,7 +27,7 @@ abstract class Sabre_DAV_Node implements Sabre_DAV_INode { } /** - * Deleted the current node + * Deletes the current node * * @throws Sabre_DAV_Exception_Forbidden * @return void diff --git a/3rdparty/Sabre/DAV/ObjectTree.php b/3rdparty/Sabre/DAV/ObjectTree.php index bce51463900..3b7f222d64b 100755..100644 --- a/3rdparty/Sabre/DAV/ObjectTree.php +++ b/3rdparty/Sabre/DAV/ObjectTree.php @@ -51,24 +51,30 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree { $path = trim($path,'/'); if (isset($this->cache[$path])) return $this->cache[$path]; - //if (!$path || $path=='.') return $this->rootNode; - $currentNode = $this->rootNode; + // Is it the root node? + if (!strlen($path)) { + return $this->rootNode; + } - // We're splitting up the path variable into folder/subfolder components and traverse to the correct node.. - foreach(explode('/',$path) as $pathPart) { + // Attempting to fetch its parent + list($parentName, $baseName) = Sabre_DAV_URLUtil::splitPath($path); - // If this part of the path is just a dot, it actually means we can skip it - if ($pathPart=='.' || $pathPart=='') continue; + // If there was no parent, we must simply ask it from the root node. + if ($parentName==="") { + $node = $this->rootNode->getChild($baseName); + } else { + // Otherwise, we recursively grab the parent and ask him/her. + $parent = $this->getNodeForPath($parentName); - if (!($currentNode instanceof Sabre_DAV_ICollection)) + if (!($parent instanceof Sabre_DAV_ICollection)) throw new Sabre_DAV_Exception_NotFound('Could not find node at path: ' . $path); - $currentNode = $currentNode->getChild($pathPart); + $node = $parent->getChild($baseName); } - $this->cache[$path] = $currentNode; - return $currentNode; + $this->cache[$path] = $node; + return $node; } diff --git a/3rdparty/Sabre/DAV/PartialUpdate/IFile.php b/3rdparty/Sabre/DAV/PartialUpdate/IFile.php new file mode 100644 index 00000000000..cf5ad55c6de --- /dev/null +++ b/3rdparty/Sabre/DAV/PartialUpdate/IFile.php @@ -0,0 +1,38 @@ +<?php + +/** + * This interface provides a way to modify only part of a target resource + * It may be used to update a file chunk, upload big a file into smaller + * chunks or resume an upload + * + * @package Sabre + * @subpackage DAV + * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. + * @author Jean-Tiare LE BIGOT (http://www.jtlebi.fr/) + * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License + */ +interface Sabre_DAV_PartialUpdate_IFile extends Sabre_DAV_IFile { + + /** + * Updates the data at a given offset + * + * The data argument is a readable stream resource. + * The offset argument is an integer describing the offset. Contrary to + * what's sent in the request, the offset here is a 0-based index. + * + * After a successful put operation, you may choose to return an ETag. The + * etag must always be surrounded by double-quotes. These quotes must + * appear in the actual string you're returning. + * + * Clients may use the ETag from a PUT request to later on make sure that + * when they update the file, the contents haven't changed in the mean + * time. + * + * @param resource $data + * @param integer $offset + * @return string|null + */ + function putRange($data, $offset); + +} + diff --git a/3rdparty/Sabre/DAV/PartialUpdate/Plugin.php b/3rdparty/Sabre/DAV/PartialUpdate/Plugin.php new file mode 100644 index 00000000000..170acbc9785 --- /dev/null +++ b/3rdparty/Sabre/DAV/PartialUpdate/Plugin.php @@ -0,0 +1,209 @@ +<?php +/** + * Partial update plugin (Patch method) + * + * This plugin provides a way to modify only part of a target resource + * It may bu used to update a file chunk, upload big a file into smaller + * chunks or resume an upload. + * + * $patchPlugin = new Sabre_DAV_Patch_Plugin(); + * $server->addPlugin($patchPlugin); + * + * @package Sabre + * @subpackage DAV + * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. + * @author Jean-Tiare LE BIGOT (http://www.jtlebi.fr/) + * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License + */ +class Sabre_DAV_PartialUpdate_Plugin extends Sabre_DAV_ServerPlugin { + + /** + * Reference to server + * + * @var Sabre_DAV_Server + */ + protected $server; + + /** + * Initializes the plugin + * + * This method is automatically called by the Server class after addPlugin. + * + * @param Sabre_DAV_Server $server + * @return void + */ + public function initialize(Sabre_DAV_Server $server) { + + $this->server = $server; + $server->subscribeEvent('unknownMethod',array($this,'unknownMethod')); + + } + + /** + * Returns a plugin name. + * + * Using this name other plugins will be able to access other plugins + * using Sabre_DAV_Server::getPlugin + * + * @return string + */ + public function getPluginName() { + + return 'partialupdate'; + + } + + /** + * This method is called by the Server if the user used an HTTP method + * the server didn't recognize. + * + * This plugin intercepts the PATCH methods. + * + * @param string $method + * @param string $uri + * @return bool|null + */ + public function unknownMethod($method, $uri) { + + switch($method) { + + case 'PATCH': + return $this->httpPatch($uri); + + } + + } + + /** + * Use this method to tell the server this plugin defines additional + * HTTP methods. + * + * This method is passed a uri. It should only return HTTP methods that are + * available for the specified uri. + * + * We claim to support PATCH method (partial update) if and only if + * - the node exist + * - the node implements our partial update interface + * + * @param string $uri + * @return array + */ + public function getHTTPMethods($uri) { + + $tree = $this->server->tree; + + if ($tree->nodeExists($uri) && + $tree->getNodeForPath($uri) instanceof Sabre_DAV_PartialUpdate_IFile) { + return array('PATCH'); + } + + return array(); + + } + + /** + * Returns a list of features for the HTTP OPTIONS Dav: header. + * + * @return array + */ + public function getFeatures() { + + return array('sabredav-partialupdate'); + + } + + /** + * Patch an uri + * + * The WebDAV patch request can be used to modify only a part of an + * existing resource. If the resource does not exist yet and the first + * offset is not 0, the request fails + * + * @param string $uri + * @return void + */ + protected function httpPatch($uri) { + + // Get the node. Will throw a 404 if not found + $node = $this->server->tree->getNodeForPath($uri); + if (!($node instanceof Sabre_DAV_PartialUpdate_IFile)) { + throw new Sabre_DAV_Exception_MethodNotAllowed('The target resource does not support the PATCH method.'); + } + + $range = $this->getHTTPUpdateRange(); + + if (!$range) { + throw new Sabre_DAV_Exception_BadRequest('No valid "X-Update-Range" found in the headers'); + } + + $contentType = strtolower( + $this->server->httpRequest->getHeader('Content-Type') + ); + + if ($contentType != 'application/x-sabredav-partialupdate') { + throw new Sabre_DAV_Exception_UnsupportedMediaType('Unknown Content-Type header "' . $contentType . '"'); + } + + $len = $this->server->httpRequest->getHeader('Content-Length'); + + // Load the begin and end data + $start = ($range[0])?$range[0]:0; + $end = ($range[1])?$range[1]:$len-1; + + // Check consistency + if($end < $start) + throw new Sabre_DAV_Exception_RequestedRangeNotSatisfiable('The end offset (' . $range[1] . ') is lower than the start offset (' . $range[0] . ')'); + if($end - $start + 1 != $len) + throw new Sabre_DAV_Exception_RequestedRangeNotSatisfiable('Actual data length (' . $len . ') is not consistent with begin (' . $range[0] . ') and end (' . $range[1] . ') offsets'); + + // Checking If-None-Match and related headers. + if (!$this->server->checkPreconditions()) return; + + if (!$this->server->broadcastEvent('beforeWriteContent',array($uri, $node, null))) + return; + + $body = $this->server->httpRequest->getBody(); + $etag = $node->putRange($body, $start-1); + + $this->server->broadcastEvent('afterWriteContent',array($uri, $node)); + + $this->server->httpResponse->setHeader('Content-Length','0'); + if ($etag) $this->server->httpResponse->setHeader('ETag',$etag); + $this->server->httpResponse->sendStatus(204); + + return false; + + } + + /** + * Returns the HTTP custom range update header + * + * This method returns null if there is no well-formed HTTP range request + * header or array($start, $end). + * + * The first number is the offset of the first byte in the range. + * The second number is the offset of the last byte in the range. + * + * If the second offset is null, it should be treated as the offset of the last byte of the entity + * If the first offset is null, the second offset should be used to retrieve the last x bytes of the entity + * + * @return array|null + */ + public function getHTTPUpdateRange() { + + $range = $this->server->httpRequest->getHeader('X-Update-Range'); + if (is_null($range)) return null; + + // Matching "Range: bytes=1234-5678: both numbers are optional + + if (!preg_match('/^bytes=([0-9]*)-([0-9]*)$/i',$range,$matches)) return null; + + if ($matches[1]==='' && $matches[2]==='') return null; + + return array( + $matches[1]!==''?$matches[1]:null, + $matches[2]!==''?$matches[2]:null, + ); + + } +} diff --git a/3rdparty/Sabre/DAV/Property.php b/3rdparty/Sabre/DAV/Property.php index 1cfada3236c..6487bf44bc4 100755..100644 --- a/3rdparty/Sabre/DAV/Property.php +++ b/3rdparty/Sabre/DAV/Property.php @@ -11,10 +11,16 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class Sabre_DAV_Property { - - abstract function serialize(Sabre_DAV_Server $server, DOMElement $prop); +abstract class Sabre_DAV_Property implements Sabre_DAV_PropertyInterface { + /** + * Unserializes the property. + * + * This static method should return a an instance of this object. + * + * @param DOMElement $prop + * @return Sabre_DAV_IProperty + */ static function unserialize(DOMElement $prop) { throw new Sabre_DAV_Exception('Unserialize has not been implemented for this class'); diff --git a/3rdparty/Sabre/DAV/Property/GetLastModified.php b/3rdparty/Sabre/DAV/Property/GetLastModified.php index bd63f573140..bd63f573140 100755..100644 --- a/3rdparty/Sabre/DAV/Property/GetLastModified.php +++ b/3rdparty/Sabre/DAV/Property/GetLastModified.php diff --git a/3rdparty/Sabre/DAV/Property/Href.php b/3rdparty/Sabre/DAV/Property/Href.php index dac564f24d7..cd1d867f71b 100755..100644 --- a/3rdparty/Sabre/DAV/Property/Href.php +++ b/3rdparty/Sabre/DAV/Property/Href.php @@ -82,7 +82,7 @@ class Sabre_DAV_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Pr */ static function unserialize(DOMElement $dom) { - if (Sabre_DAV_XMLUtil::toClarkNotation($dom->firstChild)==='{DAV:}href') { + if ($dom->firstChild && Sabre_DAV_XMLUtil::toClarkNotation($dom->firstChild)==='{DAV:}href') { return new self($dom->firstChild->textContent,false); } diff --git a/3rdparty/Sabre/DAV/Property/HrefList.php b/3rdparty/Sabre/DAV/Property/HrefList.php index 7a52272e885..282c452ca0b 100755..100644 --- a/3rdparty/Sabre/DAV/Property/HrefList.php +++ b/3rdparty/Sabre/DAV/Property/HrefList.php @@ -79,7 +79,7 @@ class Sabre_DAV_Property_HrefList extends Sabre_DAV_Property { * It will only decode {DAV:}href values. * * @param DOMElement $dom - * @return Sabre_DAV_Property_Href + * @return Sabre_DAV_Property_HrefList */ static function unserialize(DOMElement $dom) { diff --git a/3rdparty/Sabre/DAV/Property/IHref.php b/3rdparty/Sabre/DAV/Property/IHref.php index 5c0409064cb..5c0409064cb 100755..100644 --- a/3rdparty/Sabre/DAV/Property/IHref.php +++ b/3rdparty/Sabre/DAV/Property/IHref.php diff --git a/3rdparty/Sabre/DAV/Property/LockDiscovery.php b/3rdparty/Sabre/DAV/Property/LockDiscovery.php index 2ded5649a44..2ded5649a44 100755..100644 --- a/3rdparty/Sabre/DAV/Property/LockDiscovery.php +++ b/3rdparty/Sabre/DAV/Property/LockDiscovery.php diff --git a/3rdparty/Sabre/DAV/Property/ResourceType.php b/3rdparty/Sabre/DAV/Property/ResourceType.php index f6269611e54..f6269611e54 100755..100644 --- a/3rdparty/Sabre/DAV/Property/ResourceType.php +++ b/3rdparty/Sabre/DAV/Property/ResourceType.php diff --git a/3rdparty/Sabre/DAV/Property/Response.php b/3rdparty/Sabre/DAV/Property/Response.php index 88afbcfb26d..9f21163d12e 100755..100644 --- a/3rdparty/Sabre/DAV/Property/Response.php +++ b/3rdparty/Sabre/DAV/Property/Response.php @@ -138,7 +138,7 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA if (is_scalar($propertyValue)) { $text = $document->createTextNode($propertyValue); $currentProperty->appendChild($text); - } elseif ($propertyValue instanceof Sabre_DAV_Property) { + } elseif ($propertyValue instanceof Sabre_DAV_PropertyInterface) { $propertyValue->serialize($server,$currentProperty); } elseif (!is_null($propertyValue)) { throw new Sabre_DAV_Exception('Unknown property value type: ' . gettype($propertyValue) . ' for property: ' . $propertyName); diff --git a/3rdparty/Sabre/DAV/Property/ResponseList.php b/3rdparty/Sabre/DAV/Property/ResponseList.php index cae923afbf9..cae923afbf9 100755..100644 --- a/3rdparty/Sabre/DAV/Property/ResponseList.php +++ b/3rdparty/Sabre/DAV/Property/ResponseList.php diff --git a/3rdparty/Sabre/DAV/Property/SupportedLock.php b/3rdparty/Sabre/DAV/Property/SupportedLock.php index 4e3aaf23a1a..4e3aaf23a1a 100755..100644 --- a/3rdparty/Sabre/DAV/Property/SupportedLock.php +++ b/3rdparty/Sabre/DAV/Property/SupportedLock.php diff --git a/3rdparty/Sabre/DAV/Property/SupportedReportSet.php b/3rdparty/Sabre/DAV/Property/SupportedReportSet.php index e62699f3b5a..e62699f3b5a 100755..100644 --- a/3rdparty/Sabre/DAV/Property/SupportedReportSet.php +++ b/3rdparty/Sabre/DAV/Property/SupportedReportSet.php diff --git a/3rdparty/Sabre/DAV/PropertyInterface.php b/3rdparty/Sabre/DAV/PropertyInterface.php new file mode 100644 index 00000000000..515072cbd35 --- /dev/null +++ b/3rdparty/Sabre/DAV/PropertyInterface.php @@ -0,0 +1,21 @@ +<?php + +/** + * PropertyInterface + * + * Implement this interface to create new complex properties + * + * @package Sabre + * @subpackage DAV + * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License + */ +interface Sabre_DAV_PropertyInterface { + + public function serialize(Sabre_DAV_Server $server, DOMElement $prop); + + static function unserialize(DOMElement $prop); + +} + diff --git a/3rdparty/Sabre/DAV/Server.php b/3rdparty/Sabre/DAV/Server.php index 0dfac8b0c71..cf6f87e68ab 100755..100644 --- a/3rdparty/Sabre/DAV/Server.php +++ b/3rdparty/Sabre/DAV/Server.php @@ -12,7 +12,7 @@ class Sabre_DAV_Server { /** - * Inifinity is used for some request supporting the HTTP Depth header and indicates that the operation should traverse the entire tree + * Infinity is used for some request supporting the HTTP Depth header and indicates that the operation should traverse the entire tree */ const DEPTH_INFINITY = -1; @@ -102,7 +102,6 @@ class Sabre_DAV_Server { '{DAV:}getetag', '{DAV:}getlastmodified', '{DAV:}lockdiscovery', - '{DAV:}resourcetype', '{DAV:}supportedlock', // RFC4331 @@ -162,7 +161,7 @@ class Sabre_DAV_Server { * If an array is passed, we automatically create a root node, and use * the nodes in the array as top-level children. * - * @param Sabre_DAV_Tree|Sabre_DAV_INode|null $treeOrNode The tree object + * @param Sabre_DAV_Tree|Sabre_DAV_INode|array|null $treeOrNode The tree object */ public function __construct($treeOrNode = null) { @@ -207,6 +206,10 @@ class Sabre_DAV_Server { } catch (Exception $e) { + try { + $this->broadcastEvent('exception', array($e)); + } catch (Exception $ignore) { + } $DOM = new DOMDocument('1.0','utf-8'); $DOM->formatOutput = true; @@ -214,17 +217,23 @@ class Sabre_DAV_Server { $error->setAttribute('xmlns:s',self::NS_SABREDAV); $DOM->appendChild($error); - $error->appendChild($DOM->createElement('s:exception',get_class($e))); - $error->appendChild($DOM->createElement('s:message',$e->getMessage())); + $h = function($v) { + + return htmlspecialchars($v, ENT_NOQUOTES, 'UTF-8'); + + }; + + $error->appendChild($DOM->createElement('s:exception',$h(get_class($e)))); + $error->appendChild($DOM->createElement('s:message',$h($e->getMessage()))); if ($this->debugExceptions) { - $error->appendChild($DOM->createElement('s:file',$e->getFile())); - $error->appendChild($DOM->createElement('s:line',$e->getLine())); - $error->appendChild($DOM->createElement('s:code',$e->getCode())); - $error->appendChild($DOM->createElement('s:stacktrace',$e->getTraceAsString())); + $error->appendChild($DOM->createElement('s:file',$h($e->getFile()))); + $error->appendChild($DOM->createElement('s:line',$h($e->getLine()))); + $error->appendChild($DOM->createElement('s:code',$h($e->getCode()))); + $error->appendChild($DOM->createElement('s:stacktrace',$h($e->getTraceAsString()))); } if (self::$exposeVersion) { - $error->appendChild($DOM->createElement('s:sabredav-version',Sabre_DAV_Version::VERSION)); + $error->appendChild($DOM->createElement('s:sabredav-version',$h(Sabre_DAV_Version::VERSION))); } if($e instanceof Sabre_DAV_Exception) { @@ -508,7 +517,7 @@ class Sabre_DAV_Server { if (!$this->checkPreconditions(true)) return false; - if (!($node instanceof Sabre_DAV_IFile)) throw new Sabre_DAV_Exception_NotImplemented('GET is only implemented on File objects'); + if (!$node instanceof Sabre_DAV_IFile) throw new Sabre_DAV_Exception_NotImplemented('GET is only implemented on File objects'); $body = $node->get(); // Converting string into stream, if needed. @@ -696,6 +705,7 @@ class Sabre_DAV_Server { // This is a multi-status response $this->httpResponse->sendStatus(207); $this->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8'); + $this->httpResponse->setHeader('Vary','Brief,Prefer'); // Normally this header is only needed for OPTIONS responses, however.. // iCal seems to also depend on these being set for PROPFIND. Since @@ -704,7 +714,10 @@ class Sabre_DAV_Server { foreach($this->plugins as $plugin) $features = array_merge($features,$plugin->getFeatures()); $this->httpResponse->setHeader('DAV',implode(', ',$features)); - $data = $this->generateMultiStatus($newProperties); + $prefer = $this->getHTTPPrefer(); + $minimal = $prefer['return-minimal']; + + $data = $this->generateMultiStatus($newProperties, $minimal); $this->httpResponse->sendBody($data); } @@ -724,6 +737,30 @@ class Sabre_DAV_Server { $result = $this->updateProperties($uri, $newProperties); + $prefer = $this->getHTTPPrefer(); + $this->httpResponse->setHeader('Vary','Brief,Prefer'); + + if ($prefer['return-minimal']) { + + // If return-minimal is specified, we only have to check if the + // request was succesful, and don't need to return the + // multi-status. + $ok = true; + foreach($result as $code=>$prop) { + if ((int)$code > 299) { + $ok = false; + } + } + + if ($ok) { + + $this->httpResponse->sendStatus(204); + return; + + } + + } + $this->httpResponse->sendStatus(207); $this->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8'); @@ -927,7 +964,7 @@ class Sabre_DAV_Server { * This method moves one uri to a different uri. A lot of the actual request processing is done in getCopyMoveInfo * * @param string $uri - * @return void + * @return bool */ protected function httpMove($uri) { @@ -1009,7 +1046,7 @@ class Sabre_DAV_Server { if ($this->broadcastEvent('report',array($reportName,$dom, $uri))) { // If broadcastEvent returned true, it means the report was not supported - throw new Sabre_DAV_Exception_ReportNotImplemented(); + throw new Sabre_DAV_Exception_ReportNotSupported(); } @@ -1158,6 +1195,85 @@ class Sabre_DAV_Server { } + /** + * Returns the HTTP Prefer header information. + * + * The prefer header is defined in: + * http://tools.ietf.org/html/draft-snell-http-prefer-14 + * + * This method will return an array with options. + * + * Currently, the following options may be returned: + * array( + * 'return-asynch' => true, + * 'return-minimal' => true, + * 'return-representation' => true, + * 'wait' => 30, + * 'strict' => true, + * 'lenient' => true, + * ) + * + * This method also supports the Brief header, and will also return + * 'return-minimal' if the brief header was set to 't'. + * + * For the boolean options, false will be returned if the headers are not + * specified. For the integer options it will be 'null'. + * + * @return array + */ + public function getHTTPPrefer() { + + $result = array( + 'return-asynch' => false, + 'return-minimal' => false, + 'return-representation' => false, + 'wait' => null, + 'strict' => false, + 'lenient' => false, + ); + + if ($prefer = $this->httpRequest->getHeader('Prefer')) { + + $parameters = array_map('trim', + explode(',', $prefer) + ); + + foreach($parameters as $parameter) { + + // Right now our regex only supports the tokens actually + // specified in the draft. We may need to expand this if new + // tokens get registered. + if(!preg_match('/^(?P<token>[a-z0-9-]+)(?:=(?P<value>[0-9]+))?$/', $parameter, $matches)) { + continue; + } + + switch($matches['token']) { + + case 'return-asynch' : + case 'return-minimal' : + case 'return-representation' : + case 'strict' : + case 'lenient' : + $result[$matches['token']] = true; + break; + case 'wait' : + $result[$matches['token']] = $matches['value']; + break; + + } + + } + + } + + if ($this->httpRequest->getHeader('Brief')=='t') { + $result['return-minimal'] = true; + } + + return $result; + + } + /** * Returns information about Copy and Move requests @@ -1433,15 +1549,18 @@ class Sabre_DAV_Server { } - $this->broadcastEvent('afterGetProperties',array(trim($myPath,'/'),&$newProperties)); + $this->broadcastEvent('afterGetProperties',array(trim($myPath,'/'),&$newProperties, $node)); $newProperties['href'] = trim($myPath,'/'); // Its is a WebDAV recommendation to add a trailing slash to collectionnames. - // Apple's iCal also requires a trailing slash for principals (rfc 3744). - // Therefore we add a trailing / for any non-file. This might need adjustments - // if we find there are other edge cases. - if ($myPath!='' && isset($newProperties[200]['{DAV:}resourcetype']) && count($newProperties[200]['{DAV:}resourcetype']->getValue())>0) $newProperties['href'] .='/'; + // Apple's iCal also requires a trailing slash for principals (rfc 3744), though this is non-standard. + if ($myPath!='' && isset($newProperties[200]['{DAV:}resourcetype'])) { + $rt = $newProperties[200]['{DAV:}resourcetype']; + if ($rt->is('{DAV:}collection') || $rt->is('{DAV:}principal')) { + $newProperties['href'] .='/'; + } + } // If the resourcetype property was manually added to the requested property list, // we will remove it again. @@ -1476,11 +1595,14 @@ class Sabre_DAV_Server { if (!$this->broadcastEvent('beforeBind',array($uri))) return false; $parent = $this->tree->getNodeForPath($dir); + if (!$parent instanceof Sabre_DAV_ICollection) { + throw new Sabre_DAV_Exception_Conflict('Files can only be created as children of collections'); + } if (!$this->broadcastEvent('beforeCreateFile',array($uri, &$data, $parent))) return false; $etag = $parent->createFile($name,$data); - $this->tree->markDirty($dir); + $this->tree->markDirty($dir . '/' . $name); $this->broadcastEvent('afterBind',array($uri)); $this->broadcastEvent('afterCreateFile',array($uri, $parent)); @@ -1901,12 +2023,15 @@ class Sabre_DAV_Server { /** - * Generates a WebDAV propfind response body based on a list of nodes + * Generates a WebDAV propfind response body based on a list of nodes. + * + * If 'strip404s' is set to true, all 404 responses will be removed. * * @param array $fileProperties The list with nodes + * @param bool strip404s * @return string */ - public function generateMultiStatus(array $fileProperties) { + public function generateMultiStatus(array $fileProperties, $strip404s = false) { $dom = new DOMDocument('1.0','utf-8'); //$dom->formatOutput = true; @@ -1925,6 +2050,10 @@ class Sabre_DAV_Server { $href = $entry['href']; unset($entry['href']); + if ($strip404s && isset($entry[404])) { + unset($entry[404]); + } + $response = new Sabre_DAV_Property_Response($href,$entry); $response->serialize($this,$multiStatus); @@ -1995,7 +2124,7 @@ class Sabre_DAV_Server { if (!$body) return array(); $dom = Sabre_DAV_XMLUtil::loadDOMDocument($body); - $elem = $dom->getElementsByTagNameNS('urn:DAV','propfind')->item(0); + $elem = $dom->getElementsByTagNameNS('DAV:','propfind')->item(0); return array_keys(Sabre_DAV_XMLUtil::parseProperties($elem)); } diff --git a/3rdparty/Sabre/DAV/ServerPlugin.php b/3rdparty/Sabre/DAV/ServerPlugin.php index 131863d13fb..120569ffccd 100755..100644 --- a/3rdparty/Sabre/DAV/ServerPlugin.php +++ b/3rdparty/Sabre/DAV/ServerPlugin.php @@ -19,7 +19,7 @@ abstract class Sabre_DAV_ServerPlugin { * This function is called by Sabre_DAV_Server, after * addPlugin is called. * - * This method should set up the requires event subscriptions. + * This method should set up the required event subscriptions. * * @param Sabre_DAV_Server $server * @return void diff --git a/3rdparty/Sabre/DAV/SimpleCollection.php b/3rdparty/Sabre/DAV/SimpleCollection.php index 4acf971caa5..79e2eaaacd4 100755..100644 --- a/3rdparty/Sabre/DAV/SimpleCollection.php +++ b/3rdparty/Sabre/DAV/SimpleCollection.php @@ -31,7 +31,7 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection { /** * Creates this node * - * The name of the node must be passed, child nodes can also be bassed. + * The name of the node must be passed, child nodes can also be passed. * This nodes must be instances of Sabre_DAV_INode * * @param string $name @@ -78,6 +78,9 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection { * This method makes use of the getChildren method to grab all the child nodes, and compares the name. * Generally its wise to override this, as this can usually be optimized * + * This method must throw Sabre_DAV_Exception_NotFound if the node does not + * exist. + * * @param string $name * @throws Sabre_DAV_Exception_NotFound * @return Sabre_DAV_INode diff --git a/3rdparty/Sabre/DAV/SimpleDirectory.php b/3rdparty/Sabre/DAV/SimpleDirectory.php deleted file mode 100755 index 621222ebc53..00000000000 --- a/3rdparty/Sabre/DAV/SimpleDirectory.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -/** - * SimpleDirectory - * - * The SimpleDirectory is used to quickly setup static directory structures. - * Just create the object with a proper name, and add children to use it. - * - * This class is now deprecated, use Sabre_DAV_SimpleCollection instead. - * - * @package Sabre - * @subpackage DAV - * @deprecated Use Sabre_DAV_SimpleCollection instead. - * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) - * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License - */ -class Sabre_DAV_SimpleDirectory extends Sabre_DAV_SimpleCollection { - -} - diff --git a/3rdparty/Sabre/DAV/SimpleFile.php b/3rdparty/Sabre/DAV/SimpleFile.php index 58330d6861d..58330d6861d 100755..100644 --- a/3rdparty/Sabre/DAV/SimpleFile.php +++ b/3rdparty/Sabre/DAV/SimpleFile.php diff --git a/3rdparty/Sabre/DAV/StringUtil.php b/3rdparty/Sabre/DAV/StringUtil.php index b126a94c825..b126a94c825 100755..100644 --- a/3rdparty/Sabre/DAV/StringUtil.php +++ b/3rdparty/Sabre/DAV/StringUtil.php diff --git a/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php b/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php index 36096e67775..36096e67775 100755..100644 --- a/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php +++ b/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php diff --git a/3rdparty/Sabre/DAV/Tree.php b/3rdparty/Sabre/DAV/Tree.php index 50216394155..50216394155 100755..100644 --- a/3rdparty/Sabre/DAV/Tree.php +++ b/3rdparty/Sabre/DAV/Tree.php diff --git a/3rdparty/Sabre/DAV/Tree/Filesystem.php b/3rdparty/Sabre/DAV/Tree/Filesystem.php index 40580ae366f..40580ae366f 100755..100644 --- a/3rdparty/Sabre/DAV/Tree/Filesystem.php +++ b/3rdparty/Sabre/DAV/Tree/Filesystem.php diff --git a/3rdparty/Sabre/DAV/URLUtil.php b/3rdparty/Sabre/DAV/URLUtil.php index 794665a44f6..794665a44f6 100755..100644 --- a/3rdparty/Sabre/DAV/URLUtil.php +++ b/3rdparty/Sabre/DAV/URLUtil.php diff --git a/3rdparty/Sabre/DAV/UUIDUtil.php b/3rdparty/Sabre/DAV/UUIDUtil.php index f0eebe598e5..f0eebe598e5 100755..100644 --- a/3rdparty/Sabre/DAV/UUIDUtil.php +++ b/3rdparty/Sabre/DAV/UUIDUtil.php diff --git a/3rdparty/Sabre/DAV/Version.php b/3rdparty/Sabre/DAV/Version.php index 274646240ab..55611cf2148 100755..100644 --- a/3rdparty/Sabre/DAV/Version.php +++ b/3rdparty/Sabre/DAV/Version.php @@ -14,7 +14,7 @@ class Sabre_DAV_Version { /** * Full version number */ - const VERSION = '1.6.4'; + const VERSION = '1.7.1'; /** * Stability : alpha, beta, stable diff --git a/3rdparty/Sabre/DAV/XMLUtil.php b/3rdparty/Sabre/DAV/XMLUtil.php index 60eff3b159a..712fa3fc014 100755..100644 --- a/3rdparty/Sabre/DAV/XMLUtil.php +++ b/3rdparty/Sabre/DAV/XMLUtil.php @@ -20,9 +20,6 @@ class Sabre_DAV_XMLUtil { * {http://www.example.org}myelem * * This format is used throughout the SabreDAV sourcecode. - * Elements encoded with the urn:DAV namespace will - * be returned as if they were in the DAV: namespace. This is to avoid - * compatibility problems. * * This function will return null if a nodetype other than an Element is passed. * @@ -33,8 +30,7 @@ class Sabre_DAV_XMLUtil { if ($dom->nodeType !== XML_ELEMENT_NODE) return null; - // Mapping back to the real namespace, in case it was dav - if ($dom->namespaceURI=='urn:DAV') $ns = 'DAV:'; else $ns = $dom->namespaceURI; + $ns = $dom->namespaceURI; // Mapping to clark notation return '{' . $ns . '}' . $dom->localName; @@ -65,28 +61,10 @@ class Sabre_DAV_XMLUtil { } /** - * This method takes an XML document (as string) and converts all instances of the - * DAV: namespace to urn:DAV - * - * This is unfortunately needed, because the DAV: namespace violates the xml namespaces - * spec, and causes the DOM to throw errors - * - * @param string $xmlDocument - * @return array|string|null - */ - static function convertDAVNamespace($xmlDocument) { - - // This is used to map the DAV: namespace to urn:DAV. This is needed, because the DAV: - // namespace is actually a violation of the XML namespaces specification, and will cause errors - return preg_replace("/xmlns(:[A-Za-z0-9_]*)?=(\"|\')DAV:(\\2)/","xmlns\\1=\\2urn:DAV\\2",$xmlDocument); - - } - - /** * This method provides a generic way to load a DOMDocument for WebDAV use. * * This method throws a Sabre_DAV_Exception_BadRequest exception for any xml errors. - * It does not preserve whitespace, and it converts the DAV: namespace to urn:DAV. + * It does not preserve whitespace. * * @param string $xml * @throws Sabre_DAV_Exception_BadRequest @@ -118,10 +96,11 @@ class Sabre_DAV_XMLUtil { libxml_clear_errors(); $dom = new DOMDocument(); - $dom->loadXML(self::convertDAVNamespace($xml),LIBXML_NOWARNING | LIBXML_NOERROR); // We don't generally care about any whitespace $dom->preserveWhiteSpace = false; + + $dom->loadXML($xml,LIBXML_NOWARNING | LIBXML_NOERROR); if ($error = libxml_get_last_error()) { libxml_clear_errors(); diff --git a/3rdparty/Sabre/DAV/includes.php b/3rdparty/Sabre/DAV/includes.php index 6a4890677ea..6728f88ce76 100755..100644 --- a/3rdparty/Sabre/DAV/includes.php +++ b/3rdparty/Sabre/DAV/includes.php @@ -28,7 +28,7 @@ include __DIR__ . '/Locks/Backend/PDO.php'; include __DIR__ . '/Locks/LockInfo.php'; include __DIR__ . '/Node.php'; include __DIR__ . '/Property/IHref.php'; -include __DIR__ . '/Property.php'; +include __DIR__ . '/PropertyInterface.php'; include __DIR__ . '/Server.php'; include __DIR__ . '/ServerPlugin.php'; include __DIR__ . '/StringUtil.php'; @@ -60,7 +60,7 @@ include __DIR__ . '/Exception/NotFound.php'; include __DIR__ . '/Exception/NotImplemented.php'; include __DIR__ . '/Exception/PaymentRequired.php'; include __DIR__ . '/Exception/PreconditionFailed.php'; -include __DIR__ . '/Exception/ReportNotImplemented.php'; +include __DIR__ . '/Exception/ReportNotSupported.php'; include __DIR__ . '/Exception/RequestedRangeNotSatisfiable.php'; include __DIR__ . '/Exception/UnsupportedMediaType.php'; include __DIR__ . '/FS/Node.php'; @@ -72,18 +72,11 @@ include __DIR__ . '/IQuota.php'; include __DIR__ . '/Locks/Plugin.php'; include __DIR__ . '/Mount/Plugin.php'; include __DIR__ . '/ObjectTree.php'; -include __DIR__ . '/Property/GetLastModified.php'; -include __DIR__ . '/Property/Href.php'; -include __DIR__ . '/Property/HrefList.php'; -include __DIR__ . '/Property/LockDiscovery.php'; -include __DIR__ . '/Property/ResourceType.php'; -include __DIR__ . '/Property/Response.php'; -include __DIR__ . '/Property/ResponseList.php'; -include __DIR__ . '/Property/SupportedLock.php'; -include __DIR__ . '/Property/SupportedReportSet.php'; +include __DIR__ . '/PartialUpdate/IFile.php'; +include __DIR__ . '/PartialUpdate/Plugin.php'; +include __DIR__ . '/Property.php'; include __DIR__ . '/Tree/Filesystem.php'; include __DIR__ . '/Collection.php'; -include __DIR__ . '/Directory.php'; include __DIR__ . '/Exception/ConflictingLock.php'; include __DIR__ . '/Exception/FileNotFound.php'; include __DIR__ . '/File.php'; @@ -91,7 +84,15 @@ include __DIR__ . '/FS/Directory.php'; include __DIR__ . '/FS/File.php'; include __DIR__ . '/FSExt/Directory.php'; include __DIR__ . '/FSExt/File.php'; +include __DIR__ . '/Property/GetLastModified.php'; +include __DIR__ . '/Property/Href.php'; +include __DIR__ . '/Property/HrefList.php'; +include __DIR__ . '/Property/LockDiscovery.php'; +include __DIR__ . '/Property/ResourceType.php'; +include __DIR__ . '/Property/Response.php'; +include __DIR__ . '/Property/ResponseList.php'; +include __DIR__ . '/Property/SupportedLock.php'; +include __DIR__ . '/Property/SupportedReportSet.php'; include __DIR__ . '/SimpleCollection.php'; -include __DIR__ . '/SimpleDirectory.php'; include __DIR__ . '/SimpleFile.php'; // End includes |