couling / webdav-daemon Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
I ran across this after trying to solve the same issue in nginx - actually I think I responded to your initial question in the unix stack exchange, which probably spurred this development.
I started working on davt ( https://github.com/lsst-dm/davt, see this file specifically: https://github.com/lsst-dm/davt/blob/ded56645e47e8281dc74ffd36d3c12110dab36a8/davt.lua ) a lua module for use in nginx to aid in implementing impersonation per-request.
I had to make davt flexible enough to take UIDs, GIDs, and potentially a list of GIDs to impersonate a user. I haven't thoroughly tested it yet, but it works fine even with the the async/thread pool implementation of nginx (because file descriptors are done in a single process, where the impersonation happens). Probably a similar approach could be done with apache, I'm not sure.
Is chunked download & upload supported?
Usually only chunked download is being supported (to e.g. "watch video only from the middle without downloading the first half of it"), but I'd need also chunked upload support (as a prerequisite to resumable uploads).
Could you clarify on both?
Hi,
While attempting to compile with gcc-10 on Debian testing I get the following issues:
gcc -O3 -s -Werror -Wall -Wno-pointer-sign -Wno-unused-result -std=gnu99 -pthread -MMD -o build/webdavd.o webdavd.c -I/usr/include/libxml2 -c
webdavd.c: In function ‘runServer’:
webdavd.c:1962:14: error: assignment to ‘MHD_AccessHandlerCallback’ {aka ‘enum MHD_Result (*)(void *, struct MHD_Connection *, const char *, const char *, const char *, const char *, unsigned int *, void **)’} from incompatible pointer type ‘int (*)(void *, Request *, const char *, const char *, const char *, const char *, size_t *, void **)’ {aka ‘int (*)(void *, struct MHD_Connection *, const char *, const char *, const char *, const char *, unsigned int *, void **)’} [-Werror=incompatible-pointer-types]
1962 | callback = &answerForwardToRequest;
| ^
webdavd.c:1964:14: error: assignment to ‘MHD_AccessHandlerCallback’ {aka ‘enum MHD_Result (*)(void *, struct MHD_Connection *, const char *, const char *, const char *, const char *, unsigned int *, void **)’} from incompatible pointer type ‘int (*)(void *, Request *, const char *, const char *, const char *, const char *, size_t *, void **)’ {aka ‘int (*)(void *, struct MHD_Connection *, const char *, const char *, const char *, const char *, unsigned int *, void **)’} [-Werror=incompatible-pointer-types]
1964 | callback = &answerToRequest;
| ^
webdavd.c: In function ‘createRap’:
webdavd.c:416:5: error: array subscript 1 is outside array bounds of ‘int[1]’ [-Werror=array-bounds]
416 | stdLogError(errno, "Could not assign new socket (%d) to %d", newSockFd[1],
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
417 | (int) RAP_CONTROL_SOCKET);
| ~~~~~~~~~~~~~~~~~~~~~~~~~
webdavd.c:470:6: note: while referencing ‘socketFd’
470 | int socketFd;
| ^~~~~~~~
cc1: all warnings being treated as errors
make: *** [makefile:14: build/webdavd.o] Error 1
Guessing gcc-10 is a bit more strict and errors.
Cheers,
I noticed, that a "Last-Modified" header is not provided. Applications can use it for caching or other performance reasons. Would be nice to add it. (I will see if I can have a look at it later)
I've setup nginx to proxy a virtual host to webdavd on the same host but another port. This works fine with cadaver.
Creating files with macos as the client works, but hangs. I don't know if it's related to the nginx proxy or not, but I think not. As macos needs class 2 support for write access, and webdavd only supports class 1, obviously no one has tested it with macos without a proxy and found it to work.
It appears to work fine through the PUT
command which creates the file ok. Then there is a PROPFIND
on the newly created file and webdavd doesn't respond.
Here's the logs from nginx:
1.2.3.4 - tpiepho [04/Jun/2021:16:34:35 -0700] "LOCK /davtest/testfile HTTP/1.1" 200 457 "-" "WebDAVFS/3.0.0 (03008000) Darwin/19.6.0 (x86_64)" "-"
1.2.3.4 - tpiepho [04/Jun/2021:16:34:35 -0700] "PUT /davtest/testfile HTTP/1.1" 201 0 "-" "WebDAVFS/3.0.0 (03008000) Darwin/19.6.0 (x86_64)" "-"
2021/06/04 16:35:35 [error] 1776945#0: *443 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 1.2.3.4, server: vhost.server.name, request: "PROPFIND /davtest/testfile HTTP/1.1", upstream: "http://127.0.0.1:30001/davtest/testfile", host: "vhost.server.name"
1.2.3.4 - tpiepho [04/Jun/2021:16:35:35 -0700] "PROPFIND /davtest/testfile HTTP/1.1" 504 167 "-" "WebDAVFS/3.0.0 (03008000) Darwin/19.6.0 (x86_64)" "-"
1.2.3.4 - tpiepho [04/Jun/2021:16:35:35 -0700] "UNLOCK /davtest/testfile HTTP/1.1" 204 0 "-" "WebDAVFS/3.0.0 (03008000) Darwin/19.6.0 (x86_64)" "-"
1.2.3.4 - tpiepho [04/Jun/2021:16:35:35 -0700] "PROPFIND /davtest/testfile HTTP/1.1" 207 460 "-" "WebDAVFS/3.0.0 (03008000) Darwin/19.6.0 (x86_64)" "-"
The key thing to see is that exactly 1 minute after the PUT
, which worked with 201 and created the file, the PROPFIND
fails with 504, gateway timeout, because webdavd failed to respond. Then there is an UNLOCK
, which works, and a PROPFIND
of the same file, which works this time and macos, after the 1 minute timeout, is happy.
The log from webdavd:
Jun 04 2021 16:34:35 127.0.0.1 tpiepho 200 LOCK /davtest/testfile
Jun 04 2021 16:34:35 127.0.0.1 tpiepho 201 PUT /davtest/testfile
Jun 04 2021 16:35:35 127.0.0.1 tpiepho 500 UNLOCK /davtest/testfile
Jun 04 2021 16:35:35 127.0.0.1 tpiepho 207 PROPFIND /davtest/testfile
Jun 04 2021 16:35:35 127.0.0.1 tpiepho 207 PROPFIND /davtest/testfile
Notice here that webdavd responded to TWO PROPFIND
s after the UNLOCK
. The ordering is wrong here, one should be before, one after. Also notice 1st PROPFIND
is one minute after the PUT
.
I checked with wireshark while this was running, actual sequence was LOCK PUT PROPFIND
(one minute delay) UNLOCK PROPFIND
.
It seems like what is happening is the PROPFIND
on a locked file is blocking until the file is unlocked.
Partial work towards locking down the server has broken the default config.
WebDAV-Daemon/package-with/conf.xml
Lines 63 to 65 in 9afaa74
Because of this, the server cannot even create it's own log file to say whats wrong and a default install simply won't start.
Also, the default SSL settings leave port 443 unable to open and port 80 configured as a simple redirect to port 443.
WebDAV-Daemon/package-with/conf.xml
Lines 12 to 53 in 9afaa74
WebDAV-Daemon/package-with/conf.xml
Lines 104 to 117 in 9afaa74
I have create certificate in my server with this command line :
I have put my certificate path in conf file
443
ssl
build/rap
package-with/share
/etc/ssl/private/cert.crt
/etc/ssl/private/cert.key
But in Windows 10 when i put my URL : https://192.168.100.188. It don't work with error "Impossible to open a session in the network".
Nothing logs server side.
It work nice in HTTP.
Thank you for your come back
The issues appears to be that MacOS's finder requires the DAV server to be level 2 with lock support in order to allow write access. Since webdavd reports DAV 1, it will only allow read-only access.
Write access works fine with another client, e.g. cadaver.
Currently the raspberry pi dependencies are broken:
libgnutls-deb0-28
is no-longer available. This should probably be replaced with libgnutls-deb0-30
Add support for RHEL based systems (minimum RHEL8).
Users might need custom headers. Especially, if you want to allow CORS. For example:
Access-Control-Allow-Origin: 'https://www.example.com'
Access-Control-Allow-Headers: 'cache-control'
This could be included in the server section of the config.xml
webdavd.c:81:2: error: unknown type name ‘gnutls_pcert_st’
gnutls_pcert_st * certs;
^
Is it due to some version mismatch?
When an OPTIONS request is received, the server requires authentication. This will cause CORS requests to fail.
See https://www.jujens.eu/posts/en/2015/Jun/27/webdav-options/
Test: curl -i -X OPTIONS https://www.example.com
Result:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="My Server"
Content-Type: text/html
Expectation:
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Length: 0
Accept: OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, LOCK, UNLOCK
Pragma: no-cache
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Expires: Thu, 19 Nov 1980 00:00:00 GMT
Server: couling-webdavd
Accept-Ranges: bytes
DAV: 1
Content-Type: text/html
Hi, I'm looking for a WebDAV server which could handle a storage of several terabytes of data (mainly pics & videos). Therefore I need to be absolutely sure the server supports resumable uploads (e.g. after network connection interruption or after smartphone restart etc.). Is it supported by default by webdavd? If not, could this be implemented?
And btw. do I need to care myself about SSL certificates or does webdavd have something like (optional) Let's Encrypt support like caddy does?
http works well, but https:
$ cadaver https://10.0.1.140:443
....
Username: user
Password:
Could not open collection:
Could not read status line: connection was closed by server
The same with nautilus and dolphin webdav clients.
Distro: ArchLinux
Versions:
webdav-daemon v1.1.r1.bc88ec6-2
libmicrohttpd 0.9.70-3
Config:
<?xml version="1.0" encoding="utf-8" ?>
<server-config xmlns="http://couling.me/webdavd">
<server>
<rap-binary>/usr/bin/rap</rap-binary>
<static-response-dir>/usr/share/webdavd</static-response-dir>
<chroot-path>~</chroot-path>
<listen>
<port>80</port>
<encryption>none</encryption>
</listen>
<listen>
<port>443</port>
<encryption>ssl</encryption>
</listen>
<ssl-cert>
<certificate>/etc/letsencrypt/live/.../cert.pem</certificate>
<key>/etc/letsencrypt/live/.../privkey.pem</key>
</ssl-cert>
</server>
</server-config>
As of PR #21 (later than version 1.1) WebDAV Daemon will report itself as compliance levels 1 and 2 instead of just 1. As far as I'm aware it is not compliant with class 2.
The move to report compliance without actually supporting it correctly was a pragmatic decision to get some clients to interact with the server (see #17 ).
Before the next release this must be fixed. According to RFC 4918 compliance class 2 requires the server MUST:
DAV:supportedlock
property,DAV:lockdiscovery
propertyTime-Out
response headerLock-Token
request header.And SHOULD also support the
Timeout
request headerSorry I am a linux ubuntu noob. I was able to make the binary and config file. However when I go to run it I get a internal server error and it wants to load that error file from usr/share. There isn't a make install so I am not sure where to put everything. Wondering if you can help out with a little more specifics
thanks
Brad
Is it possible to chroot users to their home directories?
To facilitate better testing and builds, I need to get a few docker files created for some environments. See here for examples:
Hello @couling ,
for completeness, I would like to report a webdavd crash. I believe it happened after Microsoft Excel opened a file (from a Win10 machine). Error log:
Aug 16 2021 08:49:22 [2189108] Error: Rejecting request without auth
Aug 16 2021 08:49:22 [2189108] Error: Rejecting request without auth
Aug 16 2021 09:00:25 [2189108] Error: Rejecting request without auth
Aug 16 2021 09:00:25 [2189108] Error: Rejecting request without auth
Aug 16 2021 09:13:50 [2189108] Error: Rejecting request without auth
Aug 16 2021 09:13:51 [2189108] Error: Rejecting request without auth
Aug 16 2021 09:13:51 [2189108] Error: Rejecting request without auth
Aug 16 2021 09:13:51 [2189108] Error: Rejecting request without auth
Aug 16 2021 09:13:59 [2189108] Error: Rejecting request without auth
Aug 16 2021 07:14:00 [2193003] Error: PROPFIND not found stefan /shared/desktop.ini - No such file or directory
Aug 16 2021 07:14:03 [2193017] Error: PROPFIND not found stefan /shared/newfolder/desktop.ini - No such file or directory
Aug 16 2021 07:14:05 [2193019] Error: PROPFIND not found stefan /shared/newfolder/example/desktop.ini - No such file or directory
Aug 16 2021 09:14:11 [2189108] Error: Rejecting request without auth
Aug 16 2021 09:14:11 [2189108] Error: Rejecting request without auth
Aug 16 2021 09:14:11 [2189108] Error: Rejecting request without auth
Aug 16 2021 09:14:12 [2189108] Error: Rejecting request without auth
Aug 16 2021 09:14:20 [2189108] Error: stefan 1778
Aug 16 2021 07:14:20 [2193023] Error: PROPFIND not found stefan /shared/newfolder/example/~$File.ods - No such file or directory
Aug 16 2021 09:15:22 [2189108] Error: stefan 1778
Aug 16 2021 09:16:21 [2189108] Error: Could not receive socket message 16 -1 - Resource temporarily unavailable
Aug 16 2021 07:16:52 [2193017] Error: Could not send socket message - Broken pipe
Aug 16 2021 07:16:52 [2193023] Error: Could not send socket message - Broken pipe
access.log
Aug 16 2021 09:13:50 192.168.0.23 <auth failed> 401 OPTIONS /shared
Aug 16 2021 09:13:51 192.168.0.23 <auth failed> 401 PROPFIND /shared
Aug 16 2021 09:13:51 192.168.0.23 <auth failed> 401 OPTIONS /
Aug 16 2021 09:13:51 192.168.0.23 <auth failed> 401 PROPFIND /
Aug 16 2021 09:13:59 192.168.0.23 <auth failed> 401 PROPFIND /
Aug 16 2021 09:14:00 192.168.0.23 stefan 207 PROPFIND /
Aug 16 2021 09:14:00 192.168.0.23 stefan 207 PROPFIND /
Aug 16 2021 09:14:00 192.168.0.23 stefan 207 PROPFIND /shared
Aug 16 2021 09:14:00 192.168.0.23 stefan 207 PROPFIND /shared
Aug 16 2021 09:14:00 192.168.0.23 stefan 404 PROPFIND /shared/desktop.ini
Aug 16 2021 09:14:03 192.168.0.23 stefan 207 PROPFIND /shared/newfolder
Aug 16 2021 09:14:03 192.168.0.23 stefan 404 PROPFIND /shared/newfolder/desktop.ini
Aug 16 2021 09:14:05 192.168.0.23 stefan 207 PROPFIND /shared/newfolder/example
Aug 16 2021 09:14:05 192.168.0.23 stefan 404 PROPFIND /shared/newfolder/example/desktop.ini
Aug 16 2021 09:14:11 192.168.0.23 <auth failed> 401 OPTIONS /shared/newfolder/
Aug 16 2021 09:14:11 192.168.0.23 <auth failed> 401 OPTIONS /shared/newfolder/
Aug 16 2021 09:14:11 192.168.0.23 <auth failed> 401 OPTIONS /shared/newfolder/
Aug 16 2021 09:14:12 192.168.0.23 <auth failed> 401 OPTIONS /shared/newfolder/
Aug 16 2021 09:14:20 192.168.0.23 stefan 500 OPTIONS /shared/newfolder/
Aug 16 2021 09:14:20 192.168.0.23 stefan 200 GET /shared/newfolder/example/file.ods
Aug 16 2021 09:14:20 192.168.0.23 stefan 207 PROPFIND /shared/newfolder/example/file.ods
Aug 16 2021 09:14:20 192.168.0.23 stefan 200 LOCK /shared/newfolder/example/file.ods
Aug 16 2021 09:14:20 192.168.0.23 stefan 404 PROPFIND /shared/newfolder/example/~$file.ods
Aug 16 2021 09:14:21 192.168.0.23 stefan 201 PUT /shared/newfolder/example/~$file.ods
Aug 16 2021 09:14:21 192.168.0.23 stefan 200 LOCK /shared/newfolder/example/~$file.ods
Aug 16 2021 09:14:21 192.168.0.23 stefan 207 PROPPATCH /shared/newfolder/example/~$file.ods
Aug 16 2021 09:15:22 192.168.0.23 stefan 204 DELETE /shared/newfolder/example/~$file.ods
Aug 16 2021 09:15:23 192.168.0.23 stefan 207 PROPFIND /shared/newfolder/example
Aug 16 2021 09:15:30 192.168.0.23 stefan 200 LOCK /shared/newfolder/example/file.ods
Aug 16 2021 09:16:21 192.168.0.23 stefan 500 PROPFIND /shared/newfolder/example/file.ods
How to set up to support write for macOS? because now it can read-only.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.