Apache 2.2 mod rewrite loop. How to replace [END] - apache

RewriteEngine on
I have following code:
RewriteCond %{REQUEST_URL} ^$
RewriteRule ^files/(.*)$ getfile.php?file=$1 [L]
RewriteRule ^(.+)/index([0-9]*).html$ index.php?path=$1/&page=$2 [QSA]
RewriteRule ^(.+).html$ index.php?path=$1.html [QSA]
RewriteRule ^(.+)/(.+).htm$ index.php?path=$1/&article=$2.htm [QSA]
RewriteRule ^(.+/)$ index.php?path=$1 [QSA]
RewriteRule ^(.+)$ index.php?path=$1 [QSA]
This code translate urls to parameter path and article according to situation. All good and bad url request is routed to index.php except for files within folder files/.
I have problem with last line of code. It is primarily for all bad urls (all other is processed earlier). With this rule it start to loop over and over again, because all of url match this rule. This rule have to match once or never, but without [END] I cannot contrive. I have older version of apache (2.2) so I cannot use this direction.
Solution for this I have tried is something like this:
RewriteCond %{QUERY_STRING} !^.*path=([^&]*).*$
RewriteCond %{REQUEST_URI} !^/((files|design)/.+)$
RewriteRule ^(.+)$ index.php?path=$1 [QSA]
but cannot succeed.

Try adding a L flag to the end of each rule and add a redirect environment check in the beginning to pass through any previously internally redirected URI:
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteRule ^files/(.*)$ getfile.php?file=$1 [L]
RewriteRule ^(.+)/index([0-9]*).html$ index.php?path=$1/&page=$2 [L,QSA]
RewriteRule ^(.+).html$ index.php?path=$1.html [L,QSA]
RewriteRule ^(.+)/(.+).htm$ index.php?path=$1/&article=$2.htm [L,QSA]
RewriteRule ^(.+/)$ index.php?path=$1 [L,QSA]
RewriteRule ^(.+)$ index.php?path=$1 [L,QSA]

Related

htaccess rewrite if url doesnt have a query string

I have a htaccess that rewrites to /login if conditions aren't met.
It's working fine for urls without query_string.
However I have no clue how to include /reset?query_string to accepted conditions. And want to exclude /reset
/reset?6tdsBMxpeeJEDUvYzwKmLzIusLYLjgMtIj
RewriteEngine On
RewriteBase /index.php
RewriteCond %{REQUEST_URI} !^/login$
RewriteCond %{REQUEST_URI} !^/forgotten$
RewriteRule ^([^\.]+)$ /login [R=301,L,QSD]
RewriteRule ^(/)?$ /login [R=301,L]
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Here is a modified version of your .htaccess that excludes /reset?query:
RewriteEngine On
# /reset with query string
RewriteCond %{QUERY_STRING} .
RewriteRule ^(reset)/?$ $1.php [L,NC]
RewriteCond %{REQUEST_URI} !^/(forgotten|login)$ [NC]
RewriteRule ^([^.]*)$ /login [R=301,L,QSD]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^.]+)$ $1.php [L]
Make sure to test it after clearing your browser cache.
With your shown samples and attempts, please try following htaccess rules file. Make sure to clear your browser cache before testing your URLs.
Also I am making use of apache's variable named THE_REQUEST by which we can handle both uri as well as query string.
RewriteEngine ON
RewriteBase /
##Rules for handling rest uri without query string.
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^reset/?$ /login? [R=301,L,NC]
##Rules for reset with uri and query string.
RewriteCond %{THE_REQUEST} \s/reset\?\S+\s [NC]
RewriteRule ^ /reset? [R=301,NC]
##Rule for login page's backend rewrite.
RewriteRule ^login/?$ login.php [QSA,NC,L]
##Rule for forgotten page's backend rewrite.
RewriteRule ^forgotten/?$ forgotten.php [QSA,NC,L]
##Rules for non-existing pages should be served with index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]

RewriteRule - remove params keys and keep values in address bar

RewriteEngine ON
RewriteRule ^video$ video.php [L]
the above line works
example.com/video is interpret as example.com/video.php
now I need example.com/video?id=5&s=lorem-ipsum
to interpret as example.com/video/5/lorem-ipsum - and vice versa
RewriteCond %{THE_REQUEST} video?id=([^\s&]+)&s=([^\s&]+) [NC]
RewriteRule ^ %1/%2? [R=301,L]
RewriteRule ^([\w-]+)/([\w-]+)/?$ video?id=$1&s=$2 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/?$ video?/$1/$2 [L,QSA]
doesn't work - in both directions
pls help
With your shown attempts, please try following .htaccess rules file. These rules are assuming you want to infernally rewrite to index.php you can change php file name in 2nd set of rules as per your requirement.
Make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
##External redirect Rules from here..
##Redirect 301 to example.com/video/5/lorem-ipsum from example.com/video?id=5&s=lorem-ipsum
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{THE_REQUEST} \s/(video)\?id=([^&]*)&s=(\S+)\s [NC]
RewriteRule ^ /%1/%2/%3? [R=301,L]
##Internal rewrite for example.com/video?id=5&s=lorem-ipsum
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^video/([^/]*)/(.*)/?$ index.php?id=$1&s=$2 [QSA,NC,L]

Some .htaccess questions

First of all, I'm new to stackoverflow, so sorry if the title should've been more descriptive.
I've searched and tried different solutions posted here on stackoverflow but not a single one seems to solve my specific issue.
First of all, here's my .htaccess file
RewriteEngine On
RewriteCond %{HTTP_HOST} ^website\.io [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.website.io/$1 [R,L]
RewriteRule ^hosting/?$ hosting.php [NC,L]
RewriteRule ^premium/?$ premium.php [NC,L]
RewriteRule ^register/?$ register.php [NC,L]
RewriteRule ^auth/?$ login.php [NC,L]
RewriteRule ^contact/?$ contact.php [NC,L]
RewriteRule ^auth/forgot?$ forgot.php [NC,L]
RewriteRule ^about/?$ about.php [NC,L]
RewriteRule ^auth/activate?$ activate.php [NC,L]
RewriteRule ^website/new?$ createwebsite.php [NC,L]
RewriteRule ^profile/edit?$ editprofile.php [NC,L]
RewriteRule ^auth/logout?$ logout.php [NC,L]
RewriteRule ^privacy/?$ privacy.php [NC,L]
RewriteRule ^profile/?$ profile.php [NC,L]
RewriteRule ^auth/forgot/reset?$ resetPassword.php [NC,L]
RewriteRule ^tos/?$ tos.php [NC,L]
RewriteRule ^website/?$ websites.php [NC,L]
RewriteRule ^website/manage?$ managewebsite.php [NC,L]
RewriteRule ^website/manage/([A-Za-z0-9-]+)/?$ managewebsite.php?id=$1 [NC,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^(.*)$ https://www.website.io%1 [R,L,NC]
My first problem is that HTTPS is not being redirected properly in some cases. For example, if I enter "website[dot]io" in the address bar, it redirects to "[https]://www.website.io", the desired result. However, if I type either "[http]://website.io" or "[http]://www.website.io" or "www.website[dot]io" it stays in the HTTP, which I don't want it to. Is there a way to ALWAYS redirect the traffic to HTTPS, regardless of the way it's typed in the address bar?
My second problem is that I want to eliminate the last trailing slash from the url in case someone decides to type it that way. Example "[https]://www.site.io/register/" should redirect to "[https]://www.site.io/register" without the last trailing slash.
Thank you so much, everyone!
P.S.: I replaced some "http(s)" with "[http(s)]" because it won't let me post links.
To remove the trailing slash use: (un tested, from : Htaccess: add/remove trailing slash from URL
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
To Force HTTPS use: (What i use and works with any domains)
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L,NC,QSA]
As for the value inside the [bracket], it can change depending on you configuration or needs.

Simplifying a series of redirections using mod_rewrite

My client has an SSL cert for MAINSITE.com but gets a lot of traffic via OTHERSITE.com.
Client would like all visitors to use HTTPS all the time.
So my rules start out by checking for OTHERSITE.com and redirecting to https://MAINSITE.com if found.
Then I check to see if we are using HTTPS and redirect if not.
Then there are a series of rules aimed at using the sub-directories in the URL to pull content and load templates.
My question is whether these rules are as efficient as the should be and if anyone sees issues with how they are written? I'm no mod_rewrite expert.
Plus we have had a few users who reported IE bailing out on them when the WWW version of the URL was loaded but I can't see why? Any advice?
ErrorDocument 404 /index.php
RewriteEngine on
RewriteCond %{HTTP_HOST} OTHERSITE.com [NC]
RewriteRule ^(.*)$ https://MAINSITE.com/$1 [L,R=301]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteBase /
RewriteRule ^products - [L,NC]
RewriteRule ^sauces$ /sauces.php?sauce=our-hot-sauce [L,QSA]
RewriteRule ^sauces/([^/\.]+)/?$ /sauces.php?sauce=$1 [L,QSA]
RewriteRule ^recipes/([^/\.]+)/?$ /recipes.php?cat=$1 [L,QSA]
# user has cleared recipe name but not cat AND left trailing slash
RewriteRule ^recipe/([^/\.]+)/$ /recipes.php?cat=$1 [L,QSA]
# has sauce/cat and recipe name
RewriteRule ^recipe/([^/\.]+)/([^/\.]+)/?$ /recipe.php?cat=$1&rec=$2 [L,QSA]
# user has cleared recipe name but not cat
RewriteRule ^recipe/([^/\.]+)$ /recipes.php?cat=$1 [L,QSA]
RewriteRule ^([^/\.]+)/?$ /page.php?page=$1 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2&subsub=$3 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2&subsub=$3&subsubsub=$4 [L,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ /page.php?page=$1&sub=$2&subsub=$3&subsubsub=$4&subsubsubsub=$5 [L,QSA]
Rest of the rules like fine but first 2 301 rules can be combined into one:
RewriteCond %{HTTP_HOST} ^(www\.)?OTHERSITE\.com$ [NC,OR]
RewriteCond %{HTTPS} off
RewriteRule ^ https://MAINSITE.com%{REQUEST_URI} [L,R=301,NE]

Optional trailing slash mod_rewrite

I have a very specific problem.
The title gives a lot of other questions that have correct answers, however I don't know how to fit this to my own rewrite rules.
My .htaccess looks like so:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[^/]*/?$ index.php [NC,L]
RewriteCond %{REQUEST_URI} !(^/dev/zeroyear/$)
RewriteRule ^dev/zeroyear/([^/]+)/?([^/]*)/?([^/]*)/?([^/]*)/?$ /dev/zeroyear/index.php?var1=$1&var2=$2&var3=$3&var4=$4 [L,QSA]
I want the following 2 URLs to redirect to the same page:
http://timesheep.name/dev/zeroyear/news
http://timesheep.name/dev/zeroyear/news/
The last rewrite rule is causing a 500 because of the question mark I put, but the logs say nothing. If I change it to this:
RewriteRule ^dev/zeroyear/([^/]+)/([^/]*)/?([^/]*)/?([^/]*)/?$ /dev/zeroyear/index.php?var1=$1&var2=$2&var3=$3&var4=$4 [L,QSA]
The error goes away, but http://timesheep.name/dev/zeroyear/news will return a 404.
What can I do about this?
You've got a mix of non-greedy matches (which will eat up optional /'s) and optional /'s all mixed together. Try separating them into distinct matches:
RewriteCond %{REQUEST_URI} !(^/dev/zeroyear/$)
RewriteRule ^dev/zeroyear/([^/]+)/([^/]+)/([^/]+)/([^/]+?)/?$ /dev/zeroyear/index.php?var1=$1&var2=$2&var3=$3&var4=$4 [L,QSA]
RewriteCond %{REQUEST_URI} !(^/dev/zeroyear/$)
RewriteRule ^dev/zeroyear/([^/]+)/([^/]+)/([^/]+?)/?$ /dev/zeroyear/index.php?var1=$1&var2=$2&var3=$3 [L,QSA]
RewriteCond %{REQUEST_URI} !(^/dev/zeroyear/$)
RewriteRule ^dev/zeroyear/([^/]+)/([^/]+?)/?$ /dev/zeroyear/index.php?var1=$1&var2=$2 [L,QSA]
RewriteCond %{REQUEST_URI} !(^/dev/zeroyear/$)
RewriteRule ^dev/zeroyear/([^/]+?)/?$ /dev/zeroyear/index.php?var1=$1 [L,QSA]