Linux Networking Webserver Windows

Can’t create or delete directories on an NGINX WebDAV server? Here’s how to fix that!

I like NGINX. For the same reasons that make a lot of people like NGINX: it’s lightweight, it’s simple and it is great to set up a reverse proxy. I have it set up on a Raspberry Pi that functions as a reverse proxy and that is collecting statistics for Unsplash and similar stock photo sites. In order to work on these stats-collecting scripts I needed an easy way to connect to the Pi from my Windows machine. And since the Pi is a remote location whatever I chose would have to work via the world wide web. WebDAV seemed like an obvious and solid choice. After about 10 seconds of duckduckgo-ing I found a tutorial on how to set WebDAV up on NGINX (the tutorial has since been taken offline, unfortunately).

Once I had updated the relevant server block and reloaded NGINX I went to testing. Everything seemed to work fine. When I tried to create a new folder, however, I received Windows error 0x8000FFFF. I also tried deleting a folder via WebDAV. The folder disappeared in the Windows Explorer at first but reappeared after refreshing. Since neither the 0x8000FFFF error nor the reappearing folder told me anything about the issue I went to check the NGINX error log.

For the folder creation request the error log stated “MKCOL can create a collection only”. The entry below it said “DELETE “/folder/folder” failed (21: Is a directory)” which did not really tell me anything new since I tried to actually delete a directory. After many more tests using different clients on different operating systems with different results and way too much duckduckgo- and google-ing I found this blog post by Jason LaPorte. He had the issue using Windows and an NGINX WebDAV server. He found out, that the Windows WebDAV client does not adhere to an HTTP speficiation that requires a trailing slash when specifying a directory (“/folder/folder/” rather than “/folder/folder”). Windows does not set a trailing slash for these requests, but NGINX requires HTTP-compliant behaviour. So, Jason created two simple rewrite rules to add the trailing slashes when missing:

if (-d $request_filename) { rewrite ^(.*[^/])$ $1/ break; }
if ($request_method = MKCOL) { rewrite ^(.*[^/])$ $1/ break; }

At this point you might ask your why I basically copy/repost Jasons answer. Rather than looking at NGINX WebDAV module’s source code (which is what Jason did), I googled the error log entries in a thousand different variants without finding a solution. I just happened to stumble upon Jasons blog post while searching for quite different key words. And therein lies the sole reason for this re-post: I wanted to provide an easier way for people like me to find Jasons answer.

P.S.: Thanks Jason!

Once again, my source:

Update 2017–11–05:

While the above solution does work for DELETE and MKCOL requests, it does not work for COPY or MOVE requests as Jason explained in his post:

This solved the problem of creating and deleting directories in Windows! But there was still another problem lurking beneath the surface: the COPY and MOVE methods. See, it was the same problem as above (a lack of a trailing slash), but the destination of the COPY or MOVE is specified in the HTTP “Destination” header. While we can retrieve headers in NGINX (since they are made available in variables, such as “$http_destination”), NGINX provides no way to modify them.

He solved this with a custom PHP script that handles these requests. Unfortunately, the download link for that script does not work anymore. Since I do not feel like writing my own PHP script to handle these requests I switched to using Apache for WebDAV (Apache has much better WebDAV support).

If you don’t want to write custom scripts to make WebDAV work with NGINX either, here are some resources that should help you get WebDAV set up on Apache:

General tutotial on setting up WebDAV on Apache (with authentification): (I skipped the “Create a User”-part) I still had issues with Windows clients using the described Apache config, because Apache would redirect requests for “/folder/folder” (note the missing trailing slash) and then somehow get stuck. This can be fixed by adding “DirectorySlash Off” to the <Directory>-location in the Apache config.

If you are running Apache behind a reverse proxy like I am, you might want to also set up mod_rpaf in order to pass your clients real IP from NGINX to Apache. Simply follow steps 7 and 8 of this tutotrial:

Last but not least, here is a guide on setting up SSL on Apache (in case you want to use https to pass the request to Apache and don’t have SSL set up yet):