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).
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().')');
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"];
?>
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
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.
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
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 :(
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.
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"
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"));
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/'
Works for me, thanks!
Thank you for your quick support - works here, too! :+1:
Sorry for the delayed response. For me, this change didn't fix the problem. My fix from this comment above:
https://github.com/sabre-io/Baikal/issues/927#issuecomment-637816380
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