Skip to content

Commit

Permalink
Update php_fastcgi.md for Caddy 2.9 (#443)
Browse files Browse the repository at this point in the history
  • Loading branch information
dunglas authored Jan 9, 2025
1 parent 7b80cfe commit 8c83f56
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/docs/markdown/caddyfile/directives/php_fastcgi.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,18 @@ The `php_fastcgi` directive (without subdirectives) is the same as the following
```caddy-d
route {
# Add trailing slash for directory requests
# This redirection is automatically disabled if "{http.request.uri.path}/index.php"
# doesn't appear in the try_files list
@canonicalPath {
file {path}/index.php
not path */
}
redir @canonicalPath {http.request.orig_uri.path}/ 308
# If the requested file does not exist, try index files
# If the requested file does not exist, try index files and assume index.php always exists
@indexFiles file {
try_files {path} {path}/index.php index.php
try_policy first_exist_fallback
split_path .php
}
rewrite @indexFiles {file_match.relative}
Expand All @@ -105,15 +108,17 @@ route {

- The first section deals with canonicalizing the request path. The goal is to ensure that requests that target a directory on disk actually have the trailing slash `/` added to the request path, so that only a single URL is valid for requests to that directory.

This is performed by using a request matcher that matches only requests that _don't_ end in a slash, and which map to a directory on disk which contains an `index.php` file, and if it matches, performs a HTTP 308 redirect with the trailing slash appended. So for example, it would redirect a request with path `/foo` to `/foo/` (appending a `/`, to canonicalize the path to the directory), if `/foo/index.php` exists on disk.
This canonicalization occurs only if the `try_files` subdirective contains `{path}/index.php` (the default).

This is performed by using a request matcher that matches only requests that _don't_ end in a slash, and which map to a directory on disk which contains an `index.php` file, and if it matches, performs an HTTP 308 redirect with the trailing slash appended. So for example, it would redirect a request with path `/foo` to `/foo/` (appending a `/`, to canonicalize the path to the directory), if `/foo/index.php` exists on disk.

- The next section deals with performing path rewrites based on whether a matching file exists on disk. This also has the side-effect of remembering the part of the path after `.php` (if the request path had `.php` in it). This is important for Caddy to correctly set the FastCGI environment variables.

- First, it checks if `{path}` is a file that exists on disk. If so, it rewrites to that path. This essentially short-circuits the rest, and makes sure that requests to files that _do exist_ on disk don't get otherwise rewritten (see next steps below). So if for example you have a `/js/app.js` file on disk, then the request to that path will be kept the same.

- Second, it checks if `{path}/index.php` is a file that exists on disk. If so, it rewrites to that path. For requests to a directory like `/foo/` it'll then look for `/foo//index.php` (which gets normalized to `/foo/index.php`), and rewrite the request to that path if it exists. This behaviour is sometimes useful if you're running another PHP app in a subdirectory of your webroot.

- Lastly, it'll rewrite to `index.php` if that file exists (it almost always should for modern PHP apps). This allows your PHP app to handle any request for paths that _don't_ map to files on disk, by using the `index.php` script as its entrypoint.
- Lastly, it'll always rewrite to `index.php` (it almost always exists for modern PHP apps). This allows your PHP app to handle any request for paths that _don't_ map to files on disk, by using the `index.php` script as its entrypoint.

- And finally, the last section is what actually proxies the request to your PHP FastCGI (or PHP-FPM) service to actually run your PHP code. The request matcher will only match requests which end in `.php`, so, any file that _isn't_ a PHP script and that _does_ exist on disk, will _not_ be handled by this directive, and will fall through.

Expand Down

0 comments on commit 8c83f56

Please sign in to comment.