Sendfile

Sendfile handles static files, allowing the use of authentication and other features, while the server takes care of delivering the content to the end user.

Modules

Module Web Server Website
X-Accel-Redirect nginx X-Accel-Redirect is supported by default in nginx. Note: for security, configure a location {} with the internal directive.
X-LIGHTTPD-send-file & X-Sendfile2 Lighttpd module https://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file
X-Sendfile Apache https://tn123.org/mod_xsendfile/
Simulator Built-in Web Server The built-in simulator in Inphinit applications allows you to partially simulate the X-Accel-Redirect and X-Sendfile headers in a simple way without needing a full server, making development easier.

nginx module

nginx compares this URI with its respective directories, as if it were a normal request. Then, it serves the directory that corresponds to the defined root and the URI passed in the header. Example configuration:

location / { ... location ~ \.php$ { # Replace by your FPM or FastCGI fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; # It helps libraries detect if a resource is available fastcgi_param MOD_X_ACCEL_REDIRECT_ENABLED on; set $inphinit_prefix ""; if ($uri != "/index.php") { set $inphinit_prefix "/public"; } fastcgi_param SCRIPT_FILENAME $realpath_root$inphinit_prefix$fastcgi_script_name; } } location /protected_files { root /path/foo/bar; internal; }

It is also possible to proxy to another server:

location /protected_files { proxy_pass http://127.0.0.2; internal; }

And in scripts you can use the header, as in the example:

$app->action('GET', '/download', function () { if (isLoggedIn()) { header("X-Accel-Redirect: /protected_files/sample.txt"); } });

Using route pattern:

$app->action('GET', '/download/<file:alnum>.txt', function (App $app, array $params) { if (isLoggedIn()) { $name = $params['file']; // From <file:alnum> header("X-Accel-Redirect: /protected_files/{$name}.txt"); } });

Lighttpd module

Example of how to enable it in lighttpd:

fastcgi.server = { ".php" => { "127.0.0.1" => { # .... "allow-x-send-file" => "enable" } } }

Example of use:

use Inphinit\Http\Response; $app->action('GET', '/download/<file:alnum>.txt', function (App $app, array $params) { if (isLoggedIn()) { // Content-Disposition Response::download('download.txt'); header('X-LIGHTTPD-send-file: /path/foo/bar/sample.txt'); } });

Apache module

To define the path it is necessary to modify server config, virtual host, directory contexts. Example:

<VirtualHost ...> ... XSendFilePath /path/foo/bar </VirtualHost>

To enable it, you can do it in any context, including directly in the .htaccess file:

<IfModule mod_negotiation.c> Options -MultiViews </IfModule> XSendFile on # It helps libraries detect if a resource is available SetEnv MOD_X_SENDFILE_ENABLED 1 ...

Example of use:

use Inphinit\Http\Response; $app->action('GET', '/download/<file:alnum>.txt', function (App $app, array $params) { if (isLoggedIn()) { // Content-Disposition Response::download('download.txt'); header('X-Sendfile: /path/foo/bar/sample.txt'); } });

Simulator

Using PHP's built-in web server, it's possible to simulate the X-Accel-Redirect and X-Sendfile headers. No configuration is necessary; simply use the headers. Then, when starting a local server, use ./run serve, allowing the use of:

$app->action('GET', '/download/<file:alnum>.txt', function (App $app, array $params) { if (isLoggedIn()) { $name = $params['file']; header("X-Accel-Redirect: /path/foo/bar/{$name}.txt"); } });

FileResponse class

The Inphinit\Experimental\Http\FileResponse class can also be used to serve files, relying on environment variables to verify module support. These variables typically must be configured manually.

FileResponse::ACCEL (X-Accel-Redirect):

use Inphinit\Experimental\Http\FileResponse; $app->action('GET', '/download/<file:alnum>.txt', function (App $app, array $params) { if (isLoggedIn()) { $handle = new FileResponse($params['file'], 'output.txt'); try { // Try serving it with an X-Accel-Redirect header $handle->send(FileResponse::ACCEL); } catch (\Exception $ee) { echo 'Downloads unavailable.'; } } });

FileResponse::SENDFILE (X-Sendfile):

$handle = new FileResponse($params['file'], 'output.txt'); try { // Try serving it with an X-Sendfile header $handle->send(FileResponse::SENDFILE); } catch (\Exception $ee) { echo 'Downloads unavailable.'; }

Evaluating available modules:

$handle = new FileResponse($params['file'], 'output.txt'); try { // It will try serving with X-Accel-Redirect if available, otherwise it will try using X-Sendfile $handle->send(FileResponse::ACCEL|FileResponse::SENDFILE); } catch (\Exception $ee) { echo 'Downloads unavailable.'; }

Fallback:

The Senfile fallback is an alternative mechanism that should be used only as a last resort and only when absolutely necessary. In the example below, the system first attempts to use X-Accel-Redirect; if that is unavailable, it falls back to X-Sendfile and if neither is supported, it ultimately serves the file directly via PHP:

$handle = new FileResponse($params['file'], 'output.txt'); try { $handle->send(FileResponse::ACCEL|FileResponse::SENDFILE|FileResponse::FALLBACK); } catch (\Exception $ee) { echo 'Downloads unavailable.'; }
Go to homepage
Star us on Github