Last active
December 19, 2019 12:57
-
-
Save teameh/126048fba8822450841e2976698ffa82 to your computer and use it in GitHub Desktop.
Silex - Let NGINX handle static files after authentication with PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
server { | |
listen 80; | |
listen [::]:80; | |
server_name example.com; | |
root /var/www/project/web; | |
index index.php; | |
# catches internal redirects from php with 'X-Accel-Redirect' header | |
location /private_admin_files { | |
# and forwards them to this path: | |
alias /var/www/project/src/statics/admin | |
internal; | |
} | |
location / { | |
# Check if requested file is present and use if for procesing. | |
# Otherwise, fall back to index.php | |
try_files $uri /index.php$is_args$args; | |
} | |
location ~ \.php$ { | |
# regex to split $uri to $fastcgi_script_name and $fastcgi_path | |
fastcgi_split_path_info ^(.+\.php)(/.*)$; | |
# Check if requested file is present and use if for procesing. | |
# Otherwise, fall back to index.php | |
try_files $uri /index.php$is_args$args; | |
# Bypass the fact that try_files resets $fastcgi_path_info | |
# see: http://trac.nginx.org/nginx/ticket/321 | |
set $path_info $fastcgi_path_info; | |
# serve index.php in case '/' is requested | |
fastcgi_index index.php; | |
# use socket | |
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; | |
include fastcgi_params; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Silex\Application; | |
use Symfony\Component\HttpFoundation\Response; | |
class StaticFileController | |
{ | |
/** | |
* @param Application $app | |
* @param string $file filename of file to serve | |
* @param string $folder folder of the file to serve | |
* @param string $virtiualXAccelRedirPath virtual X-Accel-Redirect path as used in vhost | |
* | |
* This will return an empty response with the right X-Accel-Redirect header. | |
* NGINX will use this header and will match it's value against all location as defined | |
* in it's vhost. | |
* | |
* For example: | |
* | |
* $file = 'admin.js' | |
* $folder = __DIR__ . '/../statics/admin/' | |
* $virtiualXAccelRedirPath = '/private_admin_files' | |
* | |
* NGINX vhost config has a location block like: | |
* | |
* location /private_admin_files { | |
* alias /path/to/project/src/statics/admin/ | |
* internal; | |
* } | |
* | |
* This method will send a response with | |
* | |
* X-Accel-Redirect: /private_admin_files/admin.js | |
* | |
* And NGINX will rewrite it to | |
* | |
* /path/to/project/src/statics/admin/admin.js internally | |
* | |
* and will serve the requested file without much PHP overhead! | |
* | |
* @return Response | |
*/ | |
public function getFile(Application $app, $file = '', $folder = '', $virtiualXAccelRedirPath = '') | |
{ | |
if (empty($file) || empty($folder) || empty($virtiualXAccelRedirPath)) { | |
$app->abort(400); | |
} | |
// add slash if string does not end in slash | |
if (substr($folder, -1) !== '/') { | |
$folder .= '/'; | |
} | |
if (substr($virtiualXAccelRedirPath, -1) !== '/') { | |
$virtiualXAccelRedirPath .= '/'; | |
} | |
if (!is_readable($folder . $file)) { | |
$app->abort(404, 'file not readible ' . $folder . $file); | |
} | |
switch (strtolower(pathinfo($file, PATHINFO_EXTENSION))) { | |
case 'css' : { | |
$contentType = 'text/css'; | |
break; | |
} | |
case 'js' : { | |
$contentType = 'application/javascript'; | |
break; | |
} | |
case 'xml' : { | |
$contentType = 'text/xml'; | |
break; | |
} | |
case 'svg' : { | |
$contentType = 'image/svg+xml'; | |
break; | |
} | |
default : { | |
$contentType = 'text/plain'; | |
} | |
} | |
return new Response('', 200, [ | |
'X-Accel-Redirect' => $virtiualXAccelRedirPath . $file, | |
'Content-Type' => $contentType | |
]); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use Silex\Application; | |
use Silex\Api\ControllerProviderInterface; | |
use Symfony\Component\HttpFoundation\Request; | |
class Routing implements ControllerProviderInterface | |
{ | |
public function connect(Application $app) | |
{ | |
$controllers = $app['controllers_factory']; | |
$controllers->get('/', 'IndexController::getPage'); | |
// ... more controllers | |
$app->mount('/admin', new AdminRouting()); | |
return $controllers; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use Silex\Application; | |
use Silex\Api\ControllerProviderInterface; | |
use Symfony\Component\HttpFoundation\Request; | |
class AdminRouting implements ControllerProviderInterface | |
{ | |
public function connect(Application $app) | |
{ | |
$controllers = $app['controllers_factory']; | |
$controllers->before(function (Request $request, Application $app) { | |
// check auth or abort! | |
}); | |
$controllers->get('/', 'AdminController::getIndex'); | |
$controllers->get('/static/{file}', 'StaticFileController::getFile') | |
->assert('file', '.+') | |
->value('folder', __DIR__ . '/../statics/admin') | |
->value('virtiualXAccelRedirPath', '/private_admin_files'); | |
return $controllers; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment