Adding options to existing .htaccess - .htaccess

I have this .htaccess code which I have put together from different sources and I am having trouble adding a couple of extra options to it.
<Limit GET POST PUT>
order deny,allow
deny from all
allow from XXX.XXX.XXX.XXX
</Limit>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d
# allow things that are certainly necessary
RewriteCond %{REQUEST_URI} "/css/" [OR]
RewriteCond %{REQUEST_URI} "/js/" [OR]
RewriteCond %{REQUEST_URI} "/images/"
RewriteRule .* - [L]
RewriteRule ^([a-zA-Z0-9-/_]+)/([a-zA-Z0-9-/_%]+)/([a-zA-Z0-9-/_]+)/([a-zA-Z0-9-/_]+)$ index.php?primary=$1&secondary=$2&tertiary=$3&quaternary=$4 [QSA]
RewriteRule ^([a-zA-Z0-9-/_]+)/([a-zA-Z0-9-/_%]+)/([a-zA-Z0-9-/_]+)$ index.php?primary=$1&secondary=$2&tertiary=$3 [QSA]
RewriteRule ^([a-zA-Z0-9-/_]+)/([a-zA-Z0-9-/_%]+)$ index.php?primary=$1&secondary=$2 [QSA]
RewriteRule ^([a-zA-Z0-9-/_]+)$ index.php?primary=$1
Firstly I would like to add the forced use of www. in the URL. When I have tried to add this, the resulting URL becomes the output of the current RewriteRules, containing the GET variables. I believe this is because the rules work on a loop?
Another thing I would like to do is catch anything that doesnt meet the criteria of the current rules and send that to something like index.php?primary=error. The way it works now is almost perfect for my use because if there is a malformed URL or illegal character, the site is not going to even attempt to display the page. The site will create all URLs safely, so any bad URLs would be the result of experimenting in the address bar, but it would be nice to have an error page rather than a page not found.
Thanks in advance.. And sorry for the muddle-through use of RewriteRule!

Your regex are incorrect since hyphen can be unescaped only when it appears as first or last symbol in a character class, it needs to be escaped otherwise.
So instead of: [a-zA-Z0-9-/_%]
Use: [\w%/-]
Your complete set of rules:
RewriteEngine On
RewriteBase /
# add www in the URL
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,NE,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
# allow things that are certainly necessary
RewriteCond %{REQUEST_URI} ^/(css|js|images)/ [NC]
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$ index.php?primary=$1&secondary=$2&tertiary=$3&quaternary=$4 [QSA,L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ index.php?primary=$1&secondary=$2&tertiary=$3 [QSA,L]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?primary=$1&secondary=$2 [QSA,L]
RewriteRule ^([^/]+)/?$ index.php?primary=$1 [QSA,L]

Related

Clean URLs in a subfolder

I've read and followed guides and looked for answers to other people's questions, but I'm struggling with url rewriting and htaccess.
I have a subfolder on my site with an index page which handles query strings to bring up dynamic content. I'd like the variable to appear to be a subfolder name e.g.
http://mywebsite.com/subfolder/index.php?v=variable
to
http://mywebsite.com/subfolder/variable
The .htaccess file I've made is at http://mywebsite.com/subfolder/ i.e. the same folder as index.php
How can I get this to work? Any help gratefully appreciated.
You can use these rules inside your /subfolder/.htaccess
RewriteEngine On
RewriteBase /subfolder/
RewriteCond %{THE_REQUEST} \s/subfolder/index\.php\?v=([^&\s]+) [NC]
RewriteRule ^ %1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)$ index.php?v=$1 [L]
Update (passing two values)
RewriteEngine On
RewriteBase /subfolder/
RewriteCond %{THE_REQUEST} \s/subfolder/index\.php\?v=([^&\s]+)&v2=([^&\s]+)\s [NC]
RewriteRule ^ %1/%2? [R=301,L]
RewriteCond %{THE_REQUEST} \s/subfolder/index\.php\?v=([^&\s]+)\s [NC]
RewriteRule ^ %1? [R=301,L]
# Don't touch to existing files/folders
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Rewrite /xxx to /index.php?v=xxx
RewriteRule ^([^/]+)$ index.php?v=$1 [L]
# Rewrite /xxx/yyy to /index.php?v=xxx&v2=yyy
RewriteRule ^([^/]+)/([^/]+)$ index.php?v=$1&v2=$2 [L]
Use this in your .htaccess:
RewriteEngine On
RewriteCond %{QUERY_STRING} v=(.+)$ [NC]
RewriteRule ^ subfolder/%1? [R=301,L,NE]
This grabs the variable using %{QUERY_STRING} and then appends it to the rewrite using %1. You'll see I've added a ? onto the end of the rewrite. That is to stop the original query from appearing on the end of the URL.
I've used R=301 which is a permanent redirect. You might want to changes this to R=302 while you're testing, as this is temporary.
You can view a test of this rule working here: https://htaccess.madewithlove.be?share=7b6832e9-2c05-5d1d-916c-e4dd0f5b1da6
Make sure you clear your cache before testing this.

RewriteEngine Adds relative path

I have such rewrite rules
RewriteEngine On
RewriteCond %{HTTP_HOST} ^monkey.pl(.*) [NC]
RewriteRule ^(.*)$ http://www.monkey.pl/$1 [R=301,L]
RewriteRule ^horse.html$ /dog.html
and when I go to the monkey.pl/horse.html I get the message:
The requested URL /home/login/monkey/dog.html was not found on this server.
How can I get this to work. Basically what I'm trying to do is to change address of urls like:
http://www.monkey.pl/produkty.php?strona=1
to be displayed as
http://www.monkey.pl/produkty/czesci_do_mixokretow.html
but none of my rules are working. Therefore I'm trying to come with solution.
I tried many varations and I couldn't get it to work. I don't want to rewrite whole page. Just 6 pages which I need to change url and that's all. Fixed translation url => url.
If you are only doing a handful of URLs then you can do them this way.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteCond %{THE_REQUEST} /+produkty\.php\?strona=1 [NC]
RewriteRule ^ /produkty/czesci_do_mixo‌​kretow\.html [R=302,L]
RewriteRule ^produkty/czesci_do_mixo‌​kretow\.html$ /produkty.php?strona=1 [L]
RewriteRule ^horse\.html$ /dog.html [L]

Show 404 error on accessing specific folder structure

I am displaying 404 error message if the user tries to access a specific folder struture
like
RewriteCond %{REQUEST_URI} ^/protected$
RewriteRule .* /404.cfm [NC,L]
RewriteCond %{REQUEST_URI} ^/protected/pdf$
RewriteRule .* /404.cfm [NC,L]
Is there any way to combine both
/protected/pdf and /protected
in one condition and a forward slash at the end as optional
I tried this to make last forward slash optional, like
RewriteCond %{REQUEST_URI} ^/protected/?$
but it's not working.
Try :
RewriteCond %{REQUEST_URI} ^/(protected|protected/pdf)/?$
RewriteRule .* /404.cfm [NC,L]
You can also use conditions with OR flag
RewriteCond %{REQUEST_URI} ^/protected/?$ [OR]
RewriteCond %{REQUEST_URI} ^/protected/pdf/?$
RewriteRule .* /404.cfm [NC,L]
It do not match:
RewriteCond %{REQUEST_URI} ^/protected/?$
mean match everything that start with /protected with an optional / and end.
I you want to match it you have to remove the $.
RewriteCond %{REQUEST_URI} ^/protected/?.*$
or :
RewriteCond %{REQUEST_URI} ^/protected
Or you can stay restrictive as #starkeen offers solution, it depend on your needs.

RewriteRule do THIS if image file, or else do THAT

I'm having a hard time having this to work..
I have installed YOURLS wich is a PHP script to shorten urls.
In order to work, it needs to have this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /yourls-loader.php [L]
No problem here.
But I also want to use a directory for image hosting that has nothing to do with the PHP script.
It would check if the requested url ends with .jpg|.jpeg|.gif|.png and RewriteRule would redirect to /imgshare/$1
I've tried the code below but I get a server error when going to mysite.com/img.jpg but not for the url redirection "mysite.com/y4Jd":
RewriteCond %{REQUEST_URI} !(\.jpg|\.jpeg|\.gif|\.png)$ [NC]
RewriteRule ^(.*)$ /yourls-loader.php [L]
RewriteCond %{REQUEST_URI} (\.jpg|\.jpeg|\.gif|\.png)$ [NC]
RewriteRule ^(.*\.(jpeg|jpg|png|gif))$ /imgshare/$1 [L]
This is not the issue, but as a note, your second RewriteCond already matches files with image endings, so there's no need to repeat that match in the RewriteRule. Alternately, there's no need for the RewriteCond since it's redundant to the RewriteRule.
The real issue, however, may be that you have an extra slash in the final rule. $1 will contain the leading slash matched from the original URL so your rule is currently adding two slashes between imgshare and the file name. I would implement the rule like this:
RewriteCond %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
RewriteRule ^(.*)$ /imgshare$1 [L]

How can I redirect all sub-directories to root using htaccess or httpd.conf?

I have an index file that builds content based on n PATH_INFO variables.
Example:
site.com/A/B/n/
should use index.php at either:
site.com/index.php?var1=A&var2=B&varN=n
- or -
site.com/index.php/A/B/n/
instead of:
site.com/A/B/n/index.php || which doesn't exist ||
So far I've tried a number of variations of:
RedirectMatch ^/.+/.*$ /
with no success.
I have an inelegant and unscalable solution here:
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)/?$ index.php?p1=$1 [NC,L]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ index.php?p1=$1&p2=$2 [NC,L]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ index.php?p1=$1&p2=$2&p3=$3 [NC,L]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ index.php?p1=$1&p2=$2&p3=$3&p4=$4 [NC,L]
Problems with this solution:
Inelegant and unscalable, requires manual line for each subdirectory
Fails with non alphanumeric characters (primarily +,= and &) ex. site.com/ab&c/de+f/
(note, even changing the regex to ^([a-zA-Z0-9_-\+\=\&]+)/?$ does little to help and actually makes it error out entirely)
Can you help?
Option 1: (site.com/index.php?var1=A&var2=B&varN=n):
Options +FollowSymLinks -MultiViews
RewriteEngine On
# do not do anything for already existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
RewriteRule ^([^/]+)/?$ index.php?p1=$1 [QSA,L]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?p1=$1&p2=$2 [QSA,L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ index.php?p1=$1&p2=$2&p3=$3 [QSA,L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$ index.php?p1=$1&p2=$2&p3=$3&p4=$4 [QSA,L]
1. You had [NC] flag ... so there were no need to have A-Z in your pattern.
2. Instead of [a-zA-Z0-9_-\+\=\&] or [a-zA-Z0-9_-] I use [^/] which means any character except slash /.
3. [QSA] flag was added to preserve existing query string.
Option 2: (site.com/index.php/A/B/n/):
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php/$1 [L]
In reality, if you do not plan to show that URL anywhere (like, 301 redirect etc), the last line can easily be replaced by RewriteRule .* index.php [L] -- you will look for original URL using $_SERVER['REQUEST_URI'] in your PHP code anyway.
Adding the following will redirect all traffic (for files that do not exist) to the index page:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [NC]
Then, you can make your decision in index.php by parsing the 'REQUEST_URI'
RewriteRule ^/.+ / [R=301,L]
any url with any kind of path beyond root will be redirected to root.
^ = start of url
/ = a slash
.+ = 1 or more characters

Resources