psalz
psalz

Reputation: 173

Bypass other .htaccess files after RewriteRule

The problem I am facing is related to CakePHP and I will explain it in that context but it really is a mod_rewrite issue:

In CakePHP, all requests are routed into the /app/webroot directory. In that directory, I have another directory called assets in which all the user-uploaded files are stored. I now want to be able to serve thumbnails for every image in that folder, and I want to auto-generate and then cache them on the first request.

To do that, I have a .htaccess file in the assets directory, which is supposed to route all requests that start with thumbs/ to a PHPThumb script. Now I could simply put said script into the assets directory and everything would work fine. But:

  1. I want to avoid file bloat (as there can be multiple resolution thumbnails and so on) and would therefore much rather store those thumbnails in the /app/tmp directory,
  2. The whole thing is part of a CakePHP plugin I am developing, so it would be neat if the script could stay in the Plugin's folder.

What I have tried (inside the /app/webroot/assets directory):

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^thumbs\/([^\/]*)\/(.*)$ ../../Plugin/MyPlugin/Lib/thumbnail.php?size=$1&path=$2 [QSA,L,S=2]

Now this doesn't work. The problem are the .htaccess files in /app and /app/webroot which route everything to /app/webroot/index.php (or any physical file in webroot). The S flag only seems to apply to rules in the same file.

I obviously could change those files to allow thumbnail.php but as I said, its part of a Plugin and I would prefer to keep it as configuration-less as possible.

So my question: Is there a way to bypass/disable any other rewrite rules after the one in /app/webroot/assets/.htaccess was applied?

Upvotes: 1

Views: 968

Answers (1)

AD7six
AD7six

Reputation: 66169

Problems

There are two big-ish problems in the code in the question:

  1. Mixing mod rewrite with, well any FrontController-style php code
  2. Trying to route to a php file that is supposed to be inaccessible

The only php file that is supposed to be web accessible for a production CakePHP application is webroot/index.php

Create a controller action

The right way to do what you're asking is to create a route and a controller action:

Route:

<?php
// app/Config/routes.php
Router::connect(
    '/thumbs/*, 
    array('controller' => 'thumbs', 'action' => 'serve')
);

Controller:

<?php
// app/Controller/ThumbsController.php
class ThumbsController extends AppController {

    function serve() {
        // resize file, 
        //(preferably write to the request uri) 
        //and serve the image
    }
}

The controller action can use send-file (or media views in older versions) to send the file contents after resizing.

Cache in a web-accessible path

Note that serving files with php is always slow:

It’s a well known fact that serving assets through PHP is guaranteed to be slower than serving those assets without invoking PHP.

If at all possible, make sure that the request for a thumb image is processed and written to the same url as the request (or a different location, with an appropriate edit to the .htaccess file - here's an example) so that the next time the same image is requested - it is served directly via apache. If a caching technique is implemented in any form whereby php is part of a request for a cached image - the caching is not going to be particularly effective.

Upvotes: 2

Related Questions