Rewrite rule htaccess to ignore everything after last slash - .htaccess

I always have a single file per folder named test.* (* = jpg, png, video file etc) which is stored in different sizes as following
https://www.example.com/images/1500/01/100/test.jpg
https://www.example.com/images/1500/01/500/test.jpg
https://www.example.com/images/1500/01/900/test.jpg
https://www.example.com/images/1500/01/1800/test.jpg
I would like to create a rule in htaccess which will allow me to load the different files using a link.
As an example for the first image I would like to be able to load the file using the following links:
https://www.example.com/images/1500/01/100
https://www.example.com/images/1500/01/100/
https://www.example.com/images/1500/01/100/whatever
https://www.example.com/images/1500/01/100/somethingelse
The logic would be to always load the file which will always be named test however without calling it test in the link and in addition be allowed to write anything behind the trailing slash.
Is it possible using plain htaccess. I was trying with the following however it does not give the result I am looking for:
RewriteEngine On
RewriteRule ^images/(.*)/([^/]+) images/$1/$2/test.jpg

If you have a hierarchy of 3 folders deep, and they are all numeric you can do something like this:
RewriteEngine On
RewriteRule ^images/([0-9]+)/([0-9]+)/([0-9]+).+?$ images/$1/$2/$3/test.jpg [L]
This will match
https://www.example.com/images/1500/01/100
https://www.example.com/images/1500/01/100/
https://www.example.com/images/1500/01/100/whatever
https://www.example.com/images/1500/01/100/somethingelse
If they are not always numeric:
RewriteEngine On
RewriteRule ^images/([^/]+)/([^/]+)/([^/]+).+?$ images/$1/$2/$3/test.jpg [L]

Related

How to convert ULR not existent subfolder to GET variable in .htaccess?

Need to convert subfolder named exact length of chars to GET variable. If posible, code that will work and on any other than 127.0.0.1 address.
Perfect will be that logic - if in request is some subfolder named with three chars(letters or numbers), and this folder is before last slash(/) - just convert this subfolder to GET variable, maintain any other GET variables if was there.
Need to convert path from this:
http://127.0.0.1/truck/c4/sD2/
To this:
http://127.0.0.1/truck/c4/?r=sD2
Or this:
http://127.0.0.1/truck/c4/index.php?r=sD2
Very important, "sD2" - is just random code for internal purposes. It generated randomly, so it not be like that always. But it always has three chars and slash(/), so somehow need to identify htose three chars and rewrite URL to transfer it with GET variable.
Also it should keep any other GET variables in current URL if has so.
Also need to .htaccess file to be on /truck/c4/ folder, and with possibiliy to move this root folrer to another domain.
For now i have this .htaccess code:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} /?([/]..[^/])/$
RewriteRule /?(...)/$ http://127.0.0.1/truck/c4/?r=$1 [R=301,L,QSA]
</IfModule>
It works, but i very need to untied code from specific address to make it more universal, if possible.

URL redirect to use subdirectory as GET parameter

I imagine this has to be a common scenario but I'm struggling to describe it sufficiently well or to find a working answer!
Essentially I want to make hundreds of URLS that include unique reference codes but that are easy to type in the form example.com/aabbcc, which will be intercepted and all delivered to a PHP script for validating that code, located somewhere like example.com/script.php.
I need the subdirectory part of the URL (aabbcc, in this example) to become a GET parameter for that script, so a URL like the one above would be sent to example.com/script.php?id=aabbcc, while hiding this more complicated URL from the user.
I can see from other .htaccess examples that this must be possible, but I can't find one doing this.
Is there a .htaccess solution for it? Is there something else even more basic? Your help is appreciated in steering me.
If your "unique reference codes" consist of 6 lowercase letters, as in your example then you can do something like the following in your root .htaccess file using mod_rewrite:
RewriteEngine
# Internally rewrite "/abcdef" to "script.php?id=abcdef"
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[a-z]{6}$ script.php?id=$0 [L]
If you don't need direct access to any subdirectories off the root that also happen to match a "unique reference code" then you can remove the preceding condition (RewriteCond directive). With the condition in place then you naturally can't access any "unique access codes" that happen to also match the name of a subdirectory.
$0 is a backreference to the entire URL-path that the RewriteRule pattern (first argument) matches against.
Reference
Apache mod-rewrite Documentation - Contents
Apache mod_rewrite Introduction
Apache mod_rewrite Reference
RewriteRule Directive
RewriteCond Directive

Htaccess caching system in subfolder not working

Sorry if this is a duplicate: I found many questions about caching system, but my problem seems to tied to the fact that the whole script is working within a subfolder.
All I need to do is implementing a simple caching system for my website, but I can't get this to work.
Here's my .htaccess file (widely commented to be clear - sorry if too many comments are confusing):
RewriteEngine on
# Map for lower-case conversion of some case-insensitive arguments:
RewriteMap lc int:tolower
# The script lives into this subfolder:
RewriteBase /mydir/
# IMAGES
# Checks if cached version exists...
RewriteCond cache/$1-$2-$3-{lc:$4}.$5 -f
# ...if yes, redirects to cached version...
RewriteRule ^(hello|world)\/image\/([a-zA-Z0-9\.\-_]+)\/([a-zA-Z0-9\.\-_]+)\/([a-zA-Z0-9\.\-_\s]+)\.(png|gif|jpeg?|jpg)$ cache/$1-$2-$3-{lc:$4}.$5 [L]
# ...if no, tries to generate content dynamically.
RewriteRule ^(hello|world)\/image\/([a-zA-Z0-9\.\-_]+)\/([a-zA-Z0-9\.\-_]+)\/([a-zA-Z0-9\.\-_\s]+)\.(png|gif|jpeg?|jpg)$ index.php?look=$1&action=image&size=$2&data=$3&name=$4&format=$5 [L,QSA]
# OTHER
# This is always non-cached.
RewriteRule ^(hello|world)\/([a-zA-Z0-9\.\-_\s]+)\/([a-zA-Z0-9\.\-_\s]+)?\/?$ index.php?look=$1&action=$2&name=$3 [QSA]
Now, the issue is that the RewriteCond seems to be always failing, as the served image is always generated by PHP. I also tried prepending a %{DOCUMENT_ROOT}, but is still not working. If I move the whole script to the root directory, it magically starts working.
What am I doing wrong?
Well one thing that you are doing wrong is trying to use a rewrite map in an .htaccess file. in the first place. According to the Apache documentation:
The RewriteMap directive may not be used in <Directory> sections or .htaccess files. You must declare the map in server or virtualhost context. You may use the map, once created, in your RewriteRule and RewriteCond directives in those scopes. You just can't declare it in those scopes.
If your ISP / sysadmin has already defined the lc map then you can use it. If not then you can only do case-sensitive file caching on Linux, because its FS naming is case sensitive. However, since these are internally generated images, just drop the case conversion and stick to lower case.
%{DOCUMENT_ROOT} may not be set correctly at time of mod_rewrite execution on some shared hosting configurations. See my Tips for debugging .htaccess rewrite rules for more hints. Also here is the equivalent lines from my blog's .htaccess FYI. The DR variable does work here, but didn't for my previous ISP, to I had to hard-code the parth
# For HTML cacheable blog URIs (a GET to a specific list, with no query params,
# guest user and the HTML cache file exists) then use it instead of executing PHP
RewriteCond %{HTTP_COOKIE} !blog_user
RewriteCond %{REQUEST_METHOD}%{QUERY_STRING} =GET [NC]
RewriteCond %{DOCUMENT_ROOT}html_cache/$1.html -f
RewriteRule ^(article-\d+|index|sitemap.xml|search-\w+|rss-[0-9a-z]*)$ \
html_cache/$1.html [L,E=END:1]
Note that I bypass the cache if the user is logged on or for posts and if any query parameters are set.
Footnote
Your match patterns are complicated because you are not using the syntax of regexps: use the \w and you don't need to escape . in [ ] or / . Also the jpeg isn't right is it? So why not:
RewriteRule ^(hello|world)/image/([.\w\-]+)/([.\w\-]+)/([\w\-]+\.(png|gif|jpe?g))$ \
cache/$1-$2-$3-$4 [L]
etc.. Or even (given that the file rule will only match for valid files in the cache)
RewriteRule ^(hello|world)/image/(.+?)/(.+?)/(.*?\.(png|gif|jpe?g))$ \
cache/$1-$2-$3-$4 [L]
The non-greedy modifier means that (.+?) is the same as ([^/]+) so doing hacks like ../../../../etc/passwd won't walk the file hierarchy.

htaccess - creating directories and files of the same name

I want to create a bunch of files without an extension showing at the end. The easiest way to do that was to do this:
/usa/index.php
/usa/alaska/index.php
/usa/alabama/index.php
/usa/california/index.php
What I want to do is this
/usa/alaska.php
/usa/alabama.php
/usa/california.php
and have it show up as:
/usa/alaska
/usa/alabama
/usa/california
However, I have one more level I want to add to this, the cities
/usa/alaska/adak.php
/usa/alaska/anchorage.php
/usa/california/los-angles.php
I don't want the ".php" showing up, but then each state exists as both a file and a directory. What I want is an htaccess rule that serves up the file version of the file, not the directory which is the default. I also want to strip the .php off of the end of the files so the final result looks like
/usa
/usa/alaska (alaska.php)
/usa/alaska/adak (adak.php)
I know I can get close to this by creating all the directories and using index.php for each directory, but then I will have thousands of directories each with one file in it and updating is a pain in the butt. I would much rather have one directory with 1000 files in it, than 1000 directories with 1 file in it.
Please, can someone point me in the right direction and know that I am doing this for all 50 states.
Jim
I would also suggest using a single php (e.g. index.php) file and redirecting all urls starting with usa to it, instead of separating them in different directories and files. The you'd need a couple of rewrite rules like the following
RewriteEngine On
RewriteRule ^usa/([^/.]+)$ index.php?state=$1 [L]
RewriteRule ^usa/([^/]+)/([^/.]+)$ index.php?state=$1&city=$2 [L]
So then in your index.php you'd only need to check the $_GET parameters.
Update:
If you don't feel comfortable enough to use a database and pull the needed data from there you could always use the parameters to dynamically include/require the needed files. Something like this
<?php
$source = ''; //or the 'ROOT' directory
if(isset($_GET['state'])) $source .= $_GET['state'].'/';
if(isset($_GET['city'])) $source .= $_GET['city'].'.php';
include($source); // here $source would be something like 'alaska/adak.php'
// and is assumed that the dir 'alaska' is on the same
// level as 'index.php'
?>
But to answer your original question nevertheless you could use the following .htaccess
RewriteEngine On
RewriteRule ^usa/([^/.]+)$ usa/$1.php [L]
RewriteRule ^usa/([^/]+)/([^/.]+)$ usa/$1/$2.php [L]
what about creating just one single file:
/usa/index.php
With
$_SERVER["REQUEST_URI"]
you can read the current URI.
Well, now if a user enters "http://domain.foo/usa/alaska" for example, he will get an 404 error of course.
But to call your index.php instead, you could write this line to the .htaccess:
ErrorDocument 404 /usa/index.php
Now the index.php receives everything what is written to the URI and you can match the result and include files or handle errors.
But maybe there is a better solution with .htaccess only, don't know. :)

.htaccess modification

I am using direct paths for downloading files from my site. the link is something like this
http://www.site.com/download.php?dir1/dir/dir3/file.doc
i want to wrap it with mod rewite rules so that only below link should be appeared
http://www.site.com/download
file, dir and dir3 are variable.
what i'hv to do in my .htaccess file?? Any Idea??
A simple redirect would be:
RewriteRule ^http://www.site.com/download/(.*)/?$ http://www.site.com/download.php?dir1/dir/dir3/$1 [NC,L]
This will take any request for something in the 'artificial' download directory and route it to the real location.
You can add more complex rules stripping out filetypes etc depending on your needs, or redirecting a 'name' to a filename etc etc..
e.g:
RewriteRule ^http://www.site.com/download/pdf/(.*)/?$ http://www.site.com/download.php?dir1/dir/dir3/$1.pdf [L,NC]
This would have an artificial PDF folder containing a filename ex the extension, routing to a .pdf doc....you can shape the redirect any way you like really...depends on the format you prefer
Not specific question. What is dir1/dir/dir3/file.doc means? If you want to get http://www.site.com/download.php?dir1/dir/dir3/file.doc, when you go to http://www.site.com/download do the next things in your .htaccess file.
RewriteEngine on
RewriteRule ^download/(.*)/?$ download.php?dir1/dir/dir3/file.doc [L]

Resources