Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: X-Sendfile/X-Accel-Redirect #896

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ You can also run command-line scripts with:
* [The worker mode](https://frankenphp.dev/docs/worker/)
* [Early Hints support (103 HTTP status code)](https://frankenphp.dev/docs/early-hints/)
* [Real-time](https://frankenphp.dev/docs/mercure/)
* [Efficiently Serving Large Static Files](https://frankenphp.dev/docs/x-sendfile/)
* [Configuration](https://frankenphp.dev/docs/config/)
* [Docker images](https://frankenphp.dev/docs/docker/)
* [Deploy in production](docs/production.md)
Expand Down
69 changes: 69 additions & 0 deletions docs/fr/x-sendfile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Servir efficacement les gros fichiers statiques (`X-Sendfile`/`X-Accel-Redirect`)

Habituellement, les fichiers statiques peuvent être servis directement par le serveur web,
mais parfois, il est nécessaire d'exécuter du code PHP avant de les envoyer :
contrôle d'accès, statistiques, en-têtes HTTP personnalisés...

Malheureusement, utiliser PHP pour servir de gros fichiers statiques est inefficace comparé à
à l'utilisation directe du serveur web (surcharge mémoire, diminution des performances...).

FrankenPHP permet de déléguer l'envoi des fichiers statiques au serveur web
**après** avoir exécuté du code PHP personnalisé.

Pour ce faire, votre application PHP n'a qu'à définir un en-tête HTTP personnalisé
contenant le chemin du fichier à servir. FrankenPHP se chargera du reste.

Cette fonctionnalité est connue sous le nom de **`X-Sendfile`** pour Apache, et **`X-Accel-Redirect`** pour NGINX.

Dans les exemples suivants, nous supposons que le "document root" du projet est le répertoire `public/`
et que nous voulons utiliser PHP pour servir des fichiers stockés en dehors du dossier `public/`,
depuis un répertoire nommé `private-files/`.

## Configuration

Tout d'abord, ajoutez la configuration suivante à votre `Caddyfile` pour activer cette fonctionnalité :

```patch
root * public/
# ...

+ # Needed for Symfony, Laravel and other projects using the Symfony HttpFoundation component
+ request_header X-Sendfile-Type x-accel-redirect
+
+ intercept {
+ @accel header X-Accel-Redirect *
+ handle_response @accel {
+ root * private-files/
+ rewrite * {resp.header.X-Accel-Redirect}
+ method * GET
+
+ # Remove the X-Accel-Redirect header set by PHP for increased security
+ header -X-Accel-Redirect
+
+ file_server
+ }
+ }

php_server
```

## PHP simple

Définissez le chemin relatif du fichier (à partir de `private-files/`) comme valeur de l'en-tête `X-Accel-Redirect` :

```php
header('X-Accel-Redirect: file.txt') ;
```

## Projets utilisant le composant Symfony HttpFoundation (Symfony, Laravel, Drupal...)

Symfony HttpFoundation [supporte nativement cette fonctionnalité] (https://symfony.com/doc/current/components/http_foundation.html#serving-files). Il va automatiquement déterminer la bonne valeur pour l'en-tête `X-Accel-Redirect` et l'ajoutera à la réponse.

```php
use Symfony\Component\HttpFoundation\BinaryFileResponse;

BinaryFileResponse::trustXSendfileTypeHeader();
$response = new BinaryFileResponse(__DIR__.'/../private-files/file.txt');

// ...
```
70 changes: 70 additions & 0 deletions docs/x-sendfile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Efficiently Serving Large Static Files (`X-Sendfile`/`X-Accel-Redirect`)

Usually, static files can be served directly by the web server,
but sometimes it's necessary to execute some PHP code before sending them:
access control, statistics, custom HTTP headers...

Unfortunately, using PHP to serve large static files is inefficient compared to
direct use of the web server (memory overload, reduced performance...).

FrankenPHP lets you delegate the sending of static files to the web server
**after** executing customized PHP code.

To do this, your PHP application simply needs to define a custom HTTP header
containing the path of the file to be served. FrankenPHP takes care of the rest.

This feature is known as **`X-Sendfile`** for Apache, and **`X-Accel-Redirect`** for NGINX.

In the following examples, we assume that the document root of the project is the `public/` directory.
and that we want to use PHP to serve files stored outside the `public/` directory,
from a directory named `private-files/`.

## Configuration

First, add the following configuration to your `Caddyfile` to enable this feature:

```patch
root * public/
# ...

+ # Needed for Symfony, Laravel and other projects using the Symfony HttpFoundation component
+ request_header X-Sendfile-Type x-accel-redirect
+
+ intercept {
+ @accel header X-Accel-Redirect *
+ handle_response @accel {
+ root * private-files/
+ rewrite * {resp.header.X-Accel-Redirect}
+ method * GET
+
+ # Remove the X-Accel-Redirect header set by PHP for increased security
+ header -X-Accel-Redirect
+
+ file_server
+ }
+ }

php_server
```

## Plain PHP

Set the relative file path (from `private-files/`) as the value of the `X-Accel-Redirect` header:

```php
header('X-Accel-Redirect: file.txt');
```

## Projects using the Symfony HttpFoundation component (Symfony, Laravel, Drupal...)

Symfony HttpFoundation [natively supports this feature](https://symfony.com/doc/current/components/http_foundation.html#serving-files).
It will automatically determine the correct value for the `X-Accel-Redirect` header and add it to the response.

```php
use Symfony\Component\HttpFoundation\BinaryFileResponse;

BinaryFileResponse::trustXSendfileTypeHeader();
$response = new BinaryFileResponse(__DIR__.'/../private-files/file.txt');

// ...
```
Loading