fixing various webdav problems, regarding pathbuilding

This commit is contained in:
Klaus Leithoff 2009-03-09 12:23:47 +00:00
parent 7d2491678d
commit d313eb2daf
5 changed files with 76 additions and 26 deletions

View File

@ -145,7 +145,8 @@ class HTTP_WebDAV_Server
// default uri is the complete request uri
$uri = (@$this->_SERVER["HTTPS"] === "on" ? "https:" : "http:");
// we cant use SCRIPT_NAME, because it fails, if there's any url rewriting
$uri.= '//'.$this->_SERVER['HTTP_HOST'].substr($this->_SERVER['REQUEST_URI'],0,-strlen($this->_SERVER["PATH_INFO"]));
//error_log("pathinfo:\n". $this->_urldecode($this->_SERVER['REQUEST_URI']).":\n".$this->_SERVER['PATH_INFO']);
$uri.= '//'.$this->_SERVER['HTTP_HOST'].substr($this->_urldecode($this->_SERVER['REQUEST_URI']),0,-strlen($this->_SERVER["PATH_INFO"]));
$path_info = empty($this->_SERVER["PATH_INFO"]) ? "/" : $this->_SERVER["PATH_INFO"];
@ -1975,7 +1976,8 @@ class HTTP_WebDAV_Server
}
// return generated response
return $activelocks;
//error_log(__METHOD__."\n".print_r($activelocks,true));
return $activelocks;
}
/**
@ -2010,7 +2012,8 @@ class HTTP_WebDAV_Server
*/
function _urlencode($url)
{
return strtr($url, array(" "=>"%20",
//error_log( __METHOD__."\n" .print_r($url,true));
return strtr($url, array(" "=>"%20",
"&"=>"%26",
"<"=>"%3C",
">"=>"%3E",
@ -2039,14 +2042,19 @@ class HTTP_WebDAV_Server
*/
function _prop_encode($text)
{
switch (strtolower($this->_prop_encoding)) {
case "utf-8":
return $text;
case "iso-8859-1":
case "iso-8859-15":
case "latin-1":
default:
return utf8_encode($text);
//error_log( __METHOD__."\n" .print_r($text,true));
//error_log("prop-encode:" . print_r($this->_prop_encoding,true));
switch (strtolower($this->_prop_encoding)) {
case "utf-8":
//error_log( __METHOD__."allready encoded\n" .print_r($text,true));
return $text;
case "iso-8859-1":
case "iso-8859-15":
case "latin-1":
default:
//error_log( __METHOD__."utf8 encode\n" .print_r(utf8_encode($text),true));
return utf8_encode($text);
}
}
@ -2058,10 +2066,12 @@ class HTTP_WebDAV_Server
*/
function _slashify($path)
{
if ($path[strlen($path)-1] != '/') {
$path = $path."/";
}
return $path;
//error_log(__METHOD__." called with $path");
if ($path[$this->bytes($path)-1] != '/') {
//error_log(__METHOD__." added slash at the end of path");
$path = $path."/";
}
return $path;
}
/**
@ -2072,8 +2082,10 @@ class HTTP_WebDAV_Server
*/
function _unslashify($path)
{
if ($path[strlen($path)-1] == '/') {
$path = substr($path, 0, strlen($path) -1);
//error_log(__METHOD__." called with $path");
if ($path[$this->bytes($path)-1] == '/') {
$path = substr($path, 0, -1);
//error_log(__METHOD__." removed slash at the end of path");
}
return $path;
}
@ -2087,7 +2099,9 @@ class HTTP_WebDAV_Server
*/
function _mergePathes($parent, $child)
{
if ($child{0} == '/') {
//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} == '/') {
return $this->_unslashify($parent).$child;
} else {
return $this->_slashify($parent).$child;

View File

@ -349,7 +349,7 @@ class egw_vfs extends vfs_stream_wrapper
}
if ($is_dir && (!isset($options['maxdepth']) || $options['maxdepth'] > 0) && ($dir = @opendir($path)))
{
while($file = readdir($dir))
while(($file = readdir($dir)) !== false)
{
if ($file == '.' || $file == '..') continue; // ignore current and parent dir!
@ -1125,7 +1125,7 @@ class egw_vfs extends vfs_stream_wrapper
{
if (isset(self::$lock_cache[$path]))
{
error_log(__METHOD__."($path) returns from CACHE ".str_replace(array("\n",' '),'',print_r(self::$lock_cache[$path],true)));
//error_log(__METHOD__."($path) returns from CACHE ".str_replace(array("\n",' '),'',print_r(self::$lock_cache[$path],true)));
return self::$lock_cache[$path];
}
$where = 'lock_path='.self::$db->quote($path);
@ -1146,7 +1146,7 @@ class egw_vfs extends vfs_stream_wrapper
'lock_token' => $result['token'],
),__LINE__,__FILE__);
//error_log(__METHOD__."($path) lock is expired at ".date('Y-m-d H:i:s',$result['expires'])." --> removed");
//error_log(__METHOD__."($path) lock is expired at ".date('Y-m-d H:i:s',$result['expires'])." --> removed");
$result = false;
}
//error_log(__METHOD__."($path) returns ".($result?array2string($result):'false'));

View File

@ -222,7 +222,9 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
// create the hash-dirs, if they not yet exist
elseif(!file_exists($fs_dir=dirname(self::_fs_path($this->opened_fs_id))))
{
mkdir($fs_dir,0700,true);
$umaskbefore = umask();
if (self::LOG_LEVEL) error_log(__METHOD__." about to call mkdir for $fs_dir # Present UMASK:".decoct($umaskbefore)." called from:".function_backtrace());
self::mkdir_recursive($fs_dir,0700,true);
}
}
else
@ -264,6 +266,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
// do we operate directly on the filesystem
if ($this->operation == self::STORE2FS)
{
if (self::LOG_LEVEL > 1) error_log(__METHOD__." fopen (may create a directory? mkdir) ($this->opened_fs_id,$mode,$options)");
$this->opened_stream = fopen(self::_fs_path($this->opened_fs_id),$mode);
}
if ($mode[0] == 'a') // append modes: a, a+
@ -575,6 +578,18 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
));
}
/**
* due to problems with recursive directory creation, we have our own here
*/
function mkdir_recursive($pathname, $mode, $depth=0)
{
$maxdepth=10;
$depth2propagate = (int)$depth + 1;
if ($depth2propagate > $maxdepth) return is_dir($pathname);
is_dir(dirname($pathname)) || self::mkdir_recursive(dirname($pathname), $mode, $depth2propagate);
return is_dir($pathname) || @mkdir($pathname, $mode);
}
/**
* This method is called in response to mkdir() calls on URL paths associated with the wrapper.
*
@ -589,7 +604,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
static function mkdir ( $url, $mode, $options )
{
if (self::LOG_LEVEL > 1) error_log(__METHOD__."($url,$mode,$options)");
if (self::LOG_LEVEL > 1) error_log(__METHOD__." called from:".function_backtrace());
$path = parse_url($url,PHP_URL_PATH);
if (self::url_stat($path,STREAM_URL_STAT_QUIET))
@ -611,6 +626,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
// if yes call ourself recursive with the parent directory
if (($options & STREAM_MKDIR_RECURSIVE) && $path != '/' && !$parent)
{
if (self::LOG_LEVEL > 1) error_log(__METHOD__." creating parents: $parent_path, $mode");
if (!self::mkdir($parent_path,$mode,$options))
{
return false;
@ -1291,6 +1307,7 @@ class sqlfs_stream_wrapper implements iface_stream_wrapper
{
return false; // parent not found, should never happen ...
}
if (self::LOG_LEVEL > 1) error_log(__METHOD__." trying foreach with:".print_r($rows,true)."#");
foreach($rows as $fs_id => $row)
{
$parent = $row['fs_dir'] > 1 ? $parents[$row['fs_dir']] : '';

View File

@ -587,6 +587,7 @@ class vfs_stream_wrapper implements iface_stream_wrapper
*/
function dir_opendir ( $path, $options )
{
//error_log(__METHOD__." called with ".$path);
$this->opened_dir = $this->extra_dirs = null;
$this->extra_dir_ptr = 0;
@ -596,16 +597,20 @@ class vfs_stream_wrapper implements iface_stream_wrapper
}
if (!($this->opened_dir = opendir($this->opened_dir_url)))
{
//error_log(__METHOD__." dir failed: ".$this->opened_dir);
return false;
}
$this->opened_dir_writable = egw_vfs::check_access($this->opened_dir_url,egw_vfs::WRITABLE);
#error_log(__METHOD__." check for ".$this->opened_dir_url);
// check our fstab if we need to add some of the mountpoints
$basepath = parse_url($this->opened_dir_url,PHP_URL_PATH);
#error_log(__METHOD__." basepath here: ".print_r($basepath,true));
foreach(self::$fstab as $mounted => $nul)
{
if (dirname($mounted) == $basepath && $mounted != '/')
#error_log(__METHOD__." dirname mounted: ".print_r(dirname($mounted),true));
if ((dirname($mounted) == $basepath || dirname($mounted)."/" == $basepath) && $mounted != '/')
{
#error_log(__METHOD__." mounted dir: ".print_r($mounted,true));
$this->extra_dirs[] = basename($mounted);
}
}
@ -685,13 +690,16 @@ class vfs_stream_wrapper implements iface_stream_wrapper
*/
function dir_readdir ( )
{
#error_log(__METHOD__." called.");
if ($this->extra_dirs && count($this->extra_dirs) > $this->extra_dir_ptr)
{
return $this->extra_dirs[$this->extra_dir_ptr++];
}
// only return children readable by the user, if dir is not writable
do {
//error_log(__METHOD__." called with:".$this->opened_dir_url);
$file = readdir($this->opened_dir);
//error_log(__METHOD__." got:".$file);
}
while($file !== false && (is_array($this->extra_dirs) && in_array($file,$this->extra_dirs) || // dont return mountpoints twice
self::HIDE_UNREADABLES && !$this->opened_dir_writable &&
@ -791,4 +799,4 @@ class vfs_stream_wrapper implements iface_stream_wrapper
}
}
vfs_stream_wrapper::init_static();
vfs_stream_wrapper::init_static();

View File

@ -44,6 +44,16 @@ function check_access(&$account)
// if we are called with a /apps/$app path, use that $app as currentapp, to not require filemanager rights for the links
$parts = explode('/',$_SERVER['PATH_INFO']);
//error_log("webdav: explode".print_r($parts,true));
if(count($parts)== 1){
error_log(__METHOD__. "Malformed Url: missing slash:\n".$_SERVER['SERVER_NAME']."\n PATH_INFO:".$_SERVER['PATH_INFO'].
"\n REQUEST_URI".$_SERVER['REQUEST_URI']."\n ORIG_SCRIPT_NAME:".$_SERVER['ORIG_SCRIPT_NAME'].
"\n REMOTE_ADDR:".$_SERVER['REMOTE_ADDR']."\n PATH_INFO:".$_SERVER['PATH_INFO']."\n HTTP_USER_AGENT:".$_SERVER['HTTP_USER_AGENT']) ;
header("HTTP/1.1 501 Not implemented");
header("X-WebDAV-Status: 501 Not implemented", true);
exit;
}
$app = count($parts) > 3 && $parts[1] == 'apps' ? $parts[2] : 'filemanager';
$GLOBALS['egw_info'] = array(
@ -63,3 +73,4 @@ $headertime = microtime(true);
$webdav_server = new vfs_webdav_server();
$webdav_server->ServeRequest();
//error_log(sprintf("GroupDAV %s request took %5.3f s (header include took %5.3f s)",$_SERVER['REQUEST_METHOD'],microtime(true)-$starttime,$headertime-$starttime));