/** * Unlocks a uri * * This method removes a lock from a uri. It is assumed all the supplied information is correct and verified * * @param string $uri * @param LockInfo $lockInfo * @return bool */ public function unlockNode($uri, LockInfo $lockInfo) { if (!$this->server->broadcastEvent('beforeUnlock', array($uri, $lockInfo))) { return; } if ($this->locksBackend) { return $this->locksBackend->unlock($uri, $lockInfo); } }
/** * 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 IFile) { throw new DAV\Exception\MethodNotAllowed('The target resource does not support the PATCH method.'); } $range = $this->getHTTPUpdateRange(); if (!$range) { throw new 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 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 DAV\Exception\RequestedRangeNotSatisfiable('The end offset (' . $range[1] . ') is lower than the start offset (' . $range[0] . ')'); } if ($end - $start + 1 != $len) { throw new 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; }
/** * Generates the html directory index for a given url * * @param string $path * @return string */ public function generateDirectoryIndex($path) { $version = ''; if (DAV\Server::$exposeVersion) { $version = DAV\Version::VERSION . "-" . DAV\Version::STABILITY; } $html = "<html>\n<head>\n <title>Index for " . $this->escapeHTML($path) . "/ - SabreDAV " . $version . "</title>\n <style type=\"text/css\">\n body { Font-family: arial}\n h1 { font-size: 150% }\n </style>\n "; if ($this->enableAssets) { $html .= '<link rel="shortcut icon" href="' . $this->getAssetUrl('favicon.ico') . '" type="image/vnd.microsoft.icon" />'; } $html .= "</head>\n<body>\n <h1>Index for " . $this->escapeHTML($path) . "/</h1>\n <table>\n <tr><th width=\"24\"></th><th>Name</th><th>Type</th><th>Size</th><th>Last modified</th></tr>\n <tr><td colspan=\"5\"><hr /></td></tr>"; $files = $this->server->getPropertiesForPath($path, array('{DAV:}displayname', '{DAV:}resourcetype', '{DAV:}getcontenttype', '{DAV:}getcontentlength', '{DAV:}getlastmodified'), 1); $parent = $this->server->tree->getNodeForPath($path); if ($path) { list($parentUri) = DAV\URLUtil::splitPath($path); $fullPath = DAV\URLUtil::encodePath($this->server->getBaseUri() . $parentUri); $icon = $this->enableAssets ? '<a href="' . $fullPath . '"><img src="' . $this->getAssetUrl('icons/parent' . $this->iconExtension) . '" width="24" alt="Parent" /></a>' : ''; $html .= "<tr>\n <td>{$icon}</td>\n <td><a href=\"{$fullPath}\">..</a></td>\n <td>[parent]</td>\n <td></td>\n <td></td>\n </tr>"; } foreach ($files as $file) { // This is the current directory, we can skip it if (rtrim($file['href'], '/') == $path) { continue; } list(, $name) = DAV\URLUtil::splitPath($file['href']); $type = null; if (isset($file[200]['{DAV:}resourcetype'])) { $type = $file[200]['{DAV:}resourcetype']->getValue(); // resourcetype can have multiple values if (!is_array($type)) { $type = array($type); } foreach ($type as $k => $v) { // Some name mapping is preferred switch ($v) { case '{DAV:}collection': $type[$k] = 'Collection'; break; case '{DAV:}principal': $type[$k] = 'Principal'; break; case '{urn:ietf:params:xml:ns:carddav}addressbook': $type[$k] = 'Addressbook'; break; case '{urn:ietf:params:xml:ns:caldav}calendar': $type[$k] = 'Calendar'; break; case '{urn:ietf:params:xml:ns:caldav}schedule-inbox': $type[$k] = 'Schedule Inbox'; break; case '{urn:ietf:params:xml:ns:caldav}schedule-outbox': $type[$k] = 'Schedule Outbox'; break; case '{http://calendarserver.org/ns/}calendar-proxy-read': $type[$k] = 'Proxy-Read'; break; case '{http://calendarserver.org/ns/}calendar-proxy-write': $type[$k] = 'Proxy-Write'; break; } } $type = implode(', ', $type); } // If no resourcetype was found, we attempt to use // the contenttype property if (!$type && isset($file[200]['{DAV:}getcontenttype'])) { $type = $file[200]['{DAV:}getcontenttype']; } if (!$type) { $type = 'Unknown'; } $size = isset($file[200]['{DAV:}getcontentlength']) ? (int) $file[200]['{DAV:}getcontentlength'] : ''; $lastmodified = isset($file[200]['{DAV:}getlastmodified']) ? $file[200]['{DAV:}getlastmodified']->getTime()->format(\DateTime::ATOM) : ''; $fullPath = DAV\URLUtil::encodePath('/' . trim($this->server->getBaseUri() . ($path ? $path . '/' : '') . $name, '/')); $displayName = isset($file[200]['{DAV:}displayname']) ? $file[200]['{DAV:}displayname'] : $name; $displayName = $this->escapeHTML($displayName); $type = $this->escapeHTML($type); $icon = ''; if ($this->enableAssets) { $node = $this->server->tree->getNodeForPath(($path ? $path . '/' : '') . $name); foreach (array_reverse($this->iconMap) as $class => $iconName) { if ($node instanceof $class) { $icon = '<a href="' . $fullPath . '"><img src="' . $this->getAssetUrl($iconName . $this->iconExtension) . '" alt="" width="24" /></a>'; break; } } } $html .= "<tr>\n <td>{$icon}</td>\n <td><a href=\"{$fullPath}\">{$displayName}</a></td>\n <td>{$type}</td>\n <td>{$size}</td>\n <td>{$lastmodified}</td>\n </tr>"; } $html .= "<tr><td colspan=\"5\"><hr /></td></tr>"; $output = ''; if ($this->enablePost) { $this->server->broadcastEvent('onHTMLActionsPanel', array($parent, &$output)); } $html .= $output; $html .= "</table>\n <address>Generated by SabreDAV " . $version . " (c)2007-2013 <a href=\"http://code.google.com/p/sabredav/\">http://code.google.com/p/sabredav/</a></address>\n </body>\n </html>"; return $html; }