Skip to content
This repository has been archived by the owner on Feb 20, 2019. It is now read-only.

nginx config: Fix Windows WebDav client error 0x80070043 #2668

Closed
wants to merge 6 commits into from
Closed

nginx config: Fix Windows WebDav client error 0x80070043 #2668

wants to merge 6 commits into from

Conversation

adduxa
Copy link
Contributor

@adduxa adduxa commented Oct 11, 2016

Windows native client gives error 0x80070043 "The network name cannot be found." when you creating network drive for ownCloud.
After some researches I figured out problem:
WebDav client sends OPTIONS / HTTP/1.1 request even if target address was /remote.php/webdav/.
So obvious solution is to send 301 redirect to /remote.php/webdav/ for all OPTIONS requests to /.

Network dump before fix:

> OPTIONS / HTTP/1.1
< HTTP/1.1 302 Moved Temporarily
  Location: https://owncloud.example.com/login
> OPTIONS /login HTTP/1.1
< HTTP/1.1 405 Method Not Allowed

Network dump after fix:

> OPTIONS / HTTP/1.1
< HTTP/1.1 301 Moved Permanently
  Location: https://owncloud.example.com/remote.php/webdav/
> OPTIONS /remote.php/webdav/ HTTP/1.1
< HTTP/1.1 401 Unauthorized
> OPTIONS /remote.php/webdav/ HTTP/1.1
  Authorization: Basic BasicAuthTokenHere=
< HTTP/1.1 200 OK

Fix:

location = / {
    if ($request_method = OPTIONS) {
        return 301 $scheme://$server_name/remote.php/webdav/;
    }
}

Windows native WebDav client sends 'OPTIONS / HTTP/1.1' request even if target address is '/remote.php/webdav/'
@mention-bot
Copy link

@adduxa, thanks for your PR! By analyzing the history of the files in this pull request, we identified @carlaschroder and @RealRancor to be potential reviewers.

@ghost
Copy link

ghost commented Oct 12, 2016

Thanks for your PR. Before some one is asking: I have no idea and i also won't touch any Windows (especially their broken WebDAV client). I also don't know the implications of redirecting all OPTIONS requests on / to remove.php/webdav.

IMHO this shouldn't be put into the default config but into somewhere into the wiki.

@adduxa
Copy link
Contributor Author

adduxa commented Oct 12, 2016

@RealRancor, if so, this seems to be the right place to go:
https://doc.owncloud.org/server/9.1/user_manual/files/access_webdav.html

@adduxa
Copy link
Contributor Author

adduxa commented Oct 12, 2016

Some additional information for future investigations

In fact, real behavior is more complicated: it seems like Windows has two different WebDav clients (at least Windows 10) with UserAgents DavClnt and Microsoft-WebDAV-MiniRedir/10.0.14393.

DavClnt client always begin with OPTIONS / request. If it meets 401 Unauthorized response, it goes away and Microsoft-WebDAV-MiniRedir came into place. But if it meets some errors (like 405 Method Not Allowed) - whole process fails with 0x80070043 "The network name cannot be found." error.

Microsoft-WebDAV-MiniRedir client starts procedure from the beginning, and it has no this bug - it sends right OPTIONS /remote.php/webdav/ request.

The problem is Windows first trying to connect with DavClnt, and only if it gets 401 Unauthorized response, switching to Microsoft-WebDAV-MiniRedir.
But if it happens once after startup, then all new WebDav connections to all servers will be executed with Microsoft-WebDAV-MiniRedir until reboot!

So there is another workaround: first connect some other WebDav cloud which works at root directory (/) and then connect ownCloud WebDav without any problems. But it works only until reboot.

@ghost
Copy link

ghost commented Oct 12, 2016

@adduxa There is a recent report about the same issues on oC 9.1.x together with Apache:

owncloud/core#26350

The user there is saying that this worked in older oC versions so it might be possible that this is a bug in oC itself.

@adduxa
Copy link
Contributor Author

adduxa commented Oct 12, 2016

Forgot to attach more verbose network dump:

Before fix:

> OPTIONS / HTTP/1.1                     (DavClnt)
< HTTP/1.1 302 Moved Temporarily
  Location: https://owncloud.example.com/login
> OPTIONS /login HTTP/1.1                (DavClnt)
< HTTP/1.1 405 Method Not Allowed

After fix:

> OPTIONS / HTTP/1.1                     (DavClnt)
< HTTP/1.1 301 Moved Permanently
  Location: https://owncloud.example.com/remote.php/webdav/
> OPTIONS /remote.php/webdav/ HTTP/1.1   (DavClnt)
< HTTP/1.1 401 Unauthorized

> OPTIONS /remote.php/webdav/ HTTP/1.1   (Microsoft-WebDAV-MiniRedir)
< HTTP/1.1 401 Unauthorized
> OPTIONS /remote.php/webdav/ HTTP/1.1   (Microsoft-WebDAV-MiniRedir)
  Authorization: Basic BasicAuthTokenHere=
< HTTP/1.1 200 OK

Connect to some WebDav server binded to root /:

> OPTIONS / HTTP/1.1                     (DavClnt)
< HTTP/1.1 401 Unauthorized

> OPTIONS / HTTP/1.1                     (Microsoft-WebDAV-MiniRedir)
< HTTP/1.1 401 Unauthorized
> OPTIONS / HTTP/1.1                     (Microsoft-WebDAV-MiniRedir)
  Authorization: Basic BasicAuthTokenHere=
< HTTP/1.1 200 OK

Just realize, that WebDav client sends first request to '/', not to '/owncloud/'.
Adding 'location = /' section is unacceptably.
@mmattel
Copy link
Contributor

mmattel commented Nov 10, 2016

@RealRancor
The fix looks valid to me but not tested 👍

@adduxa
suggestion: put your comment: # Fixes Windows WebDav into the location, above the if statement .

@ghost
Copy link

ghost commented Nov 10, 2016

IMHO this is something which should be either put into the documentation wiki or commented out (not enabled by default) in the nginx config.

I won't test nor give a :+1: here as i don't know the implications if all OPTIONS requests to / are redirected to /remote.php/webdav

@mmattel
Copy link
Contributor

mmattel commented Nov 10, 2016

Valid point, beeing part of the official documentation but commented out is fine and very helpful.

# Fixes Windows WebDav client error 0x80070043 "The network name cannot be found."
location = / {
if ($request_method = OPTIONS) {
return 301 $scheme://$server_name/remote.php/webdav/;
Copy link

@ghost ghost Nov 10, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be /remote.php/dav for oC9+

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We talking about WebDav - just files access, not calendar, address book and etc. Even official OC desktop client use /remote.php/webdav/

Copy link

@ghost ghost Nov 10, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the official endpoint since oC9 (for which you have created the PR here). Sync clients still using remote.php/webdav because they still need to support oC8.2 and below. Once oC8.2 is end-of-life the sync client will switch to remote.php/dav

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, now I saw it. Why, then, in the web-interface link with webdav in it?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are in the mid of changing this for oC9.2: owncloud/core#23904

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, in this situation it does not matter - we just should redirect DavClnt somwhere, where server returns 401 Unauthorized code... Hmm.. and what if we will not send 301 Redirect, but 401 Unauthorized at once?
I just test it out and it works! Think it is better solution

We just should redirect DavClnt somwhere, where server returns 401 Unauthorized code.
So it will work if we return it right here.
Make fix working only for Windows DavClnt client UserAgent.
Nginx doesn't allow multiple or nested if statements. So it is little tricky to implement AND-like behavior.
@mmattel
Copy link
Contributor

mmattel commented Nov 11, 2016

Because I do not like IF statements in nginx very much, only where really needed, another suggestion.
I tested it and it works like a charm 😄 (EDIT: works with nginx version since 0.9.0)

Create a file in nginx/conf.d like common_map.conf. All .conf files are read by nginx autimatically (see include in nginx.conf file) and are part of the http block (map needs to be in http not in server or location)

# owncloud: Fixes Windows WebDav client error 0x80070043 "The network name cannot be found."
        map "$http_user_agent:$request_method" $WinWebDav {
                default             0;
                "DavClnt:OPTIONS"   1;
        }

Than add the following to your server block

        location = / {
                # Uncomment if you are going to use Windows WebDav client
                # map for $WinWebDav is found in conf.d/common_map.com
                if ($WinWebDav) { return 401; }
        }

The nice thing here is, that you can add as many map directives as you want and commenting it out is only one line in location and not many.

Info: in map, ":" is used just like delimiter, you can use any other symbol not used in checked variables.
Example:

        map "$A:$B:C" $X {
                default  0;
                "a:b:c"  1;
        }

@adduxa
Copy link
Contributor Author

adduxa commented Nov 11, 2016

This is good replacement for that huge IF-AND statement, I'll remember it. But with the requirement to split the config to a several files things becomes even more complicated.
I think we can remove $request_method = OPTIONS and stay only with $http_user_agent = DavClnt condition since DavClnt always send OPTIONS requests, so we don't have to check it.

We can remove `$request_method = OPTIONS` and stay only with `$http_user_agent = DavClnt` condition since DavClnt always send OPTIONS requests, so we don't have to check it.
@adduxa
Copy link
Contributor Author

adduxa commented Nov 15, 2016

The solution is found in this comment: owncloud/core#26350 (comment)
Microsoft-WebDAV-MiniRedir client is implemented in Windows WebClient service. However, by default it starts "on demand" - only when DavClnt meets something it can't handle.
If the service is stopped manually, requests comes from DavClnt again.
Making this service starts "Automatically" fixes the problem.

Fix:
Control panel -> Administration -> Services -> WebClient -> Startup type -> Automatic

Or in cmd (as admin):

sc config "WebClient" start=auto
sc start "WebClient"

@adduxa adduxa closed this Nov 15, 2016
@ghost
Copy link

ghost commented Nov 15, 2016

@adduxa Thanks for the follow-up information. Maybe something to document in https://doc.owncloud.org/server/latest/user_manual/files/access_webdav.html#known-problems

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants