Hi I asked this one on the list during Drupalcon SF but got no response (the list was quiet that week!) so here goes again: *The Background* --------------- I've got a module I'm working on that needs to force some images to go via the private download method. This is working fine rerouting links via system/files in combination with a htaccess file limiting direct access to the directory. I also need thumbnails in various sizes of the images so it makes sense to use imagecache. I want the site in public download method except for these files and I've successfully got the imagecache integration working. I've used hook_menu_alter to prevent people accessing the relevant imagecache file path directly, rerouting the imagecache cached images via system/files. The problem is, once the imagecache file is created, the file is no longer being served via Drupal, with Apache serving it direct. This obviously does not get near my access callback. *The Questions* --------------- Is this down to Drupal's rewrite rules? Are the rewrite rules not evaluated if the file actually exists? Can I create a rewrite rule to force this file to go through Drupal - the relevant files all contain a common element in their path so I should be able to match it) or do I need to consider alternatives such as creating .htaccess files in the subfolders for each imagecache preset, monitoring for new presets? Any suggestions welcome. Lee Rowlands
I had the same issue at one point. I think the end solution was writing a new callback (so it didn't map directly to a file), setting up a perm check on it, and on success returning what imagecache would have. Then I denied direct access to the imagecache path. - Ken Winters On Jul 14, 2010, at 5:58 AM, Lee Rowlands wrote:
Hi I asked this one on the list during Drupalcon SF but got no response (the list was quiet that week!) so here goes again:
*The Background* --------------- I've got a module I'm working on that needs to force some images to go via the private download method. This is working fine rerouting links via system/files in combination with a htaccess file limiting direct access to the directory. I also need thumbnails in various sizes of the images so it makes sense to use imagecache. I want the site in public download method except for these files and I've successfully got the imagecache integration working. I've used hook_menu_alter to prevent people accessing the relevant imagecache file path directly, rerouting the imagecache cached images via system/files. The problem is, once the imagecache file is created, the file is no longer being served via Drupal, with Apache serving it direct. This obviously does not get near my access callback.
*The Questions* --------------- Is this down to Drupal's rewrite rules? Are the rewrite rules not evaluated if the file actually exists? Can I create a rewrite rule to force this file to go through Drupal - the relevant files all contain a common element in their path so I should be able to match it) or do I need to consider alternatives such as creating .htaccess files in the subfolders for each imagecache preset, monitoring for new presets?
Any suggestions welcome. Lee Rowlands
Thanks Ken This is essentially what I'm doing, its the 'denying direct access to the imagecache path' that I'm stumbling on, this site is an online print store where the user designs and pays for their printing in the browser (lots of js!). They need to upload images for their design (scale, crop etc) but these need to be private (even for anonymous). Each of the printing options is a node and each can have a different print size requiring a new imagecache preset. I can handle protecting these presets with my node hooks by creating the imagecache folders and adding the .htaccess on hook_insert, but my module isn't in isolation so Ubercart, the client and other modules are defining their own presets - I'm hoping for a more elegant solution than say a hook_init to check the defined presets against a list that has been previously protected, creating new .htaccess files for those that are unprotected. This is mainly because once the site is live, the bulk of the new presets will be from the custom module so the hook_init will be largely redundant but (in my belief) a necessary security measure. Lee On Wed, 2010-07-14 at 08:17 -0400, Ken Winters wrote:
I had the same issue at one point. I think the end solution was writing a new callback (so it didn't map directly to a file), setting up a perm check on it, and on success returning what imagecache would have. Then I denied direct access to the imagecache path.
- Ken Winters
On Jul 14, 2010, at 5:58 AM, Lee Rowlands wrote:
Hi I asked this one on the list during Drupalcon SF but got no response (the list was quiet that week!) so here goes again:
*The Background* --------------- I've got a module I'm working on that needs to force some images to go via the private download method. This is working fine rerouting links via system/files in combination with a htaccess file limiting direct access to the directory. I also need thumbnails in various sizes of the images so it makes sense to use imagecache. I want the site in public download method except for these files and I've successfully got the imagecache integration working. I've used hook_menu_alter to prevent people accessing the relevant imagecache file path directly, rerouting the imagecache cached images via system/files. The problem is, once the imagecache file is created, the file is no longer being served via Drupal, with Apache serving it direct. This obviously does not get near my access callback.
*The Questions* --------------- Is this down to Drupal's rewrite rules? Are the rewrite rules not evaluated if the file actually exists? Can I create a rewrite rule to force this file to go through Drupal - the relevant files all contain a common element in their path so I should be able to match it) or do I need to consider alternatives such as creating .htaccess files in the subfolders for each imagecache preset, monitoring for new presets?
Any suggestions welcome. Lee Rowlands
The best trick is to not use regular Drupal file paths on your pages and instead use an internal Drupal path, the same way the private download method does. Just alter your links using hook_node_view. If you want to keep the paths intact, then it takes a couple of .htaccess tricks. First to answer your question, yes Drupal's .htaccess rules check if a file exists and if so it serves it directly. This is necessary for things like css, js and theme images to load properly. You can force .htaccess to ignore certain paths. In Drupal's .htaccess, right before Drupal's rewrite rules (right after # RewriteBase /): RewriteCond %{REQUEST_URI} /sites/default/files/imagecache/.* RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] Now any file request to /sites/default/files/imagecache/* will go through Drupal. Everything else will be handled normally. One note of caution though. If you are using this for thumbnails and you have a page with say 20 thumbnails on it, it will be a major performance hit. You are requiring Drupal to bootstrap for every one of those requests, so if a person hits that page, Drupal has to fire up 21 times (20 for images, once for the page). Even a decent dedicated server will have problems with that. The better alternatives are to either watermark all your thumbnails (ie: ImageCache Actions) and serve them directly, or to use a CDN that offers token based authentication, like VoxCAST. Jamie Holly http://www.intoxination.net http://www.hollyit.net On 7/14/2010 5:58 AM, Lee Rowlands wrote:
Hi I asked this one on the list during Drupalcon SF but got no response (the list was quiet that week!) so here goes again:
*The Background* --------------- I've got a module I'm working on that needs to force some images to go via the private download method. This is working fine rerouting links via system/files in combination with a htaccess file limiting direct access to the directory. I also need thumbnails in various sizes of the images so it makes sense to use imagecache. I want the site in public download method except for these files and I've successfully got the imagecache integration working. I've used hook_menu_alter to prevent people accessing the relevant imagecache file path directly, rerouting the imagecache cached images via system/files. The problem is, once the imagecache file is created, the file is no longer being served via Drupal, with Apache serving it direct. This obviously does not get near my access callback.
*The Questions* --------------- Is this down to Drupal's rewrite rules? Are the rewrite rules not evaluated if the file actually exists? Can I create a rewrite rule to force this file to go through Drupal - the relevant files all contain a common element in their path so I should be able to match it) or do I need to consider alternatives such as creating .htaccess files in the subfolders for each imagecache preset, monitoring for new presets?
Any suggestions welcome. Lee Rowlands
The better alternatives are to either watermark all your thumbnails (ie: ImageCache Actions) and serve them directly, or to use a CDN that offers token based authentication, like VoxCAST.
Or upgrade to D7, as can handle simultaneous private and public files. You have imagecache in core as well. D7 beta is "any day now"
Thanks Moshe Forever the salesman. I believe this module will also be redundant in 7 as it is essentially a module to provide a private file repo for authenticated and anonymous users (via session api). Correct me if I'm wrong but that too will be straight forward with D7. Lee On Wed, 2010-07-14 at 09:57 -0400, Moshe Weitzman wrote:
The better alternatives are to either watermark all your thumbnails (ie: ImageCache Actions) and serve them directly, or to use a CDN that offers token based authentication, like VoxCAST.
Or upgrade to D7, as can handle simultaneous private and public files. You have imagecache in core as well. D7 beta is "any day now"
Thanks Jamie This is the missing piece of the puzzle (lightbulb goes on). So the question is - which offers the biggest performance hit - a hook_init call to test which preset paths are protected by .htaccess files (my files are in a subdirectory of each imagecache preset folder) - protecting those that are not protected by creating the new .htaccess file or the bootstrap? There are places where lists of thumbnails are rendered. I think the first option sounds like the lesser (albeit ugly) evil Thanks everyone for all of your help and advice. Lee On Wed, 2010-07-14 at 09:15 -0400, Jamie Holly wrote:
The best trick is to not use regular Drupal file paths on your pages and instead use an internal Drupal path, the same way the private download method does. Just alter your links using hook_node_view.
If you want to keep the paths intact, then it takes a couple of .htaccess tricks.
First to answer your question, yes Drupal's .htaccess rules check if a file exists and if so it serves it directly. This is necessary for things like css, js and theme images to load properly.
You can force .htaccess to ignore certain paths. In Drupal's .htaccess, right before Drupal's rewrite rules (right after # RewriteBase /):
RewriteCond %{REQUEST_URI} /sites/default/files/imagecache/.* RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Now any file request to /sites/default/files/imagecache/* will go through Drupal. Everything else will be handled normally.
One note of caution though. If you are using this for thumbnails and you have a page with say 20 thumbnails on it, it will be a major performance hit. You are requiring Drupal to bootstrap for every one of those requests, so if a person hits that page, Drupal has to fire up 21 times (20 for images, once for the page). Even a decent dedicated server will have problems with that.
The better alternatives are to either watermark all your thumbnails (ie: ImageCache Actions) and serve them directly, or to use a CDN that offers token based authentication, like VoxCAST.
Jamie Holly http://www.intoxination.net http://www.hollyit.net
On 7/14/2010 5:58 AM, Lee Rowlands wrote:
Hi I asked this one on the list during Drupalcon SF but got no response (the list was quiet that week!) so here goes again:
*The Background* --------------- I've got a module I'm working on that needs to force some images to go via the private download method. This is working fine rerouting links via system/files in combination with a htaccess file limiting direct access to the directory. I also need thumbnails in various sizes of the images so it makes sense to use imagecache. I want the site in public download method except for these files and I've successfully got the imagecache integration working. I've used hook_menu_alter to prevent people accessing the relevant imagecache file path directly, rerouting the imagecache cached images via system/files. The problem is, once the imagecache file is created, the file is no longer being served via Drupal, with Apache serving it direct. This obviously does not get near my access callback.
*The Questions* --------------- Is this down to Drupal's rewrite rules? Are the rewrite rules not evaluated if the file actually exists? Can I create a rewrite rule to force this file to go through Drupal - the relevant files all contain a common element in their path so I should be able to match it) or do I need to consider alternatives such as creating .htaccess files in the subfolders for each imagecache preset, monitoring for new presets?
Any suggestions welcome. Lee Rowlands
participants (5)
-
Jamie Holly -
Ken Winters -
Lee Rowlands -
Lee Rowlands -
Moshe Weitzman