.htaccess for download of file if query string matches - .htaccess

I have a PDF section that I want to give users the option to either view the file in their browser, or download it to their computer. I do not want to duplicate the files so have hit upon the idea of using a query string to tell the server the force the file to download, e.g.
FileName
In my .htaccess file for the pdfs folder, what do I need to put force the file to download if the query string is present?
What I have at the moment forces every pdf to download (instead of view):
<Files *.pdf>
ForceType applicaton/octet-stream
</Files>

You can do something like this with mod_rewrite:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^view=download$
RewriteRule .*\.pdf$ - [L,T=applicaton/octet-stream]
http://httpd.apache.org/docs/current/rewrite/flags.html#flag_t
P.S.
Depending on your rewrite logic (if you have any) you may need to remove the L, flag.
The above rule will work for URLs that end with .pdf and having view=download as query string EXACTLY. This means that it will work for example.com/some/file/here/hello.pdf?view=download but will not work for example.com/some/file/here/hello.pdf?view=download&var1=param1. To have it working for such scenario as well you will have to adjust the rule accordingly (but considering the URL examples you have provided in your Question, it should not happen).

Related

.htaccess to remove the need for adding .html in the address bar versus creating new folders for all pages

I'm sure that with any effort I could figure out how to make this work inside of a .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.html$ /$1 [L,R=301]
But, would that be more or less efficient than just creating a folder with new index.html in each folder?
For me, the real end result that I'm trying to achieve is to not require somebody to type:
skypodstudios.com/solar.html
I would rather let it be good enough to just type:
skypodstudios.com/solar
Both seem to accomplish it, I'm just wondering which is more efficient or if either are frowned upon?
Using folders instead of files is a bad practice. You don't need a folder for each html file you create and it will only invite clutter. Using the .htaccess solution you specified is also not optimal since it will force you to put all your html files in one folder (and will not be useful if you use other file types).
I suggest you use one of the following instead:
For a small project with few files, include HTML files depending on the URI segment. You do that by telling your .htaccess to pass all url queries to your index file (usually index.php) and then that file breaks down the URL segments and retrieve the correct file from the correct folder.
For a big project with hundreds of files, ask yourself if you are using the same template (file structure) over and over again. If your project is a blog or a store chances are the answer is yes. If it is then instead of including files you'd better store your data in a database and then retrieve the current page's data via your index.php file using a database query.

How can I use mod_rewrite and preserve the url's fragment (anchor part)?

I'm taking a site that used to be static html (generated by an offline tool) and converting it to PHP. I'm sending all page urls to a single PHP file which parses the url. At first I just stuck FallbackResource MyPage.php in the .htaccess file, and it worked fine... except for urls with a fragment part. Many of the old urls were like /some-page.html#part2, and in the new scheme, part2 is a whole separate page, so I can't ignore that part of the url. With FallbackResource, all that MyPage.php would ever see is /some-page.html.
Now I've read some other questions on here about the topic, such as this one, and it seemed clear that mod_rewrite should in theory be able to do the job, but I can't get it to work. Here's my most current attempt:
Options +Indexes
DirectoryIndex MyPage.php
RewriteEngine on
#RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^[^:/.?#&]+\.html#(\w+) MyPage.php#$1 [NC,NE]
RewriteRule ^[^:/.?#&]+\.(html|php) MyPage.php [NC]
This works, again, for everything except anchors. It works no better than the old FallbackResource command did. I've tried juggling various parts of this in random ways, such as looking for %23 instead of #, omitting the NE flag, passing the value in a querystring instead of as a fragment, and whatnot.
I will note that I don't want to use redirection to translate the urls -- the PHP has to perform a lookup on it.
Well, I guess the answer is that it can't be done. The fragment part is never even sent to the server as part of the HTTP request. It stays inside the browser. Which means if anyone's saved an old link, it's just gonna go to the wrong page and that's all there is to it.
But I can write javascript into the page to redirect from the client. The PHP can iterate through the known list of old anchors on a given page and emit conditions to send them to the new page.

htaccess URL overwrite - Magento

I have some URLs that I would need to overwrite so that if someone looks at the source code they can't actually see the real URLs for the product images in Magento. Currently, the link is as
externalsub.domain.com/images/image123.jpg
I want to make it as
mydomain.com/images/image123.jpg
How can I achieve this via .htaccess? Any help is much appreciated!
Then in an htaccess file, you can use this (above whatever rules you may already have):
RewriteEngine On
RewriteRule ^images/([^/]+\.(?:jpe?g|png|gif))$ http://externalsub.domain.com/images/$1 [L,P]
You don't need the line turning on the rewrite engine if you already have that (only needs to be in your file once).

htaccess removing index.php and search queries from URL

I have a site that, for a certain php function to work, needs the url to be:
/topic/index.php?height=###
I would like the URL to read
/topic/
What can I put in the .htaccess file to achieve this? Can I put one htaccess file in the root, or would I need to put one in each /topic/ directory?
I think the following might work for your issue:
RewriteRule ^([^/]*)/?$ $1/index.php?height=###
Of course, that's assuming a static number. If you need a dynamic number or one provided by the client, you're going to need something like:
RewriteRule ^([^/]*)/(\d+)/?$ $1/index.php?height=$2

Fastest way to redirect missing image files

I have an on-the-fly thumbnailing system and am trying to find the best way to make sure it's as fast as possible when serving up images. Here is the current flow:
User requests thumbnail thumbnails/this-is-the-image-name.gif?w=200&h=100&c=true
htaccess file uses modrewrite to send requests from this folder to a PHP file
PHP file checks file_exists() for the requested image based on the query string values
If it does:
header('content-type: image/jpeg');
echo file_get_contents($file_check_path);
die();
If it doesn't it creates the thumbnail and returns it.
My question is whether there is a way to optimize this into being faster? Ideally my htaccess file would do a file_exists and only send you to the PHP file when it doesn't... but since I am using query strings there is no way to build a dynamic URL to check. Is it worth switching from query strings to an actual file request and then doing the existence check in htaccess? Will that be any faster? I prefer the query string syntax, but currently all requests go to the PHP file which returns images whether they exist or not.
Thank you for any input in advance!
You should be able to do this in theory. The RewriteCond command has a flag -f which can be used to check for the existence of a file. You should be able to have a rule like this:
# If the file doesn't exist
RewriteCond %{REQUEST_FILENAME} !-f
# off to PHP we go
RewriteRule (.*) your-code.php [L,QSA]
The twist here is that I imagine you're naming files according to the parameters that come in -- so the example above might be thumbnails/this-is-the-image-name-200-100.gif. If that is the case, you'll need to generate a filename to test on the fly, and check for that instead of the REQUEST_FILENAME -- the details of this are really specific to your setup. If you can, I would recommend some sort of system that doesn't involve too much effort. For example, you could store your thumbnails to the filesystem in a directory structure like /width/height/filename, which would be easier to check for in a rewrite rule than, modified-filename-width-height.gif.
If you haven't checked it out, Apache's mod_rewrite guide has a bunch of decent examples.
UPDATE: so, you'll actually need to check for the dynamic filename from the looks of it. I think that the easiest way to do something like this will be to stick the filename you generate into an environment variable, like this (I've borrowed from your other question to flesh this out):
# generate potential thumbnail filename
RewriteCond %{SCRIPT_FILENAME}%{QUERY_STRING} /([a-zA-Z0-9-]+).(jpg|gif|png)w=([0-9]+)&h=([0-9]+)(&c=(true|false))
# store it in a variable
RewriteRule .* - [E=thumbnail:%1-%2-%3-%4-%6.jpg]
# check to see if it exists
RewriteCond %{DOCUMENT_ROOT}/path/%{ENV:thumbnail} !-f
# off to PHP we go
RewriteRule (.*) thumbnail.php?file_name=%1&type=%2&w=%3&h=%4&c=%6 [L,QSA]
This is completely untested, and subject to not working for sure. I would recommend a couple other things:
Also, one huge recommendation I have for you is that if possible, turn on logging and set RewriteLogLevel to a high level. The log for rewrite rules can be pretty convoluted, but definitely gives you an idea of what is going on. You need server access to do this -- you can't put the logging config in an .htaccess file if I recall.

Resources