tags:

views:

25

answers:

1

Hiya,

I have a folder structure like this /img/products/{product name}/ and then the sub folders hi, low, and thumb.

I want to use htacess to force-download any files in a 'hi' or 'low' subfolder (but not 'thumb').

I was hoping something like this would work:

<FilesMatch "\(.*)(\/hi|\/low)(.*)">
ForceType applicaton/octet-stream
</FilesMatch>

Now I'm not great with regex, but that seems to work in regex testers against paths like

/img/products/active/low/something.jpg

However it's not working on the site.

Any suggestions?

Thanks

Pete

A: 

This probably should have been a ServerFault question based on what I think that you're trying to do, but since you actually can't do what you're trying to do (the way I think you're trying to do it), I'll provide two alternatives; one that likely won't work, and another that involves a PHP script (which should hopefully be alright for you, since your question history shows you asking something about PHP before).

The Problem:

First, what I think you're trying to do, so you can correct me if I'm wrong:

# Apply ForceType to anything that's in a path that matches this
<FilesMatch "img/products/[^/]+/(hi|low)/[^/]+$">
    ForceType applicaton/octet-stream
</FilesMatch>

However, this won't work, because FilesMatch only examines the filename, under the assumption that you could either appropriately place the .htaccess file, or combine the directive with a Directory statement in the server or virtual server configuration.

In your case though, this isn't possible (Well, I assume anyway, maybe you do have access to the necessary configurations, but since your question is tagged .htaccess I'm guessing probably not), given that copying a .htaccess file to every folder isn't realistic.

The Solutions:

As it turns out, mod_rewrite, along with performing all sorts of voodoo in the way of filename resolution, also gives you extensions of other Apache functionality that you would not necessarily have been able to use otherwise. Case in point, we can set the MIME type using the T flag, making the easiest solution this:

RewriteEngine On

# Force the MIME-type, but don't actually perform a rewrite
RewriteRule ^img/products/[^/]+/(hi|low)/[^/]+$ - [T=application/octet-stream]

This actually works pretty well, but chances are good that your Apache installation thinks that it knows better than you, and includes a mimes.types file in the main configuration that maps the jpg extension to image/jpeg. This value takes precedence over the RewriteRule, making it ineffective in that case.

The other solution is to create a small script that acts as the go-between, passing the appropriate headers and image data from the server to the client. You would then use mod_rewrite to pass the request on to that script:

RewriteEngine On

# For an added bit of sanity, make the test pattern even more restrictive
RewriteRule ^img/products/[A-Za-z._-]+/(hi|low)/[A-Za-z._-]\.[A-Za-z]+$ imageDownloader.php

As for the script itself, to keep this answer from getting ridiculously long, I suggest taking a look at this answer or one of the other questions on this topic, keeping in mind that it's imperative that you screen the filenames that can be downloaded for reasons of security. Note that you would be able to get the original request path from $_SERVER['REQUEST_URI'], and could use that to locate the proper image.

Tim Stone