/** * Returns the relative path. * * This is being calculated using the base url. This path will not start * with a slash, so it will always return something like * 'example/path.html'. * * If the full path is equal to the base url, this method will return an * empty string. * * This method will also urldecode the path, and if the url was incoded as * ISO-8859-1, it will convert it to UTF-8. * * If the path is outside of the base url, a LogicException will be thrown. * * @return string */ public function getPath() { // Removing duplicated slashes. $uri = str_replace('//', '/', $this->getUrl()); if (strpos($uri, $this->getBaseUrl()) === 0) { // We're not interested in the query part (everything after the ?). list($uri) = explode('?', $uri); return trim(URLUtil::decodePath(substr($uri, strlen($this->getBaseUrl()))), '/'); } elseif ($uri . '/' === $this->getBaseUrl()) { return ''; } else { throw new \LogicException('Requested uri (' . $this->getUrl() . ') is out of base uri (' . $this->getBaseUrl() . ')'); } }
/** * Calculates the uri for a request, making sure that the base uri is stripped out * * @param string $uri * @throws Exception\Forbidden A permission denied exception is thrown whenever there was an attempt to supply a uri outside of the base uri * @return string */ function calculateUri($uri) { if ($uri[0] != '/' && strpos($uri, '://')) { $uri = parse_url($uri, PHP_URL_PATH); } $uri = Uri\normalize(str_replace('//', '/', $uri)); $baseUri = Uri\normalize($this->getBaseUri()); if (strpos($uri, $baseUri) === 0) { return trim(URLUtil::decodePath(substr($uri, strlen($baseUri))), '/'); // A special case, if the baseUri was accessed without a trailing // slash, we'll accept it as well. } elseif ($uri . '/' === $baseUri) { return ''; } else { throw new Exception\Forbidden('Requested uri (' . $uri . ') is out of base uri (' . $this->getBaseUri() . ')'); } }
public function generateDirectoryIndex($path) { $version = DAV\Server::$exposeVersion ? DAV\Version::VERSION : ''; $node = $this->server->tree->getNodeForPath($path); $html = <<<HTML <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Index for {$this->escapeHTML($path)}/ - SambaDAV</title> <link rel="stylesheet" href="{$this->server->getBaseUri()}style.css"/> <link rel="shortcut icon" href="{$this->server->getBaseUri()}favicon.ico" type="image/vnd.microsoft.icon"/> </head> <body> HTML; if ($this->config->anonymous_only === false) { $html .= "\n <p id=\"logout\"><a href=\"?logout\">switch user (logout)</a></p>"; } $html .= <<<HTML <h1>{$this->escapeHTML($node->uri->uriFull())}</h1> <table id="actions"> <tbody> HTML; $output = ''; if ($this->enablePost) { $this->server->emit('onHTMLActionsPanel', [$node, &$output]); } if ($output) { $html .= $output; } $html .= <<<HTML </tbody> </table> <table> <colgroup> <col width="15px"/> <col/> <col/> <col/> <col/> </colgroup> <thead> <tr> <th></th> <th>Name</th> <th>Type</th> <th>Size</th> <th>Last modified</th> HTML; if ($this->config->browserplugin_enable_delete === true) { $html .= "<th>Delete</th>"; } $html .= <<<HTML </tr> </thead> <tbody> HTML; // If path is empty, there is no parent: if ($path) { list($parentUri) = URLUtil::splitPath($path); $fullPath = URLUtil::encodePath($this->server->getBaseUri() . $parentUri); $html .= <<<HTML <tr class="dir"> <td><a href="{$fullPath}"><img src="{$this->server->getBaseUri()}dir.png" alt="Parent"/></a></td> <td><a href="{$fullPath}">..</a></td> <td>[parent]</td> <td></td> <td></td> HTML; if ($this->config->browserplugin_enable_delete === true) { $html .= "<td></td>"; } $html .= <<<HTML </tr> HTML; } if ($node instanceof DAV\ICollection) { $subNodes = $this->server->getPropertiesForChildren($path, ['{DAV:}displayname', '{DAV:}resourcetype', '{DAV:}getcontenttype', '{DAV:}getcontentlength', '{DAV:}getlastmodified']); foreach ($subNodes as $subPath => $subProps) { $subNode = $this->server->tree->getNodeForPath($subPath); $fullPath = URLUtil::encodePath($this->server->getBaseUri() . $subPath); list(, $displayPath) = URLUtil::splitPath($subPath); $subNodes[$subPath]['subNode'] = $subNode; $subNodes[$subPath]['fullPath'] = $fullPath; $subNodes[$subPath]['displayPath'] = $displayPath; } uasort($subNodes, [$this, 'compareNodes']); foreach ($subNodes as $subProps) { $size = isset($subProps['{DAV:}getcontentlength']) ? $subProps['{DAV:}getcontentlength'] : ''; $lastmodified = isset($subProps['{DAV:}getlastmodified']) ? $subProps['{DAV:}getlastmodified']->getTime()->format('F j, Y, H:i:s') : ''; $fullPath_decoded = URLUtil::decodePath($subProps['fullPath']); $fullPath = $this->escapeHTML($subProps['fullPath']); if (isset($subProps['{DAV:}resourcetype']) && in_array('{DAV:}collection', $subProps['{DAV:}resourcetype']->getValue())) { $trclass = 'class="dir"'; $icon = 'dir.png'; $type = 'Directory'; } else { $trclass = 'class="file"'; $icon = 'file.png'; $type = isset($subProps['{DAV:}getcontenttype']) ? $subProps['{DAV:}getcontenttype'] : 'Unknown'; } $html .= " <tr {$trclass}>\n"; $html .= " <td><a href=\"{$fullPath}\"><img src=\"{$this->server->getBaseUri()}{$icon}\" alt=\"\"/></a></td>\n"; $html .= " <td><a href=\"{$fullPath}\">{$subProps['displayPath']}</a></td>\n"; $html .= " <td>{$type}</td>\n"; $html .= " <td>{$size}</td>\n"; $html .= " <td>{$lastmodified}</td>\n"; if ($this->config->browserplugin_enable_delete === true) { $html .= " <td>\n"; $html .= " <form method=\"post\" enctype=\"multipart/form-data\" onsubmit=\"return confirm('Are you sure you want to delete " . $subProps['displayPath'] . "');\">\n"; $html .= " <input name=\"sabreActionExtra\" value=\"del\" type=\"hidden\">\n"; $html .= " <input name=\"path\" value=\"{$fullPath_decoded}\" type=\"hidden\">\n"; $html .= " <input value=\"Delete\" type=\"submit\">\n"; $html .= " </form>\n"; $html .= " </td>\n"; } $html .= " </tr>\n"; } } $html .= <<<HTML </tbody> </table> <img src="{$this->server->getBaseUri()}logo-sambadav.png" id="sambadav-logo"/><address>Generated by SabreDAV {$version}</address> </body> </html> HTML; $this->server->httpResponse->setHeader('Content-Security-Policy', "img-src 'self'; style-src 'self';"); return $html; }