openrat-webdav

git clone http://git.code.weiherhei.de/openrat-webdav.git
Log | Files | Refs

commit df5f5873763243ca942e0e323c39f98133403335
parent bbbc3db4ebbd51419320f8d59f3fbf9a6720340e
Author: Jan Dankert <develop@jandankert.de>
Date:   Thu, 31 Oct 2019 02:13:16 +0100

Fix: Directories are now browseable.

Diffstat:
CMS.class.php | 60+++++++++++++++++++++++++++++++++++++++++-------------------
Client.class.php | 23++++++++++++++---------
Logger.class.php | 2+-
NotFoundException.php | 14++++++++++++++
URIParser.class.php | 10++++++----
WebDAV.class.php | 204+++++++++++++++++++++++++++++++++++++++++--------------------------------------
dav.ini | 3+++
dav.php | 33+++++++++++++++++++++------------
test.xml | 243+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 450 insertions(+), 142 deletions(-)

diff --git a/CMS.class.php b/CMS.class.php @@ -17,8 +17,8 @@ class CMS extends Client $result = $this->call(CMS_WRITE,'login','login',array('login_name'=>$user,'login_password'=>$password,'dbid'=>$dbid) ); - if ( $result['success'] != 'true' ) { - throw new Exception( 'Login failed. '.print_r($result['notices'],true)); + if ( ! $this->success ) { + throw new Exception( 'Login failed.',true ); } } @@ -27,8 +27,7 @@ class CMS extends Client { $result = $this->call(CMS_READ,'projectlist','edit' ); -// Logger::debug( print_r($result,true) ); - return( $result['output'] ); + return $result; } @@ -36,44 +35,68 @@ class CMS extends Client { $result = $this->call(CMS_READ,'project','prop',array('id'=>$projectid) ); - return( $result['output'] ); + return $result; } function folder($id) { - $result = $this->call(CMS_READ,'folder','edit',array('id'=>$id) ); - - return( $result['output'] ); + $content = $this->call(CMS_READ,'folder','edit',array('id'=>$id) ); + $prop = $this->call(CMS_READ,'folder','info',array('id'=>$id) ); + + return( array( 'content'=>$content, 'properties'=>$prop ) ); } function page($id) { $result = $this->call(CMS_READ,'page','edit',array('id'=>$id) ); - return( $result['output'] ); + return $result; } function link($id) { $result = $this->call(CMS_READ,'link','edit',array('id'=>$id) ); - return( $result['output'] ); + return $result; } function file($id) { $result = $this->call(CMS_READ,'file','edit',array('id'=>$id) ); - return( $result['output'] ); + return $result; } - function filevalue($id) + function filevalue($id) { - $result = $this->call(CMS_READ,'file','show',array('id'=>$id) ); - - return( $result['output'] ); + $result = parent::call(CMS_READ,'file','show',array('id'=>$id),true ); + + return $result; } - -} -?>- \ No newline at end of file + + public function fileWrite($id,$value) + { + $result = parent::call(CMS_WRITE,'file','save',array('id'=>$id,'value'=>$value) ); + + return $result; + } + + public function fileAdd($value) + { + $result = parent::call(CMS_WRITE,'file','save',array('value'=>$value) ); + + return $result; + } + + + protected function call( $method,$action,$subaction,$parameter=array(),$direct=false ) + { + $result = parent::call( $method,$action,$subaction,$parameter,false ); + + Logger::trace( "API-Result of $method $action/$subaction:\n".print_r($result,true)); + + return $result; + } + +} diff --git a/Client.class.php b/Client.class.php @@ -15,9 +15,11 @@ class Client protected $method; // GET oder POST protected $responseHeader; + + protected $success; - protected function call($method,$action,$subaction,$parameter=array()) + protected function call($method,$action,$subaction,$parameter=array(),$direct=false) { global $config; $error = ''; @@ -155,11 +157,13 @@ class Client } } } - + + if ( $direct ) + return $body; + $result = unserialize($body); if ( $result === false ) { - error_log('Not unserializable: '.$body); throw new RuntimeException('The server response cannot be unserialized into a PHP array'); } else @@ -167,11 +171,13 @@ class Client $this->sessionName = $result['session']['name']; $this->sessionId = $result['session']['id']; $this->token = $result['session']['token']; -// var_dump($result); - return $result; - } - + + $this->success = @$result['success'] == 'true'; + $this->notices = $result['notices']; + + return $result['output']; + } + } } } -?>- \ No newline at end of file diff --git a/Logger.class.php b/Logger.class.php @@ -129,7 +129,7 @@ class Logger $text = str_replace( '%action',str_pad($action,12),$text ); $text = str_replace( '%text' ,$message,$text ); $text = str_replace( '%time' ,date('M j H:i:s'),$text ); - $text = str_replace( "\n" ,"\n ",$text ); + $text = str_replace( "\n" ,"\n ",$text ); // indent with 1 space. // Schreiben in Logdatei error_log( $text."\n",3,$filename ); diff --git a/NotFoundException.php b/NotFoundException.php @@ -0,0 +1,13 @@ +<?php + +namespace dav\exception; + +use Exception; + +class NotFoundException extends Exception +{ + public function __construct($message = "") + { + parent::__construct($message); + } +}+ \ No newline at end of file diff --git a/URIParser.class.php b/URIParser.class.php @@ -1,6 +1,8 @@ <?php +use dav\exception\NotFoundException; + class URIParser { const ROOT = 'root'; @@ -74,12 +76,12 @@ class URIParser $folder = $this->client->folder($objectid); $found = false; - foreach ($folder['object'] as $oid => $object) { + foreach ($folder['content']['object'] as $oid => $object) { if ($object['filename'] == $name) { $found = true; - $type = $object['type' ]; - $objectid = $object['objectid']; + $type = $object['type']; + $objectid = $object['id' ]; break; } @@ -87,7 +89,7 @@ class URIParser } if (!$found) { - throw new RuntimeException('Not found path segment: '.$name ); + throw new NotFoundException('Not found path segment: '.$name ); } } diff --git a/WebDAV.class.php b/WebDAV.class.php @@ -9,13 +9,14 @@ class WebDAV public $database; public $depth; public $projectid; - public $object; + public $request; public $filename; public $uri; public $headers; - public $request; + public $data; + public $destination = null; - public $fullSkriptName; + public $sitePath; public $create; public $readonly; public $maxFileSize; @@ -146,22 +147,17 @@ class WebDAV } - $scriptName = $_SERVER['SCRIPT_NAME']; - - $this->fullSkriptName = 'http://'.$_SERVER['HTTP_HOST'].$scriptName.'/'; - - // URL parsen. - $uri = substr($_SERVER['REQUEST_URI'],strlen($scriptName)); + $this->sitePath = $this->siteURL().$_SERVER['PHP_SELF']; - $this->object = new URIParser($this->client, $uri ); + // Path-Info. If not set, use '/' + $pathInfo = @$_SERVER['PATH_INFO'] ? $_SERVER['PATH_INFO'] : '/'; - Logger::debug( $this->object->__toString() ); + $this->request = new URIParser($this->client, $pathInfo); - if ( $this->object->type == 'folder' ) - $this->fullSkriptName .= '/'; + Logger::trace( $this->request->__toString() ); /* - * Verzeichnisse muessen mit einem '/' enden. Falls nicht, Redirect aussfuehren. + * Directories MUST end with a '/'. If not, redirect. * * RFC 2518, 5.2 Collection Resources, Page 11: * "For example, if a client invokes a @@ -171,16 +167,25 @@ class WebDAV * http://foo.bar/blah/ in it. In general clients SHOULD use the "/" * form of collection names." */ - if ( $this->request == 'folder' && - $_GET['subaction'] == 'get' && - substr($_SERVER['REQUEST_URI'],strlen($_SERVER['REQUEST_URI'])-1 ) != '/' ) - { - Logger::debug( 'Redirecting lame client to slashyfied URL' ); - - header('HTTP/1.1 302 Moved Temporarily'); - header('Location: '.$_SERVER['REQUEST_URI'].'/'); - exit; - } + if ( in_array($this->request->type,array('folder','root')) && + substr($this->sitePath,-1 ) != '/' ) + if ( $config['dav.redirect_collections_to_trailing_slash'] ) + { + // redirect the collection to append the trailing slash. + // this is recommended by the spec (see above). + Logger::debug( 'Redirecting lame client to slashyfied folder URL' ); + + header('HTTP/1.1 302 Moved Temporarily'); + header('Location: '.$this->sitePath.'/'); + exit; + } + else + { + // no redirect - so we append the trailing slash. + // this is allowed by the spec (see above). + $this->sitePath .= '/'; + } + // Falls vorhanden, den "Destination"-Header parsen. if ( isset($_SERVER['HTTP_DESTINATION']) ) @@ -194,7 +199,7 @@ class WebDAV } // Den Request-BODY aus der Standardeingabe lesen. - $this->request = implode('',file('php://input')); + $this->data = implode('',file('php://input')); } /** @@ -221,11 +226,11 @@ class WebDAV */ public function davHEAD() { - if ( ! $this->object->objectid ) + if ( ! $this->request->objectid ) { $this->httpStatus( '404 Not Found' ); } - elseif ( $this->object->type == 'folder' ) + elseif ( $this->request->type == 'folder' ) { $this->httpStatus( '200 OK' ); } @@ -251,7 +256,7 @@ class WebDAV */ public function davGET() { - switch( $this->object->type ) + switch( $this->request->type ) { case 'root': case 'folder': @@ -264,7 +269,7 @@ class WebDAV echo '<html><head><title>OpenRat WEBDAV Access</title></head>'; echo '<body>'; - echo '<h1>'.$this->object->type.'</h1>'; + echo '<h1>'.$this->request->type.'</h1>'; echo '<pre>'; echo 'No Content available'; echo '</pre>'; @@ -277,7 +282,7 @@ class WebDAV header('Content-Type: text/plain'); - $link = $this->client->link( $this->object->objectid ); + $link = $this->client->link( $this->request->objectid ); echo 'url: ' .$link['url'] ."\n"; echo 'target-id: '.$link['linkedObjectId']."\n"; @@ -288,11 +293,11 @@ class WebDAV case 'text': $this->httpStatus( '200 OK' ); - $file = $this->client->file ( $this->object->objectid ); - $filevalue = $this->client->filevalue( $this->object->objectid ); + $file = $this->client->file ( $this->request->objectid ); + $filevalue = $this->client->filevalue( $this->request->objectid ); header('Content-Type: '.$file['mimetype']); - header('X-File-Id: ' .$this->object->objectid ); + header('X-File-Id: ' .$this->request->objectid ); // Angabe Content-Disposition // - Bild soll "inline" gezeigt werden @@ -305,20 +310,19 @@ class WebDAV // Der Browser hat so die Moeglichkeit, einen Fortschrittsbalken zu zeigen header('Content-Length: '.$file['size'] ); - echo base64_decode( $filevalue['value'] ); + echo $filevalue; break; default: - case 'page': $this->httpStatus( '200 OK' ); header('Content-Type: text/html'); echo '<html><head><title>OpenRat WEBDAV Access</title></head>'; echo '<body>'; - echo '<h1>'.$this->object->type.'</h1>'; + echo '<h1>'.$this->request->type.'</h1>'; echo '<pre>'; - echo 'Unknown node type: '.$this->object->type; + echo 'Unknown node type: '.$this->request->type; echo '</pre>'; echo '</body>'; echo '</html>'; @@ -344,7 +348,7 @@ class WebDAV - $titel = 'Index of '.htmlspecialchars($this->fullSkriptName); + $titel = 'Index of '.htmlspecialchars($this->sitePath); $format = "%15s %-19s %-s\n"; echo '<html><head><title>'.$titel.'</title></head>'; @@ -355,7 +359,7 @@ class WebDAV printf($format, "Size", "Last modified", "Filename"); - switch( $this->object->type ) + switch( $this->request->type ) { case 'root': // Projektliste @@ -369,7 +373,7 @@ class WebDAV case 'folder': // Verzeichnisinhalt - $folder = $this->client->folder( $this->object->objectid ); + $folder = $this->client->folder( $this->request->objectid ); foreach( $folder['object'] as $object ) { @@ -437,7 +441,7 @@ class WebDAV public function davMKCOL() { - if ( !empty($this->request) ) + if ( !empty($this->data) ) { $this->httpStatus('415 Unsupported Media Type' ); // Kein Body erlaubt } @@ -453,7 +457,7 @@ class WebDAV { // Die URI ist noch nicht vorhanden $f = new Folder(); - $f->filename = basename($this->fullSkriptName); + $f->filename = basename($this->sitePath); $f->parentid = $this->folder->objectid; $f->projectid = $this->project->projectid; $f->add(); @@ -711,59 +715,38 @@ class WebDAV */ public function davPUT() { - // TODO: 409 (Conflict) wenn �bergeordneter Ordner nicht da. + // TODO: 409 (Conflict) wenn übergeordneter Ordner nicht da. - if ( $config['readonly'] ) + if ( $this->readonly ) { $this->httpStatus('405 Not Allowed' ); } - elseif ( strlen($this->request) > $this->maxFileSize*1000 ) + elseif ( strlen($this->data) > $this->maxFileSize*1000 ) { // Maximale Dateigroesse ueberschritten. // Der Status 207 "Zuwenig Speicherplatz" passt nicht ganz, aber fast :) $this->httpStatus('507 Insufficient Storage' ); } - elseif ( $this->obj == null ) + elseif ( ! $this->request->objectid ) { // Neue Datei anlegen - if ( !$config['create'] ) + if ( !$this->create ) { Logger::warn('WEBDAV: Creation of files not allowed by configuration' ); $this->httpStatus('405 Not Allowed' ); } - if ( ! $this->folder->hasRight( ACL_CREATE_FILE ) ) - { - $this->httpStatus('403 Forbidden'); - return; - } - - $file = new File(); - $file->filename = basename($this->fullSkriptName); - $file->extension = ''; - $file->size = strlen($this->request); - $file->parentid = $this->folder->objectid; - $file->projectid = $this->project->projectid; - $file->value = $this->request; - $file->add(); + $this->client->fileAdd( $this->data ); $this->httpStatus('201 Created'); return; } - elseif ( $this->obj->isFile ) + elseif ( $this->request->objectid ) { - if ( ! $this->obj->hasRight( ACL_WRITE ) ) - { - Logger::debug('PUT failed, parent folder not writable by user' ); - $this->httpStatus('403 Forbidden'); - return; - } - // Bestehende Datei ueberschreiben. - $file = new File( $this->obj->objectid ); - $file->saveValue( $this->request ); - $file->setTimestamp(); + $id = $this->request->objectid; + $this->client->fileAdd( $id,$this->data ); + $this->httpStatus('204 No Content'); - Logger::debug('PUT ok, file is created' ); return; } elseif ( $this->obj->isFolder ) @@ -793,7 +776,7 @@ class WebDAV */ public function davPROPFIND() { - switch( $this->object->type ) + switch( $this->request->type ) { case 'root': // Projektliste @@ -804,7 +787,7 @@ class WebDAV $objektinhalt['createdate' ] = $z; $objektinhalt['lastchangedate'] = $z; $objektinhalt['size' ] = 1; - $objektinhalt['name' ] = $this->fullSkriptName; + $objektinhalt['name' ] = $this->sitePath; $objektinhalt['displayname' ] = ''; $objektinhalt['type'] = 'folder'; @@ -818,7 +801,7 @@ class WebDAV $objektinhalt['createdate' ] = TIME_20000101; $objektinhalt['lastchangedate'] = TIME_20000101; $objektinhalt['size' ] = 1; - $objektinhalt['name' ] = $this->fullSkriptName.$p['name'].'/'; + $objektinhalt['name' ] = $this->sitePath.$p['name'].'/'; $objektinhalt['displayname' ] = $p['name']; $objektinhalt['type'] = 'folder'; $inhalte[] = $objektinhalt; @@ -829,14 +812,14 @@ class WebDAV case 'folder': // Verzeichnisinhalt - $folder = $this->client->folder( $this->object->objectid ); - + $folder = $this->client->folder( $this->request->objectid ); + $inhalte = array(); $objektinhalt = array(); $objektinhalt['createdate' ] = $folder['properties']['create_date']; $objektinhalt['lastchangedate'] = $folder['properties']['lastchange_date']; - $objektinhalt['name' ] = $this->fullSkriptName; + $objektinhalt['name' ] = $this->sitePath; $objektinhalt['displayname' ] = $folder['properties']['filename']; $objektinhalt['type' ] = 'folder'; $objektinhalt['size' ] = 0; @@ -846,7 +829,7 @@ class WebDAV if ( $this->depth > 0 ) { - foreach( $folder['object'] as $object ) + foreach( $folder['content']['object'] as $object ) { $objektinhalt = array(); $objektinhalt['createdate' ] = $object['date']; @@ -856,27 +839,37 @@ class WebDAV switch( $object['type'] ) { case 'folder': - $objektinhalt['name'] = $this->fullSkriptName.$object['filename'].'/'; + $objektinhalt['name'] = $this->sitePath.$object['filename'].'/'; $objektinhalt['type'] = 'folder'; $objektinhalt['size'] = 0; $inhalte[] = $objektinhalt; break; case 'file': - $objektinhalt['name'] = $this->fullSkriptName.$object['filename']; + case 'image': + case 'text': + $objektinhalt['name'] = $this->sitePath.$object['filename']; $objektinhalt['type'] = 'file'; $objektinhalt['size'] = $object['size']; $objektinhalt['mime'] = 'application/x-non-readable'; $inhalte[] = $objektinhalt; break; case 'link': - $objektinhalt['name'] = $this->fullSkriptName.$object['filename']; + $objektinhalt['name'] = $this->sitePath.$object['filename']; + $objektinhalt['type'] = 'file'; + $objektinhalt['size'] = 0; + $objektinhalt['mime'] = 'application/x-non-readable'; + $inhalte[] = $objektinhalt; + break; + case 'url': + case 'alias': + $objektinhalt['name'] = $this->sitePath.$object['filename']; $objektinhalt['type'] = 'file'; $objektinhalt['size'] = 0; $objektinhalt['mime'] = 'application/x-non-readable'; $inhalte[] = $objektinhalt; break; case 'page': - $objektinhalt['name'] = $this->fullSkriptName.$object['filename']; + $objektinhalt['name'] = $this->sitePath.$object['filename']; $objektinhalt['type'] = 'file'; $objektinhalt['size'] = 0; $inhalte[] = $objektinhalt; @@ -889,39 +882,44 @@ class WebDAV break; case 'page': - $page = $this->client->page( $this->object->objectid ); + $page = $this->client->page( $this->request->objectid ); $prop = $page['properties']; $objektinhalt = array(); - $objektinhalt['name'] = $this->fullSkriptName.'/'.$prop['filename'].'/'; + $objektinhalt['name'] = $this->sitePath; $objektinhalt['displayname'] = $prop['filename']; $objektinhalt['createdate' ] = $prop['date']; $objektinhalt['lastchangedate'] = $prop['date']; $objektinhalt['size' ] = 0; $objektinhalt['type' ] = 'file'; - break; + + $this->multiStatus( array($objektinhalt) ); + + break; case 'file': case 'text': case 'image': - $file = $this->client->file( $this->object->objectid ); + $file = $this->client->file( $this->request->objectid ); $objektinhalt = array(); - $objektinhalt['name'] = $this->fullSkriptName.'/'.$file['filename'].'/'; + $objektinhalt['name'] = $this->sitePath; $objektinhalt['displayname'] = $file['filename']; $objektinhalt['createdate' ] = $file['date']; $objektinhalt['lastchangedate'] = $file['date']; $objektinhalt['size' ] = $file['size']; $objektinhalt['type' ] = 'file'; - - break; + + $this->multiStatus( array($objektinhalt) ); + + break; case 'link': - $link = $this->client->link( $this->object->objectid ); + $link = $this->client->link( $this->request->objectid ); $objektinhalt = array(); - $objektinhalt['name'] = $this->fullSkriptName.'/'.$link['filename'].'/'; + $objektinhalt['name'] = $this->sitePath; $objektinhalt['displayname'] = $link['filename']; $objektinhalt['createdate' ] = $link['date']; $objektinhalt['lastchangedate'] = $link['date']; @@ -936,10 +934,10 @@ class WebDAV case 'url': - $link = $this->client->link( $this->object->objectid ); + $link = $this->client->link( $this->request->objectid ); $objektinhalt = array(); - $objektinhalt['name'] = $this->fullSkriptName.'/'.$link['filename'].'/'; + $objektinhalt['name'] = $this->sitePath; $objektinhalt['displayname'] = $link['filename']; $objektinhalt['createdate' ] = $link['date']; $objektinhalt['lastchangedate'] = $link['date']; @@ -953,7 +951,7 @@ class WebDAV break; default: - Logger::warn('Internal Error, unknown request type: '. $this->object->type); + Logger::warn('Internal Error, unknown request type: '. $this->request->type); $this->httpStatus('500 Internal Server Error'); } } @@ -991,7 +989,7 @@ class WebDAV $response = utf8_encode($response); header('Content-Length: '.strlen($response)); - //Logger::debug('Multistatus: '.$response); + Logger::trace('Sending Multistatus:'."\n".$response); echo $response; } @@ -1084,4 +1082,16 @@ class WebDAV } + + private function siteURL() + { + $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; + $domainName = $_SERVER['HTTP_HOST']; + return $protocol.$domainName; + } + + private function slashify( $path ) + { + return $path.( substr( $path,-1 ) != '/' )?'/':''; + } } diff --git a/dav.ini b/dav.ini @@ -15,3 +15,5 @@ cms.password=davdav cms.database=pdo_my_prod cms.host=duese cms.path="/~dankert/cms/cms09/" + +dav.redirect_collections_to_trailing_slash = false+ \ No newline at end of file diff --git a/dav.php b/dav.php @@ -2,24 +2,24 @@ /** * WebDAV für OpenRat Content Management System<br> - * + * * Das virtuelle Ordnersystem dieses CMS kann ueber das WebDAV-Protokoll * dargestellt werden. - * + * * Diese Klasse nimmt die Anfragen von WebDAV-Clients entgegen, zerlegt die * Anfrage und erzeugt eine Antwort, die im HTTP-Body zurueck uebertragen * wird. * <br> * WebDAV ist spezifiziert in der RFC 2518.<br> * Siehe <code>http://www.ietf.org/rfc/rfc2518.txt</code><br> - * + * * Implementiert wird DAV-Level 1 (d.h. ohne LOCK). - * + * * Der Zugang über WebDAV beinhaltet einige Nachteile: * - Login ist nur mit Name/Kennwort möglich (kein OpenId) * - Nur die Standard-Datenbank kann verwendet werden * - Der Client muss Cookies unterstützen - * + * * @author Jan Dankert * @package openrat.actions */ @@ -37,6 +37,7 @@ $config = array('dav.enable' => false, 'dav.readonly' => false, 'dav.expose_openrat' => true, 'dav.compliant_to_redmond' => true, + 'dav.redirect_collections_to_trailing_slash' => true, 'dav.realm' =>'OpenRat CMS WebDAV Login', 'dav.anonymous' => false, 'cms.host' => 'localhost', @@ -51,22 +52,30 @@ $config = array('dav.enable' => false, ); // Configuration-Loader -foreach( array( 'dav-'.$_SERVER['HTTP_HOST'].'.ini', - 'dav-custom.ini', - 'dav.ini') as $iniFile ) +foreach( array( + 'dav-'.$_SERVER['HTTP_HOST'].'.ini', + @$_ENV['dav.config.file'], + 'dav.ini', + '/etc/openrat-webdav.ini' + ) as $iniFile ) if ( is_file($iniFile)) $config = array_merge($config,parse_ini_file( $iniFile) ); +// Config values are overwritable by Environment variables. +array_walk($config, function(&$value,$key) { + if ( @$_ENV[$key] ) + $value = $_ENV[$key]; +} ); + +require('NotFoundException.php'); require('Logger.class.php'); require('Client.class.php'); require('CMS.class.php'); require('URIParser.class.php'); require('WebDAV.class.php'); -//Logger::info( print_r($config,true)); - - +Logger::trace( 'DAV config:'."\n".print_r($config,true)); // PHP-Fehler ins Log schreiben, damit die Ausgabe nicht zerstoert wird. if (version_compare(PHP_VERSION, '5.0.0', '>')) @@ -100,7 +109,7 @@ catch( Exception $e ) * Daher wird der Fehler-Handler umgebogen, so dass nur ein Logeintrag sowie ein * Server-Fehler erzeugt wird. */ -function webdavErrorHandler($errno, $errstr, $errfile, $errline) +function webdavErrorHandler($errno, $errstr, $errfile, $errline) { error_log('WEBDAV ERROR: '.$errno.'/'.$errstr.'/file:'.$errfile.'/line:'.$errline); diff --git a/test.xml b/test.xml @@ -0,0 +1,242 @@ +<?xml version="1.0" encoding="utf-8" ?> +<d:multistatus xmlns:d="DAV:"> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Thu, 01 Jan 1970 01:00:00 +0100</d:creationdate> + <d:displayname>www.jandankert.de</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Fri, + 11 Jan 2019 21:20:51 +0100 + </d:getlastmodified> + <d:resourcetype> + <d:collection/> + </d:resourcetype> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//bilder/</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Thu, 10 Jan 2019 22:41:34 +0100</d:creationdate> + <d:displayname>bilder</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Thu, + 10 Jan 2019 22:41:34 +0100 + </d:getlastmodified> + <d:resourcetype> + <d:collection/> + </d:resourcetype> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//archive/</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Thu, 10 Jan 2019 22:25:17 +0100</d:creationdate> + <d:displayname>archive</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Thu, + 10 Jan 2019 22:25:17 +0100 + </d:getlastmodified> + <d:resourcetype> + <d:collection/> + </d:resourcetype> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//photo/</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Thu, 04 Jan 2018 23:30:16 +0100</d:creationdate> + <d:displayname>photo</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Thu, + 04 Jan 2018 23:30:16 +0100 + </d:getlastmodified> + <d:resourcetype> + <d:collection/> + </d:resourcetype> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//category/</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Mon, 05 Jan 2015 21:32:40 +0100</d:creationdate> + <d:displayname>category</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Mon, + 05 Jan 2015 21:32:40 +0100 + </d:getlastmodified> + <d:resourcetype> + <d:collection/> + </d:resourcetype> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//tag/</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Thu, 09 Jan 2014 23:18:54 +0100</d:creationdate> + <d:displayname>tag</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Thu, + 09 Jan 2014 23:18:54 +0100 + </d:getlastmodified> + <d:resourcetype> + <d:collection/> + </d:resourcetype> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//script/</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Sun, 09 Dec 2018 23:56:45 +0100</d:creationdate> + <d:displayname>script</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sun, + 09 Dec 2018 23:56:45 +0100 + </d:getlastmodified> + <d:resourcetype> + <d:collection/> + </d:resourcetype> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//it/</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Thu, 10 Jan 2019 21:26:43 +0100</d:creationdate> + <d:displayname>it</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Thu, + 10 Jan 2019 21:26:43 +0100 + </d:getlastmodified> + <d:resourcetype> + <d:collection/> + </d:resourcetype> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//politik/</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Thu, 10 Jan 2019 21:27:15 +0100</d:creationdate> + <d:displayname>politik</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Thu, + 10 Jan 2019 21:27:15 +0100 + </d:getlastmodified> + <d:resourcetype> + <d:collection/> + </d:resourcetype> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//index</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Fri, 07 Dec 2018 23:26:15 +0100</d:creationdate> + <d:displayname>index</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Fri, + 07 Dec 2018 23:26:15 +0100 + </d:getlastmodified> + <d:resourcetype/> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//rss</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Tue, 17 Mar 2009 00:00:29 +0100</d:creationdate> + <d:displayname>rss</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Tue, + 17 Mar 2009 00:00:29 +0100 + </d:getlastmodified> + <d:resourcetype/> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//atom</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Wed, 24 Nov 2010 22:46:45 +0100</d:creationdate> + <d:displayname>atom</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Wed, + 24 Nov 2010 22:46:45 +0100 + </d:getlastmodified> + <d:resourcetype/> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> + <d:response> + <d:href>http://duese/~dankert/cms/dav/dav.php//suchindex</d:href> + <d:propstat> + <d:prop> + <d:creationdate>Sun, 09 Dec 2018 22:32:42 +0100</d:creationdate> + <d:displayname>suchindex</d:displayname> + <d:getcontentlength>0</d:getcontentlength> + <d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sun, + 09 Dec 2018 22:32:42 +0100 + </d:getlastmodified> + <d:resourcetype/> + <d:categories/> + <d:fields></d:fields> + </d:prop> + <d:status>HTTP/1.1 200 OK</d:status> + </d:propstat> + </d:response> +</d:multistatus>+ \ No newline at end of file