openrat-webdav

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

commit ab22f3fb8f2d23170e49dc336b6b05c4cf6bab51
Author: Jan Dankert <develop@jandankert.de>
Date:   Mon, 15 Apr 2019 23:02:33 +0200

moved from repository openrat-cms into this fresh new repository.

Diffstat:
CMS.class.php | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Client.class.php | 178+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Logger.class.php | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
README.md | 15+++++++++++++++
WebDAV.class.php | 1134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dav.ini | 17+++++++++++++++++
dav.log | 126+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dav.php | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
index.php | 6++++++
9 files changed, 1808 insertions(+), 0 deletions(-)

diff --git a/CMS.class.php b/CMS.class.php @@ -0,0 +1,79 @@ +<?php + +define('CMS_READ' ,'GET' ); +define('CMS_WRITE' ,'POST'); + +class CMS extends Client +{ + var $login = false; + var $token; + + function login($user, $password,$dbid ) + { + + // Erster Request der Sitzung muss ein GET-Request sein. + // Hier wird auch der Token gelesen. + $result = $this->call(CMS_READ,'login','login' ); + + $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)); + } + } + + + function projectlist() + { + $result = $this->call(CMS_READ,'projectlist','edit' ); + +// Logger::debug( print_r($result,true) ); + return( $result['output'] ); + } + + + function project($projectid) + { + $result = $this->call(CMS_READ,'project','edit',array('id'=>$projectid) ); + + return( $result['output'] ); + } + + function folder($id) + { + $result = $this->call(CMS_READ,'folder','edit',array('id'=>$id) ); + + return( $result['output'] ); + } + + function page($id) + { + $result = $this->call(CMS_READ,'page','edit',array('id'=>$id) ); + + return( $result['output'] ); + } + + function link($id) + { + $result = $this->call(CMS_READ,'link','edit',array('id'=>$id) ); + + return( $result['output'] ); + } + + function file($id) + { + $result = $this->call(CMS_READ,'file','edit',array('id'=>$id) ); + + return( $result['output'] ); + } + + function filevalue($id) + { + $result = $this->call(CMS_READ,'file','show',array('id'=>$id) ); + + return( $result['output'] ); + } + +} + +?>+ \ No newline at end of file diff --git a/Client.class.php b/Client.class.php @@ -0,0 +1,177 @@ +<?php + + +class Client +{ + protected $action; + protected $subaction; + protected $cookies = array(); + protected $useCookies = false; + + protected $sessionName; + protected $sessionId; + protected $token; + + protected $method; // GET oder POST + + protected $responseHeader; + + + protected function call($method,$action,$subaction,$parameter=array()) + { + global $config; + $error = ''; + $status = ''; + + $errno = 0; + $errstr = ''; + + $host = $config['cms.host']; + $port = $config['cms.port']; + $path = $config['cms.path']; + + // Vorbedingungen checken: + // Slash an Anfang und Ende? + if ( substr($path,-1 ) != '/' ) + $path = $path.'/'; + if ( substr($path,0,1 ) != '/' ) + $path = '/'.$path; + $path .= '/api/'; + + // Methode: Fallback GET + if ( empty($method)) + $method='GET'; + + // Die Funktion fsockopen() erwartet eine Protokollangabe (bei TCP optional, bei SSL notwendig). + if ( $port == '443' || @$config['ssl'] ) + $prx_proto = 'ssl://'; // SSL + else + $prx_proto = 'tcp://'; // Default + + $fp = fsockopen ($prx_proto.$host,$port, $errno, $errstr, 30); + + if ( !$fp || !is_resource($fp) ) + { + echo "Connection refused: '".$prx_proto.$host.':'.$port." - $errstr ($errno)"; + } + else + { + $lb = "\r\n"; + $http_get = $path; + + $parameter += array('action'=>$action,'subaction'=>$subaction); + if ( $method=='POST') + $parameter += array('token'=>$this->token); + + $parameterString = ''; + + foreach( $parameter as $name=>$value ) + { + if ( !empty($parameterString) ) + $parameterString .= '&'; + + $parameterString .= urlencode($name).'='.urlencode($value); + } + + if ( $method == 'GET') + $http_get .= '?'.$parameterString; + + $header = array(); + + $header[] = $method.' '.$http_get.' HTTP/1.0'; + $header[] = 'Host: '.$host; + $header[] = 'Accept: application/php-serialized'; + + if ( $this->useCookies) + foreach( $this->cookies as $cookieName=>$cookieValue) + $header[] = 'Cookie: '.$cookieName.'='.$cookieValue; + + if ( ! empty($this->sessionName)) + $header[] = 'Cookie: '.$this->sessionName.'='.$this->sessionId; + + if ( $method == 'POST' ) + { + $header[] = 'Content-Type: application/x-www-form-urlencoded'; + $header[] = 'Content-Length: '.strlen($parameterString); + } + + $http_request = implode($lb,$header).$lb.$lb; + + if ( $method == 'POST' ) + { + $http_request .= $parameterString; + } + if (!is_resource($fp)) { + $error = 'Connection lost after connect: '.$prx_proto.$host.':'.$port; + return false; + } + fputs($fp, $http_request); // Die HTTP-Anfrage zum Server senden. + + // Jetzt erfolgt das Auslesen der HTTP-Antwort. + $isHeader = true; + + // RFC 1945 (Section 6.1) schreibt als Statuszeile folgendes Format vor + // "HTTP/" 1*DIGIT "." 1*DIGIT SP 3DIGIT SP + if (!is_resource($fp)) { + echo 'Connection lost during transfer: '.$host.':'.$port; + } + elseif (!feof($fp)) { + $line = fgets($fp,1028); + $status = substr($line,9,3); + } + else + { + echo 'Unexpected EOF while reading HTTP-Response'; + } + + $body=''; + while (!feof($fp)) { + $line = fgets($fp,1028); + if ( $isHeader && trim($line)=='' ) // Leerzeile nach Header. + { + $isHeader = false; + } + elseif( $isHeader ) + { + list($headerName,$headerValue) = explode(': ',$line) + array(1=>''); + $this->responseHeader[$headerName] = trim($headerValue); + } + else + { + $body .= $line; + } + } + fclose($fp); // Verbindung brav schlie�en. + + foreach( $this->responseHeader as $headerName => $headerValue) + { + if ( $headerName == 'Set-Cookie' ) + { + $parts = explode(';',$headerValue); + $payload = $parts[0]; + list( $cookieName,$cookieValue) = explode('=',$payload); + { + $this->cookies[trim($cookieName)] = trim($cookieValue); + } + } + } + + $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 + { + $this->sessionName = $result['session']['name']; + $this->sessionId = $result['session']['id']; + $this->token = $result['session']['token']; +// var_dump($result); + return $result; + } + + } + } +} +?>+ \ No newline at end of file diff --git a/Logger.class.php b/Logger.class.php @@ -0,0 +1,139 @@ +<?php +// OpenRat Content Management System +// Copyright (C) 2002-2012 Jan Dankert, cms@jandankert.de +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +define('DAV_LOG_LEVEL_TRACE',5 ); +define('DAV_LOG_LEVEL_DEBUG',4 ); +define('DAV_LOG_LEVEL_INFO' ,3 ); +define('DAV_LOG_LEVEL_WARN' ,2 ); +define('DAV_LOG_LEVEL_ERROR',1 ); + +define('DAV_LOG_LEVEL', constant('DAV_LOG_LEVEL_'.strtoupper($config['log.level']))); + + +/** + * Schreiben eines Eintrages in die Logdatei + * + * @author $Author$ + * @version $Rev: $ + * @package openrat.services + */ +class Logger +{ + /** + * Schreiben einer Trace-Meldung in die Logdatei + * + * @param message Log-Text + */ + function trace( $message ) + { + if ( DAV_LOG_LEVEL >= DAV_LOG_LEVEL_TRACE ) + Logger::doLog( 'trace',$message ); + } + + + /** + * Schreiben einer Debug-Meldung in die Logdatei + * + * @param message Log-Text + */ + function debug( $message ) + { + if ( DAV_LOG_LEVEL >= DAV_LOG_LEVEL_DEBUG ) + Logger::doLog( 'debug',$message ); + } + + + /** + * Schreiben einer Information in die Logdatei + * + * @param message Log-Text + */ + function info( $message ) + { + if ( DAV_LOG_LEVEL >= DAV_LOG_LEVEL_INFO ) + Logger::doLog( 'TemplateEngineInfo',$message ); + } + + + /** + * Schreiben einer Warnung in die Logdatei + * + * @param message Log-Text + */ + function warn( $message ) + { + if ( DAV_LOG_LEVEL >= DAV_LOG_LEVEL_WARN ) + Logger::doLog( 'warn',$message ); + } + + + /** + * Schreiben einer normalen Fehlermeldung in die Logdatei + * + * @param message Log-Text + */ + function error( $message ) + { + if ( DAV_LOG_LEVEL >= DAV_LOG_LEVEL_ERROR ) + Logger::doLog( 'error',$message ); + } + + + /** + * Schreiben der Meldung in die Logdatei + * + * @author $Author$ + * @param facility Schwere dieses Logdatei-Eintrages (z.B. warning) + * @param message Log-Text + * @access private + */ + function doLog( $facility,$message ) + { + global $config; + + $filename = $config['log.file']; + + if ( empty($filename) ) + return; + + if ( ! is_writable($filename) ) + throw new \LogicException( "logfile $filename is not writable by the server" ); + + $thisLevel = strtoupper($facility); + + $text = "%time %level %host %action %text"; // Format der Logdatei + + // Ersetzen von Variablen + $text = str_replace( '%host',getenv('REMOTE_ADDR'),$text ); + + $action = strtoupper($_SERVER['REQUEST_METHOD']); + + $text = str_replace( '%level' ,str_pad($thisLevel,5),$text ); + $text = str_replace( '%agent' ,getenv('HTTP_USER_AGENT'),$text ); + $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 ); + + // Schreiben in Logdatei + error_log( $text."\n",3,$filename ); + } +} + +?>+ \ No newline at end of file diff --git a/README.md b/README.md @@ -0,0 +1,14 @@ + +WebDAV für OpenRat Content Management System +=== + +**The virtual CMS file system is accessable via a DAV client** + +WebDAV is specified in [RFC 2518](http://www.ietf.org/rfc/rfc2518.txt). + +Implemented is DAV level 1 (without Locks). + +Following impliciments: +- Login only with username/password +- Only 1 database +- DAV-client must support cookies (the most clients should)+ \ No newline at end of file diff --git a/WebDAV.class.php b/WebDAV.class.php @@ -0,0 +1,1134 @@ +<?php + + +class WebDAV +{ + /** + * CMS-Client + * @var CMS + */ + private $client; + + // Zahlreiche Instanzvariablen, die im Konstruktor + // beim Zerlegen der Anfrag gef�llt werden. + var $defaultSubAction = 'show'; + var $database; + var $depth; + var $projectid; + var $objectid; + var $filename; + var $pathnames = array(); + var $uri; + var $headers; + var $requestType; + var $request; + var $destination = null; + var $fullSkriptName; + var $create; + var $readonly; + var $maxFileSize; + var $webdav_conf; + var $overwrite = false; + + private $httpMethod; + + + /** + * Im Kontruktor wird der Request analysiert und ggf. eine Authentifzierung + * durchgefuehrt. Anschließend wird eine interne Methode mit dem Namen davXXX() aufgerufen. + */ + function __construct() + { + global $config; + + $this->httpMethod = strtoupper($_SERVER['REQUEST_METHOD']); + + Logger::trace( 'WEBDAV request' ); + + if ( $config['dav.compliant_to_redmond'] ) + header('MS-Author-Via: DAV' ); // Extrawurst fuer MS-Clients. + + if ( $config['dav.expose_openrat'] ) + header('X-Dav-powered-by: OpenRat CMS'); // Bandbreite verschwenden :) + +// Logger::trace( 'WEBDAV: URI='.$_SERVER['REQUEST_URI']); + + if ( !$config['dav.enable']) + { + Logger::warn( 'WEBDAV is disabled by configuration' ); + + $this->httpStatus('403 Forbidden'); + exit; + } + + $this->create = $config['dav.create']; + $this->readonly = $config['dav.readonly']; + $this->maxFileSize = $config['cms.max_file_size']; + + $this->headers = getallheaders(); + /* DAV compliant servers MUST support the "0", "1" and + * "infinity" behaviors. By default, the PROPFIND method without a Depth + * header MUST act as if a "Depth: infinity" header was included. */ + if ( !isset($this->headers['Depth']) ) + $this->depth = 1; + elseif ( strtolower($this->headers['Depth'])=='infinity') + $this->depth = 1; + else + $this->depth = intval($this->headers['Depth']); + + if ( isset($this->headers['Destination']) ) + $this->destination = $this->headers['Destination']; + + if ( isset($this->headers['Overwrite']) ) + $this->overwrite = $this->headers['Overwrite'] == 'T'; + + + session_start(); + if ( !empty($_SESSION['DAV_CLIENT']) ) + $this->client = $_SESSION['DAV_CLIENT']; + else + { + $this->client = new CMS(); + $_SESSION['DAV_CLIENT'] = $this->client; + } + + if ( $this->client->login ) + { + // Benutzer ist bereits im CMS eingeloggt. + } + else + { + // Login + if ( $this->httpMethod != 'OPTIONS' ) // Bei OPTIONS kein Login anfordern + { + if ( isset($_SERVER['PHP_AUTH_USER']) ) + { + + $username = $_SERVER['PHP_AUTH_USER']; + $pass = $_SERVER['PHP_AUTH_PW' ]; + + try { + $this->client->login($username, $pass, $config['cms.database']); + } + catch( Exception $e ) + { + $this->httpStatus('401 Unauthorized'); + header('WWW-Authenticate: Basic realm="'.$config['dav.realm'].'"'); + echo 'Failed login for user '.$username; + exit; + } + } + elseif ( $config['dav.anonymous']) + { + $username = $config['cms.user']; + $pass = $config['cms.password']; + + $loginOk = $this->client->login($username, $pass, $config['cms.database']); + if ( !$loginOk ) { + $this->httpStatus('500 Internal Server Error'); + echo 'Could not authenticate user '.$username; + exit; + } + } + else + { + // Client ist nicht angemeldet, daher wird nun die + // Authentisierung angefordert. + header('WWW-Authenticate: Basic realm="'.$config['dav.realm'].'"'); + $this->httpStatus('401 Unauthorized'); + echo 'Authentification required for '.$config['dav.realm']; + exit; + + } + } + else + { + return; // + } + } + + + $scriptName = $_SERVER['SCRIPT_NAME']; + +// if ( substr($scriptName,-10) == '/index.php' ) +// $scriptName = substr($scriptName,0,-10); + + $this->fullSkriptName = 'http://'.$_SERVER['HTTP_HOST'].$scriptName.'/'; + + // URL parsen. + $uri = substr($_SERVER['REQUEST_URI'],strlen($scriptName)); + + $uri = $this->parseURI( $uri ); + $this->requestType = $uri['type' ]; + $this->objectid = $uri['objectid' ]; + $this->projectid = $uri['projectid']; + +// $this->fullSkriptName .= implode('/',$uri['path']); + + if ( $this->requestType == 'folder' ) + $this->fullSkriptName .= '/'; + + /* + * Verzeichnisse muessen mit einem '/' enden. Falls nicht, Redirect aussfuehren. + * + * RFC 2518, 5.2 Collection Resources, Page 11: + * "For example, if a client invokes a + * method on http://foo.bar/blah (no trailing slash), the resource + * http://foo.bar/blah/ (trailing slash) may respond as if the operation + * were invoked on it, and should return a content-location header with + * 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; + } + + // Falls vorhanden, den "Destination"-Header parsen. + if ( isset($_SERVER['HTTP_DESTINATION']) ) + { + $destUri = parse_url( $_SERVER['HTTP_DESTINATION'] ); + + $uri = substr($destUri['path'],strlen($_SERVER['SCRIPT_NAME'])+$sos); + + // URL parsen. + $this->destination = $this->parseURI( $uri ); + } + + // Den Request-BODY aus der Standardeingabe lesen. + $this->request = implode('',file('php://input')); + } + + /** + * HTTP-Methode OPTIONS.<br> + * <br> + * Es werden die verfuegbaren Methoden ermittelt und ausgegeben. + */ + public function davOPTIONS() + { + header('DAV: 1'); // Wir haben DAV-Level 1. + header('Allow: '.implode(', ',$this->allowed_methods()) ); + + Logger::trace('OPTIONS: '.'Allow: '.implode(', ',$this->allowed_methods())); + + $this->httpStatus( '200 OK' ); + } + + + + + + /** + * WebDav-HEAD-Methode. + */ + public function davHEAD() + { + if ( $this->objectid == null ) + { + $this->httpStatus( '404 Not Found' ); + } + elseif ( $this->requestType == 'folder' ) + { + $this->httpStatus( '200 OK' ); + } + elseif( $this->obj->isPage ) + { + $this->httpStatus( '200 OK' ); + } + elseif( $this->obj->isLink ) + { + $this->httpStatus( '200 OK' ); + } + elseif( $this->obj->isFile ) + { + $this->httpStatus( '200 OK' ); + } + } + + + + /** + * WebDav-GET-Methode. + * Die gew�nschte Datei wird geladen und im HTTP-Body mitgeliefert. + */ + public function davGET() + { + switch( $this->requestType ) + { + case 'root': + case 'folder': + $this->getDirectoryIndex(); + break; + + 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->requestType.'</h1>'; + echo '<pre>'; + echo 'No Content available'; + echo '</pre>'; + echo '</body>'; + echo '</html>'; + break; + + case 'link': + $this->httpStatus( '200 OK' ); + + header('Content-Type: text/plain'); + + $link = $this->client->link( $this->objectid ); + echo 'url: ' .$link['url'] ."\n"; + echo 'target-id: '.$link['linkedObjectId']."\n"; + + break; + + case 'file': + $this->httpStatus( '200 OK' ); + + $file = $this->client->file ( $this->objectid ); + $filevalue = $this->client->filevalue( $this->objectid ); + + header('Content-Type: '.$file['mimetype']); + header('X-File-Id: ' .$this->objectid ); + + // Angabe Content-Disposition + // - Bild soll "inline" gezeigt werden + // - Dateiname wird benutzt, wenn der Browser das Bild speichern moechte + header('Content-Disposition: inline; filename='.$file['filename'].'.'.$file['extension'] ); + header('Content-Transfer-Encoding: binary' ); + header('Content-Description: '.$file['filename'].'.'.$file['extension'] ); + + // Groesse des Bildes in Bytes + // Der Browser hat so die Moeglichkeit, einen Fortschrittsbalken zu zeigen + header('Content-Length: '.$file['size'] ); + + echo base64_decode( $filevalue['value'] ); + + break; + } + } + + + + /** + * Erzeugt ein Unix-�hnliche Ausgabe des Verzeichnisses als HTML. + */ + private function getDirectoryIndex() + { + $this->httpStatus( '200 OK' ); + + // Verzeichnis ausgeben + header('Content-Type: text/html'); + $nl = "\n"; + + + + + $titel = 'Index of '.htmlspecialchars($this->fullSkriptName); + $format = "%15s %-19s %-s\n"; + + echo '<html><head><title>'.$titel.'</title></head>'; + echo '<body>'; + echo '<h1>'.$titel.'</h1>'.$nl; + echo '<pre>'; + + printf($format, "Size", "Last modified", "Filename"); + + + switch( $this->requestType ) + { + case 'root': // Projektliste + + $result = $this->client->projectlist(); + $projects = $result['projects']; + foreach( $projects as $projectid=>$p ) + { + echo '<a href="'.$p['name'].'">'.$p['name'].'</a>'.$nl; + } + break; + + case 'folder': // Verzeichnisinhalt + + $folder = $this->client->folder( $this->objectid ); + + foreach( $folder['object'] as $object ) + { + + printf($format, + number_format(1), + strftime("%Y-%m-%d %H:%M:%S",$object['date'] ), + '<a href="'.$object['filename'].'">'.$object['filename'].'</a>'); + echo $nl; + + } + } + + echo '</pre>'; + echo '</body>'; + echo '</html>'; + } + + + + /** + * Die Methode LOCK sollte garnicht aufgerufen werden, da wir nur + * Dav-Level 1 implementieren und dies dem Client auch mitteilen.<br> + * <br> + * Ausgabe von HTTP-Status 412 (Precondition failed) + */ + function davLOCK() + { + $this->httpStatus('412 Precondition failed'); + $this->davOPTIONS(); + } + + + + /** + * Die Methode UNLOCK sollte garnicht aufgerufen werden, da wir nur + * Dav-Level 1 implementieren und dies dem Client auch mitteilen.<br> + * <br> + * Ausgabe von HTTP-Status 412 (Precondition failed) + */ + public function davUNLOCK() + { + $this->httpStatus('412 Precondition failed'); + $this->davOPTIONS(); + } + + + + /** + * Die Methode POST ist bei WebDav nicht sinnvoll.<br> + * <br> + * Ausgabe von HTTP-Status 405 (Method Not Allowed) + */ + public function davPOST() + { + // Die Methode POST ist bei Webdav nicht sinnvoll. + $this->httpStatus('405 Method Not Allowed' ); + } + + + + /** + * Verzeichnis anlegen. + */ + public function davMKCOL() + { + + if ( !empty($this->request) ) + { + $this->httpStatus('415 Unsupported Media Type' ); // Kein Body erlaubt + } + elseif ( $this->readonly ) + { + $this->httpStatus('403 Forbidden' ); // Kein Schreibzugriff erlaubt + } + elseif ( !$this->folder->hasRight( ACL_CREATE_FOLDER ) ) + { + $this->httpStatus('403 Forbidden' ); // Benutzer darf das nicht + } + elseif ( $this->obj == null ) + { + // Die URI ist noch nicht vorhanden + $f = new Folder(); + $f->filename = basename($this->fullSkriptName); + $f->parentid = $this->folder->objectid; + $f->projectid = $this->project->projectid; + $f->add(); + $this->httpStatus('201 Created'); + } + else + { + // MKCOL ist nicht moeglich, wenn die URI schon existiert. + Logger::warn('MKCOL-Request to an existing resource'); + $this->httpStatus('405 Method Not Allowed' ); + } + } + + + + /** + * Objekt l�schen. + */ + public function davDELETE() + { + if ( $this->readonly ) + { + $this->httpStatus('403 Forbidden' ); // Kein Schreibzugriff erlaubt + } + else + { + if ( $this->obj == null ) + { + // Nicht existente URIs kann man auch nicht loeschen. + $this->httpStatus('404 Not Found' ); + } + elseif ( ! $this->obj->hasRight( ACL_DELETE ) ) + { + $this->httpStatus('403 Forbidden' ); // Benutzer darf die Resource nicht loeschen + } + elseif ( $this->obj->isFolder ) + { + $f = new Folder( $this->obj->objectid ); + $f->deleteAll(); + $this->httpStatus( true ); // OK + Logger::debug('Deleted folder with id '.$this->obj->objectid ); + } + elseif ( $this->obj->isFile ) + { + $f = new File( $this->obj->objectid ); + $f->delete(); + $this->httpStatus( true ); // OK + } + elseif ( $this->obj->isPage ) + { + $p = new Page( $this->obj->objectid ); + $p->delete(); + $this->httpStatus( true ); // OK + } + elseif ( $this->obj->isLink ) + { + $l = new Link( $this->obj->objectid ); + $l->delete(); + $this->httpStatus( true ); // OK + } + + } + } + + + + /** + * Kopieren eines Objektes.<br> + * Momentan ist nur das Kopieren einer Datei implementiert.<br> + * Das Kopieren von Ordnern, Verkn�pfungen und Seiten ist nicht moeglich. + */ + public function davCOPY() + { + if ( $this->readonly || !$this->create ) + { + error_log('WEBDAV: COPY request, but readonly or no creating'); + $this->httpStatus('405 Not Allowed' ); + } + elseif( $this->obj == null ) + { + // Was nicht da ist, laesst sich auch nicht verschieben. + error_log('WEBDAV: COPY request, but Source not found'); + $this->httpStatus('405 Not Allowed' ); + } + elseif ( $this->destination == null ) + { + error_log('WEBDAV: COPY request, but no "Destination:"-Header'); + // $this->httpStatus('405 Not Allowed' ); + $this->httpStatus('412 Precondition failed'); + } + else + { + // URL parsen. + $dest = $this->destination; + $destinationProject = $dest['project']; + $destinationFolder = $dest['folder' ]; + $destinationObject = $dest['object' ]; + + if ( $dest['type'] != 'object' ) + { + Logger::debug('WEBDAV: COPY request, but "Destination:"-Header mismatch'); + $this->httpStatus('405 Not Allowed'); + } + elseif ( $this->project->projectid != $destinationProject->projectid ) + { + // Kopieren in anderes Projekt nicht moeglich. + Logger::debug('WEBDAV: COPY request denied, project does not match'); + $this->httpStatus('403 Forbidden'); + } + elseif ( $destinationObject != null ) + { + Logger::debug('WEBDAV: COPY request denied, Destination exists. Overwriting is not supported'); + $this->httpStatus('403 Forbidden'); + } + elseif ( is_object($destinationFolder) && ! $destinationFolder->hasRight( ACL_CREATE_FILE ) ) + { + $this->httpStatus('403 Forbidden' ); // Benutzer darf das nicht + } + elseif ( is_object($destinationObject) && $destinationObject->isFolder) + { + Logger::debug('WEBDAV: COPY request denied, Folder-Copy not implemented'); + $this->httpStatus('405 Not Allowed'); + } + elseif ( is_object($destinationObject) && $destinationObject->isLink) + { + Logger::debug('WEBDAV: COPY request denied, Link copy not implemented'); + $this->httpStatus('405 Not Allowed'); + } + elseif ( is_object($destinationObject) && $destinationObject->isPage) + { + Logger::debug('WEBDAV: COPY request denied, Page copy not implemented'); + $this->httpStatus('405 Not Allowed'); + } + else + { + $f = new File(); + $f->filename = basename($_SERVER['HTTP_DESTINATION']); + $f->name = ''; + $f->parentid = $destinationFolder->objectid; + $f->projectid = $this->project->projectid; + $f->add(); + $f->copyValueFromFile( $this->obj->objectid ); + + Logger::debug('WEBDAV: COPY request accepted' ); + // Objekt wird in anderen Ordner kopiert. + $this->httpStatus('201 Created' ); + } + } + + } + + + + /** + * Verschieben eines Objektes.<br> + * <br> + * Folgende Operationen sind m�glich:<br> + * - Unbenennen eines Objektes (alle Typen)<br> + * - Verschieben eines Objektes (alle Typen) in einen anderen Ordner.<br> + */ + public function davMOVE() + { + if ( $this->readonly ) + { + $this->httpStatus('403 Forbidden - Readonly Mode' ); // Schreibgeschuetzt + } + elseif ( !$this->create ) + { + $this->httpStatus('403 Forbidden - No creation' ); // Schreibgeschuetzt + } + elseif( $this->obj == null ) + { + // Was nicht da ist, laesst sich auch nicht verschieben. + $this->httpStatus('404 Not Found' ); + } + elseif( is_object($this->obj) && ! $this->obj->hasRight( ACL_WRITE ) ) + { + // Was nicht da ist, laesst sich auch nicht verschieben. + Logger::error('Source '.$this->obj->objectid.' is not writable: Forbidden'); + $this->httpStatus('403 Forbidden' ); + } + elseif ( $this->destination == null ) + { + Logger::error('WEBDAV: MOVE request, but no "Destination:"-Header'); + // $this->httpStatus('405 Not Allowed' ); + $this->httpStatus('412 Precondition failed'); + } + else + { + $dest = $this->destination; + $destinationProject = $dest['project']; + $destinationFolder = $dest['folder' ]; + $destinationObject = $dest['object' ]; + + if ( $dest['type'] != 'object' ) + { + Logger::debug('WEBDAV: MOVE request, but "Destination:"-Header mismatch'); + $this->httpStatus('405 Not Allowed'); + return; + } + + if ( is_object($destinationFolder) && ! $destinationFolder->hasRight( ACL_CREATE_FILE ) ) + { + Logger::error('Source '.$this->obj->objectid.' is not writable: Forbidden'); + $this->httpStatus('403 Forbidden' ); + } + + if ( $destinationObject != null ) + { + Logger::debug('WEBDAV: MOVE request denied, destination exists'); + $this->httpStatus('412 Precondition Failed'); + return; + } + + if ( $this->project->projectid != $destinationProject->projectid ) + { + // Verschieben in anderes Projekt nicht moeglich. + Logger::debug('WEBDAV: MOVE request denied, project does not match'); + $this->httpStatus('405 Not Allowed'); + return; + } + + if ( $this->folder->objectid == $destinationFolder->objectid ) + { + Logger::debug('WEBDAV: MOVE request accepted, object renamed'); + // Resource bleibt in gleichem Ordner. + $this->obj->filename = basename($_SERVER['HTTP_DESTINATION']); + $this->obj->objectSave(false); + $this->httpStatus('201 Created' ); + return; + } + + if ( $destinationFolder->isFolder ) + { + Logger::debug('WEBDAV: MOVE request accepted, Destination: '.$destinationFolder->filename ); + // Objekt wird in anderen Ordner verschoben. + $this->obj->setParentId( $destinationFolder->objectid ); + $this->httpStatus('201 Created' ); + return; + } + + Logger::warn('WEBDAV: MOVE request failed' ); + $this->httpStatus('500 Internal Server Error' ); + } + } + + + + /** + * Anlegen oder �berschreiben Dateien �ber PUT.<br> + * Dateien k�nnen neu angelegt und �berschrieben werden.<br> + * <br> + * Seiten k�nnen nicht �berschrieben werden. Wird versucht, + * eine Seite mit PUT zu �berschreiben, wird der Status "405 Not Allowed" gemeldet.<br> + */ + public function davPUT() + { + // TODO: 409 (Conflict) wenn �bergeordneter Ordner nicht da. + + if ( $config['readonly'] ) + { + $this->httpStatus('405 Not Allowed' ); + } + elseif ( strlen($this->request) > $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 ) + { + // Neue Datei anlegen + if ( !$config['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->httpStatus('201 Created'); + return; + } + elseif ( $this->obj->isFile ) + { + 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(); + $this->httpStatus('204 No Content'); + Logger::debug('PUT ok, file is created' ); + return; + } + elseif ( $this->obj->isFolder ) + { + Logger::error('PUT on folder is not supported, use PROPFIND. Lame client?' ); + $this->httpStatus('405 Not Allowed' ); + } + else + { + // Fuer andere Objekttypen (Links, Seiten) ist kein PUT moeglich. + Logger::warn('PUT only available for files. Pages and links are ignored' ); + $this->httpStatus('405 Not Allowed' ); + } + } + + + + /** + * WebDav-Methode PROPFIND. + * + * Diese Methode wird + * - beim Ermitteln von Verzeichnisinhalten und + * - beim Ermitteln von Metainformationen zu einer Datei + * verwendet. + * + * Das Ergebnis wird in einer XML-Zeichenkette geliefert. + */ + public function davPROPFIND() + { + switch( $this->requestType ) + { + case 'root': // Projektliste + + $inhalte = array(); + + $objektinhalt = array(); + $z = 30*365.25*24*60*60; + $objektinhalt['createdate' ] = $z; + $objektinhalt['lastchangedate'] = $z; + $objektinhalt['size' ] = 1; + $objektinhalt['name' ] = $this->fullSkriptName; + $objektinhalt['displayname' ] = ''; + $objektinhalt['type'] = 'folder'; + + $inhalte[] = $objektinhalt; + + $result = $this->client->projectlist(); + $projects = $result['projects']; + foreach( $projects as $projectid=>$p ) + { + $objektinhalt = array(); + $objektinhalt['createdate' ] = TIME_20000101; + $objektinhalt['lastchangedate'] = TIME_20000101; + $objektinhalt['size' ] = 1; + $objektinhalt['name' ] = $this->fullSkriptName.$p['name'].'/'; + $objektinhalt['displayname' ] = $p['name']; + $objektinhalt['type'] = 'folder'; + $inhalte[] = $objektinhalt; + } + + $this->multiStatus( $inhalte ); + break; + + case 'folder': // Verzeichnisinhalt + + $folder = $this->client->folder( $this->objectid ); + + $inhalte = array(); + + $objektinhalt = array(); + $objektinhalt['createdate' ] = $folder['properties']['create_date']; + $objektinhalt['lastchangedate'] = $folder['properties']['lastchange_date']; + $objektinhalt['name' ] = $this->fullSkriptName; + $objektinhalt['displayname' ] = $folder['properties']['filename']; + $objektinhalt['type' ] = 'folder'; + $objektinhalt['size' ] = 0; + + $inhalte[] = $objektinhalt; + + if ( $this->depth > 0 ) + { + + foreach( $folder['object'] as $object ) + { + $objektinhalt = array(); + $objektinhalt['createdate' ] = $object['date']; + $objektinhalt['lastchangedate'] = $object['date']; + $objektinhalt['displayname' ] = $object['filename']; + + switch( $object['type'] ) + { + case 'folder': + $objektinhalt['name'] = $this->fullSkriptName.$object['filename'].'/'; + $objektinhalt['type'] = 'folder'; + $objektinhalt['size'] = 0; + $inhalte[] = $objektinhalt; + break; + case 'file': + $objektinhalt['name'] = $this->fullSkriptName.$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['type'] = 'file'; + $objektinhalt['size'] = 0; + $objektinhalt['mime'] = 'application/x-non-readable'; + $inhalte[] = $objektinhalt; + break; + case 'page': + $objektinhalt['name'] = $this->fullSkriptName.$object['filename']; + $objektinhalt['type'] = 'file'; + $objektinhalt['size'] = 0; + $inhalte[] = $objektinhalt; + break; + default: + } + } + } + $this->multiStatus( $inhalte ); + break; + + case 'page': + $page = $this->client->page( $objectid ); + $prop = $page['properties']; + $objektinhalt = array(); + $objektinhalt['name'] = $this->fullSkriptName.'/'.$prop['filename'].'/'; + $objektinhalt['displayname'] = $prop['filename']; + $objektinhalt['createdate' ] = $prop['date']; + $objektinhalt['lastchangedate'] = $prop['date']; + + $objektinhalt['size' ] = 0; + $objektinhalt['type' ] = 'file'; + break; + + case 'file': + $file = $this->client->file( $objectid ); + $objektinhalt = array(); + $objektinhalt['name'] = $this->fullSkriptName.'/'.$file['filename'].'/'; + $objektinhalt['displayname'] = $file['filename']; + $objektinhalt['createdate' ] = $file['date']; + $objektinhalt['lastchangedate'] = $file['date']; + + $objektinhalt['size' ] = $file['size']; + $objektinhalt['type' ] = 'file'; + + break; + + case 'link': + + $link = $this->client->link( $objectid ); + + $objektinhalt = array(); + $objektinhalt['name'] = $this->fullSkriptName.'/'.$link['filename'].'/'; + $objektinhalt['displayname'] = $link['filename']; + $objektinhalt['createdate' ] = $link['date']; + $objektinhalt['lastchangedate'] = $link['date']; + + $objektinhalt['size' ] = 0; + $objektinhalt['type' ] = 'file'; + + + $this->multiStatus( array($objektinhalt) ); + + break; + + default: + Logger::warn('Internal Error, unknown request type: '. $this->requestType); + $this->httpStatus('500 Internal Server Error'); + } + } + + + /** + * Webdav-Methode PROPPATCH ist nicht implementiert. + */ + public function davPROPPATCH() + { + // TODO: Multistatus erzeugen. + // Evtl. ist '409 Conflict' besser? + $this->httpStatus('405 Not Allowed'); + } + + + /** + * Erzeugt einen Multi-Status. + * @access private + */ + private function multiStatus( $files ) + { + $this->httpStatus('207 Multi-Status'); + header('Content-Type: text/xml; charset=utf-8'); + + $response = ''; + $response .= '<?xml version="1.0" encoding="utf-8" ?>'; + $response .= '<d:multistatus xmlns:d="DAV:">'; + + foreach( $files as $file ) + $response .= $this->getResponse( $file['name'],$file ); + + $response .= '</d:multistatus>'; + + $response = utf8_encode($response); + + header('Content-Length: '.strlen($response)); + Logger::debug('Multistatus: '.$response); + echo $response; + } + + + /** + * Erzeugt ein "response"-Element, welches in ein "multistatus"-element verwendet werden kann. + */ + private function getResponse( $file,$options ) + { + // TODO: Nur angeforderte Elemente erzeugen. + $response = ''; + $response .= '<d:response>'; + $response .= '<d:href>'.$file.'</d:href>'; + $response .= '<d:propstat>'; + $response .= '<d:prop>'; + // $response .= '<d:source></d:source>'; + $response .= '<d:creationdate>'.date('r',$options['createdate']).'</d:creationdate>'; + $response .= '<d:displayname>'.$options['displayname'].'</d:displayname>'; + $response .= '<d:getcontentlength>'.$options['size'].'</d:getcontentlength>'; + $response .= '<d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">'.date('r',$options['lastchangedate']).'</d:getlastmodified>'; + + if ( $options['type'] == 'folder') + $response .= '<d:resourcetype><d:collection/></d:resourcetype>'; + else + $response .= '<d:resourcetype />'; + + $response .= '<d:categories />'; + $response .= '<d:fields></d:fields>'; + + + +// $response .= '<d:getcontenttype>text/html</d:getcontenttype>'; +// $response .= '<d:getcontentlength />'; +// $response .= '<d:getcontentlanguage />'; +// $response .= '<d:executable />'; +// $response .= '<d:resourcetype>'; +// $response .= '<d:collection />'; +// $response .= '</d:resourcetype>'; +// $response .= '<d:getetag />'; + + $response .= '</d:prop>'; + $response .= '<d:status>HTTP/1.1 200 OK</d:status>'; + $response .= '</d:propstat>'; + $response .= '</d:response>'; + + return $response; + } + + + + /** + * URI parsen. + */ + private function parseURI( $uri ) + { + // Ergebnis initialisieren (damit alle Schl�ssel vorhanden sind) + $ergebnis = array('type' => null, + 'projectid' => null, + 'objectid' => null ); + + +// Logger::trace( 'WEBDAV: Parsen der URI '.$uri); + $uriParts = explode('/',$uri); + + $projectName = array_shift($uriParts); + + if ( empty($projectName) ) + { + $ergebnis['type'] = 'root'; + return $ergebnis; // Root-Verzeichnis + } + + $result = $this->client->projectlist(); + $projects = $result['projects']; + + $projectid = array_search($projectName,$projects); + + if ( $projectid === FALSE ) + { + $this->httpStatus("404 Project not found"); + echo 'project not found'; + exit; + } + + $project = $this->client->project($projectid); + + $ergebnis['projectid'] = $projectid; + + $objectid = $project['rootobjectid']; + $type = 'folder'; + + while( length($uriParts) > 0 ) + { + $name = array_shift($uriParts); + + $folder = $this->client->folder($objectid); + + $found = false; + foreach( $folder['object'] as $oid => $object) + { + if ( $object['filename'] == $name ) + { + $found = true; + + $type = $object['type']; + $objectid = $object['objectid']; + + break; + } + + } + + if ( ! $found ) + { + httpStatus('404 Not Found'); + exit; + } + } + + $ergebnis['type' ] = $type; + $ergebnis['objectid'] = $objectid; + + + return $ergebnis; + } + + + + /** + * Setzt einen HTTP-Status.<br> + * <br> + * Es wird ein HTTP-Status gesetzt, zus�tzlich wird der Status in den Header "X-WebDAV-Status" geschrieben.<br> + * Ist der Status nicht 200 oder 207 (hier folgt ein BODY), wird das Skript beendet. + */ + protected function httpStatus( $status = true ) + { + if ( $status === true ) + $status = '200 OK'; + + // Logger::debug('WEBDAV: HTTP-Status: '.$status); + + header('HTTP/1.1 '.$status); + header('X-WebDAV-Status: '.$status,true); + + // RFC 2616 (HTTP/1.1), Section 10.4.6 "405 Method Not Allowed" says: + // "[...] The response MUST include an + // Allow header containing a list of valid methods for the requested + // resource." + // + // RFC 2616 (HTTP/1.1), Section 14.7 "Allow" says: + // "[...] An Allow header field MUST be + // present in a 405 (Method Not Allowed) response." + if ( substr($status,0,3) == '405' ) + header('Allow: '.implode(', ',$this->allowed_methods()) ); + } + + + + + private function allowed_methods() + { + + if ($this->readonly) + return array('OPTIONS','HEAD','GET','PROPFIND'); // Readonly-Modus + else + // PROPPATCH unterstuetzen wir garnicht, aber lt. Spec sollten wir das. + return array('OPTIONS','HEAD','GET','PROPFIND','DELETE','PUT','COPY','MOVE','MKCOL','PROPPATCH'); + } + + +} diff --git a/dav.ini b/dav.ini @@ -0,0 +1,17 @@ +; you may copy this file dav.ini to a custom file dav.custom.ini or dav.<hostname>.ini +; +; beware of publishing this file via the webserver because it may contain secret information! + +dav.enable=true +dav.create=true +dav.readonly = true +dav.anonymous = false + +log.file=dav.log +log.level=trace + +cms.username=dav +cms.password=davdav +cms.database=pdo_my_prod +cms.host=duese +cms.path="/~dankert/cms/cms09/" diff --git a/dav.log b/dav.log @@ -0,0 +1,126 @@ +Jan 9 22:49:58 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 22:49:58 WARN 127.0.0.1 OPTIONS WEBDAV is disabled by configuration +Jan 9 22:50:50 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 22:50:50 WARN 127.0.0.1 OPTIONS WEBDAV is disabled by configuration +Jan 9 22:55:33 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 22:55:37 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 22:55:47 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 22:55:50 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 22:57:25 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 22:57:28 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:04:17 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:04:19 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:04:26 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:14:14 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:14:19 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:14:27 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:17:48 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:17:51 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:18:19 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:19:21 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:19:30 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:26:11 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:26:16 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:26:34 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:26:36 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:26:38 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:26:41 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:27:46 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:27:46 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Jan 9 23:35:20 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:35:20 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Jan 9 23:35:20 TRACE 127.0.0.1 PROPFIND WEBDAV request +Jan 9 23:35:24 TRACE 127.0.0.1 PROPFIND WEBDAV request +Jan 9 23:35:32 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:35:32 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Jan 9 23:35:32 TRACE 127.0.0.1 PROPFIND WEBDAV request +Jan 9 23:35:35 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:35:35 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Jan 9 23:35:35 TRACE 127.0.0.1 PROPFIND WEBDAV request +Jan 9 23:35:43 TRACE 127.0.0.1 PROPFIND WEBDAV request +Jan 9 23:37:38 TRACE 127.0.0.1 OPTIONS WEBDAV request +Jan 9 23:37:38 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Jan 9 23:37:38 TRACE 127.0.0.1 PROPFIND WEBDAV request +Jan 9 23:37:42 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 22 23:11:28 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 22 23:11:28 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Mar 22 23:14:41 TRACE 127.0.0.1 GET WEBDAV request +Mar 22 23:14:56 TRACE 127.0.0.1 GET WEBDAV request +Mar 22 23:16:08 TRACE 127.0.0.1 GET WEBDAV request +Mar 22 23:16:36 TRACE 127.0.0.1 GET WEBDAV request +Mar 22 23:16:44 TRACE 127.0.0.1 GET WEBDAV request +Mar 22 23:16:50 TRACE 127.0.0.1 GET WEBDAV request +Mar 22 23:16:57 TRACE 127.0.0.1 GET WEBDAV request +Mar 22 23:18:29 TRACE 127.0.0.1 GET WEBDAV request +Mar 22 23:19:06 TRACE 127.0.0.1 GET WEBDAV request +Mar 22 23:19:24 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 22 23:19:24 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Mar 22 23:20:14 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 22 23:20:14 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Mar 22 23:58:20 TRACE 127.0.0.1 GET WEBDAV request +Mar 22 23:59:43 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 22 23:59:47 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 22 23:59:48 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Mar 23 00:01:36 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 23 00:01:39 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 23 00:01:39 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Mar 23 00:16:21 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 23 00:16:24 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 23 00:16:25 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Mar 23 00:16:25 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:16:26 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:16:29 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:16:30 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:16:39 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:16:41 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:17:00 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:17:02 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:17:03 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:17:05 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:17:10 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:17:11 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:17:24 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:17:25 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:17:29 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:17:31 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:17:32 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:17:33 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:17:34 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:17:35 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:19:20 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:19:22 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:19:41 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:19:42 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:19:43 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:19:44 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:20:07 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 23 00:20:08 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 23 00:23:51 TRACE 127.0.0.1 GET WEBDAV request +Mar 23 00:23:57 TRACE 127.0.0.1 GET WEBDAV request +Mar 26 21:54:33 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 26 21:54:33 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Mar 26 21:54:33 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 26 21:54:37 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 26 21:54:41 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 26 21:54:41 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Mar 26 21:54:41 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 26 21:54:43 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 26 21:54:45 TRACE 127.0.0.1 OPTIONS WEBDAV request +Mar 26 21:54:45 TRACE 127.0.0.1 OPTIONS OPTIONS: Allow: OPTIONS, HEAD, GET, PROPFIND +Mar 26 21:54:45 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 26 21:54:47 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 26 21:54:49 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 26 21:54:53 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 26 21:54:54 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 26 21:55:09 TRACE 127.0.0.1 GET WEBDAV request +Mar 26 21:55:11 TRACE 127.0.0.1 GET WEBDAV request +Mar 26 21:55:14 TRACE 127.0.0.1 GET WEBDAV request +Mar 26 21:55:36 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 26 21:55:38 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 26 21:55:39 TRACE 127.0.0.1 PROPFIND WEBDAV request +Mar 26 21:55:41 DEBUG 127.0.0.1 PROPFIND Multistatus: <?xml version="1.0" encoding="utf-8" ?><d:multistatus xmlns:d="DAV:"><d:response><d:href>http://duese/~dankert/cms/cms09/dav/dav.php/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 13:00:00 +0100</d:creationdate><d:displayname></d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 13:00:00 +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/cms09/dav/dav.php/heimkino.jandankert.de/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>heimkino.jandankert.de</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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/cms09/dav/dav.php/Test Forum/</d:href><d:propstat><d:prop><d:creationdate>Sat, 01 Jan 2000 00:00:00 +0100</d:creationdate><d:displayname>Test Forum</d:displayname><d:getcontentlength>1</d:getcontentlength><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Sat, 01 Jan 2000 00:00:00 +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:multistatus> +Mar 26 21:56:32 TRACE 127.0.0.1 GET WEBDAV request +Mar 26 21:56:42 TRACE 127.0.0.1 GET WEBDAV request +Mar 26 22:01:11 TRACE 127.0.0.1 GET WEBDAV request +Mar 26 22:40:45 TRACE 127.0.0.1 GET WEBDAV request +Mar 26 22:40:57 TRACE 127.0.0.1 GET WEBDAV request diff --git a/dav.php b/dav.php @@ -0,0 +1,112 @@ +<?php + +/** + * 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 + */ + + + +if (!defined('E_STRICT')) + define('E_STRICT', 2048); + +define('TIME_20000101',946681200); // default time for objects without time information. + +// Default-Configuration. +$config = array('dav.enable' => false, + 'dav.create' => true, + 'dav.readonly' => false, + 'dav.expose_openrat' => true, + 'dav.compliant_to_redmond' => true, + 'dav.realm' =>'OpenRat CMS WebDAV Login', + 'dav.anonymous' => false, + 'cms.host' => 'localhost', + 'cms.port' => 80, + 'cms.username' => null, + 'cms.password' => null, + 'cms.database' => 'db1', + 'cms.path' => '/', + 'cms.max_file_size' => 1000, + 'log.level' => 'info', + 'log.file' => null + ); + +// Configuration-Loader +foreach( array( 'dav-'.$_SERVER['HTTP_HOST'].'.ini', + 'dav-custom.ini', + 'dav.ini') as $iniFile ) + if ( is_file($iniFile)) + $config = array_merge($config,parse_ini_file( $iniFile) ); + + +require('Logger.class.php'); +require('Client.class.php'); +require('CMS.class.php'); +require('WebDAV.class.php'); + +//Logger::info( print_r($config,true)); + + + +// PHP-Fehler ins Log schreiben, damit die Ausgabe nicht zerstoert wird. +if (version_compare(PHP_VERSION, '5.0.0', '>')) + set_error_handler('webdavErrorHandler',E_ERROR | E_WARNING); +else + set_error_handler('webdavErrorHandler'); + + +try { + + $dav = new WebDAV(); + + $httpMethod = strtoupper($_SERVER['REQUEST_METHOD']); + $davMethodName = 'dav' . $httpMethod; + + $dav->$davMethodName(); +} +catch( Exception $e ) +{ + error_log('WEBDAV ERROR: '.$e->getMessage()."\n".$e->getTraceAsString() ); + + // Wir teilen dem Client mit, dass auf dem Server was schief gelaufen ist. + header('HTTP/1.1 503 Internal WebDAV Server Error'); + echo 'WebDAV-Request failed'."\n".$e->getTraceAsString(); +} + +/** + * Fehler-Handler fuer WEBDAV.<br> + * Bei einem Laufzeitfehler ist eine Ausgabe des Fehlers auf der Standardausgabe sinnlos, + * da der WebDAV-Client dies nicht lesen oder erkennen kann. + * Daher wird der Fehler-Handler umgebogen, so dass nur ein Logeintrag sowie ein + * Server-Fehler erzeugt wird. + */ +function webdavErrorHandler($errno, $errstr, $errfile, $errline) +{ + error_log('WEBDAV ERROR: '.$errno.'/'.$errstr.'/file:'.$errfile.'/line:'.$errline); + + + header('HTTP/1.1 503 Internal WebDAV Server Error'); + + // Wir teilen dem Client mit, dass auf dem Server was schief gelaufen ist. + echo 'WebDAV-Request failed with "'.$errstr.'"'; + exit; +} diff --git a/index.php b/index.php @@ -0,0 +1,6 @@ +<html> +<body> +<a href="./dav.php/">DAV</a> +</body> +</html> +