sergix44 / XBackBone

A lightweight file manager with full ShareX support and more
https://xbackbone.app
GNU Affero General Public License v3.0
993 stars 81 forks source link

File stored in S3-compatible storage can't be download or viewed in PHP 8.2 #536

Open TonyRL opened 1 year ago

TonyRL commented 1 year ago

System Info

Describe the bug XBackBone returns 502 when downloading / view file as raw in PHP 8.2.

To Reproduce Steps to reproduce the behavior:

  1. Create a bucket in Cloudflare R2 and a R2 API token with Edit permission.
  2. Deploy latest (3.6.3-ls99) linuxserver/docker-nginx with reference to the example configuration
    nginx conf
server {

    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;

    root /config/www/xbackbone;

    access_log /config/log/nginx/xbackbone.access.log;
    error_log /config/log/nginx/xbackbone.error.log;

    autoindex off;

    location /app { return 403; }
    location /bin { return 403; }
    location /bootstrap { return 403; }
    location /resources { return 403; }
    location /storage { return 403; }
    location /vendor { return 403; }
    location /logs { return 403; }
    location CHANGELOG.md { return 403; }

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_index index.php;

        include /etc/nginx/fastcgi_params;
    }
}

  1. Configure XBackBone as followed
    XBackBone conf
<?php
return array (
  'base_url' => 'https://example.com',
  'db' => 
  array (
    'connection' => 'sqlite',
    'dsn' => '/app/www/public/resources/database/xbackbone.db',
    'username' => NULL,
    'password' => NULL,
  ),
  'storage' => 
  array (
    'driver' => 's3',
    'path' => '/',
    'key' => '***',
    'secret' => '********',
    'region' => 'auto',
    'endpoint' => 'https://******.r2.cloudflarestorage.com',
    'bucket' => 'xbackbone',
  ),
  'debug' => true,
);

  1. Update a random txt file to XBackBone
  2. Preview the txt on XBackBone (https://example.com/UID/FID.txt)
  3. View as the txt raw on XBackBone (https://example.com/UID/FID.txt/raw)
  4. Download the txt from XBackBone (https://example.com/UID/FID.txt/download)

Expected behavior XBackBone behaves the same as PHP 7.4 / 8.0 / 8.1 which means you can download the file and view as raw.

Screenshots

None.

Logs XBackBone logs (logs/log-2023-06-22.txt)

[2023-06-22 18:23:03] app.INFO: User admin uploaded new media. ["1"] []

nginx logs (xbackbone.error.log)

2023/06/22 18:24:51 [error] 398#398: *6 upstream sent invalid "Content-Length" header: "Content-Length: " while reading response header from upstream, client: 1.2.3.4, server: _, request: "GET /BUPI0/lukuzule41.txt/download HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "example.com", referrer: "https://example.com/home"
2023/06/22 18:47:31 [error] 400#400: *19 upstream sent invalid "Content-Length" header: "Content-Length: " while reading response header from upstream, client: 1.2.3.4, server: _, request: "GET /BUPI0/lukuzule41.txt/download HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "example.com", referrer: "https://example.com/BUPI0/lukuzule41.txt"
2023/06/22 18:48:50 [error] 400#400: *21 upstream sent invalid "Content-Length" header: "Content-Length: " while reading response header from upstream, client: 1.2.3.4, server: _, request: "GET /BUPI0/lukuzule41.txt/raw HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "example.com", referrer: "http://example.com/BUPI0/lukuzule41.txt"

Nothing useful returned in browser (debug is true in XBackBone conf):

502 Bad Gateway
nginx

Quick tests against other PHP version

I've also tested on linuxserver/docker-nginx against different PHP version and the latest linuxserver/xbackbone

PHP 7.4.26 PHP 8.0.25 PHP 8.1.19 PHP 8.2.7 PHP 8.2.7
Image tag linuxserver/docker-nginx:1.20.2-r1-ls191 linuxserver/docker-nginx:1.20.2-r1-ls203 linuxserver/docker-nginx:1.22.1-r0-ls225 linuxserver/docker-nginx:1.24.0-r6-ls228 (latest) linuxserver/xbackbone:3.6.3-ls99 (latest)
Preview (step 5 above) ✔️ ✔️ ✔️ ✔️ ✔️
View as raw (step 6 above) ✔️ ✔️ ✔️
Download (step 7 above) ✔️ ✔️ ✔️

Dirty workaround

https://github.com/SergiX44/XBackBone/blob/0951638dc8e80667cbd9053bf1a6926470d7cc6e/app/Controllers/MediaController.php#L400-L407

 $stream = new Stream($storage->readStream($media->storage_path)); 

 if (!in_array(explode('/', $mime)[0], ['image', 'video', 'audio']) || $disposition === 'attachment') { 
     return $response->withHeader('Content-Type', $mime) 
         ->withHeader('Content-Disposition', $disposition.'; filename="'.$media->filename.'"') 
-         ->withHeader('Content-Length', $stream->getSize()) 
+        // ->withHeader('Content-Length', $stream->getSize())
         ->withBody($stream); 
 } 

This dirty hack works for the random txt file above I uploaded. Files I stored like doc, zip and pdf also works again. I've also tried commenting out (one at a time) other set Content-Length header in L421, L480, L501. Only commenting L405 works in this case.

1drturtle commented 1 year ago

Got the same issue.

kymppi commented 1 year ago

Same issue.