File stored in S3-compatible storage can't be download or viewed in PHP 8.2
System Info
- PHP Version: Affect 8.2 only (also tested in 7.4.26 / 8.0.25 / 8.1.19)
- XBackBone Version: 3.6.3
- Webserver: Nginx from linuxserver/docker-nginx
- Database backend: SQLite
- S3 Backend: Cloudflare R2
Describe the bug XBackBone returns 502 when downloading / view file as raw in PHP 8.2.
To Reproduce Steps to reproduce the behavior:
- Create a bucket in Cloudflare R2 and a R2 API token with Edit permission.
- 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;
}
}
- 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,
);
- Update a random txt file to XBackBone
- Preview the txt on XBackBone (https://example.com/UID/FID.txt)
- View as the txt raw on XBackBone (https://example.com/UID/FID.txt/raw)
- 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.
Got the same issue.
Same issue.