updating own HTTP_WebDAV_Server to upstream version 1.0.0RC6: http://pear.php.net/package/HTTP_WebDAV_Server/download/1.0.0RC6

This commit is contained in:
Ralf Becker 2011-07-31 09:57:20 +00:00
parent 8c2a149760
commit 996efca1ac
7 changed files with 444 additions and 185 deletions

View File

@ -1,24 +1,38 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Hartmut Holzgraefe <hholzgra@php.net> |
// | Christian Stocker <chregu@bitflux.ch> |
// +----------------------------------------------------------------------+
//
// $Id: Server.php,v 1.56 2006/10/10 11:53:16 hholzgra Exp $
//
<?php // $Id$
/*
+----------------------------------------------------------------------+
| Copyright (c) 2002-2007 Christian Stocker, Hartmut Holzgraefe |
| All rights reserved |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions |
| are met: |
| |
| 1. Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| 2. Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in |
| the documentation and/or other materials provided with the |
| distribution. |
| 3. The names of the authors may not be used to endorse or promote |
| products derived from this software without specific prior |
| written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| POSSIBILITY OF SUCH DAMAGE. |
+----------------------------------------------------------------------+
*/
require_once "HTTP/WebDAV/Tools/_parse_propfind.php";
require_once "HTTP/WebDAV/Tools/_parse_proppatch.php";
require_once "HTTP/WebDAV/Tools/_parse_lockinfo.php";
@ -169,19 +183,23 @@ class HTTP_WebDAV_Server
// default uri is the complete request uri
$uri = (@$this->_SERVER["HTTPS"] === "on" ? "https:" : "http:") . '//'.$this->_SERVER['HTTP_HOST'];
}
// support for PHP running as (F)CGI
if (!isset($this->_SERVER['PATH_INFO']) && isset($this->_SERVER['ORIG_PATH_INFO']))
{
$this->_SERVER['PATH_INFO'] = $this->_SERVER['ORIG_PATH_INFO'];
}
// we cant use SCRIPT_NAME, because it fails, if there's any url rewriting
//error_log("pathinfo:\n". $this->_urldecode($this->_SERVER['REQUEST_URI']).":\n".$this->_SERVER['PATH_INFO']);
$uri .= substr($this->_urldecode($this->_SERVER['REQUEST_URI']),0,-strlen($this->_SERVER["PATH_INFO"]));
$uri .= $this->_SERVER["SCRIPT_NAME"];
$path_info = empty($this->_SERVER["PATH_INFO"]) ? "/" : $this->_SERVER["PATH_INFO"];
// WebDAV has no concept of a query string and clients (including cadaver)
// seem to pass '?' unencoded, so we need to extract the path info out
// of the request URI ourselves
$path_info = substr($this->_SERVER["REQUEST_URI"], strlen($this->_SERVER["SCRIPT_NAME"]));
// just in case the path came in empty ...
if (empty($path_info)) {
$path_info = "/";
}
$path_info = $this->_urldecode($path_info);
$this->base_uri = $uri;
$this->uri = $uri . $path_info;
// set path
// $_SERVER['PATH_INFO'] is already urldecoded
//$this->path = $this->_urldecode($path_info);
@ -542,7 +560,7 @@ class HTTP_WebDAV_Server
* OPTIONS method handler
*
* The OPTIONS method handler creates a valid OPTIONS reply
* including Dav: and Allowed: heaers
* including Dav: and Allowed: headers
* based on the implemented methods found in the actual instance
*
* @param void
@ -806,8 +824,10 @@ class HTTP_WebDAV_Server
/* TODO right now the user implementation has to make sure
collections end in a slash, this should be done in here
by checking the resource attribute */
// path needs to be urlencoded (only basic version of this class!)
$href = $this->_urlencode($this->_mergePathes($this->base_uri, $path));
$href = $this->_mergePaths($this->_SERVER['SCRIPT_NAME'], $path);
/* minimal urlencoding is needed for the resource path */
$href = $this->_urlencode($href);
if ($this->crrnd)
{
@ -858,6 +878,17 @@ class HTTP_WebDAV_Server
echo $prop["val"];
echo ' </'.($this->crrnd?'':'D:')."lockdiscovery>\n";
break;
// the following are non-standard Microsoft extensions to the DAV namespace
case "lastaccessed":
echo ' <'.($this->crrnd?'':'D:')."lastaccessed ns0:dt=\"dateTime.rfc1123\">"
. gmdate("D, d M Y H:i:s ", $prop['val'])
. 'GMT</'.($this->crrnd?'':'D:')."lastaccessed>\n";
break;
case "ishidden":
echo ' <'.($this->crrnd?'':'D:')."ishidden>"
. is_string($prop['val']) ? $prop['val'] : ($prop['val'] ? 'true' : 'false')
. '</'.($this->crrnd?'':'D:')."</D:ishidden>\n";
break;
default:
$ns_defs = '';
if (is_array($prop['val']))
@ -1030,7 +1061,7 @@ class HTTP_WebDAV_Server
echo "<D:multistatus xmlns:D=\"DAV:\">\n";
echo ' <'.($this->crrnd?'':'D:')."response>\n";
echo ' <'.($this->crrnd?'':'D:')."href>".$this->_urlencode($this->_mergePathes($this->_SERVER["SCRIPT_NAME"], $this->path)).'</'.($this->crrnd?'':'D:')."href>\n";
echo ' <'.($this->crrnd?'':'D:')."href>".$this->_urlencode($this->_mergePaths($this->_SERVER["SCRIPT_NAME"], $this->path)).'</'.($this->crrnd?'':'D:')."href>\n";
foreach ($options["props"] as $prop) {
echo ' <'.($this->crrnd?'':'D:')."propstat>\n";
@ -1206,7 +1237,7 @@ class HTTP_WebDAV_Server
if (false === $status) {
$this->http_status("404 not found");
} else {
// TODO: check setting of headers in various code pathes above
// TODO: check setting of headers in various code paths above
$this->http_status("$status");
}
}
@ -1557,11 +1588,16 @@ class HTTP_WebDAV_Server
return;
}
$range = array("start"=>$matches[1], "end"=>$matches[2]);
$range = array("start" => $matches[1], "end" => $matches[2]);
if (is_numeric($matches[3])) {
$range["total_length"] = $matches[3];
}
$option["ranges"][] = $range;
if (!isset($options['ranges'])) {
$options['ranges'] = array();
}
$options["ranges"][] = $range;
// TODO make sure the implementation supports partial PUT
// this has to be done in advance to avoid data being overwritten
@ -1599,17 +1635,36 @@ class HTTP_WebDAV_Server
if (!empty($options["ranges"])) {
// TODO multipart support is missing (see also above)
if (0 == fseek($stream, $range[0]["start"], SEEK_SET)) {
$length = $range[0]["end"]-$range[0]["start"]+1;
if (!fwrite($stream, fread($options["stream"], $length))) {
$stat = "403 Forbidden";
if (0 == fseek($stream, $options['ranges'][0]["start"], SEEK_SET)) {
$length = $options['ranges'][0]["end"] - $options['ranges'][0]["start"]+1;
while (!feof($options['stream'])) {
if ($length <= 0) {
break;
}
if ($length <= 8192) {
$data = fread($options['stream'], $length);
} else {
$data = fread($options['stream'], 8192);
}
if ($data === false) {
$stat = "400 Bad request";
} elseif (strlen($data)) {
if (false === fwrite($stream, $data)) {
$stat = "403 Forbidden";
break;
}
$length -= strlen($data);
}
}
} else {
$stat = "403 Forbidden";
}
} else {
while (!feof($options["stream"])) {
if (false === fwrite($stream, fread($options["stream"], 4096))) {
if (false === fwrite($stream, fread($options["stream"], 8192))) {
$stat = "403 Forbidden";
break;
}
@ -1617,7 +1672,7 @@ class HTTP_WebDAV_Server
}
fclose($stream);
}
}
$this->http_status($stat);
} else {
@ -1775,26 +1830,32 @@ class HTTP_WebDAV_Server
if (is_bool($stat)) {
$http_stat = $stat ? "200 OK" : "423 Locked";
} else {
$http_stat = $stat;
$http_stat = (string)$stat;
}
$this->http_status($http_stat);
if ($http_stat{0} == 2) { // 2xx states are ok
if ($options["timeout"]) {
if (is_numeric($options["timeout"]))
{
// more than a million is considered an absolute timestamp
// less is more likely a relative value
if ($options["timeout"]>1000000) {
$timeout = "Second-".($options['timeout']-time());
} else {
$timeout = "Second-$options[timeout]";
}
}
else
{
$timeout = $options[timeout];
}
// if multiple timeout values were given we take the first only
if (is_array($options["timeout"])) {
reset($options["timeout"]);
$options["timeout"] = current($options["timeout"]);
}
// if the timeout is numeric only we need to reformat it
if (is_numeric($options["timeout"])) {
// more than a million is considered an absolute timestamp
// less is more likely a relative value
if ($options["timeout"]>1000000) {
$timeout = "Second-".($options['timeout']-time());
} else {
$timeout = "Second-$options[timeout]";
}
} else {
// non-numeric values are passed on verbatim,
// no error checking is performed here in this case
// TODO: send "Infinite" on invalid timeout strings?
$timeout = $options["timeout"];
}
} else {
$timeout = "Infinite";
}
@ -1908,14 +1969,21 @@ class HTTP_WebDAV_Server
$options["depth"] = "infinity";
}
extract(parse_url($this->_SERVER["HTTP_DESTINATION"]));
$path = urldecode($path);
$http_host = $host;
if (isset($port) && $port != 80)
$http_host.= ":$port";
$http_header_host = preg_replace("/:80$/", "", $this->_SERVER["HTTP_HOST"]);
$url = parse_url($this->_SERVER["HTTP_DESTINATION"]);
$path = urldecode($url["path"]);
if (isset($url["host"])) {
// TODO check url scheme, too
$http_host = $url["host"];
if (isset($url["port"]) && $url["port"] != 80)
$http_host.= ":".$url["port"];
} else {
// only path given, set host to self
$http_host == $http_header_host;
}
if ($http_host == $http_header_host &&
!strncmp($this->_SERVER["SCRIPT_NAME"], $path,
strlen($this->_SERVER["SCRIPT_NAME"]))) {
@ -2412,7 +2480,7 @@ class HTTP_WebDAV_Server
/**
* private minimalistic version of PHP urlencode()
*
* only blanks and XML special chars must be encoded here
* only blanks, percent and XML special chars must be encoded here
* full urlencode() encoding confuses some clients ...
*
* @param string URL to encode
@ -2431,6 +2499,7 @@ class HTTP_WebDAV_Server
}
//error_log( __METHOD__."\n" .print_r($url,true));
return strtr($url, array(' ' => '%20',
'%' => '%25',
'&' => '%26',
'<' => '%3C',
'>' => '%3E',
@ -2448,7 +2517,7 @@ class HTTP_WebDAV_Server
*/
function _urldecode($path)
{
return urldecode($path);
return rawurldecode($path);
}
/**
@ -2592,17 +2661,17 @@ class HTTP_WebDAV_Server
}
/**
* Merge two pathes, make sure there is exactly one slash between them
* Merge two paths, make sure there is exactly one slash between them
*
* @param string parent path
* @param string child path
* @return string merged path
*/
function _mergePathes($parent, $child)
function _mergePaths($parent, $child)
{
//error_log("merge called :\n$parent \n$child\n" . function_backtrace());
//error_log("merge :\n".print_r($this->_mergePathes($this->_SERVER["SCRIPT_NAME"], $this->path)true));
if ($child{0} == '/') {
//error_log("merge called :\n$parent \n$child\n" . function_backtrace());
//error_log("merge :\n".print_r($this->_mergePaths($this->_SERVER["SCRIPT_NAME"], $this->path)true));
if ($child{0} == '/') {
return $this->_unslashify($parent).$child;
} else {
return $this->_slashify($parent).$child;

View File

@ -1,4 +1,37 @@
<?php
<?php // $Id: Filesystem.php 312282 2011-06-19 13:39:05Z clockwerx $
/*
+----------------------------------------------------------------------+
| Copyright (c) 2002-2007 Christian Stocker, Hartmut Holzgraefe |
| All rights reserved |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions |
| are met: |
| |
| 1. Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| 2. Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in |
| the documentation and/or other materials provided with the |
| distribution. |
| 3. The names of the authors may not be used to endorse or promote |
| products derived from this software without specific prior |
| written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| POSSIBILITY OF SUCH DAMAGE. |
+----------------------------------------------------------------------+
*/
require_once "HTTP/WebDAV/Server.php";
require_once "System.php";
@ -73,11 +106,9 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
// special treatment for litmus compliance test
// reply on its identifier header
// not needed for the test itself but eases debugging
foreach (apache_request_headers() as $key => $value) {
if (stristr($key, "litmus")) {
error_log("Litmus test $value");
header("X-Litmus-reply: ".$value);
}
if (isset($this->_SERVER['HTTP_X_LITMUS'])) {
error_log("Litmus test ".$this->_SERVER['HTTP_X_LITMUS']);
header("X-Litmus-reply: ".$this->_SERVER['HTTP_X_LITMUS']);
}
// set root directory, defaults to webserver document root if not set
@ -135,13 +166,13 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
$files["files"][] = $this->fileinfo($options["path"]);
// information for contained resources requested?
if (!empty($options["depth"])) { // TODO check for is_dir() first?
if (!empty($options["depth"]) && is_dir($fspath) && $this->_is_readable($fspath)) {
// make sure path ends with '/'
$options["path"] = $this->_slashify($options["path"]);
// try to open directory
$handle = @opendir($fspath);
$handle = opendir($fspath);
if ($handle) {
// ok, now get all its contents
@ -183,15 +214,19 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
$info["props"][] = $this->mkprop("creationdate", filectime($fspath));
$info["props"][] = $this->mkprop("getlastmodified", filemtime($fspath));
// Microsoft extensions: last access time and 'hidden' status
$info["props"][] = $this->mkprop("lastaccessed", fileatime($fspath));
$info["props"][] = $this->mkprop("ishidden", ('.' === substr(basename($fspath), 0, 1)));
// type and size (caller already made sure that path exists)
if (is_dir($fspath)) {
// directory (WebDAV collection)
$info["props"][] = $this->mkprop("resourcetype", array($this->mkprop('collection', '')));
$info["props"][] = $this->mkprop("resourcetype", "collection");
$info["props"][] = $this->mkprop("getcontenttype", "httpd/unix-directory");
} else {
// plain file (WebDAV resource)
$info["props"][] = $this->mkprop("resourcetype", "");
if (is_readable($fspath)) {
if ($this->_is_readable($fspath)) {
$info["props"][] = $this->mkprop("getcontenttype", $this->_mimetype($fspath));
} else {
$info["props"][] = $this->mkprop("getcontenttype", "application/x-non-readable");
@ -255,6 +290,31 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
return false;
}
/**
* Check if path is readable by current user
*
* Allow extending classes to overwrite it
*
* @param string $fspath
* @return boolean
*/
function _is_readable($fspath)
{
return is_readable($fspath);
}
/**
* Check if path is writable by current user
*
* Allow extending classes to overwrite it
*
* @param string $fspath
* @return boolean
*/
function _is_writable($fspath)
{
return is_writable($fspath);
}
/**
* try to detect the mime type of a file
@ -264,7 +324,7 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
*/
function _mimetype($fspath)
{
if (@is_dir($fspath)) {
if (is_dir($fspath)) {
// directories are easy
return "httpd/unix-directory";
} else if (function_exists("mime_content_type")) {
@ -325,12 +385,12 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
}
/**
* GET method handler
* HEAD method handler
*
* @param array parameter passing array
* @return bool true on success
*/
function GET(&$options)
function HEAD(&$options)
{
// get absolute fs path to requested resource
$fspath = $this->base . $options["path"];
@ -338,11 +398,6 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
// sanity check
if (!file_exists($fspath)) return false;
// is this a collection?
if (is_dir($fspath)) {
return $this->GetDir($fspath, $options);
}
// detect resource type
$options['mimetype'] = $this->_mimetype($fspath);
@ -355,11 +410,33 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
// detect resource size
$options['size'] = filesize($fspath);
// no need to check result here, it is handled by the base class
if (!($options['stream'] = fopen($fspath, "r")))
{
return '403 Forbidden';
return true;
}
/**
* GET method handler
*
* @param array parameter passing array
* @return bool true on success
*/
function GET(&$options)
{
// get absolute fs path to requested resource
$fspath = $this->base . $options["path"];
// is this a collection?
if (is_dir($fspath)) {
return $this->GetDir($fspath, $options);
}
// the header output is the same as for HEAD
if (!$this->HEAD($options)) {
return false;
}
// no need to check result here, it is handled by the base class
$options['stream'] = fopen($fspath, "r");
return true;
}
@ -383,12 +460,16 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
// fixed width directory column format
$format = "%15s %-19s %-s\n";
$handle = @opendir($fspath);
if (!$this->_is_readable($fspath)) {
return false;
}
$handle = opendir($fspath);
if (!$handle) {
return false;
}
echo "<html><head><title>Index of ".htmlspecialchars($options['path'])."</title></head>\n";
echo "<html><head><title>Index of ".htmlspecialchars(urldecode($options['path']))."</title></head>\n";
echo "<h1>Index of ".htmlspecialchars($options['path'])."</h1>\n";
@ -403,7 +484,7 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
printf($format,
number_format(filesize($fullpath)),
strftime("%Y-%m-%d %H:%M:%S", filemtime($fullpath)),
'<a href="'.$name.'">'.$name.'</a>');
'<a href="'.$name.'">'.urldecode($name).'</a>');
}
}
@ -426,12 +507,23 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
{
$fspath = $this->base . $options["path"];
if (!@is_dir(dirname($fspath))) {
return "409 Conflict";
$dir = dirname($fspath);
if (!file_exists($dir) || !is_dir($dir)) {
return "409 Conflict"; // TODO right status code for both?
}
$options["new"] = ! file_exists($fspath);
if ($options["new"] && !$this->_is_writable($dir)) {
return "403 Forbidden";
}
if (!$options["new"] && !$this->_is_writable($fspath)) {
return "403 Forbidden";
}
if (!$options["new"] && is_dir($fspath)) {
return "403 Forbidden";
}
$fp = fopen($fspath, "w");
return $fp;
@ -493,7 +585,7 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
$query = "DELETE FROM {$this->db_prefix}properties
WHERE path LIKE '".$this->_slashify($options["path"])."%'";
mysql_query($query);
System::rm("-rf $path");
System::rm(array("-rf", $path));
} else {
unlink($path);
}
@ -535,10 +627,34 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
return "502 bad gateway";
}
$source = $this->base .$options["path"];
if (!file_exists($source)) return "404 Not found";
$source = $this->base . $options["path"];
if (!file_exists($source)) {
return "404 Not found";
}
if (is_dir($source)) { // resource is a collection
switch ($options["depth"]) {
case "infinity": // valid
break;
case "0": // valid for COPY only
if ($del) { // MOVE?
return "400 Bad request";
}
break;
case "1": // invalid for both COPY and MOVE
default:
return "400 Bad request";
}
}
$dest = $this->base . $options["dest"];
$destdir = dirname($dest);
if (!file_exists($destdir) || !is_dir($destdir)) {
return "409 Conflict";
}
$new = !file_exists($dest);
$existing_col = false;
@ -568,11 +684,6 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
}
}
if (is_dir($source) && ($options["depth"] != "infinity")) {
// RFC 2518 Section 9.2, last paragraph
return "400 Bad request";
}
if ($del) {
if (!rename($source, $dest)) {
return "500 Internal server error";
@ -610,14 +721,19 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
$destfile = str_replace($source, $dest, $file);
if (is_dir($file)) {
if (!is_dir($destfile)) {
// TODO "mkdir -p" here? (only natively supported by PHP 5)
if (!@mkdir($destfile)) {
if (!file_exists($destfile)) {
if (!$this->_is_writable(dirname($destfile))) {
return "403 Forbidden";
}
if (!mkdir($destfile)) {
return "409 Conflict";
}
} else if (!is_dir($destfile)) {
return "409 Conflict";
}
} else {
if (!@copy($file, $destfile)) {
if (!copy($file, $destfile)) {
return "409 Conflict";
}
}
@ -683,6 +799,7 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
$fspath = $this->base . $options["path"];
// TODO recursive locks on directories not supported yet
// makes litmus test "32. lock_collection" fail
if (is_dir($fspath) && !empty($options["depth"])) {
return "409 Conflict";
}

View File

@ -1,24 +1,38 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Hartmut Holzgraefe <hholzgra@php.net> |
// | Christian Stocker <chregu@bitflux.ch> |
// +----------------------------------------------------------------------+
//
// $Id: _parse_lockinfo.php,v 1.4 2006/10/10 11:53:17 hholzgra Exp $
//
<?php // $Id: _parse_lockinfo.php 246152 2007-11-14 10:49:27Z hholzgra $
/*
+----------------------------------------------------------------------+
| Copyright (c) 2002-2007 Christian Stocker, Hartmut Holzgraefe |
| All rights reserved |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions |
| are met: |
| |
| 1. Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| 2. Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in |
| the documentation and/or other materials provided with the |
| distribution. |
| 3. The names of the authors may not be used to endorse or promote |
| products derived from this software without specific prior |
| written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| POSSIBILITY OF SUCH DAMAGE. |
+----------------------------------------------------------------------+
*/
/**
* helper class for parsing LOCK request bodies

View File

@ -1,24 +1,37 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Hartmut Holzgraefe <hholzgra@php.net> |
// | Christian Stocker <chregu@bitflux.ch> |
// +----------------------------------------------------------------------+
//
// $Id: _parse_propfind.php,v 1.4 2006/10/10 11:53:17 hholzgra Exp $
//
<?php // $Id: _parse_propfind.php 246152 2007-11-14 10:49:27Z hholzgra $
/*
+----------------------------------------------------------------------+
| Copyright (c) 2002-2007 Christian Stocker, Hartmut Holzgraefe |
| All rights reserved |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions |
| are met: |
| |
| 1. Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| 2. Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in |
| the documentation and/or other materials provided with the |
| distribution. |
| 3. The names of the authors may not be used to endorse or promote |
| products derived from this software without specific prior |
| written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| POSSIBILITY OF SUCH DAMAGE. |
+----------------------------------------------------------------------+
*/
/**
* helper class for parsing PROPFIND request bodies

View File

@ -1,24 +1,38 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Hartmut Holzgraefe <hholzgra@php.net> |
// | Christian Stocker <chregu@bitflux.ch> |
// +----------------------------------------------------------------------+
//
// $Id: _parse_proppatch.php,v 1.6 2006/10/10 11:53:17 hholzgra Exp $
//
<?php // $Id: _parse_proppatch.php 246152 2007-11-14 10:49:27Z hholzgra $
/*
+----------------------------------------------------------------------+
| Copyright (c) 2002-2007 Christian Stocker, Hartmut Holzgraefe |
| All rights reserved |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions |
| are met: |
| |
| 1. Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| 2. Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in |
| the documentation and/or other materials provided with the |
| distribution. |
| 3. The names of the authors may not be used to endorse or promote |
| products derived from this software without specific prior |
| written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| POSSIBILITY OF SUCH DAMAGE. |
+----------------------------------------------------------------------+
*/
/**
* helper class for parsing PROPPATCH request bodies

View File

@ -400,6 +400,19 @@ class egw_vfs extends vfs_stream_wrapper
return true;
}
/**
* Check if file is hidden: name starts with a '.' or is Thumbs.db
*
* @param string $path
* @return boolean
*/
public static function is_hidden($path)
{
$file = self::basename($path);
return $file[0] == '.' || $file == 'Thumbs.db';
}
/**
* find = recursive search over the filesystem
*
@ -499,7 +512,7 @@ class egw_vfs extends vfs_stream_wrapper
{
if ($file == '.' || $file == '..') continue; // ignore current and parent dir!
if (($file[0] == '.' || $file == 'Thumbs.db') && !$options['hidden']) continue; // ignore hidden files
if (self::is_hidden($file) && !$options['hidden']) continue; // ignore hidden files
$file = self::concat($path,$file);

View File

@ -62,16 +62,9 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem
// special treatment for litmus compliance test
// reply on its identifier header
// not needed for the test itself but eases debugging
if (function_exists('apache_request_headers'))
{
foreach (apache_request_headers() as $key => $value)
{
if (stristr($key, 'litmus'))
{
error_log("Litmus test $value");
header('X-Litmus-reply: '.$value);
}
}
if (isset($this->_SERVER['HTTP_X_LITMUS'])) {
error_log("Litmus test ".$this->_SERVER['HTTP_X_LITMUS']);
header("X-Litmus-reply: ".$this->_SERVER['HTTP_X_LITMUS']);
}
// let the base class do all the work
HTTP_WebDAV_Server::ServeRequest();
@ -260,6 +253,10 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem
$info['props'][] = HTTP_WebDAV_Server::mkprop ('creationdate', filectime($fspath));
$info['props'][] = HTTP_WebDAV_Server::mkprop ('getlastmodified', filemtime($fspath));
// Microsoft extensions: last access time and 'hidden' status
$info["props"][] = HTTP_WebDAV_Server::mkprop("lastaccessed", fileatime($fspath));
$info["props"][] = HTTP_WebDAV_Server::mkprop("ishidden", egw_vfs::is_hidden($fspath));
// type and size (caller already made sure that path exists)
if (is_dir($fspath)) {
// directory (WebDAV collection)
@ -354,6 +351,28 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem
return egw_vfs::mime_content_type($path);
}
/**
* Check if path is readable by current user
*
* @param string $fspath
* @return boolean
*/
function _is_readable($fspath)
{
return egw_vfs::is_readable($fspath);
}
/**
* Check if path is writable by current user
*
* @param string $fspath
* @return boolean
*/
function _is_writable($fspath)
{
return egw_vfs::is_writable($fspath);
}
/**
* PROPPATCH method handler
*
@ -472,7 +491,7 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem
{
return egw_vfs::checkLock($path);
}
/**
* GET method handler for directories
*