mod_rewrite "too many redirects" problem - mod-rewrite

Trying,
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^TRACE
RewriteRule .* - [F]
RewriteCond %{HTTP_HOST} ^(.*)dev\.example\.edu$ [NC]
RewriteRule ^/test(.*)$ http://dev.example.edu/test/index.php/test$1 [NC]
</IfModule>
on an apache 2.2 server, to get this rewrite working to hide the "index.php/test" part of the path.
everything i've tried either loops the url part (index.php/test) within the address bar or gives a "too many redirects" error.
i suspect that the "test" part of the equation being on both sides is throwing it off but am not sure how to get it to work.
i just want:
dev.example.edu/test/index.php/test*
to rewrite to:
dev.example.edu/test/*
thanks

You need to exclude the destination path to avoid an infinite recursion:
RewriteCond %{HTTP_HOST} ^(.*)dev\.example\.com$ [NC]
RewriteCond $1 !^/index\.php/test/
RewriteRule ^/test/(.*)$ http://dev.example.com/test/index.php/test/$1 [NC]
Here the match of the first grouping ($1) is checked not to match ^/index\.php/test/.
But if you want to rewrite /test/index.php/test/… to /test/…, you will rather need this rule:
RewriteCond %{HTTP_HOST} ^(.*)dev\.example\.com$ [NC]
RewriteRule ^/index\.php/test/(.*)$ http://dev.example.com/test/$1 [NC]

Per Jim at webmasterworld (thanks!)
"The [P] flag invokes a reverse-proxy request to the server at the designated URL; That is, it opens a new out-going HTTP connection and sends a request to that server. So at the very least, your configuration is twice as slow as it should be, just using the original working rule, because your server is sending itself a new request via HTTP instead of just serving the content from a non-default-mapped filepath.
It seems to me that all that's needed is an internal rewrite, so that requests for the resource at URL
http://dev.example.edu/distribution/ are served with the content generated by the script at the server filepath /distribution/index.php/distribution/"
RewriteEngine on
#
# Return 403-Forbidden response to TRACE requests
RewriteCond %{REQUEST_METHOD} ^TRACE
RewriteRule .* - [F]
#
# Internally rewrite requests for URL-path /recreation/<anything>
# to filepath /eel/index.php/recreation/<anything>
RewriteCond %{HTTP_HOST} ^dev\.example\.edu [NC]
RewriteRule ^/recreation/(.*)$ /ee1/index.php/recreation/$1 [L]
#
# Internally rewrite requests for URL-path /distribution/<anything>
# to filepath /distribution/index.php/distribution/<anything>
RewriteCond %{HTTP_HOST} ^dev\.example\.edu [NC]
RewriteRule ^/distribution/(.*)$ /distribution/index.php/distribution/$1 [L]
So I think I was just making it more complicated than it had to be. I've removed the P flag and removed the full server address from the rewriterule.

Related

"If request" in .htaccess?

I use rewrite condition to redirect website always to www. my code is:
RewriteCond %{HTTP_HOST} !^www\.website\.com$ [NC]
RewriteRule ^(.*)$ http://www.website.com/$1 [L,R=301]
I can't found on the internet how can i do request if in url '.com' i need it because the website must be also localy accessible.
For example: i found this, but i can't understand how can i implement it with my script.
Your current RewriteCond is correct for applying www. to website.com if it is not already present. To avoid the RewriteRule happening when working on localhost, you need an additional RewriteCond to check the host.
This is because the condition !^www\.example\.com$ matches any domain except www.example.com, which includes localhost.
# Only apply other conditions if not working on localhost
RewriteCond %{HTTP_HOST} !localhost [NC]
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
You can make it a little more dynamic in case you need to work with multiple domains (example.com, example.org) and transform each to www.example.com, www.example.org:
# If not on localhost
RewriteCond %{HTTP_HOST} !localhost [NC]
# and the domain does not begin www.
RewriteCond %{HTTP_HOST} !^www\.
# Redirect to apply the www. to HTTP_HOST
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L,R=301]
Use caution when testing - your browser may cache old 301 redirects. You may need to change them to R=302 during testing and clear your browser cache. When you are satisfied it works, change it back to R=301.
That RewriteCond should already work for your case, the next rule is processed only if the condition matches, so that rule is not processed for localhost.

mod_rewrite: 2 files should always be SSL, the rest always HTTP

I want to ensure that a small number of URLs in my application are always served over SSL; the rest should always be served over HTTP.
My current mod_rewrite ruleset goes like this:
RewriteCond %{HTTPS} off
RewriteRule ^/?account.html$ https://example.com/account.html [L]
RewriteRule ^/?checkout.html$ https://example.com/checkout.html [L]
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !/account.html$
RewriteCond %{REQUEST_URI} !/checkout.html$
RewriteRule (.*) http://example.com/$1 [L]
The first file in each RewriteCond works OK (account.html in this example). The 2nd file doesn't work - the server is "redirecting in a way that will never complete".
Any ideas on how to make this work? In production there'll be more than 2 SSL-only URLs, likely 7 - 10.
Thanks
You must use R flag to redirect url
RewriteEngine On
# redirect account.html or checkout.html (if http) to https
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/(account|checkout)\.html$ [NC]
RewriteRule ^ https://%{HTTP_HOST}/%1.html [R,L]
# redirect other urls (if https) to http
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/(account|checkout)\.html$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R,L]
Note: i used R flag, which performs a 302 redirect by default. Feel free to replace [R,L] by [R=301,L] when it works (301 redirect is a permanent redirect and is cached by browsers)

Rewrite subdomain to main domain for images only using htaccess

I have a domain, where everything except image\css etc. are handled by a single php file. However after a reorganisation, alot of images have been moved from sub-domains to the main domain. So I'm looking for a way to redirect all image\css files to the main domain if they were originally on one of the sub-domains. My current code is
RewriteEngine On
RewriteCond %{REQUEST_URI} !(\.png|\.jpg|\.gif|\.jpeg|\.ico|\.bmp|\.css|\.ts|\.js)$
RewriteRule !^index\.php$ /index.php [L]
I've tried a couple of ways to redirect it, but I seem to break on of the existing rules, whatever I try.
Thanks
The final solution I came up with
RewriteEngine On
# Check the request isn't for the main domain
RewriteCond %{HTTP_HOST} !^domain\.com$
# Check the request is for a static resource
RewriteCond %{REQUEST_URI} \.(png|jpg|gif|jpeg|ico|bmp|css|ts|js)$
# Redirect to main domain
RewriteRule (.*) http://domain\.com/$1 [R=301,L]
# if the request isn't for index.php,
# (invisibly) redirect to index.php
RewriteCond %{REQUEST_URI} !(\.png|\.jpg|\.gif|\.jpeg|\.ico|\.bmp|\.css|\.ts|\.js)$
RewriteRule !^index\.php$ /index.php [L]
For information only. As really the credit goes to jon for the answer I just tweaked it for my needs.
If the URLs in your HTML still point to the subdomains, you'll need to setup htaccess redirects on those subdomains, not on the main domain, as the requests will still be going to the subdomains.
For example in /var/www/vhosts/sub.domain.com/httpdocs/.htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI} \.(png|jpg|gif|jpeg|ico|bmp|css|ts|js)$
RewriteRule (.*) http://domain.com/$1 [R=301,L]
And in /var/www/vhosts/sub2.domain.com/httpdocs/.htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI} \.(png|jpg|gif|jpeg|ico|bmp|css|ts|js)$
RewriteRule (.*) http://domain.com/$1 [R=301,L]
UPDATE
Based on your comment that Apache handles each subdomain as if it were the main one, try this:
RewriteEngine On
# Check the request isn't for the main domain
RewriteCond %{HTTP_HOST} !(www\.)?domain\.com$
# Check the request is for a static resource
RewriteCond %{REQUEST_URI} \.(png|jpg|gif|jpeg|ico|bmp|css|ts|js)$
# Redirect to main domain
RewriteRule (.*) http://domain.com/$1 [R=301,L]

mod_rewrite secure redirect

Struggling with mod_rewrite trying to redirect a non-secure page to a secure one. This works:
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} (help/returns)
RewriteRule .? https://mysite.localhost/%1/ [R=301,L]
But this doesn't:
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP:Host} (mysite.localhost|mylivesite.com)
RewriteCond %{REQUEST_URI} (help/returns)
RewriteRule .? https://%1/%2/ [R=301,L]
The URL it tries to give me is https://help/returns//
I can't seem to get the HTTP:host into the final RewriteRule line.
I need the host in there so I can use the same file for local dev and live deployment.
Most grateful for any input.
You can use this rule:
RewriteCond %{HTTPS} =off
RewriteRule ^help/returns https://%{HTTP_HOST}%{REQUEST_URI} [QSA,R=301,L]
This rule will redirect all requests to http://example.com/help/returns to a secure (HTTPS) location: https://example.com/help/returns -- it will preserve full URL path + query string. You have too many conditions, rule becomes complex which is not a good thing when your server is REALLY busy (regular expressions are expensive).
I have replaced %{SERVER_PORT} 80 by more proper %{HTTPS} =off (this especially useful if your site is run on non-default port, which is 80).
I have also removed HTTP_HOST matching part -- you don't really need it unless you have more than one domain name/subdomain bound to the same site. In case if you need this condition just add this line after 1st line: RewriteCond %{HTTP_HOST} ^(mysite.localhost|mylivesite.com)

Mapping a secondary domain to a subdirectory using mod_rewrite

I am looking to map a secondary domain to a subfolder on my document root.
For example, if requests to the domain www.example.com map to my DocumentToot, then requests to www.exampletwo.com go to /sites/files/.
I am unable to accomplish a redirect from www.exampletwo.com/index.html to www.exampletwo.com/sites/files/index.html while making the URL still display www.exampletwo.com/index.html. Any ideas?
I believe you're looking for something like this:
RewriteCond %{HTTP_HOST} ^(www\.)?exampletwo\.com [NC]
RewriteRule ^/(.*) /sites/files/$1 [L]
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com [NC]
RewriteRule ^/(.*) http://www.exampletwo.com/$1 [L,R]
RewriteCond %{HTTP_HOST} ^(www\.)?exampletwo\.com [NC]
RewriteRule ^/(.*) http://www.exampletwo.com/sites/files/$1 [L,P]
The P flag uses the proxy module, therefore the url is not changed (no redirect) on the client.

Resources