openrat-webdav

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

commit 97074f9397628c8756e9e2131b690fa19c476999
parent 51cc2675676ade717ba816cc5902957308795449
Author: Jan Dankert <develop@jandankert.de>
Date:   Mon,  4 Nov 2019 23:54:13 +0100

Refactoring: Splitting DAV methods into single files.

Diffstat:
dav.php | 16+++++++++++++---
dav/WebDAV.class.php | 801+++----------------------------------------------------------------------------
dav/method/COPY.class.php | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dav/method/DELETE.class.php | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dav/method/GET.class.php | 152+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dav/method/HEAD.class.php | 32++++++++++++++++++++++++++++++++
dav/method/LOCK.class.php | 16++++++++++++++++
dav/method/MKCOL.class.php | 42++++++++++++++++++++++++++++++++++++++++++
dav/method/MOVE.class.php | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dav/method/OPTIONS.class.php | 20++++++++++++++++++++
dav/method/POST.class.php | 16++++++++++++++++
dav/method/PROPFIND.class.php | 202+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dav/method/PROPPATCH.class.php | 16++++++++++++++++
dav/method/PUT.class.php | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dav/method/UNLOCK.class.php | 18++++++++++++++++++
15 files changed, 861 insertions(+), 779 deletions(-)

diff --git a/dav.php b/dav.php @@ -87,12 +87,22 @@ else try { - $dav = new WebDAV(); $httpMethod = strtoupper($_SERVER['REQUEST_METHOD']); - $davMethodName = 'dav' . $httpMethod; - $dav->$davMethodName(); + $davMethodFile = './dav/method/'.$httpMethod.'.class.php'; + + if ( ! file_exists($davMethodFile ) ) + { + Logger::warn('Unknown HTTP method '.$httpMethod); + $this->httpStatus('405 Method Not Allowed' ); + } + + require( $davMethodFile ); + + $davClass = new ReflectionClass('DAV_'.$httpMethod ); + $davAction = $davClass->newInstance(); + $davAction->execute(); } catch( Exception $e ) { diff --git a/dav/WebDAV.class.php b/dav/WebDAV.class.php @@ -1,7 +1,8 @@ <?php define('LB',"\n"); -class WebDAV + +abstract class WebDAV { // Zahlreiche Instanzvariablen, die im Konstruktor @@ -29,7 +30,7 @@ class WebDAV * CMS-Client * @var CMS */ - private $client; + protected $client; const MEMKEY = 1; private $shm; @@ -232,782 +233,12 @@ class WebDAV $this->data = 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->request->objectid ) - { - $this->httpStatus( '404 Not Found' ); - } - elseif ( $this->request->type == '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->request->type ) - { - 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->request->type.'</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->request->objectid ); - echo 'url: ' .$link['url'] ."\n"; - echo 'target-id: '.$link['linkedObjectId']."\n"; - - break; - - case 'file': - case 'image': - case 'text': - $this->httpStatus( '200 OK' ); - - $file = $this->client->file ( $this->request->objectid ); - $filevalue = $this->client->filevalue( $this->request->objectid ); - - header('Content-Type: '.$file['mimetype']); - header('X-File-Id: ' .$this->request->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 $filevalue; - - break; - - default: - $this->httpStatus( '200 OK' ); - header('Content-Type: text/html'); - - echo '<html><head><title>OpenRat WEBDAV Access</title></head>'; - echo '<body>'; - echo '<h1>'.$this->request->type.'</h1>'; - echo '<pre>'; - echo 'Unknown node type: '.$this->request->type; - echo '</pre>'; - echo '</body>'; - echo '</html>'; - 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->sitePath); - $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->request->type ) - { - 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->request->objectid ); - - foreach( $folder['content']['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->data) ) - { - $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->sitePath); - $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 ( $this->readonly ) - { - $this->httpStatus('405 Not Allowed' ); - } - 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->request->objectid ) - { - // Neue Datei anlegen - if ( !$this->create ) - { - Logger::warn('WEBDAV: Creation of files not allowed by configuration' ); - $this->httpStatus('405 Not Allowed' ); - } - - $this->client->fileAdd( $this->data ); - $this->httpStatus('201 Created'); - return; - } - elseif ( $this->request->objectid ) - { - // Bestehende Datei ueberschreiben. - $id = $this->request->objectid; - $this->client->fileAdd( $id,$this->data ); - - $this->httpStatus('204 No Content'); - 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->request->type ) - { - 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->sitePath; - $objektinhalt['displayname' ] = ''; - $objektinhalt['type'] = 'folder'; - - $inhalte[] = $objektinhalt; - - try { - $result = $this->client->projectlist(); - } catch( Exception $e) { - Logger::error($e->__toString().$this->client->__toString()); - throw $e; - } - $projects = $result['projects']; - foreach( $projects as $projectid=>$p ) - { - $objektinhalt = array(); - $objektinhalt['createdate' ] = TIME_20000101; - $objektinhalt['lastchangedate'] = TIME_20000101; - $objektinhalt['size' ] = 1; - $objektinhalt['name' ] = $this->sitePath.$p['name'].'/'; - $objektinhalt['displayname' ] = $p['name']; - $objektinhalt['type'] = 'folder'; - $inhalte[] = $objektinhalt; - } - - $this->multiStatus( $inhalte ); - break; - - case 'folder': // Verzeichnisinhalt - - $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->sitePath; - $objektinhalt['displayname' ] = $folder['properties']['filename']; - $objektinhalt['type' ] = 'folder'; - $objektinhalt['size' ] = 0; - - $inhalte[] = $objektinhalt; - - if ( $this->depth > 0 ) - { - - foreach( $folder['content']['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->sitePath.$object['filename'].'/'; - $objektinhalt['type'] = 'folder'; - $objektinhalt['size'] = 0; - $inhalte[] = $objektinhalt; - break; - case 'file': - 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->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->sitePath.$object['filename']; - $objektinhalt['type'] = 'file'; - $objektinhalt['size'] = 0; - $inhalte[] = $objektinhalt; - break; - default: - } - } - } - $this->multiStatus( $inhalte ); - break; - - case 'page': - $page = $this->client->page( $this->request->objectid ); - $prop = $page['properties']; - $objektinhalt = array(); - $objektinhalt['name'] = $this->sitePath; - $objektinhalt['displayname'] = $prop['filename']; - $objektinhalt['createdate' ] = $prop['date']; - $objektinhalt['lastchangedate'] = $prop['date']; - - $objektinhalt['size' ] = 0; - $objektinhalt['type' ] = 'file'; - - $this->multiStatus( array($objektinhalt) ); - - break; - - case 'file': - case 'text': - case 'image': - $file = $this->client->file( $this->request->objectid ); - $objektinhalt = array(); - $objektinhalt['name'] = $this->sitePath; - $objektinhalt['displayname'] = $file['filename']; - $objektinhalt['createdate' ] = $file['date']; - $objektinhalt['lastchangedate'] = $file['date']; - - $objektinhalt['size' ] = $file['size']; - $objektinhalt['type' ] = 'file'; - - $this->multiStatus( array($objektinhalt) ); - - break; - - case 'link': - - $link = $this->client->link( $this->request->objectid ); - - $objektinhalt = array(); - $objektinhalt['name'] = $this->sitePath; - $objektinhalt['displayname'] = $link['filename']; - $objektinhalt['createdate' ] = $link['date']; - $objektinhalt['lastchangedate'] = $link['date']; - - $objektinhalt['size' ] = 0; - $objektinhalt['type' ] = 'file'; - - - $this->multiStatus( array($objektinhalt) ); - - break; - - case 'url': - - $link = $this->client->link( $this->request->objectid ); - - $objektinhalt = array(); - $objektinhalt['name'] = $this->sitePath; - $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->request->type); - $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 ) + protected function multiStatus( $files ) { $this->httpStatus('207 Multi-Status'); header('Content-Type: text/xml; charset=utf-8'); @@ -1081,15 +312,28 @@ class WebDAV * 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 ) + public static function httpStatus( $status = true ) { if ( $status === true ) $status = '200 OK'; - // Logger::debug('WEBDAV: HTTP-Status: '.$status); + Logger::debug('WEBDAV: HTTP-Status: '.$status); header('HTTP/1.1 '.$status); header('X-WebDAV-Status: '.$status,true); + } + + /** + * 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. + */ + public function httpMethodNotAllowed() + { + $status = 405; + 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 @@ -1101,12 +345,14 @@ class WebDAV // present in a 405 (Method Not Allowed) response." if ( substr($status,0,3) == '405' ) header('Allow: '.implode(', ',$this->allowed_methods()) ); + + self::httpStatus('405 Method Not Allowed'); } - private function allowed_methods() + protected function allowed_methods() { if ($this->readonly) @@ -1135,4 +381,7 @@ class WebDAV $this->store[$this->username] = $this->client->client->cookies; shm_put_var($this->shm,self::MEMKEY,$this->store); } + + + public abstract function execute(); } diff --git a/dav/method/COPY.class.php b/dav/method/COPY.class.php @@ -0,0 +1,92 @@ +<?php + +class DAV_COPY extends WebDAV +{ + + /** + * 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 execute() + { + if ( $this->readonly || !$this->create ) + { + error_log('WEBDAV: COPY request, but readonly or no creating'); + $this->httpMethodNotAllowed(); + } + elseif( $this->obj == null ) + { + // Was nicht da ist, laesst sich auch nicht verschieben. + error_log('WEBDAV: COPY request, but Source not found'); + $this->httpMethodNotAllowed(); + } + 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->httpMethodNotAllowed(); + } + 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->httpMethodNotAllowed(); + } + elseif ( is_object($destinationObject) && $destinationObject->isLink) + { + Logger::debug('WEBDAV: COPY request denied, Link copy not implemented'); + $this->httpMethodNotAllowed(); + } + elseif ( is_object($destinationObject) && $destinationObject->isPage) + { + Logger::debug('WEBDAV: COPY request denied, Page copy not implemented'); + $this->httpMethodNotAllowed(); + } + 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' ); + } + } + + } + + +} diff --git a/dav/method/DELETE.class.php b/dav/method/DELETE.class.php @@ -0,0 +1,56 @@ +<?php + +class DAV_DELETE extends WebDAV +{ + + + /** + * Objekt l�schen. + */ + public function execute() + { + 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 + } + + } + } + +} diff --git a/dav/method/GET.class.php b/dav/method/GET.class.php @@ -0,0 +1,152 @@ +<?php + +class DAV_GET extends WebDAV +{ + + /** + * WebDav-GET-Methode. + * Die gew�nschte Datei wird geladen und im HTTP-Body mitgeliefert. + */ + public function execute() + { + switch( $this->request->type ) + { + 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->request->type.'</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->request->objectid ); + echo 'url: ' .$link['url'] ."\n"; + echo 'target-id: '.$link['linkedObjectId']."\n"; + + break; + + case 'file': + case 'image': + case 'text': + $this->httpStatus( '200 OK' ); + + $file = $this->client->file ( $this->request->objectid ); + $filevalue = $this->client->filevalue( $this->request->objectid ); + + header('Content-Type: '.$file['mimetype']); + header('X-File-Id: ' .$this->request->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 $filevalue; + + break; + + default: + $this->httpStatus( '200 OK' ); + header('Content-Type: text/html'); + + echo '<html><head><title>OpenRat WEBDAV Access</title></head>'; + echo '<body>'; + echo '<h1>'.$this->request->type.'</h1>'; + echo '<pre>'; + echo 'Unknown node type: '.$this->request->type; + echo '</pre>'; + echo '</body>'; + echo '</html>'; + break; + + + } + } + + + + + /** + * Erzeugt ein Unix-�hnliche Ausgabe des Verzeichnisses als HTML. + */ + protected function getDirectoryIndex() + { + $this->httpStatus( '200 OK' ); + + // Verzeichnis ausgeben + header('Content-Type: text/html'); + $nl = "\n"; + + + + + $titel = 'Index of '.htmlspecialchars($this->sitePath); + $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->request->type ) + { + 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->request->objectid ); + + foreach( $folder['content']['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>'; + } + + + + +} diff --git a/dav/method/HEAD.class.php b/dav/method/HEAD.class.php @@ -0,0 +1,32 @@ +<?php + +class DAV_HEAD extends WebDAV +{ + + /** + * WebDav-HEAD-Methode. + */ + public function execute() + { + if ( ! $this->request->objectid ) + { + $this->httpStatus( '404 Not Found' ); + } + elseif ( $this->request->type == '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' ); + } + } +} diff --git a/dav/method/LOCK.class.php b/dav/method/LOCK.class.php @@ -0,0 +1,16 @@ +<?php + +class DAV_LOCK extends WebDAV +{ + /** + * 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 execute() + { + $this->httpStatus('412 Precondition failed'); + $this->davOPTIONS(); + } +} diff --git a/dav/method/MKCOL.class.php b/dav/method/MKCOL.class.php @@ -0,0 +1,42 @@ +<?php + +class DAV_MKCOL extends WebDAV +{ + + /** + * Verzeichnis anlegen. + */ + public function execute() + { + + if ( !empty($this->data) ) + { + $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->sitePath); + $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->httpMethodNotAllowed(); + } + } + +} diff --git a/dav/method/MOVE.class.php b/dav/method/MOVE.class.php @@ -0,0 +1,97 @@ +<?php + +class DAV_MOVE extends WebDAV +{ + /** + * 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 execute() + { + 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->httpMethodNotAllowed(); + 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->httpMethodNotAllowed(); + 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' ); + } + } +} diff --git a/dav/method/OPTIONS.class.php b/dav/method/OPTIONS.class.php @@ -0,0 +1,20 @@ +<?php + +class DAV_OPTIONS extends WebDAV +{ + + /** + * HTTP-Methode OPTIONS.<br> + * <br> + * Es werden die verfuegbaren Methoden ermittelt und ausgegeben. + */ + public function execute() + { + 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' ); + } +} diff --git a/dav/method/POST.class.php b/dav/method/POST.class.php @@ -0,0 +1,16 @@ +<?php + +class DAV_POST extends WebDAV +{ + + /** + * Die Methode POST ist bei WebDav nicht sinnvoll.<br> + * <br> + * Ausgabe von HTTP-Status 405 (Method Not Allowed) + */ + public function execute() + { + // Die Methode POST ist bei Webdav nicht sinnvoll. + $this->httpMethodNotAllowed(); + } +} diff --git a/dav/method/PROPFIND.class.php b/dav/method/PROPFIND.class.php @@ -0,0 +1,202 @@ +<?php + +class DAV_PROPFIND extends WebDAV +{ + + /** + * 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 execute() + { + switch( $this->request->type ) + { + 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->sitePath; + $objektinhalt['displayname' ] = ''; + $objektinhalt['type'] = 'folder'; + + $inhalte[] = $objektinhalt; + + try { + $result = $this->client->projectlist(); + } catch( Exception $e) { + Logger::error($e->__toString().$this->client->__toString()); + throw $e; + } + $projects = $result['projects']; + foreach( $projects as $projectid=>$p ) + { + $objektinhalt = array(); + $objektinhalt['createdate' ] = TIME_20000101; + $objektinhalt['lastchangedate'] = TIME_20000101; + $objektinhalt['size' ] = 1; + $objektinhalt['name' ] = $this->sitePath.$p['name'].'/'; + $objektinhalt['displayname' ] = $p['name']; + $objektinhalt['type'] = 'folder'; + $inhalte[] = $objektinhalt; + } + + $this->multiStatus( $inhalte ); + break; + + case 'folder': // Verzeichnisinhalt + + $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->sitePath; + $objektinhalt['displayname' ] = $folder['properties']['filename']; + $objektinhalt['type' ] = 'folder'; + $objektinhalt['size' ] = 0; + + $inhalte[] = $objektinhalt; + + if ( $this->depth > 0 ) + { + + foreach( $folder['content']['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->sitePath.$object['filename'].'/'; + $objektinhalt['type'] = 'folder'; + $objektinhalt['size'] = 0; + $inhalte[] = $objektinhalt; + break; + case 'file': + 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->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->sitePath.$object['filename']; + $objektinhalt['type'] = 'file'; + $objektinhalt['size'] = 0; + $inhalte[] = $objektinhalt; + break; + default: + } + } + } + $this->multiStatus( $inhalte ); + break; + + case 'page': + $page = $this->client->page( $this->request->objectid ); + $prop = $page['properties']; + $objektinhalt = array(); + $objektinhalt['name'] = $this->sitePath; + $objektinhalt['displayname'] = $prop['filename']; + $objektinhalt['createdate' ] = $prop['date']; + $objektinhalt['lastchangedate'] = $prop['date']; + + $objektinhalt['size' ] = 0; + $objektinhalt['type' ] = 'file'; + + $this->multiStatus( array($objektinhalt) ); + + break; + + case 'file': + case 'text': + case 'image': + $file = $this->client->file( $this->request->objectid ); + $objektinhalt = array(); + $objektinhalt['name'] = $this->sitePath; + $objektinhalt['displayname'] = $file['filename']; + $objektinhalt['createdate' ] = $file['date']; + $objektinhalt['lastchangedate'] = $file['date']; + + $objektinhalt['size' ] = $file['size']; + $objektinhalt['type' ] = 'file'; + + $this->multiStatus( array($objektinhalt) ); + + break; + + case 'link': + + $link = $this->client->link( $this->request->objectid ); + + $objektinhalt = array(); + $objektinhalt['name'] = $this->sitePath; + $objektinhalt['displayname'] = $link['filename']; + $objektinhalt['createdate' ] = $link['date']; + $objektinhalt['lastchangedate'] = $link['date']; + + $objektinhalt['size' ] = 0; + $objektinhalt['type' ] = 'file'; + + + $this->multiStatus( array($objektinhalt) ); + + break; + + case 'url': + + $link = $this->client->link( $this->request->objectid ); + + $objektinhalt = array(); + $objektinhalt['name'] = $this->sitePath; + $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->request->type); + $this->httpStatus('500 Internal Server Error'); + } + } +} diff --git a/dav/method/PROPPATCH.class.php b/dav/method/PROPPATCH.class.php @@ -0,0 +1,16 @@ +<?php + +class DAV_PROPPATCH extends WebDAV +{ + + /** + * Webdav-Methode PROPPATCH ist nicht implementiert. + */ + public function execute() + { + // TODO: Multistatus erzeugen. + // Evtl. ist '409 Conflict' besser? + $this->httpMethodNotAllowed(); + } + +} diff --git a/dav/method/PUT.class.php b/dav/method/PUT.class.php @@ -0,0 +1,64 @@ +<?php + +class DAV_PUT extends WebDAV +{ + + + /** + * 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 execute() + { + // TODO: 409 (Conflict) wenn übergeordneter Ordner nicht da. + + if ( $this->readonly ) + { + $this->httpMethodNotAllowed(); + } + 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->request->objectid ) + { + // Neue Datei anlegen + if ( !$this->create ) + { + Logger::warn('WEBDAV: Creation of files not allowed by configuration' ); + $this->httpStatus('405 Not Allowed' ); + } + + $this->client->fileAdd( $this->data ); + $this->httpStatus('201 Created'); + return; + } + elseif ( $this->request->objectid ) + { + // Bestehende Datei ueberschreiben. + $id = $this->request->objectid; + $this->client->fileAdd( $id,$this->data ); + + $this->httpStatus('204 No Content'); + return; + } + elseif ( $this->obj->isFolder ) + { + Logger::error('PUT on folder is not supported, use PROPFIND. Lame client?' ); + $this->httpMethodNotAllowed(); + } + else + { + // Fuer andere Objekttypen (Links, Seiten) ist kein PUT moeglich. + Logger::warn('PUT only available for files. Pages and links are ignored' ); + $this->httpMethodNotAllowed(); + } + } + + +} diff --git a/dav/method/UNLOCK.class.php b/dav/method/UNLOCK.class.php @@ -0,0 +1,18 @@ +<?php + +class DAV_UNLOCK extends WebDAV +{ + + + /** + * 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 execute() + { + $this->httpStatus('412 Precondition failed'); + $this->davOPTIONS(); + } +}