Core: Webdav doesn't work behind a reverse proxy with non-root url

Created on 16 Jan 2016  路  11Comments  路  Source: owncloud/core

I try to configure an owncloud docker container (latest) behind an nginx reverse proxy. Using the browser works fine but if I want to sync my calendars via webdav (thunderbird / lightning), I got the following error in /var/www/html/data/owncloud.log:

{"reqId":"oq32Qo79zWIxlrZkpbR+","remoteAddr":"192.168.178.36","app":"caldav","message":"Exception: {\"Message\":\"Requested uri (\/owncloud\/remote.phpp\/caldav\/calendars\/Thomas\/aufgaben\/) is out of base uri (\/owncloud\/remote.php\/caldav\/)\",\"Exception\":\"LogicException\",\"Code\":0,\"Trace\":\"#0 \/var\/www\/html\/3rdparty\/sabre\/dav\/lib\/DAVACL\/Plugin.php(756): SabreHTTP\Request->getPath()\n#1 [internal function]: Sabre\DAVACLPlugin->beforeMethod(Object(SabreHTTP\Request), Object(SabreHTTP\Response))\n#2 \/var\/www\/html\/3rdparty\/sabre\/event\/lib\/EventEmitterTrait.php(105): call_user_func_array(Array, Array)\n#3 \/var\/www\/html\/3rdparty\/sabre\/dav\/lib\/DAV\/Server.php(456): Sabre\Event\EventEmitter->emit('beforeMethod', Array)\n#4 \/var\/www\/html\/3rdparty\/sabre\/dav\/lib\/DAV\/Server.php(254): Sabre\DAV\Server->invokeMethod(Object(SabreHTTP\Request), Object(SabreHTTP\Response))\n#5 \/var\/www\/html\/apps\/calendar\/appinfo\/remote.php(60): Sabre\DAV\Server->exec()\n#6 \/var\/www\/html\/remote.php(137): require_once('\/var\/www\/html\/a...')\n#7 {main}\",\"File\":\"\/var\/www\/html\/3rdparty\/sabre\/http\/lib\/Request.php\",\"Line\":210}","level":4,"time":"2016-01-02T19:03:09+00:00"}

The core error message is:
Exception: Requested uri (/owncloud/remote.phpp/caldav/calendars/Thomas/aufgaben/) is out of base uri (/owncloud/remote.php/caldav)

Very strange is the requested uri - it contains remote.phpp with a double p at the end.
The remotAddr 192.168.178.36 is the IP-adress of the nginx reverse proxy.

The owncloud desktop clients fails with the same error-message. It is therefore not a configuration error in thunderbird.

If I access ownCloud direct (bypassing the reverse proxy) it works fine. It also works if I use the root-url for onwCloud at the proxy.

There must be a problem with the config.php parameter 'overwritewebroot' => '/owncloud'

Most helpful comment

For those who use Apache as a reverse proxy, this is the correct mod_proxy configuration:

# Correct configuration :-)
ProxyPass "/urlToProxy" "http://yourowncloudhost:80"
ProxyPassReverse "/urlToProxy" "http://yourowncloudhost:80"

Make sure you have no trailing / at the end of the second argument. This will not work and produce the error described above:

# Wrong configuration!!!!!
ProxyPass "/urlToProxy" "http://yourowncloudhost:80/"
ProxyPassReverse "/urlToProxy" "http://yourowncloudhost:80/"

All 11 comments

The problem is very likely the remote.phpp bit, I'd suggest you search through your config files both on ownCloud and on the reverse proxy to make sure it's all correct.

You will also get better support for configuration issues like this from https://owncloud.org/support

Yes - looks like config issues

Hi guys, just found this also bug and how to repair (few hours of debuging whats wrong :(). Its not a config problem, its bug in your code. You have to change function GetRequestUri in "lib/private/appframework/http/request.php, from:

        public function getRequestUri() {
                $uri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : '';
                if($this->config->getSystemValue('overwritewebroot') !== '' && $this->isOverwriteCondition()) {
                        $uri = $this->getScriptName() . substr($uri, strlen($this->server['SCRIPT_NAME']));
                }
                return $uri;
        }

to:

        public function getRequestUri() {
                $uri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : '';
                if($this->config->getSystemValue('overwritewebroot') !== '' && $this->isOverwriteCondition()) {
                        $uri = $this->getScriptName() . substr($uri, strlen($this->server['SCRIPT_NAME']) + 1);
                }
                return $uri;
        }

Problem is that missing "+1" in substr function.

Edit: Just +1 is not right for every situation, updated to + strpos($uri, $this->server['SCRIPT_NAME'])

@Morlinest Mind opening a PR and adding a unit test for this? THX.

@LukasReschke Yes, just did it (first time doing it, wasnt sure how but its so easy :D) - #22104

@LukasReschke
Sorry, this is semi bug/config problem. Its bug if u dont have good proxy settings on proxy server.

@thomasreus
Hi, I think, problem can be solved in your proxy settings (if the reason is same as mine). Ive changed rewrite rule on nginx from rewrite ^/owncloud(.*) /$1 break; to rewrite ^/owncloud(.*) $1 break; (there was "/" before "$1", that means URL pased to app looked like "//remote.php/webdav") and its OK now without need to change your owncloud app source code :). Hope this helps.

see also https://github.com/owncloud/core/issues/26350 , i had to rewrite the / OPTIONS request for windows explorer webdav clients from a 302 to a 200 OK, to get it working behind reverse proxy (only the windows explorer as webdav client needs this).

For those who use Apache as a reverse proxy, this is the correct mod_proxy configuration:

# Correct configuration :-)
ProxyPass "/urlToProxy" "http://yourowncloudhost:80"
ProxyPassReverse "/urlToProxy" "http://yourowncloudhost:80"

Make sure you have no trailing / at the end of the second argument. This will not work and produce the error described above:

# Wrong configuration!!!!!
ProxyPass "/urlToProxy" "http://yourowncloudhost:80/"
ProxyPassReverse "/urlToProxy" "http://yourowncloudhost:80/"

@romixch I had a trailing / so that fixed it for me. Thanks!

@Morlinest

To further expand on your rewrite rule for an nginx reverse proxy I have the following Nginx config in a "/owncloud" location block working with Owncloud 10.0.6 running in a Docker container.

rewrite ^/owncloud(.*) $1 break;
proxy_pass https://yourdomain.com:80;

At first I tried using just the proxy_pass entry with a trailing slash:

proxy_pass https://yourdomain.com:80/;

this _appeared_ to work, but got the "requested uri (\/owncloud\/remote.phpp\/webdav) is out of base uri (\/owncloud\/remote.php\/webdav\/)\" error when trying to browse files.

So changing the Nginx reverse proxy config to use the rewrite rule along with the proxy_pass worked well for me!

As a side note that may help others in the future, this is all working with the following entries also being set properly in the ownCloud config.php file:

  'overwritehost'     => 'yourdomain.com',
  'overwriteprotocol' => 'https',
  'overwritewebroot'  => '/owncloud',

Thanks for the help @Morlinest 馃憤

I can confirm this works for nginx:

  location /cloud/ {
    proxy_pass            http://my-cloud-server.de:80/;
    proxy_set_header      Host $host;
    proxy_set_header      X-Real-IP $remote_addr;
    proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;
  }

Was this page helpful?
0 / 5 - 0 ratings

Related issues

michaelstingl picture michaelstingl  路  5Comments

j-holub picture j-holub  路  3Comments

fridaynext picture fridaynext  路  5Comments

michaelstingl picture michaelstingl  路  3Comments

gxgani picture gxgani  路  5Comments