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
  ServerName cloud.xxx.de
  <Directory /var/lib/cloud/data>
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews
  </Directory>
  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://127.0.0.1:14589/var/www/html/"

  SSLEngine on
  SSLCertificateFile "/etc/letsencrypt/live/xxx.de/fullchain.pem"
  SSLCertificateKeyFile "/etc/letsencrypt/live/xxx.de/privkey.pem"

  <FilesMatch "\.(cgi|shtml|phtml|php)$">
      SSLOptions +StdEnvVars
  </FilesMatch>
  
  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
  SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
  SSLHonorCipherOrder on
  SSLCompression off
</VirtualHost> 

When trying to access the files with the plain dav URL it get’s really interesting.
For example this one:
https://cloud.xxx.de/remote.php/dav/files/xxx/Reasons%20to%20use%20Nextcloud.pdf

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.

Adding

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.