Lines Matching +full:fetch +full:- +full:depth
15 * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
22 …* Infinity is used for some request supporting the HTTP Depth header and indicates that the operat…
24 const DEPTH_INFINITY = -1;
79 * plugins override this. For example, the WebDAV-Sync sync-collection
80 * report will set this to 'report-sync-collection'.
87 * This is a list of properties that are always server-controlled, and
104 '{DAV:}quota-available-bytes',
105 '{DAV:}quota-used-bytes',
108 '{DAV:}supported-privilege-set',
109 '{DAV:}current-user-privilege-set',
111 '{DAV:}acl-restrictions',
112 '{DAV:}inherited-acl-set',
115 '{DAV:}supported-method-set',
116 '{DAV:}supported-report-set',
119 '{DAV:}sync-token',
125 '{http://sabredav.org/ns}sync-token',
151 * This property allows the usage of Depth: infinity on PROPFIND requests.
153 * By default Depth: infinity is treated as Depth: 1. Allowing Depth:
191 * the nodes in the array as top-level children.
198 $this->tree = $treeOrNode;
200 $this->tree = new Tree($treeOrNode);
212 $this->tree = new Tree($root);
216 $this->tree = new Tree($root);
221 $this->xml = new Xml\Service();
222 $this->sapi = new HTTP\Sapi();
223 $this->httpResponse = new HTTP\Response();
224 $this->httpRequest = $this->sapi->getRequest();
225 $this->addPlugin(new CorePlugin());
238 // If nginx (pre-1.2) is used as a proxy server, and SabreDAV as an
243 // to buffer entire responses to calculate Content-Length.
244 $this->httpResponse->setHTTPVersion($this->httpRequest->getHTTPVersion());
247 $this->httpRequest->setBaseUrl($this->getBaseUri());
248 $this->invokeMethod($this->httpRequest, $this->httpResponse);
253 $this->emit('exception', [$e]);
256 $DOM = new \DOMDocument('1.0', 'utf-8');
257 $DOM->formatOutput = true;
259 $error = $DOM->createElementNS('DAV:', 'd:error');
260 $error->setAttribute('xmlns:s', self::NS_SABREDAV);
261 $DOM->appendChild($error);
265 return htmlspecialchars($v, ENT_NOQUOTES, 'UTF-8');
270 … $error->appendChild($DOM->createElement('s:sabredav-version', $h(Version::VERSION)));
273 $error->appendChild($DOM->createElement('s:exception', $h(get_class($e))));
274 $error->appendChild($DOM->createElement('s:message', $h($e->getMessage())));
275 if ($this->debugExceptions) {
276 $error->appendChild($DOM->createElement('s:file', $h($e->getFile())));
277 $error->appendChild($DOM->createElement('s:line', $h($e->getLine())));
278 $error->appendChild($DOM->createElement('s:code', $h($e->getCode())));
279 … $error->appendChild($DOM->createElement('s:stacktrace', $h($e->getTraceAsString())));
282 if ($this->debugExceptions) {
284 while ($previous = $previous->getPrevious()) {
285 $xPrevious = $DOM->createElement('s:previous-exception');
286 … $xPrevious->appendChild($DOM->createElement('s:exception', $h(get_class($previous))));
287 … $xPrevious->appendChild($DOM->createElement('s:message', $h($previous->getMessage())));
288 … $xPrevious->appendChild($DOM->createElement('s:file', $h($previous->getFile())));
289 … $xPrevious->appendChild($DOM->createElement('s:line', $h($previous->getLine())));
290 … $xPrevious->appendChild($DOM->createElement('s:code', $h($previous->getCode())));
291 … $xPrevious->appendChild($DOM->createElement('s:stacktrace', $h($previous->getTraceAsString())));
292 $error->appendChild($xPrevious);
299 $httpCode = $e->getHTTPCode();
300 $e->serialize($this, $error);
301 $headers = $e->getHTTPHeaders($this);
309 $headers['Content-Type'] = 'application/xml; charset=utf-8';
311 $this->httpResponse->setStatus($httpCode);
312 $this->httpResponse->setHeaders($headers);
313 $this->httpResponse->setBody($DOM->saveXML());
314 $this->sapi->sendResponse($this->httpResponse);
329 if ($uri[strlen($uri) - 1] !== '/')
332 $this->baseUri = $uri;
343 if (is_null($this->baseUri)) $this->baseUri = $this->guessBaseUri();
344 return $this->baseUri;
358 $pathInfo = $this->httpRequest->getRawServerValue('PATH_INFO');
359 $uri = $this->httpRequest->getRawServerValue('REQUEST_URI');
376 if (substr($decodedUri, strlen($decodedUri) - strlen($pathInfo)) === $pathInfo) {
377 $baseUri = substr($decodedUri, 0, strlen($decodedUri) - strlen($pathInfo));
400 $this->plugins[$plugin->getPluginName()] = $plugin;
401 $plugin->initialize($this);
415 if (isset($this->plugins[$name]))
416 return $this->plugins[$name];
429 return $this->plugins;
443 $method = $request->getMethod();
445 if (!$this->emit('beforeMethod:' . $method, [$request, $response])) return;
446 if (!$this->emit('beforeMethod', [$request, $response])) return;
449 $response->setHeader('X-Sabre-Version', Version::VERSION);
452 $this->transactionType = strtolower($method);
454 if (!$this->checkPreconditions($request, $response)) {
455 $this->sapi->sendResponse($response);
459 if ($this->emit('method:' . $method, [$request, $response])) {
460 if ($this->emit('method', [$request, $response])) {
466 if (!$this->emit('afterMethod:' . $method, [$request, $response])) return;
467 if (!$this->emit('afterMethod', [$request, $response])) return;
470 $this->sapi->sendResponse($response);
471 $this->emit('afterResponse', [$request, $response]);
501 $this->tree->getNodeForPath($path);
507 …foreach ($this->plugins as $plugin) $methods = array_merge($methods, $plugin->getHTTPMethods($path…
521 return $this->calculateUri($this->httpRequest->getUrl());
541 $baseUri = Uri\normalize($this->getBaseUri());
555 …ception\Forbidden('Requested uri (' . $uri . ') is out of base uri (' . $this->getBaseUri() . ')');
562 * Returns the HTTP depth header
564 …* This method returns the contents of the HTTP depth request header. If the depth header was 'infi…
565 …s possible to supply a default depth value, which is used when the depth header has invalid conten…
573 $depth = $this->httpRequest->getHeader('Depth');
575 if (is_null($depth)) return $default;
577 if ($depth == 'infinity') return self::DEPTH_INFINITY;
581 if (!ctype_digit($depth)) return $default;
583 return (int)$depth;
590 * This method returns null if there is no well-formed HTTP range request
603 $range = $this->httpRequest->getHeader('range');
606 // Matching "Range: bytes=1234-5678: both numbers are optional
608 if (!preg_match('/^bytes=([0-9]*)-([0-9]*)$/i', $range, $matches)) return null;
623 * http://tools.ietf.org/html/draft-snell-http-prefer-14
629 * 'return-asynch' => true,
630 * 'return-minimal' => true,
631 * 'return-representation' => true,
638 * 'return-minimal' if the brief header was set to 't'.
649 'respond-async' => false,
658 if ($prefer = $this->httpRequest->getHeader('Prefer')) {
665 } elseif ($this->httpRequest->getHeader('Brief') == 't') {
681 * * destination - Destination path
682 …* * destinationExists - Whether or not the destination is an existing url (and should therefore …
687 * non-collection.
699 …if (!$request->getHeader('Destination')) throw new Exception\BadRequest('The destination header wa…
700 $destination = $this->calculateUri($request->getHeader('Destination'));
701 $overwrite = $request->getHeader('Overwrite');
711 $destinationParent = $this->tree->getNodeForPath($destinationDir);
721 $destinationNode = $this->tree->getNodeForPath($destination);
734 $requestPath = $request->getPath();
763 $result = $this->getPropertiesForPath($path, $propertyNames, 0);
769 * A kid-friendly way to fetch properties for a node's children.
783 foreach ($this->getPropertiesForPath($path, $propertyNames, 1) as $k => $row) {
810 '{DAV:}getcontenttype' => 'Content-Type',
811 '{DAV:}getcontentlength' => 'Content-Length',
812 '{DAV:}getlastmodified' => 'Last-Modified',
816 $properties = $this->getProperties($path, array_keys($propertyMap));
827 $headers[$header] = HTTP\Util::toHTTPDate($properties[$property]->getTime());
845 $newDepth = $propFind->getDepth();
846 $path = $propFind->getPath();
849 $newDepth--;
852 foreach ($this->tree->getChildren($path) as $childNode) {
854 $subPropFind->setDepth($newDepth);
856 $subPath = $path . '/' . $childNode->getName();
858 $subPath = $childNode->getName();
860 $subPropFind->setPath($subPath);
868 $this->addPathNodesRecursively($propFindRequests, $subPropFind);
881 * If a depth of 1 is requested child elements will also be returned.
885 * @param int $depth
888 function getPropertiesForPath($path, $propertyNames = [], $depth = 0) { argument
890 …// The only two options for the depth of a propfind is 0 or 1 - as long as depth infinity is not e…
891 if (!$this->enablePropfindDepthInfinity && $depth != 0) $depth = 1;
896 $propFind = new PropFind($path, (array)$propertyNames, $depth, $propFindType);
898 $parentNode = $this->tree->getNodeForPath($path);
905 if (($depth > 0 || $depth === self::DEPTH_INFINITY) && $parentNode instanceof ICollection) {
906 $this->addPathNodesRecursively($propFindRequests, $propFind);
914 $r = $this->getPropertiesByNode($propFind, $node);
916 $result = $propFind->getResultForMultiStatus();
917 $result['href'] = $propFind->getPath();
922 // principals. This is non-standard, but we support it.
923 $resourceType = $this->getResourceTypeForNode($node);
955 $nodes = $this->tree->getMultipleNodes($paths);
960 $r = $this->getPropertiesByNode($propFind, $node);
962 $result[$path] = $propFind->getResultForMultiStatus();
965 $resourceType = $this->getResourceTypeForNode($node);
994 return $this->emit('propFind', [$propFind, $node]);
999 * This method is invoked by sub-systems creating a new file.
1016 if (!$this->emit('beforeBind', [$uri])) return false;
1018 $parent = $this->tree->getNodeForPath($dir);
1029 if (!$this->emit('beforeCreateFile', [$uri, &$data, $parent, &$modified])) return false;
1031 $etag = $parent->createFile($name, $data);
1035 $this->tree->markDirty($dir . '/' . $name);
1037 $this->emit('afterBind', [$uri]);
1038 $this->emit('afterCreateFile', [$uri, $parent]);
1044 * This method is invoked by sub-systems updating a file.
1055 $node = $this->tree->getNodeForPath($uri);
1063 if (!$this->emit('beforeWriteContent', [$uri, $node, &$data, &$modified])) return false;
1065 $etag = $node->put($data);
1067 $this->emit('afterWriteContent', [$uri, $node]);
1075 * This method is invoked by sub-systems creating a new directory.
1082 $this->createCollection($uri, new MkCol(['{DAV:}collection'], []));
1099 $parent = $this->tree->getNodeForPath($parentUri);
1113 $parent->getChild($newName);
1123 if (!$this->emit('beforeBind', [$uri])) return;
1132 $parent->createExtendedCollection($newName, $mkCol);
1141 if (count($mkCol->getResourceType()) > 1) {
1145 $parent->createDirectory($newName);
1152 if ($mkCol->getRemainingMutations()) {
1153 $this->emit('propPatch', [$uri, $mkCol]);
1155 $success = $mkCol->commit();
1158 $result = $mkCol->getResult();
1164 $this->tree->markDirty($parentUri);
1165 $this->emit('afterBind', [$uri]);
1172 * The properties array must be a list of properties. Array-keys are
1173 * property names in clarknotation, array-values are it's values.
1189 $this->emit('propPatch', [$path, $propPatch]);
1190 $propPatch->commit();
1192 return $propPatch->getResult();
1200 * * If-Match
1201 * * If-None-Match
1202 * * If-Modified-Since
1203 * * If-Unmodified-Since
1211 * related to If-None-Match, If-Match and If-Unmodified Since. It will
1212 * set the status to 304 Not Modified for If-Modified_since.
1220 $path = $request->getPath();
1225 if ($ifMatch = $request->getHeader('If-Match')) {
1227 // If-Match contains an entity tag. Only if the entity-tag
1229 // If the entity-tag is '*' we are only allowed to make the
1232 $node = $this->tree->getNodeForPath($path);
1234 …hrow new Exception\PreconditionFailed('An If-Match header was specified and the resource did not e…
1248 $etag = $node instanceof IFile ? $node->getETag() : null;
1261 if ($etag) $response->setHeader('ETag', $etag);
1262 … Exception\PreconditionFailed('An If-Match header was specified, but none of the specified the ETa…
1267 if ($ifNoneMatch = $request->getHeader('If-None-Match')) {
1269 // The If-None-Match header contains an ETag.
1276 $node = $this->tree->getNodeForPath($path);
1288 $etag = $node instanceof IFile ? $node->getETag() : null;
1302 if ($etag) $response->setHeader('ETag', $etag);
1303 if ($request->getMethod() === 'GET') {
1304 $response->setStatus(304);
1307 …eption\PreconditionFailed('An If-None-Match header was specified, but the ETag matched (or * was s…
1314 if (!$ifNoneMatch && ($ifModifiedSince = $request->getHeader('If-Modified-Since'))) {
1316 // The If-Modified-Since header contains a date. We
1320 // Note that this header only has to be checked if there was no If-None-Match header
1326 $node = $this->tree->getNodeForPath($path);
1328 $lastMod = $node->getLastModified();
1332 $response->setStatus(304);
1333 $response->setHeader('Last-Modified', HTTP\Util::toHTTPDate($lastMod));
1340 if ($ifUnmodifiedSince = $request->getHeader('If-Unmodified-Since')) {
1342 // The If-Unmodified-Since will allow allow the request if the
1349 $node = $this->tree->getNodeForPath($path);
1351 $lastMod = $node->getLastModified();
1355 …ditionFailed('An If-Unmodified-Since header was specified, but the entity has been changed since t…
1363 // urls, ETags and so-called 'state tokens'.
1365 // Examples of state tokens include lock-tokens (as defined in rfc4918)
1366 // and sync-tokens (as defined in rfc6578).
1370 $ifConditions = $this->getIfConditions($request);
1381 $this->emit('validateTokens', [ $request, &$ifConditions ]);
1407 $node = $this->tree->getNodeForPath($uri);
1408 $etagValid = $node instanceof IFile && $node->getETag() == $token['etag'];
1437 * * uri - the uri the condition applies to.
1438 * * tokens - The lock token. another 2 dimensional array containing 3 elements
1442 * If: (<opaquelocktoken:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>)
1453 * 'token' => 'opaquelocktoken:181d4fae-7d8c-11d0-a765-00a0c91e6bf2',
1463 …* If: </path/> (Not <opaquelocktoken:181d4fae-7d8c-11d0-a765-00a0c91e6bf2> ["Im An ETag"]) (["Anot…
1474 * 'token' => 'opaquelocktoken:181d4fae-7d8c-11d0-a765-00a0c91e6bf2',
1504 $header = $request->getHeader('If');
1520 $conditions[count($conditions) - 1]['tokens'][] = [
1528 $realUri = $request->getPath();
1530 $realUri = $this->calculateUri($match['uri']);
1561 foreach ($this->resourceTypeMapping as $className => $resourceType) {
1602 return $this->xml->write('{DAV:}multistatus', $xml, $this->baseUri);