Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Many URLs result in "Requested uri... is out of base uri (/s/html/dav.php)" #927

Closed
nathanzachary opened this issue Jun 2, 2020 · 13 comments · Fixed by #933
Closed

Many URLs result in "Requested uri... is out of base uri (/s/html/dav.php)" #927

nathanzachary opened this issue Jun 2, 2020 · 13 comments · Fixed by #933

Comments

@nathanzachary
Copy link

nathanzachary commented Jun 2, 2020

After a fresh installation of Baikal 0.7.0, I run into many URLs resulting in the following error message / trace:

[Tue Jun 02 14:13:05.529805 2020] [proxy_fcgi:error] [pid 32165:tid 139743908050688] [client 71.81.87.208:38910] AH01071: Got error 'PHP message: LogicException: Requested uri (/html/dav.php) is out of base uri (/s/html/dav.php/) in /var/www/domains/MYDOMAIN/dav/htdocs/vendor/sabre/http/lib/Request.php:184
Stack trace:
#0 /var/www/domains/MYDOMAIN/dav/htdocs/vendor/sabre/dav/lib/DAVACL/Plugin.php(832): Sabre\\HTTP\\Request->getPath()
#1 /var/www/domains/MYDOMAIN/dav/htdocs/vendor/sabre/event/lib/WildcardEmitterTrait.php(89): Sabre\\DAVACL\\Plugin->beforeMethod()
#2 /var/www/domains/MYDOMAIN/dav/htdocs/vendor/sabre/dav/lib/DAV/Server.php(454): Sabre\\DAV\\Server->emit()
#3 /var/www/domains/MYDOMAIN/dav/htdocs/vendor/sabre/dav/lib/DAV/Server.php(251): Sabre\\DAV\\Server->invokeMethod()
#4 /var/www/domains/MYDOMAIN/dav/htdocs/vendor/sabre/dav/lib/DAV/Server.php(319): Sabre\\DAV\\Server->start()
#5 /var/www/domains/MYDOMAIN/dav/htdocs/Core/Frameworks/Baikal/Core/Server.php(119): Sabre\\DAV\\Server->exec()
#6 /var/www/domains/MYDOMAIN/dav/htdocs/html/dav.php(69): Baikal\\Core\\Server->start()
#7 {main}'

I have changed my actual domain to "MYDOMAIN" in the above trace.

The key problem here seems to be that the base uri is showing as /s/html/dav.php, and I'm not certain where the "/s" portion is coming from. I have Baikal installed in the root of a subdomain, but there is no "s" directory there.

I first realised the problem when I tried to go to:

https://dav.MYDOMAIN/html/dav.php/calendars/MYUSERNAME/default

but it happens with many other URLs within the Baikal installation as well. So, I'm not able to connect to a calendar via any client (Thunderbird with Lightning, DAVx5, et cetera).

@nathanzachary
Copy link
Author

The only thing that I can see is that those error messages seem to be coming from sabre:

# grep -Ri 'is out of base uri' ./
./vendor/sabre/http/lib/Request.php: throw new \LogicException('Requested uri ('.$this->getUrl().') is out of base uri ('.$this->getBaseUrl().')');
./vendor/sabre/dav/lib/DAV/Server.php: throw new Exception\Forbidden('Requested uri ('.$uri.') is out of base uri ('.$this->getBaseUri().')');

@ByteHamster
Copy link
Member

Do you use nginx?

Could you please create the file /var/www/domains/MYDOMAIN/dav/htdocs/html/test.php, add the following and then post its output (removing the domain again)?

<?php
echo $_SERVER["SCRIPT_FILENAME"] . "|" . $_SERVER["DOCUMENT_ROOT"];
?>

@nathanzachary
Copy link
Author

Hello there good sir,

Thanks for your response! I don't use nginx. I use Apache with PHP-FPM instead of mod_php. Here's the document root that is listed from the test.php file:

//var/www/domains/MYDOMAIN/dav/htdocs/html/test.php|/var/www/domains/MYDOMAIN/dav/htdocs

@ByteHamster
Copy link
Member

Thanks a lot. This is interesting. Any idea where the duplicate slash in the first path might come from? Maybe a typo in the Apache vhosts file?

I'm not certain where the "/s" portion is coming from

To determine the base uri, Baikal trims the beginning of $_SERVER["SCRIPT_FILENAME"] with the length of $_SERVER["DOCUMENT_ROOT"]. In your case with the duplicate slash, the s from .../htdocs/... is still there.

@nathanzachary
Copy link
Author

nathanzachary commented Jun 2, 2020

So, this is indeed fascinating! I made one change to the vhost here:

# pwd && diff -Nut dav.MYDOMAIN.conf.PRE-20200602_docroot dav.MYDOMAIN.conf
/etc/apache2/vhosts.d/includes
--- dav.MYDOMAIN.conf.PRE-20200602_docroot 2020-06-02 17:23:20.246281195 -0400 +++ dav.MYDOMAIN.conf 2020-06-02 17:20:59.892270352 -0400
@@ -1,7 +1,7 @@
- DocumentRoot "/var/www/domains/MYDOMAIN/dav/htdocs"
+ DocumentRoot "/var/www/domains/MYDOMAIN/dav/htdocs/"

and thereafter, the error goes away. Hundreds of other vhosts are set up the same way (without the trailing slash on the DocumentRoot), and work just fine. So, I'm guessing that the problem is how Baikal is trimming based on length. There must be some way to make it more robust so that Baikal can accommodate a trailing slash or lack thereof.

GREAT find, though, and thanks for helping me figure out the problem!

Cheers,
Nathan Zachary

@ByteHamster
Copy link
Member

Hmm while it is great to hear that this works, the duplicate slash in the beginning of the first path is still pretty strange. If the first path does not have a duplicate slash, DocumentRoot can be written in both ways. I have no idea where that slash comes from, though :(

@nathanzachary
Copy link
Author

If you have anything that you would like me to investigate, please let me know and I'm more than happy to go through my environment to try to figure out the mystery of that duplicate slash. I can even try with some other vhosts and other physical servers.

@tempura-san
Copy link

Hi there - I am just wondering if setting the base URI (formerly via Specific/config.system.php - variable BAIKAL_DAV_BASEURI, similarly for cards and cal) is deprecated? At least I find no hint in the 0.7.0 code how to set this.
I am using NGINX and access via http://<host>/baikal/dav.php/... and according to the logs it chokes on the extra /baikal giving me the same errors (for example):

2020/06/03 00:11:40 [error] 788#788: *64259 FastCGI sent in stderr: "PHP message: LogicException: Requested uri (/baikal/dav.php/calendars/user/holidays/) is out of base uri (/dav.php/) in /var/www/baikal/vendor/sabre/http/lib/Request.php:184
Stack trace:
#0 /var/www/baikal/vendor/sabre/dav/lib/DAVACL/Plugin.php(832): Sabre\HTTP\Request->getPath()
#1 /var/www/baikal/vendor/sabre/event/lib/WildcardEmitterTrait.php(89): Sabre\DAVACL\Plugin->beforeMethod(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))
#2 /var/www/baikal/vendor/sabre/dav/lib/DAV/Server.php(454): Sabre\DAV\Server->emit('beforeMethod:PR...', Array)
#3 /var/www/baikal/vendor/sabre/dav/lib/DAV/Server.php(251): Sabre\DAV\Server->invokeMethod(Object(Sabre\HTTP\Request), Object(Sabre\HTTP\Response))
#4 /var/www/baikal/vendor/sabre/dav/lib/DAV/Server.php(319): Sabre\DAV\Server->start()
#5 /var/www/baikal/Core/Frameworks/Baikal/Core/Server.php(119): Sabre\DAV\Server->exec()
#6 /var/www/baikal/html/dav.php(69): Baikal\Core\Server->start()
#7 {main}" while reading response header from upstream, client: xxx, server: xxx, request: "PROPFIND /baikal/dav.php/calendars/user/holidays/ HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.3-fpm.sock:", host: "xxx"

@Yenya
Copy link

Yenya commented Jun 8, 2020

FWIW, I have the same problem. The above test.php script located at the baikal/html/test.php gives SCRIPT_FILENAME=/var/www/baikal/html/test.php, and DOCUMENT_ROOT=/var/www/html. FWIW, I use Apache 2.4 on Fedora, and I have Baikal outside of the DocumentRoot, with only the baikal/html directory mapped to DocumentRoot using the following in httpd.conf:

Alias /cal/ /var/www/baikal/html/
<Directory /var/www/baikal/html/>
Order deny,allow
Allow from all
</Directory>

I think the code in Core/Frameworks/Flake/Framework.php which determines PROJECT_BASEURI is wrong - it silently assumes that the SCRIPT_FILENAME is below DOCUMENT_ROOT:

        # Determine PROJECT_BASEURI
        $sScript = substr($_SERVER["SCRIPT_FILENAME"], strlen($_SERVER["DOCUMENT_ROOT"]));

Replacing it with hardcoded value works:

        # Determine PROJECT_BASEURI
        $sScript = "/cal/" . substr($_SERVER["SCRIPT_FILENAME"], strlen("/var/www/baikal/html")); 

@ByteHamster
Copy link
Member

Version 0.7.1 was just released with support for setting the base uri. Let me know if it works with your setups :)

baikal.yaml:

system:
    base_uri: '/custom/'

@Yenya
Copy link

Yenya commented Jun 15, 2020

Works for me, thanks!

@tempura-san
Copy link

Thank you for your quick support - works here, too! 👍

@nathanzachary
Copy link
Author

Sorry for the delayed response. For me, this change didn't fix the problem. My fix from this comment above:

#927 (comment)

is still necessary. The trailing slash is still needed in the DocumentRoot. I tried configuring the 'base_uri' in baikal.yaml as both blank and as '/', but neither fixed the problem.

Not a big deal as the fix was easy enough to implement, but thank you for your continued work!

Cheers,
Nathan Zachary

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

Successfully merging a pull request may close this issue.

4 participants