Using routing to serve static files


#1

I’m using Slim3 on my membership website. I have some of the content hosted in /public/ due to some nightmares with iOS and the HTML5 audio player. Anyway, now that it is in /public/ anyone can access the content. Is it possible for me to use routing with Slim3 to first check if a user is logged in and then serve the static content in the same way Apache would (that is key!).

For example this is how I restrict admin pages to a user logged in as an admin

$app->group('/admin', function () use ($app, $user) {
    // admin page
    $app->get('', function(Request $request, Response $response) use ($user) {
        if (!$user->isAdmin()) {
            return RouteManager::$instance->responseNope($this, $response);
        }
        return RouteManager::$instance->responsePage($this, $response, 'admin.php');
    });
});

I of course have the same kind of stuff going for users, but only to server php template files. Can I do this but serve static files WITHOUT manually setting PHP headers and reading file contents, etc? Something like

$app->group('/content', function () use ($app, $user) {
    // content stuff 
    $app->get('/audio/somefilename.mp3', function(Request $request, Response $response) use ($user) {
        if (!$user->isLoggedIn()) {
            return RouteManager::$instance->responseNope($this, $response);
        }
        return 'somefilename.mp3';
    });
})

#2

Depending on your .htaccess and front-controller setup every static file in the public directory will be served directly via Apache. That’s just the default behavior.

Just some ideas:

If you have only small files (< 50 MB) then maybe you could send the file content directly (instead of an redirect) from a non public directory. Because of the PSR-7 architecture all the response content is getting buffered in a “stream”. So the maximum filesize depends on your free server ram etc. If the file size exceeds the available RAM, you would have to override the response and send it directly via readfile(). Using the readfile function would break the request/response and middleware concept of course.