File viewers don't work - $pathInfo is wrong in remote.php

Nextcloud version: 21.0.0
Operating system and version: Arch Linux
Apache or nginx version: Apache 2.4.46
PHP version: 7.4

The issue you are facing:
When trying to open certain files (e.g. PDF or mp4) in the web UI there is only a black screen and the spinner keeps spinning forever.

I am running the nextcloud docker image nexcloud:21-fpm and all static files are served from the Arch Linux host. Everything works as expected, only the local file preview is not working.

Here is my apache configuration

<VirtualHost *:443>
  DocumentRoot /var/lib/cloud/data
  <Directory /var/lib/cloud/data>
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews
  ServerAdmin webmaster@xxxde
  ErrorLog "/var/log/httpd/cloud.ssl.error_log"
  TransferLog "/var/log/httpd/cloud.ssl.access_log"
  Header always add Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"

  RewriteEngine On
  RewriteCond %{HTTP:Authorization} ^(.*)
  RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
  RewriteRule ^/\.well-known/carddav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]
  RewriteRule ^/\.well-known/caldav https://%{SERVER_NAME}/remote.php/dav/ [R=301,L]

  ProxyPassMatch "^/(.*\.php(/.*)?)$" "fcgi://"

  SSLEngine on
  SSLCertificateFile "/etc/letsencrypt/live/"
  SSLCertificateKeyFile "/etc/letsencrypt/live/"

  <FilesMatch "\.(cgi|shtml|phtml|php)$">
      SSLOptions +StdEnvVars
  BrowserMatch "MSIE [2-5]" \
           nokeepalive ssl-unclean-shutdown \
           downgrade-1.0 force-response-1.0
  CustomLog "/var/log/httpd/ssl_request_log" \
            "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

  ServerSignature On
  SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
  SSLHonorCipherOrder on
  SSLCompression off

When trying to access the files with the plain dav URL it get’s really interesting.
For example this one:

I get an exception saying the app is not installed without any additional info. I have found out this is coming from remote.php line 160 where $app is empty.

$app is empty because $pathInfo (line 129) contains only “/Reasons to use Nextcloud.pdf” and nothing else. When I run the same scenario on another instance not running via docker I get the full path in $pathInfo: “/dav/files/xxx/Reasons to use Nextcloud.pdf”. Apparently the “\OC::$server->getRequest()” yields something which is not correct for some reason.

I have no clue where this is coming from, maybe some misconfiguration of my apache on the Arch Linux host?

I can (temporarily) fix this issue by prepending “/dav/files/username/” to the $pathInfo variable, but that solution is not viable for multiple users.

I have narrowed down the issue to the $_SERVER[‘SCRIPT_NAME’] variable. For some reason this is set to “/remote.php/dav/files/xxx/Nextcloud Manual.pdf” instead of simply “/remote.php”.

When I put a file “test.php” in the server root with a “phpinfo();” I can see that the variable there is correctly set as “/test.php” even when I call the script as “/test.php/a/b/c”.

But when I put a space in the name it fails to properly set the script name. Will investigate how to properly handle spaces in the apache config.

Apparently this is a known bug, soltution is here: PHP :: Bug #74129 :: Incorrect SCRIPT_NAME with apache ProxyPassMatch when spaces are in path.


ProxyFCGISetEnvIf "reqenv('SCRIPT_FILENAME') =~ m|.*${APP_DIR}(/.*)|" SCRIPT_NAME "$1"

to the apache config resolves this issue, just replace ${APP_DIR} with the DocumentRoot folder.