Architecture#
This document gives a brief introduction to the WsgiDAV application package (targeted to developers).
WSGI Application Stack#
WsgiDAV is a WSGI application.
WSGI stands for Web Server Gateway Interface, a proposed standard interface between web servers and Python web applications or frameworks, to promote web application portability across a variety of web servers. If you are unfamiliar with WSGI, do take a moment to read the PEP.
As most WSGI applications, WsgiDAV consists of middleware which serve as pre-filters and post-processors, and the actual application.
WsgiDAV implements this WSGI application stack:
<Request>
|
<Server> -> wsgidav_app.WsgiDavApp (container)
|
+-> debug_filter.WsgiDavDebugFilter (middleware, optional)
|
error_printer.ErrorPrinter (middleware)
|
http_authenticator.HTTPAuthenticator (middleware)
| \- Uses a domain controller object
|
dir_browser.WsgiDavDirBrowser (middleware, optional)
|
request_resolver.RequestResolver (middleware)
|
*-> request_server.RequestServer (application)
\- Uses a DAVProvider object
\- Uses a lock manager object
and a property manager object
Note
This is the default stack. Middleware applications and order can be configured using
middleware_stack
option. You can write your own or extend existing
middleware and place it on middleware stack.
See the following sections for details.
Building Blocks#
DAV Providers#

DAV providers are abstractions layers that are used by the
RequestServer
to access and manipulate DAV resources.
All DAV providers must implement a common interface. This is usually done by
deriving from the abstract base class DAVProvider
.
WsgiDAV comes with a DAV provider for file systems, called
FilesystemProvider
. That is why WsgiDAV is a
WebDAV file server out-of-the-box.
There are also a few other modules that may serve as examples on how to plug-in your own custom DAV providers (see also Writing Custom Providers).
Property Managers#

DAV providers may use a property manager to support persistence for dead properties.
WsgiDAV comes with two default implementations, one based on a in-memory dictionary, and a persistent one based on shelve:
prop_man.property_manager.PropertyManager
prop_man.property_manager.ShelvePropertyManager
PropertyManager
is used by default,
but ShelvePropertyManager
can be enabled by
uncommenting two lines in the configuration file.
In addition, this may be replaced by a custom version, as long as the required interface is implemented.
Lock Managers#

DAV providers have a LockManager
to support
exclusive and shared write locking.
The lock manager uses a lock storage implementation for persistence.
WsgiDAV comes with two default implementations, one based on a in-memory dictionary, and a persistent one based on shelve:
lock_storage.LockStorageDict
lock_storage.LockStorageShelve
LockStorageDict
is used by default, but
LockStorageShelve
can be enabled by uncommenting
two lines in the configuration file.
In addition, this may be replaced by a custom version, as long as the required interface is implemented.
Domain Controllers#

A domain controller provides user/password checking for a realm to the HTTPAuthenticator.
WsgiDAV comes with a default implementation that reads a user/password list from the config file.
However, this may be replaced by a custom version, as long as the required interface is implemented.
wsgidav.dc.nt_dc
is an example for such an extension.
SimpleDomainController
Default implementation of a domain controller as used by
HTTPAuthenticator
.
Applications#

WsgiDavApp#
Cors#
Middleware wsgidav.mw.cors.Cors
.
Respond to CORS preflight OPTIONS request and inject CORS headers.
- On init:
Store CORS preferences and prepare header lists.
- For every request:
Add CORS headers to responses.
ErrorPrinter#
Middleware wsgidav.error_printer.ErrorPrinter
.
Handle DAV exceptions and internal errors.
- On init:
Store error handling preferences.
- For every request:
Pass the request to the next middleware. If a DAV exception occurs, log info, then pass it on. Internal exceptions are converted to HTTP_INTERNAL_ERRORs.
HTTPAuthenticator#
Middleware wsgidav.http_authenticator.HTTPAuthenticator
.
Uses a domain controller to establish HTTP authentication.
- On init:
Store the domain controller object that is used for authentication.
- For every request:
if authentication is required and user is not logged in: return authentication response.
Else set these values:
``environ['httpauthentication.realm']`` ``environ['httpauthentication.username']``
WsgiDavDirBrowser#
Middleware wsgidav.dir_browser._dir_browser.WsgiDavDirBrowser
.
Handles GET requests on collections to display a HTML directory listing.
On init:
For every request:
- If path maps to a collection:
Render collection members as directory (HTML table).
RequestResolver#
Middleware wsgidav.request_resolver.RequestResolver
.
Must be configured as last in middleware_stack config option.
Find the mapped DAV-Provider, create a new RequestServer
instance, and dispatch the request.
On init:
Store URL-to-DAV-Provider mapping.
For every request:
Setup
environ["SCRIPT_NAME"]
to request realm and andenviron["PATH_INFO"]
to resource path.Then find the registered DAV-Provider for this realm, create a new
RequestServer
instance, and pass the request to it.Note: The OPTIONS method for ‘*’ is handled directly.
WsgiDavDebugFilter#
RequestServer#
Application wsgidav.request_server.RequestServer
.
Handles one single WebDAV request.
On init:
Store a reference to the DAV-Provider object.
For every request:
Handle one single WebDAV method (PROPFIND, PROPPATCH, LOCK, …) using a DAV-Provider instance. Then return the response body or raise an DAVError.
Note: this object only handles one single request.