Forcing a download using <filesMatch> in htaccess

I'm trying to force the download of all files of one folder.

The link on the page looks like this

<a href="http://example.com/uploads/documents/file.pdf">Click to download</a>

And I have this snippet in my .htaccess

<filesMatch ".*uploads/documents.*">
    ForceType application/octet-stream
    Header set Content-Disposition attachment
</filesMatch>

I already know that the 2 lines inside the tag works, because it works when I put a .htaccess directly inside the folder where I want to force the download with the following code:

<Files *.*>
    ForceType application/octet-stream
    Header set Content-Disposition attachment
</Files>

There seems to be something which I don't understand about the filesMatch tag.


Searching more info found this code:

<FilesMatch "\.(mov|mp3|jpg|pdf|mp4|avi|wmv)$">
   ForceType application/octet-stream
   Header set Content-Disposition attachment
</FilesMatch>

Worked for me.


Please look at the documentation for FilesMatch and Files, respectively. It clearly states

The directives given within this section will be applied to any object with a basename (last component of filename) matching the specified filename.

That means that in your example it matches against file.pdf. Your second example *.* matches file.pdf, however your first example .*uploads/documents.* does not. It actually can never match, since it contains a slash, which is used as a directory separator.

If you can edit the apache config

You should enclose either <Files *.*> or <Files *.pdf> (depending on what you want to enforce downloading) in a Location directive:

<Location "/uploads/documents/">
    <Files *.*>
        ForceType application/octet-stream
        Header set Content-Disposition attachment
    </Files>
</Location>

If you cannot edit the apache config

Unfortunately, the Location directive is not allowed inside .htaccess files. Just create a .htaccess inside your /uploads/documents/ directory.


This code is perfect if you don't use - in the file name!

For example, for name-1.mp3, change to name1.mp3

<FilesMatch "\.(mp3|avi)$" >
    ForceType application/octet-stream
    Header add Content-Disposition "attachment"
</FilesMatch>

Clear your browser and check it.