Apache rewrite rule for normalizing case - .htaccess

I run a web-accessible linguistic database on a server. The file lexirumah in the document root of my server contains a WSGI python script serving the application.
I want the application to be available on all matches, independent of case, of http://www\.example\.eu/lexirumah?/?. Currently, I am using the following .htaccess file.
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.example.eu$ [NC]
RewriteRule ^(.*)$ http://www.example.eu/$1 [L,R=301,NC]
RewriteRule ^lexirumah?$ http://www.example.eu/lexirumah/ [L,R=301,NC]
RewriteRule ^lexiruma/$ http://www.example.eu/lexirumah/ [L,R=301,NC]
RewriteRule ^LexiRumah/$ http://www.example.eu/lexirumah/ [L,R=301]
Options +ExecCGI
<Files "lexirumah">
SetHandler fcgid-script
</Files>
When I change the last RewriteRule to
RewriteRule ^LexiRumah/$ http://www.example.eu/lexirumah/ [L,R=301,NC]
I get an infinitite number of redirects. I want to keep the 301 status for the non-canonical URLs, so I tried
RewriteRule ^lexirumah/$ http://www.example.eu/lexirumah/ [L]
RewriteRule ^lexirumah?$ http://www.example.eu/lexirumah/ [L,R=301,NC]
RewriteRule ^lexiruma/$ http://www.example.eu/lexirumah/ [L,R=301,NC]
RewriteRule ^LexiRumah/$ http://www.example.eu/lexirumah/ [L,R=301,NC]
leading to an internal server error. (Presumably the infinite redirection loop that was caught by my browser previously now happens inside mod_rewrite?)
Now I have changed the rules to use a RewriteCond to skip the case normalization when it is already lowercase.
RewriteCond %{REQUEST_URI} !^/lexirumah/$
RewriteRule ^LexiRumah/$ http://www.example.eu/lexirumah/ [L,R=301,NC]
RewriteRule ^lexirumah?$ http://www.example.eu/lexirumah/ [L,R=301,NC]
RewriteRule ^lexiruma/$ http://www.example.eu/lexirumah/ [L,R=301,NC]
Does this set of rules do what I want it to do, or are there any hidden pitfalls that I need to take into account?

Short answer
Yes, your set of rules does what you expect.
Note, though, that you could simply use ^lexirulah/$ in first RewriteRule, since you include the NC flag. As a consequence, the matching will be case-insensitive (No Case). Official documentation of NC flag can be found here.
Also, you don't need a full url (host included) to redirect. You can directly use RewriteRule ^xxxx$ /lexirumah/ [L,R=301,NC] for each rule.
Your initial question
When I change the last RewriteRule to
RewriteRule ^LexiRumah/$ http://www.example.eu/lexirumah/ [L,R=301,NC]
I get an infinitite number of redirects.
If you think about it, it's easy to understand why you end up with an infinite loop. Since NC matches in case-insensitive mode, your redirect will always match your rule, again and again.

Related

Redirect in .htaccess makes me cracy

Following ws call https://training-deluxe.de/nlpdocs/podcast/feed/
should be redirected to podcast hoster podigee
.htaccess
RewriteEngine On
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^(.*)$ https://www.training-deluxe.de/$1 [R=301,L]
RewriteCond %{SERVER_PORT} !^443$
#Whats wrong with the next line
RewriteRule /nlpdocs/podcast/feed/ https://coachingundwissenschaft.podigee.io/feed/mp3 [R=301,L]
RewriteRule /coaching_ausbildung/gesundheitscoach_somatic_release_achtsamkeit.html https://rubin-institut.de/health-practitioner-und-gesundheitscoach/ [L,R=301]
RewriteRule ^(nlpdocs/.*)$ https://www.rubin-institut.de/$1 [R=301,L]
RewriteRule ^(.*)$ https://rubin-institut.de/$1 [L,R=301]
Redirect goes to rubin-institut/nlpdocs/podcast...
I cant get the clue
There's a couple of issues...
RewriteEngine On
RewriteCond %{SERVER_PORT} !=443
RewriteRule ^(.*)$ https://www.training-deluxe.de/$1 [R=301,L]
RewriteCond %{SERVER_PORT} !^443$
You need to remove that 2nd/last RewriteCond directive above as that will break the rule that follows. RewriteCond directives are conditions that apply to the first RewriteRule directive that follows.
#Whats wrong with the next line
RewriteRule /nlpdocs/podcast/feed/ https://coachingundwissenschaft.podigee.io/feed/mp3 [R=301,L]
The first argument to the RewriteRule directive takes a regular expression (regex) - as you've used in later rules. It is not a simple URL-path. And, importantly, in .htaccess the URL-path matched by the RewriteRule pattern does not start with a slash. (You have omitted the slash prefix in the later rule that is evidentally "working".)
It should be like this instead:
RewriteRule ^nlpdocs/podcast/feed/$ https://coachingundwissenschaft.podigee.io/feed/mp3 [R=301,L]
You will need to clear your browser cache before testing since the erroneous 301 (permanent) redirect will have been cached by the browser. Test first with 302 (temporary) redirects to avoid caching issues.
You will also need to check the rule that follows, as that looks like it would have the same problem.
Reference:
https://httpd.apache.org/docs/current/rewrite/intro.html
https://httpd.apache.org/docs/current/mod/mod_rewrite.html

301redirect to remove folder from URL

I have:
mydomain.com/folder-name/segment1/segment2
I want to change it to:
mydomain.com/segment1/segment2
using a 301 redirect.
I've tried:
RewriteCond %{REQUEST_URI} !^/test/.*$
RewriteRule ^(.*)$ /test/$1 [L]
but its not working
here is my htacess file:
# #AddHandler application/x-httpd-php53 .php .php5 .php4 .php3
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} ^/b1/.*$
RewriteRule ^(.*)$ /b1/$1 [R=301,L]
The answer for the first part of the question should be like this:
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/? $2/$3 [R=301,L]
The second code that you've tried is the opposite of what you're asking for initially. This line matches anything not starting with /test/:
RewriteCond %{REQUEST_URI} !^/test/.*$
This line says take everything and rewrite it to the /test/ directory:
RewriteRule ^(.*)$ /test/$1 [L]
So together anything that's not in the test directory is being rewritten to the test directory.
If you're trying to specifically remove the word test then you would remove the ! symbol in your attempt to create a match. Since you already know it's called test there's no need to even make Apache perform this look for 'test' because Apache handles the RewriteCond statement after the RewriteRule (rather unintuitively).
RewriteCond %{REQUEST_URI} ^/?test
You can specialize the rewrite rule like this (I've added [QSA] to catch any query strings:
RewriteRule ^test/([^/]+)/([^/]+)/? $1/$2/ [R=301,L,QSA]
Simply change your code to:
RewriteRule ^test/(.*)$ /$1 [R=301,L,NC]

Deny access to all files but index.php but allow GET variables

Basically I do not want people that visit my site to get all of the files, but all the things I tried and found on the internet disallow the usage of GET variables after the index.php. I'm using a rewrite to make domain.com/lol go to index.php?lol.
This is my current .htaccess file, if you'd like to modify it to make it easier for me, go ahead too.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.domain\.com [NC]
RewriteRule .? http://domain.com%{REQUEST_URI} [L,R=301]
RewriteRule ^act/(.*)$ index.php?act=$1
RewriteRule ^code/(.*)$ index.php?code=$1
RewriteRule ^login$ index.php?login
RewriteRule ^logout$ index.php?logout
RewriteRule ^add$ index.php?add
RewriteRule ^tac$ index.php?tac
RewriteRule ^profile$ index.php?profile
Following rule stops direct requests to index.php (either with or without) arguments:
# block direct requests to index.php and redirect it to /
RewriteCond %{ENV:REDIRECT_STATUS} =""
RewriteRule ^index.php$ /
If needed, you can change the rewrite target and/or add some more conditions based on what exactly is allowed and what's not.

right order of rewrite rules in an htaccess file

I need to have :
http://www.example.com/v1/my-project/ redirected to http://example.com/my-project/
so :
(1) remove the www from the http_host
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
(2) remove the 'v1/' part of the request_uri
RewriteCond %{REQUEST_URI} ^/v1/(.*)$ [NC]
RewriteRule . %1 [R=301,L]
(3) I also want to redirect all 404 to the homepage.
ErrorDocument 404 /
(4) Finally, all my documents actually reside in a "v2/" folder which hosts the current active website, but i don't want "v2" in the url, just "/"
RewriteCond %{REQUEST_URI} !^/v2/ [NC]
RewriteRule ^(.*)$ /v2/$1 [NC,L]
So, here are my rules. My question is: i don't manage (2): it gets redirected to / (because of rule (3) i guess. I think the order of my rules must be faulty but i can't seem to get it right. Can you help ?
"Rule 3" isn't a rule at all, and its order relative to your RewriteRules doesn't matter. Rule 2 is failing for some other reason. I'm not sure whether it will address your problem, but I would simplify your rules somewhat by writing them like this:
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule (.*) http://example.com/$1 [R=301,L]
RewriteRule ^v1/(.*) /$1 [R=301,L,NC]
RewriteCond %{REQUEST_URI} !^/v2/ [NC]
RewriteRule (.*) /v2/$1 [NC,L]
You should first write any rule that is causing an external redirect (R flag) and then the other rules. Otherwise an already rewritten URL can be used for an external redirect though it was just intended for an internal redirect.
So I won’t change the order you have right now.

.htaccess mod_rewrite playing with variables

I want to have my site urls look like
http://example.com/place/info?var=info&morevars=ifneeded
Place and info are also variables but they have a fixed name, the ones after would vary. EDIT This is the url I am trying to rewrite
http://example.com/test.php?place=test&action=info&var=info&morevars=ifneeded
This is what I have so far
RewriteEngine on
RewriteRule ^([A-Za-z0-9-]+)/?$ test.php?place=$1 [NC]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ test.php?place=$1&action=$2 [NC]
I think there a way to do this with {QUERY_STRING} but I can't get it to work just 500 errors or it don't make a differences.
You have set the QSA flag that automatically appends the original requested query to the new one:
RewriteEngine on
RewriteRule ^([A-Za-z0-9-]+)/?$ test.php?place=$1 [NC,QSA]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ test.php?place=$1&action=$2 [NC,QSA]
You're missing the first /
RewriteEngine on
RewriteRule ^/([A-Za-z0-9-]+)/ test2.php?place=$1 [NC]
RewriteRule ^/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/ test2.php?place=$1&action=$2 [NC]

Resources