Configuration¶
This document describes the configuration options of a WsgiDAV server.
The WsgiDAVApp object is configured by passing
a Python dict with distinct options, that define
Server options (hostname, port, SSL cert, …)
List of share-name / WebDAV provider mappings
Optional list of users for authentication
Optional custom DAV providers (i.e. other than
FilesystemProvider)Optional custom lock manager, property manager and domain controller
Advanced debugging options
(and more)
This section shows the available options and defaults:
1# (c) 2009-2024 Martin Wendt and contributors; see WsgiDAV https://github.com/mar10/wsgidav
2# Original PyFileServer (c) 2005 Ho Chun Wei.
3# Licensed under the MIT license:
4# http://www.opensource.org/licenses/mit-license.php
5r"""
6::
7
8 _ __ _ ___ ___ _ __
9 | | /| / /__ ___ (_) _ \/ _ | | / /
10 | |/ |/ (_-</ _ `/ / // / __ | |/ /
11 |__/|__/___/\_, /_/____/_/ |_|___/
12 /___/
13
14Default configuration.
15"""
16
17# from wsgidav.mw.debug_filter import WsgiDavDebugFilter
18from wsgidav.dir_browser import WsgiDavDirBrowser
19from wsgidav.error_printer import ErrorPrinter
20from wsgidav.http_authenticator import HTTPAuthenticator
21from wsgidav.mw.cors import Cors
22from wsgidav.request_resolver import RequestResolver
23
24__docformat__ = "reStructuredText"
25
26# Use these settings, if config file does not define them (or is totally missing)
27DEFAULT_VERBOSE = 3
28DEFAULT_LOGGER_DATE_FORMAT = "%H:%M:%S"
29DEFAULT_LOGGER_FORMAT = "%(asctime)s.%(msecs)03d - %(levelname)-8s: %(message)s"
30
31DEFAULT_CONFIG = {
32 "server": "cheroot",
33 "server_args": {},
34 "host": "localhost",
35 "port": 8080,
36 "mount_path": None, # Application root, e.g. <mount_path>/<share_name>/<res_path>
37 "provider_mapping": {},
38 "fs_dav_provider": {
39 "shadow_map": {},
40 "follow_symlinks": False,
41 },
42 "honor_mtime_header": False,
43 "add_header_MS_Author_Via": True,
44 "default_charset": "utf-8", # e.g. "utf-8"
45 "hotfixes": {
46 "emulate_win32_lastmod": False, # True: support Win32LastModifiedTime
47 "re_encode_path_info": True, # (See issue #73)
48 "unquote_path_info": False, # (See issue #8, #228)
49 # "accept_put_without_content_length": True, # (See issue #10, #282)
50 # "treat_root_options_as_asterisk": False, # Hotfix for WinXP / Vista: accept 'OPTIONS /' for a 'OPTIONS *'
51 # "win_accept_anonymous_options": False,
52 # "winxp_accept_root_share_login": False,
53 },
54 "property_manager": None, # True: use property_manager.PropertyManager
55 "mutable_live_props": [],
56 "lock_storage": True, # True: use LockManager(lock_storage.LockStorageDict)
57 "middleware_stack": [
58 # WsgiDavDebugFilter,
59 Cors,
60 ErrorPrinter,
61 HTTPAuthenticator,
62 WsgiDavDirBrowser, # configured under dir_browser option (see below)
63 RequestResolver, # this must be the last middleware item
64 ],
65 # HTTP Authentication Options
66 "http_authenticator": {
67 # None: dc.simple_dc.SimpleDomainController(user_mapping)
68 "domain_controller": None,
69 "accept_basic": True, # Allow basic authentication, True or False
70 "accept_digest": True, # Allow digest authentication, True or False
71 "default_to_digest": True, # True (default digest) or False (default basic)
72 # Name of a header field that will be accepted as authorized user
73 "trusted_auth_header": None,
74 },
75 #: Used by SimpleDomainController only
76 "simple_dc": {"user_mapping": {}}, # NO anonymous access by default
77 #: Verbose Output
78 #: 0 - no output
79 #: 1 - no output (excepting application exceptions)
80 #: 2 - show warnings
81 #: 3 - show single line request summaries (for HTTP logging)
82 #: 4 - show additional events
83 #: 5 - show full request/response header info (HTTP Logging)
84 #: request body and GET response bodies not shown
85 "verbose": DEFAULT_VERBOSE,
86 #: Suppress version info in HTTP response headers and error responses
87 "suppress_version_info": False,
88 #: Log options
89 "logging": {
90 "enable": None, # True: activate 'wsgidav' logger (in library mode)
91 "logger_date_format": DEFAULT_LOGGER_DATE_FORMAT,
92 "logger_format": DEFAULT_LOGGER_FORMAT,
93 "enable_loggers": [],
94 "debug_methods": [],
95 },
96 #: Options for `WsgiDavDirBrowser`
97 "dir_browser": {
98 "enable": True, # Render HTML listing for GET requests on collections
99 # Add a trailing slash to directory URLs (by generating a 301 redirect):
100 "directory_slash": True,
101 # List of fnmatch patterns:
102 "ignore": [
103 ".DS_Store", # macOS folder meta data
104 "._*", # macOS hidden data files
105 "Thumbs.db", # Windows image previews
106 ],
107 "icon": True,
108 "response_trailer": True, # Raw HTML code, appended as footer (True: use a default)
109 "show_user": True, # Show authenticated user an realm
110 # Send <dm:mount> response if request URL contains '?davmount' (rfc4709)
111 "davmount": True,
112 # Add 'Mount' link at the top
113 "davmount_links": False,
114 "ms_sharepoint_support": True, # Invoke MS Office documents for editing using WebDAV
115 "libre_office_support": True, # Invoke Libre Office documents for editing using WebDAV
116 # The path to the directory that contains template.html and associated assets.
117 # The default is the htdocs directory within the dir_browser directory.
118 "htdocs_path": None,
119 },
120}
When a Python dict is passed to the WsgiDAVApp
constructor, its values will override the defaults from above:
root_path = gettempdir()
provider = FilesystemProvider(root_path, readonly=False, fs_opts={})
config = {
"host": "0.0.0.0",
"port": 8080,
"provider_mapping": {"/": provider},
"verbose": 1,
}
app = WsgiDAVApp(config)
Use a Configuration File¶
When running from the CLI (command line interface), some settings may be passed as arguments, e.g.:
$ wsgidav --host=0.0.0.0 --port=8080 --root=/tmp --auth=anonymous
Serving on http://0.0.0.0:8080 ...
Much more options are available when a configuration file is used.
By default wsgidav.yaml and wsgidav.json are searched in the
local directory.
An alternative file name can be specified like so:
$ wsgidav --config=my_config.yaml
To prevent the use of a local default configuration file, use this option:
$ wsgidav --no-config
The options described below can be defined for the CLI either
Note
The two supported file formats are just different ways for the CLI to
generate a Python dict that is then passed to the
WsgiDAVApp constructor.
The YAML format is recommended.
For a start, copy
YAML Sample Configuration
and edit it to your needs.
(Alternatively use
JSON Sample Configuration.)
Verbosity Level¶
The verbosity level can have a value from 0 to 5 (default: 3):
Verbosity |
Option |
Log level |
Remarks |
|---|---|---|---|
0 |
-qqq |
CRITICAL |
quiet |
1 |
ERROR |
no output (excepting application exceptions) |
|
2 |
-q |
WARN |
warnings and errors only |
3 |
INFO |
show single line request summaries (for HTTP logging) |
|
4 |
-v |
DEBUG |
show additional events |
5 |
-vv |
DEBUG |
show full request/response header info (HTTP Logging) request body and GET response bodies not shown |
Middleware Stack¶
WsgiDAV is built as WSGI application (WsgiDAVApp)
that is extended by a list of middleware components which implement additional
functionality.
This stack is defined as a list of WSGI compliant application instances, e.g.:
from wsgidav.mw.debug_filter import WsgiDavDebugFilter
debug_filter = WsgiDavDebugFilter(wsgidav_app, next_app, config)
conf = {
...
"middleware_stack": [
debug_filter,
...
],
...
}
If the middleware class constructor has a common signature, it is sufficient to
pass the class instead of the instantiated object.
The built-in middleware derives from BaseMiddleware,
so we can simplify as:
from wsgidav.dir_browser import WsgiDavDirBrowser
from wsgidav.mw.debug_filter import WsgiDavDebugFilter
from wsgidav.error_printer import ErrorPrinter
from wsgidav.http_authenticator import HTTPAuthenticator
from wsgidav.request_resolver import RequestResolver
conf = {
...
"middleware_stack": [
WsgiDavDebugFilter,
ErrorPrinter,
HTTPAuthenticator,
WsgiDavDirBrowser,
RequestResolver, # this must be the last middleware item
],
...
}
The middleware stack can be configured and extended. The following example removes the directory browser, and adds a third-party debugging tool:
import dozer
# from wsgidav.dir_browser import WsgiDavDirBrowser
from wsgidav.mw.debug_filter import WsgiDavDebugFilter
from wsgidav.error_printer import ErrorPrinter
from wsgidav.http_authenticator import HTTPAuthenticator
from wsgidav.request_resolver import RequestResolver
# Enable online profiling and GC inspection. See https://github.com/mgedmin/dozer
# (Requires `pip install Dozer`):
dozer_app = dozer.Dozer(wsgidav_app)
dozer_profiler = dozer.Profiler(dozer_app, None, "/tmp")
conf = {
...
"middleware_stack": [
dozer_app,
dozer_profiler,
WsgiDavDebugFilter,
ErrorPrinter,
HTTPAuthenticator,
# WsgiDavDirBrowser,
RequestResolver, # this must be the last middleware item
],
...
}
The stack can also be defined in text files, for example YAML. Again, we can pass an import path for a WSGI compliant class if the signature is known. For third-party middleware however, the constructor’s positional arguments should be explicitly listed:
...
middleware_stack:
- class: dozer.Dozer
args:
- "${application}"
- class: dozer.Profiler
args:
- "${application}"
- null # global_conf
- /tmp # profile_path
- wsgidav.mw.debug_filter.WsgiDavDebugFilter
- wsgidav.error_printer.ErrorPrinter
- wsgidav.http_authenticator.HTTPAuthenticator
- wsgidav.dir_browser.WsgiDavDirBrowser
- wsgidav.request_resolver.RequestResolver
It is also possible to pass options as named args (i.e. ‘kwargs’):
...
middleware_stack:
...
- class: dozer.Profiler
kwargs:
app: "${application}"
profile_path: /tmp
...
Note that the external middleware must be available, for example by calling
pip install Doze, so this will not be possible if WsgiDAV is running from
the MSI installer.
DAVProvider¶
A DAVProvider handles read and write requests for all URLs that start with a given share path.
WsgiDAV comes bundled with FilesystemProvider,
a DAVProvider that serves DAV requests by reading and writing to the server’s
file system.
However, custom DAVProviders may be implemented and used, that publish a
database backend, cloud drive, or any virtual data structure.
The provider_mapping configuration routes share paths to specific
DAVProvider instances.
By default a writable FilesystemProvider is
assumed, but can be forced to read-only.
Note that a DomainController may still restrict access completely or prevent
editing depending on authentication.
Three syntax variants are supported:
<share_path>: <folder_path>: useFilesystemProvider(folder_path)<share_path>: { "root": <folder_path>, "readonly": <bool> }: useFilesystemProvider(folder_path, readonly)<share_path>: { "class": <class_path>, args: [arg, ...], kwargs: {"arg1": val1, "arg2": val2, ... }}Instantiate a custom class (derived fromDAVProvider) using named kwargs.
For example:
provider_mapping:
"/": "/path/to/share1"
"/home": "~"
"/pub":
root: "/path/to/share2"
readonly: true
"/share3":
class: path.to.CustomDAVProviderClass
args:
- pos_arg1
- pos_arg2
kwargs:
path: '/path/to/share3'
another_arg: 42
Property Manager¶
The built-in PropertyManager`.
Possible options are:
Disable locking, by passing
property_manager: null.Enable default storage, which is implemented using a memory-based, not persistent storage, by passing
property_manager: true. (This is an alias forproperty_manager: wsgidav.prop_man.property_manager.PropertyManager)Enable an installed or custom storage
Example: Use a persistent shelve based property storage:
property_manager:
class: wsgidav.prop_man.property_manager.ShelvePropertyManager
storage_path: /path/to/wsgidav_locks.shelve
Lock Manager and Storage¶
The built-in LockManager requires a
LockStorageDict instance.
Possible options are:
Disable locking, by passing
lock_storage: null.Enable default locking, which is implemented using a memory-based, not persistent storage, by passing
lock_storage: true. (This is an alias forlock_storage: wsgidav.lock_man.lock_storage.LockStorageDict)Enable an installed lock storage
A persistent, shelve based LockStorageShelve
is also available:
lock_storage:
class: wsgidav.lock_man.lock_storage.LockStorageShelve
kwargs:
storage_path: /path/to/wsgidav_locks.shelve
Domain Controller¶
The HTTP authentication middleware relies on a domain controller. Currently three variants are supported.
SimpleDomainController¶
The wsgidav.dc.simple_dc.SimpleDomainController allows to authenticate
against a plain mapping of shares and user names.
The pseudo-share "*" maps all URLs that are not explicitly listed.
A value of true can be used to enable anonymous access.
Example YAML configuration:
http_authenticator:
domain_controller: null # Same as wsgidav.dc.simple_dc.SimpleDomainController
accept_basic: true # Pass false to prevent sending clear text passwords
accept_digest: true
default_to_digest: true
simple_dc:
user_mapping:
"*":
"user1":
password: "abc123"
"user2":
password: "qwerty"
"/pub": true
An optional roles list will be passed in environ[“wsgidav.auth.roles”] to downstream middleware. This is currently not used by the provided middleware, but may be handy for custom handlers:
simple_dc:
user_mapping:
"*":
"user1":
password: "abc123"
roles: ["editor", "admin"]
"user2":
password: "abc123"
roles: []
If no config file is used, anonymous authentication can be enabled on the command line like:
$ wsgidav ... --auth=anonymous
which simply defines this setting:
simple_dc:
user_mapping:
"*": true
NTDomainController¶
Allows users to authenticate against a Windows NT domain or a local computer.
The wsgidav.dc.nt_dc.NTDomainController requires basic authentication
and therefore should use SSL.
Example YAML configuration:
ssl_certificate: wsgidav/server/sample_bogo_server.crt
ssl_private_key: wsgidav/server/sample_bogo_server.key
ssl_certificate_chain: None
http_authenticator:
domain_controller: wsgidav.dc.nt_dc.NTDomainController
accept_basic: true
accept_digest: false
default_to_digest: false
nt_dc:
preset_domain: null
preset_server: null
If no config file is used, NT authentication can be enabled on the command line like:
$ wsgidav ... --auth=nt
PAMDomainController¶
Allows users to authenticate against a PAM (Pluggable Authentication Modules), that are at the core of user authentication in any modern linux distribution and macOS.
The wsgidav.dc.pam_dc.PAMDomainController requires basic
authentication and therefore should use SSL.
Example YAML configuration that authenticates users against the server’s known user accounts:
ssl_certificate: wsgidav/server/sample_bogo_server.crt
ssl_private_key: wsgidav/server/sample_bogo_server.key
ssl_certificate_chain: None
http_authenticator:
domain_controller: wsgidav.dc.pam_dc.PAMDomainController
accept_basic: true
accept_digest: false
default_to_digest: false
pam_dc:
service: "login"
allow_users: "all"
#: or "current" for the current user, or a list of user names like deny_users
# deny_users:
# - "root"
# - "daemon"
If no config file is used, PAM authentication can be enabled on the command line like:
$ wsgidav ... --auth=pam-login
Custom Domain Controllers¶
A custom domain controller can be used like so:
http_authenticator:
domain_controller: path.to.CustomDomainController
The constructor must accept two arguments:
def __init__(self, wsgidav_app, config)
Note that this allows the custom controller to read the configuration dict and look for a custom section there.
Cors Middleware¶
The wsgidav.mw.cors.Cors Respond to CORS preflight OPTIONS request and
inject CORS headers.
This middleware is available by default, but needs configuration to be enabled.
A minimal (yet ):
cors:
#: List of allowed Origins or '*'
#: Default: false, i.e. prevent CORS
# allow_origin: null
allow_origin: '*'
This may be too unspecific though. See Cross-Origin Resource Sharing (CORS) .
Annotated YAML configuration:
cors:
#: List of allowed Origins or '*'
#: Default: false, i.e. prevent CORS
allow_origin: null
# allow_origin: '*'
# allow_origin:
# - 'https://example.com'
# - 'https://localhost:8081'
#: List or comma-separated string of allowed methods (returned as
#: response to preflight request)
allow_methods:
# allow_methods: POST,HEAD
#: List or comma-separated string of allowed header names (returned as
#: response to preflight request)
allow_headers:
# - X-PINGOTHER
#: List or comma-separated string of allowed headers that JavaScript in
#: browsers is allowed to access.
expose_headers:
#: Set to true to allow responses on requests with credentials flag set
allow_credentials: false
#: Time in seconds for how long the response to the preflight request can
#: be cached (default: 5)
max_age: 600
#: Add custom response headers (dict of header-name -> header-value items)
#: (This is not related to CORS or required to implement CORS functionality)
add_always:
# 'X-Foo-Header: 'qux'
Sample wsgidav.yaml¶
The YAML syntax is the recommended format to define configuration:
Download Sample Configuration.
1# WsgiDAV configuration file
2#
3# 1. Rename this file to `wsgidav.yaml`.
4# 2. Adjust settings as appropriate.
5# 3. Run `wsgidav` from the same directory or pass file path with `--config` option.
6#
7# See https://wsgidav.readthedocs.io/en/latest/user_guide_configure.html
8#
9# ============================================================================
10# SERVER OPTIONS
11
12#: Run WsgiDAV inside this WSGI server.
13#: Supported servers:
14#: cheroot, ext-wsgiutils, gevent, gunicorn, paste, uvicorn, wsgiref
15#: 'wsgiref' and 'ext_wsgiutils' are simple builtin servers that should *not* be
16#: used in production.
17#: All other servers must have been installed before, e.g. `pip install cheroot`.
18#: (The binary MSI distribution already includes 'cheroot'.)
19#: NOTE: Using 'gunicorn' with more than 1 worker can cause problems with the
20#: in-memory and shelve-based lock storage as both are not safe for concurrent
21#: access. (see issue #332) Instead, you can use 'gunicorn' with multiple `threads`
22#: or try the 'redis' based lock storage (#186).
23#: Default: 'cheroot', use the `--server` command line option to change this.
24
25server: cheroot
26
27#: Server specific arguments, passed to the server. For example cheroot:
28#: https://cheroot.cherrypy.dev/en/latest/pkg/cheroot.wsgi.html#cheroot.wsgi.Server
29# server_args:
30# max: -1
31# numthreads: 10
32# request_queue_size: 5
33# shutdown_timeout: 5
34# timeout: 10
35
36# Server hostname (default: localhost, use --host on command line)
37host: 0.0.0.0
38
39# Server port (default: 8080, use --port on command line)
40port: 8080
41
42# Transfer block size in bytes
43block_size: 8192
44
45#: Add the MS-Author-Via Response Header to OPTIONS command to allow editing
46#: with Microsoft Office (default: true)
47add_header_MS_Author_Via: true
48
49#: Default encoding for text files. #: If null (default), use system default encoding.
50#: Otherwise specify a string like "utf-8". Pass None to prevent '; charset=' header.
51default_charset: 'utf-8'
52
53hotfixes:
54 #: Handle Microsoft's Win32LastModifiedTime property.
55 #: This is useful only in the case when you copy files from a Windows
56 #: client into a WebDAV share. Windows sends the "last modified" time of
57 #: the file in a Microsoft extended property called "Win32LastModifiedTime"
58 #: instead of the standard WebDAV property "getlastmodified". So without
59 #: this config option set to "True", the "last modified" time of the copied
60 #: file will be "now" instead of its original value.
61 #: The proper solution for dealing with the Windows WebDAV client is to use
62 #: a persistent property manager. This setting is merely a work-around.
63 #: NOTE: Works with Win10, can't work with Win7. Other versions untested.
64 emulate_win32_lastmod: false
65 #: Re-encode PATH_INFO using UTF-8 (falling back to ISO-8859-1).
66 #: This seems to be wrong, since per PEP 3333 PATH_INFO is always ISO-8859-1
67 #: encoded (see https://www.python.org/dev/peps/pep-3333/#unicode-issues).
68 #: However it also seems to resolve errors when accessing resources with
69 #: Chinese characters, for example (see issue #73).
70 re_encode_path_info: true
71 #: Force unquoting of PATH_INFO. This should already be done by the WSGI
72 #: Framework, so this setting should only be used to fix unexpected problems
73 #: there (false fixes issue #8, true fixes issue #228).
74 unquote_path_info: false
75 #: Hotfix for WinXP / Vista: accept 'OPTIONS /' for a 'OPTIONS *'
76 #: (default: false)
77 treat_root_options_as_asterisk: false
78
79
80# ----------------------------------------------------------------------------
81# SSL Support
82
83#: The certificate should match the servers hostname, so the bogus certs will
84#: not work in all scenarios.
85#: (Paths can be absolute or relative to this config file.)
86
87# ssl_certificate: 'wsgidav/server/sample_bogo_server.crt'
88# ssl_private_key: 'wsgidav/server/sample_bogo_server.key'
89# ssl_certificate_chain: null
90
91#: Cheroot server supports 'builtin' and 'pyopenssl' (default: 'builtin')
92# ssl_adapter: 'pyopenssl'
93
94# ----------------------------------------------------------------------------
95
96#: Modify to customize the WSGI application stack.
97#: See here for an example how to add custom middlewares:
98#: https://wsgidav.readthedocs.io/en/latest/user_guide_configure.html#middleware-stack
99middleware_stack:
100 - wsgidav.mw.cors.Cors
101 # - wsgidav.mw.debug_filter.WsgiDavDebugFilter
102 - wsgidav.error_printer.ErrorPrinter
103 - wsgidav.http_authenticator.HTTPAuthenticator
104 - wsgidav.dir_browser.WsgiDavDirBrowser
105 - wsgidav.request_resolver.RequestResolver # this must be the last middleware item
106
107# ==============================================================================
108# SHARES
109
110#: Application root, applied before provider mapping shares, e.g.
111#: <mount_path>/<share_name>/<res_path>
112#: Set this to the mount point (aka location) when WsgiDAV is running behind a
113#: reverse proxy.
114#: If set, the mount path must have a leading (but not trailing) slash.
115mount_path: null
116
117#: Route share paths to DAVProvider instances
118#: By default a writable `FilesystemProvider` is assumed, but can be forced
119#: to read-only.
120#: Note that a DomainController may still restrict access completely or prevent
121#: editing depending on authentication.
122#:
123#: The following syntax variants are supported to use FilesystemProvider:
124#: <share_path>: <folder_path>
125#: or
126#: <share_path>: { 'root': <folder_path>, 'readonly': <bool> }
127#:
128#: or instantiate an arbitrary custom class:
129#:
130#: <share_path>: { 'class': <class_path>, args: [<arg>, ...], kwargs: {<arg>: <val>, ...} }
131
132provider_mapping:
133 '/': '/path/to/share1'
134 '/pub':
135 root: '/path/to/share2'
136 readonly: true
137 '/share3':
138 class: path.to.CustomDAVProviderClass
139 args:
140 - foo
141 - 42
142 kwargs:
143 path: '/path/to/share3'
144 another_arg: 42
145
146#: Additional configuration passed to `FilesystemProvider(..., fs_opts)`
147fs_dav_provider:
148 #: Mapping from request URL to physical file location, e.g.
149 #: make sure that a `/favicon.ico` URL is resolved, even if a `*.html`
150 #: or `*.txt` resource file was opened using the DirBrowser
151 # shadow_map:
152 # '/favicon.ico': 'file_path/to/favicon.ico'
153
154 #: Serve symbolic link files and folders (default: false)
155 follow_symlinks: false
156
157#: Set last modification based on timestamp provided by `X-OC-Mtime` header
158honor_mtime_header: false
159
160# ==============================================================================
161# AUTHENTICATION
162http_authenticator:
163 #: Allow basic authentication
164 accept_basic: true
165 #: Allow digest authentication
166 accept_digest: true
167 #: true (default digest) or false (default basic)
168 default_to_digest: true
169 #: Header field that will be accepted as authorized user.
170 #: Including quotes, for example: trusted_auth_header = 'REMOTE_USER'
171 trusted_auth_header: null
172 #: Domain controller that is used to resolve realms and authorization.
173 #: Default null: which uses SimpleDomainController and the
174 #: `simple_dc.user_mapping` option below.
175 #: (See http://wsgidav.readthedocs.io/en/latest/user_guide_configure.html
176 #: for details.)
177 domain_controller: null
178 # domain_controller: wsgidav.dc.simple_dc.SimpleDomainController
179 # domain_controller: wsgidav.dc.pam_dc.PAMDomainController
180 # domain_controller: wsgidav.dc.nt_dc.NTDomainController
181 # domain_controller: wsgidav.dc.htpasswd_dc.HtpasswdDomainController
182 # domain_controller: wsgidav.dc.htdigest_dc.HtdigestDomainController
183
184
185# Additional options for SimpleDomainController only:
186simple_dc:
187 # Access control per share.
188 # These routes must match the provider mapping.
189 # NOTE: Provider routes without a matching entry here, are inaccessible.
190 user_mapping:
191 '*': # default (used for all shares that are not explicitly listed)
192 'user1':
193 password: 'abc123'
194 # Optional: passed to downstream middleware as environ["wsgidav.auth.roles"]
195 roles: ['editor']
196 'user2':
197 password: 'def456'
198 password: 'qwerty'
199 '/pub': true # Pass true to allow anonymous access
200
201# Additional options for NTDomainController only:
202nt_dc:
203 preset_domain: null
204 preset_server: null
205
206# Additional options for PAMDomainController only:
207pam_dc:
208 service: 'login'
209 encoding: 'utf-8'
210 resetcreds: true
211
212# Additional options for HtpasswdDomainController only:
213htpasswd_dc:
214 htpasswd_file: '/path/to/wsgidav.htpasswd'
215
216# Additional options for HtdigestDomainController only:
217htdigest_dc:
218 htdigest_file: '/path/to/wsgidav.htdigest'
219
220
221# ----------------------------------------------------------------------------
222# CORS
223# (Requires `wsgidav.mw.cors.Cors`, which is enabled by default.)
224cors:
225 #: List of allowed Origins or '*'
226 #: Default: false, i.e. prevent CORS
227 allow_origin: null
228 # allow_origin: '*'
229 # allow_origin:
230 # - 'https://example.com'
231 # - 'https://localhost:8081'
232
233 #: List or comma-separated string of allowed methods (returned as
234 #: response to preflight request)
235 allow_methods:
236 # allow_methods: POST,HEAD
237 #: List or comma-separated string of allowed header names (returned as
238 #: response to preflight request)
239 allow_headers:
240 # - X-PINGOTHER
241 #: List or comma-separated string of allowed headers that JavaScript in
242 #: browsers is allowed to access.
243 expose_headers:
244 #: Set to true to allow responses on requests with credentials flag set
245 allow_credentials: false
246 #: Time in seconds for how long the response to the preflight request can
247 #: be cached (default: 5)
248 max_age: 600
249 #: Add custom response headers (dict of header-name -> header-value items)
250 #: (This is not related to CORS or required to implement CORS functionality)
251 add_always:
252 # 'X-Foo-Header: 'qux'
253
254# ----------------------------------------------------------------------------
255# Property Manager
256# null: (default) no support for dead properties
257# true: Use wsgidav.prop_man.property_manager.PropertyManager
258# which is an in-memory property manager (NOT persistent)
259#
260# Example: Use persistent shelve based property manager
261# property_manager:
262# class: wsgidav.prop_man.property_manager.ShelvePropertyManager
263# kwargs:
264# storage_path: 'wsgidav-props.shelve'
265
266property_manager: null
267
268#: Optional additional live property modification
269#: Note: by default live properties like file size and last-modified time are
270#: read-only, but that can be overridden here if the underlying DAV provider
271#: supports it. For now only the FileSystemProvider supports it and only namely
272#: changes to the last-modified timestamp. Enable it with the mutable_live_props
273#: list as below to allow clients to use the utime system call or e.g. the
274#: touch or cp / rsync commands with the preserve-timestamp flags on a mounted
275#: DAV share.
276#: Please note that the timestamp is set on the actual file or directory, so it
277#: is persistent even for in-memory property managers. It should also be noted
278#: that mutable last-modified may not be compliant with the RFC 4918.
279mutable_live_props:
280 # Enable to allow clients to use e.g. the touch or cp / rsync commands with the
281 # preserve-timestamp flags in a mounted DAV share (may be RFC4918 incompliant)
282 - '{DAV:}getlastmodified'
283
284
285# ----------------------------------------------------------------------------
286# Lock Manager Storage
287#
288# null: No lock support
289# true: (default) shortcut for
290# lock_storage: wsgidav.lock_man.lock_storage.LockStorageDict
291#
292# Note that the default LockStorageDict works in-memory, so it is
293# NOT persistent.
294#
295# Example: Use persistent shelve based lock storage:
296# lock_storage:
297# class: wsgidav.lock_man.lock_storage.LockStorageShelve
298# kwargs:
299# storage_path: /path/to/wsgidav_locks.shelve
300#
301# Check the documentation on how to develop custom lock storage.
302
303lock_storage: true
304
305
306# ==============================================================================
307# DEBUGGING
308
309#: Set verbosity level (can be overridden by -v or -q arguments)
310verbose: 3
311
312#: Suppress version info in HTTP response headers and error responses
313suppress_version_info: false
314
315logging:
316 #: Enable logging when using wsgidav in library mode (always on, when running as CLI)
317 enable: null
318 #: Set logging output format
319 #: (see https://docs.python.org/3/library/logging.html#logging.Formatter)
320 logger_date_format: '%H:%M:%S'
321 logger_format: '%(asctime)s.%(msecs)03d - %(levelname)-8s: %(message)s'
322 # Example: Add date,thread id, and logger name:
323 # logger_date_format: '%Y-%m-%d %H:%M:%S'
324 # logger_format: '%(asctime)s.%(msecs)03d - <%(thread)05d> %(name)-27s %(levelname)-8s: %(message)s'
325
326 #: Enable specific module loggers
327 #: E.g. ['lock_manager', 'property_manager', 'http_authenticator', ...]
328 # enable_loggers: ['http_authenticator', ]
329
330 # Enable max. logging for certain http methods
331 # E.g. ['COPY', 'DELETE', 'GET', 'HEAD', 'LOCK', 'MOVE', 'OPTIONS', 'PROPFIND', 'PROPPATCH', 'PUT', 'UNLOCK']
332 debug_methods: []
333
334 # Enable max. logging during litmus suite tests that contain certain strings
335 # E.g. ['lock_excl', 'notowner_modify', 'fail_cond_put_unlocked', ...]
336 debug_litmus: []
337
338
339# ----------------------------------------------------------------------------
340# WsgiDavDirBrowser
341
342dir_browser:
343 enable: true
344 #: List of fnmatch patterns that will be hidden in the directory listing
345 ignore:
346 - '.DS_Store' # macOS folder meta data
347 - 'Thumbs.db' # Windows image previews
348 - '._*' # macOS hidden data files
349 #: Add a trailing slash to directory URLs (by generating a 301 redirect)
350 directory_slash: true
351 #: Display WsgiDAV icon in header
352 icon: true
353 #: Raw HTML code, appended as footer (true: use a default trailer)
354 response_trailer: true
355 #: Display the name and realm of the authenticated user (or 'anomymous')
356 show_user: true
357 show_logout: true
358 #: Send <dm:mount> response if request URL contains '?davmount'
359 #: (See https://tools.ietf.org/html/rfc4709)
360 davmount: true
361 #: Add a 'Mount' link at the top of the listing
362 davmount_links: false
363 #: Invoke MS Office documents for editing using WebDAV by adding a JavaScript
364 #: click handler.
365 #: - For IE 11 and below invokes the SharePoint ActiveXObject("SharePoint.OpenDocuments")
366 #: - If the custom legacy Firefox plugin is available, it will be used
367 #: https://docs.microsoft.com/en-us/previous-versions/office/developer/sharepoint-2010/ff407576(v%3Doffice.14)
368 #: - Otherwise the Office URL prefix is used (e.g. 'ms-word:ofe|u|http://server/path/file.docx')
369 ms_sharepoint_support: true
370 #: Invoke Libre Office documents for editing using WebDAV
371 libre_office_support: true
372 #: The path to the directory that contains template.html and associated
373 #: assets.
374 #: The default is the htdocs directory within the dir_browser directory.
375 htdocs_path: null
Sample wsgidav.json¶
We can also use a JSON file for configuration. The structure is identical to the YAML format.
See the ./sample_wsgidav.json example. (Note that the parser allows JavaScript-style comments)
Configuration Tips¶
Running Behind a Reverse Proxy¶
If WsgiDAV is running behind a reverse proxy, …
For example, when nginx is used to expose the
local WsgiDAV share http://127.0.0.1:8080/public_drive as
http://example.com/drive, the configuration files may look like this:
wsgidav.yaml
host: 127.0.0.1
port: 8080
mount_path: "/drive"
provider_mapping:
"/public_drive": # Exposed as http://HOST/drive by nginx reverse proxy
root: "fixtures/share"
nginx.conf:
http {
...
server {
listen 80;
server_name example.com;
...
location /drive/ {
proxy_pass http://127.0.0.1:8080/public_drive/;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
}
# If dir browser is enabled for WsgiDAV:
location /drive/:dir_browser/ {
proxy_pass http://127.0.0.1:8080/:dir_browser/;
}
See the nginx docs for details.