UNIXwork

WsgiDAV - ein einfacher WebDAV-Server

30. Oktober 2022

WsgiDAV ist ein in Python geschriebener WebDAV-Server, der sowohl stand-alone über HTTP oder über WSGI in Kombination mit einem Webserver verwendet werden kann. Die Feature-Liste beinhaltet:

Was mich natürlich interessiert ist, ob Dead Properties richtig funktionieren und XML-Namespaces korrekt behandelt werden (nicht so wie bei anderen). Dazu habe ich aus dem WebDAV-RFC den Beispiel-Request aus Section 9.2.2 ausgeführt.

<?xml version="1.0" encoding="utf-8" ?>
<D:propertyupdate xmlns:D="DAV:"
	 xmlns:Z="http://ns.example.com/standards/z39.50/">
<D:set>
 <D:prop>
   <Z:Authors>
	 <Z:Author>Jim Whitehead</Z:Author>
	 <Z:Author>Roy Fielding</Z:Author>
   </Z:Authors>
 </D:prop>
</D:set>
<D:remove>
 <D:prop><Z:Copyright-Owner/></D:prop>
</D:remove>
</D:propertyupdate>

Dieser speichert eine Property mit XML-Werten, die Namespace-Definition dazu ist allerdings im Root-Element, nicht im Property-Element Z:Authors. Einige Server-Implementierungen haben mit dieser Art Request Probleme. WsgiDAV hingegen verarbeitet dies problemlos. Man muss allerdings dazu sicherstellen, dass Dead Properties aktiviert sind und persistent gespeichert werden. Dazu muss der property_manager konfiguriert sein:

# Property Manager
# null: (default) no support for dead properties
# true: Use wsgidav.prop_man.property_manager.PropertyManager
#       which is an in-memory property manager (NOT persistent)
#
# Example: Use persistent shelve based property manager
property_manager:
    	class: wsgidav.prop_man.property_manager.ShelvePropertyManager
    	kwargs:
        	storage_path: 'wsgidav-props.shelve'

Ein anderer Test von mir war dav-sync. Auch dies funktioniert problemlos. Bisher war meine Empfehlung für einen Server für dav-sync in der Regel Apache. Wer einen anderen Webserver benutzt, dem kann ich hiermit jetzt WsgiDAV empfehlen.

Autor: Olaf | 0 Kommentare | Tags: webdav, dav

dav 1.3 veröffentlicht

15. Dezember 2019

Bestimmt über ein Jahr später als geplant kann ich nun endlich eine neue Version von dav veröffentlichen. Dabei handelt es sich um einen WebDAV-Client für die Kommandozeile. Ebenfalls dabei ist das Programm dav-sync, welches Dateien per WebDAV synchronisieren kann.

Die Ursache der Verzögerung ist eine Geschichte für sich, die Kurzfassung ist, dass ich versucht habe, zu viele Features in das Release zu packen. Diese alle zu stabilisieren hat eine Ewigkeit gedauert.

Doch die positive Folge ist, dass vor allem dav-sync jetzt vermutlich eine der featurereichsten Dateisynchronisierungslösungen ist. War bisher vermutlich das einzige Killerfeature die integrierte Dateiverschlüsselung, hat dav-sync jetzt eine ganze Reihe an Alleinstellungsmerkmalen und dürfte vor allem das Nextcloud-Synctool deutlich in den Schatten stellen.

Die Highlights des neuen Releases sind:

Datei-Versionierung in dav-sync

Ich hatte in dav-sync schon immer Wert auf Datensicherheit gelegt. So gab es schon immer die Möglichkeit, lokale Sicherheitskopien von Dateien automatisch anlegen zu lassen, bevor diese durch einen Synchronisationsvorgang gelöscht oder überschrieben werden. Jetzt gibt es das ganze auch auf Serverseite, denn dav-sync kann nun automatisch auf dem Server alte Datei-Versionen speichern. Dazu gibt es auch einen einfach zu benutzenden Befehl, der lokale Dateien wiederherstellen kann. Versehentlich Dateien löschen oder überschreiben, und dies erst nach diversen Synchronisationsvorgängen merken, ist somit kein Problem mehr.

Datei-Aufteilung in Blöcke für eine partielle Dateisynchronisation

Mir ist aufgefallen, dass praktisch zu jedem Artikel zu Dateisynchronisierungslösungen bei heise jemand im Forum nachfragte, ob auch nur einzelne Dateibestandteile synchronisiert werden können. Bei mehreren Gigabyte großen Dateien möchte man schließlich nicht immer die vollständige Datei uploaden müssen. Dies wird nun von dav-sync unterstützt, in dem Dateien in mehrere Blöcke mit fester Blockgröße aufgeteilt werden können. Synchronisiert werden dann nur die Blöcke, die geändert wurden.

Metadaten- und Symlink-Synchronisation

Neu ist die Möglichkeit, das Dateiänderungsdatum oder Dateiberechtigungen zu synchronisieren. Dies ist vermutlich nicht so ungewöhnlich. Darüber hinaus kann dav-sync jedoch auch Extended Attributes synchronisieren, was vermutlich die wenigsten Tools können. Ebenfalls neu ist die Möglichkeit, Symlinks zu synchronisieren. Bisher wurden sie als normale Dateien behandelt, jetzt können sie von dav-sync selber angelegt werden. Das besondere daran ist auch der Windows-Support, denn Windows hat praktisch keine brauchbaren Symlinks, zumindestens nicht für normale Benutzer. Verbreiteter sind dort Verknüpfungen (.lnk-Dateien), die von dav-sync zu Symlinks übersetzt werden können.

Copy/Move in dav-sync

In dieser Hinsicht hinkte dav-sync etwas hinterher, denn andere Tools konnten schon länger erkennen, wenn Dateien nur umbenannt oder verschoben wurden.

Neue dav-Features

Auch das Tool dav hat ein paar Verbesserungen erhalten. So gibt es jetzt einen Secret-Store, in dem passwortgeschützt Zugangsdaten gespeichert werden können. Neu sind auch ein paar Befehle für WebDAV-Server, die die Versionierungserweiterung DeltaV unterstützen.

Den Quellcode kann man hier downloaden. Auf SourceForge stehen auch Windows-Binaries bereit.

dav Projektseite SourceForge Projektseite

Autor: Olaf | 0 Kommentare | Tags: dav, webdav

Wie man nicht einen WebDAV-Server implementiert

20. Februar 2019

Ich hatte vor, als eine Ergänzung für dav, einen leichtgewichtigen WebDAV-Server zu entwickeln. Wäre gut wenn ich zu dav-sync gleich noch eine kompatible Server-Komponente anbieten kann, denn von verbreiteten Webservern kann eigentlich nur Apache WebDAV richtig. Alternativ könnte man hierfür auch Nextcloud verwenden, aber das will vielleicht auch nicht jeder.

Verwenden wollte ich das Go Package golang.org/x/net/webdav. Bis ich es mir genauer angeschaut habe.

Ein essentielles Feature sind die sogenannten Dead Properties. WebDAV erlaubt es beliebige XML-Werte als Properties in einer Ressource zu speichern. Dummerweise wird dies immer wieder schlecht implementiert. Ein Auszug aus der Dokumentation aus dem Go-Package:

// Property values of complex type or mixed-content must have fully
// expanded XML namespaces or be self-contained with according
// XML namespace declarations. They must not rely on any XML
// namespace declarations within the scope of the XML document,
// even including the DAV: namespace.
InnerXML []byte `xml:",innerxml"`

Es wird gefordert, dass wenn XML-Elemente darin vorkommen, diese ihren Namespace selbst deklarieren. Anders könnte man den Content auch nicht als einfaches Byte-Array speichern.

Man zwingt damit den Client dazu, seine XML-Requests auf besondere Art zu gestalten, die nirgendwo im WebDAV RFC gefordert wird. Es ist sogar so, dass im RFC Beispiele vorhanden sind, die dies schon nicht erfüllen.

Und wieder mal ein Beispiel für "zu faul um XML richtig zu verarbeiten". Leider nicht das erste mal, dass ich das bei einer WebDAV-Implementierung sehe.

Autor: Olaf | 2 Kommentare | Tags: webdav, go, google, rant

WebDAV Locks

20. Dezember 2017

WebDAV kennt zwei Arten von Locks: Exclusive und Shared Locks. Ein Exclusive Lock wird vom Server pro Resource immer nur einem User gestattet. Dies verhindert effektiv, dass andere User eine Ressource überschreiben. Shared Locks hingegen können von mehreren Usern gleichzeitig erhalten werden. Damit sind Shared Locks kein Schutz davor, dass andere eine Ressource überschreiben, sondern sind eher da, um andere Clients zu informieren, dass die Datei gerade in Bearbeitung ist.

Ein Lock bezieht sich entweder auf eine einzelne Ressource, oder auf ganze Collection. Bei letzterem hat man auch die Wahl, ob nur alle direkten Kind-Ressourcen gelockt werden sollen, oder alles was sich unterhalb der gelockten Collection befindet.

Kann ein Client einen Exclusive Lock erfolgreich erstellen, erhält er vom Server ein Locktoken. Dieses Locktoken muss bei allen Schreiboperationen auf die gelockte Resource angegeben werden.

In dav werden bisher nur Exclusive Locks unterstützt. Hierfür gibt es für das Tool dav die Befehle lock und unlock, um Resourcen zu sperren oder zu entsperren. Das Tool dav-sync kann bei Bedarf auch die ganze Collection locken, in dem man die passende Option angibt oder in der Konfigurationsdatei Locking aktiviert.

Um mit dav eine Ressource zu sperren benutzt man den Befehl lock und übergibt die URL der Ressource. Optional kann auch ein Lock-Timeout angegeben werden. Wenn die Ressource erfolgreich gelockt werden konnte, wird auf stdout das Locktoken ausgegeben.

$ dav lock myserv/file.txt
opaquelocktoken:cde48dcb-c860-0512-a770-x38b4f980dbc

Das Locktoken muss man unbedingt irgendwo speichern oder es muss im Terminal zumindestens in Sichtweite bleiben. Denn verliert man das Locktoken ist vor Ablauf des Timeouts kein Schreibzugriff auf die Ressource mehr möglich, was ungünstig bei einem unendlichen Timeout ist. In diesem Fall müsste der Serveradministrator im Webserver den Lock entfernen.

Hat man nun das Locktoken, kann dies bei allen dav-Befehlen, die Schreibvorgänge ausführen, angeben. Also z.B. um eine gelockte Ressource zu überschreiben, gibt man mit der -L Option das Locktoken an:

$ dav put -L opaquelocktoken:cde48dcb-c860-0512-a770-x38b4f980dbc myserv/file.txt localfile.txt

Eine Ressource unlocken kann man mit dem unlock Befehl. Dabei muss auch das Locktoken angegeben werden. Falls nicht mit der -L Option angegeben wird, liest dav von stdin das Locktoken.

$ dav unlock -L opaquelocktoken:cde48dcb-c860-0512-a770-x38b4f980dbc myserv/file.txt

Es ist empfehlenswert, das Locktoken direkt in einer Datei zu speichern.

$ dav lock myserv/file.txt > locktoken
$ dav put -L `cat locktoken` myserv/file.txt uploadthisfile.txt
$ dav unlock myserv/file.txt < locktoken

Um in dav-sync WebDAV-Locks zu nutzen, kann man entweder bei den Synchronisationskommandos (pull, push, archive) die Option -l angeben, oder man aktiviert standardmäßig Locking für das Sync-Verzeichniss, in dem man in der Datei $HOME/.dav/sync.xml innerhalb eines <directory>-Elements folgendes einfügt:

<directory>
	...
	<!-- enable lock for pull command -->
	<lock-pull>true</lock-pull>
	
	<!-- enable lock for push/archive command -->
	<lock-push>true</lock-push>
</directory>

Natürlich ist es auch möglich, nur pull oder nur push mit Lock zu nutzen.

Wenn dav-sync die Collection lockt, wird im Verzeichnis $HOME/.dav temporär eine Datei (locktoken-$syncdir.txt) angelegt, die das Locktoken enthält. Sollte dav-sync unerwartet beendet werden, kann man somit noch manuell die Collection unlocken. Wenn dav-sync sauber terminiert, wird automatisch die Collection entsperrt und die temporäre Datei entfernt.

Autor: Olaf | 0 Kommentare | Tags: dav, webdav

dav 1.1 veröffentlicht

07. Oktober 2017

Es ist an der Zeit für ein dav Minor-Update. Dieses beinhalt hauptsächlich kleine neue Features sowie ein paar Detailänderungen und einen kritischen Bugfix.

Neu bei dav-sync ist, dass der Synchronisationsvorgang mit SIGINT (Ctrl+C) sauber abgebrochen werden kann. Die aktuelle Datei wird noch zuende gedownloadet bzw geuploadet und danach das Programm beendet. Beim nächsten pull/push wird dann der Rest synchronisiert.

Desweiteren gibt es jetzt für dav-sync das archive Kommando, was nur geänderte oder neue Dateien auf den Server uploadet, jedoch keine Dateien auf dem Server löscht.

Neu bei dav ist das remove-property Kommando. Um den Umgang mit Properties zu erleichtern können nun auch XML-Namespaces in der config.xml Datei mit dem neuen <namespace>-Element konfiguriert werden, so dass man bei den Befehlen nur noch einen benutzerdefinierten Prefix angeben muss.

Sowohl dav als auch dav-sync können jetzt auch WebDAV-Locks mit Timeout erstellen.

Eine vollstände Liste der Änderung gibt es in der CHANGELOG-Datei.

Downloads gibt es hier oder auf Sourceforge. Die Dokumentation liegt dem Quellcode bei und ist auch online verfügbar.

Autor: Olaf | 0 Kommentare | Tags: dav, webdav, sync
Weiter