Forum Moderators: phranque
# index.php to www.domain.com
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ [domain.com...] [R=301]
# index.shtml to www.domain.com
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.shtml\ HTTP/
RewriteRule ^index\.shtml$ [domain.com...] [R=301]
that should work
I think this is what you need to acheive?
# index.php or index.shtml to www.domain.com/subdir/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.(php¦shtml)\ HTTP/
RewriteRule ^index\.(php¦shtml)$ http://www.domain.com/subdir/ [R=301]
It is not clear why you would wish to "expose" the "/subdir" path by including it in the redirect, so I'm just answering the question you asked.
Jim
Thanks for your response. I didn't know about the pipe, that looks great.
As for the subdir, I would rather not expose it but haven't figured out how to redirect to a subdir without exposing it.
I am sitting up straight, hands folded, and all eyes on the teacher if you're so willing to teach me. ;)
Thanks for your help again!
This is what I have so far:
AddHandler server-parsed .htm .html
Options +FollowSymLinks
RewriteEngine On
rewritecond %{http_host} ^www\.domain\.com [NC]
rewritecond %{REQUEST_URI}!^/subdir/ [NC]
rewriterule ^(.*)$ [domain.com...] [R=301]
RewriteCond %{HTTP_HOST} ^domain\.com [NC]
RewriteRule ^(.*)$ [domain.com...] [r=301,NC]
# index.php or index.shtml to www.domain.com
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.(php¦shtml)\ HTTP/
RewriteRule ^index\.(php¦shtml)$ [domain.com...] [R=301]
External redirects and internal rewrites are not at all the same thing, and mod_rewrite can do either -- and more.
Also, URLs and filepaths are not the same thing, and need not, in fact, have any similarities to each other. As an example, many dynamic sites have thousands of URLs, but only one main file -- the script that accesses a database to generate all of the pages corresponding to those URLs.
An internal rewrite simply changes the filepath associated with a URL. The server uses the rewritten URL-path to determine the actual filepath to use to retrieve the content to be served. This occurs entirely within the server and within the context of the current HTTP request.
An external redirect, in contrast, sends a response back to the client browser or robot that says, "The content you have requested has moved. Please ask for it again at this new address." A redirect response causes the current HTTP transaction to end, and the browser must start a new HTTP request using the URL supplied with the redirect response in order to get the content of the originally-requested page, image, etc. It is this second HTTP request that causes the browser's address bar to change and 'expose' the redirect to the user.
Right, and now to the assignment:
Options +FollowSymLinks
RewriteEngine on
#
# Redirect direct client requests for /index.php or /index.shtml in
# any subdirectory back to www.example.com/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+/)*index\.(php¦shtml)\ HTTP/
RewriteRule ^([^/]+/)*index\.(php¦shtml)$ http://www.example.com/ [R=301,L]
#
# Redirect non-canonical hostname to canonical host
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
#
# [b]Rewrite[/b] Web root directory requests to /subdir
RewriteCond %{REQUEST_URI} !^/subdir/
RewriteRule (.*) /subdir/$1 [L]
Replace the broken pipe "¦" characters in the code above with solid pipe characters before use; Posting on this forum modifies the pipe characters.
Lastly, always flush your browser cache (or IE Temporary Internet Files) before testing any change to .htaccess or any other server config file -- Forcing a reload is not necessarily the same thing as flushing the cache.
Since you have already exposed the /subdir, you may also want to add a redirect much like the first one for the index pages, except that it externally redirects direct client requests for /subdir back to root. This should be placed as the second rule. This addition is left as an exercise for the student. ;)
Jim
Here's what I think I learned so far.
[L] needs to go at the end of all rules per rewrite condition and not just the end of all rewrite rules in a file?
I need to read up on why use THE_REQUEST vs. HTTP_HOST vs. REQUEST_URI, but I'm guessing the use of REQUEST_URI has something to do with not exposing the subdir.
^(.*)$ Basically means all files with a dot in it.
Rewriting the 'subdir' as below means all requests 'not' to the subdir are redirected to that 'subdir'. And since I've exposed that subdir, I now have to figure out how to redirect requests to it.
In the first rule, you are basically saying there should only be one 'index' file for the site and that is in the root and all requests to any index.php or .shtml will be redirected to the root.
So this:([^/]+/) means include requests to any subdirectory.
Now for redirecting the exposed subdir back to root externally putting this at rule #2 and before the other subdir redirect:
# Redirect direct client requests for /subdir/ back to #www.example.com/
RewriteCond %{THE_REQUEST} ^/subdir/ HTTP/
RewriteRule ^/subdir/$ http://www.example.com/$1 [R=301,L]
I think that is it. I will try all this out tonight when the site is less busy. Thanks for all your help Professor. ;) Let me know if I've totally misunderstood something.
Options +FollowSymLinks
RewriteEngine on
#
# Redirect direct client requests for /index.php or /index.shtml in
# any subdirectory back to www.example.com/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+/)*index\.(php¦shtml)\ HTTP/
RewriteRule ^([^/]+/)*index\.(php¦shtml)$ http://www.example.com/ [R=301,L]
#
# Redirect non-canonical hostname to canonical host
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
#
# Rewrite Web root directory requests to /subdir
RewriteCond %{REQUEST_URI}!^/subdir/
RewriteRule (.*) /subdir/$1 [L]
# Redirect direct client requests for /subdir/ back to www.example.com/
RewriteCond %{THE_REQUEST} ^/subdir/[^\ ]*\ HTTP/
RewriteRule ^subdir/(.*)$ http://www.example.com/$1 [R=301,L]
".*" means "any number of any character."
"[^\ ]*" means "any number of any character except for a space."
If the request is a GET of the URL "http://example.com/subdir/foo.html" using an HTTP/1.1 client, then in an .htaccess context:
In regular expressions, certain characters have special meanings, as outlined in the regex tutorial cited in our charter. If you wish to match a special character's literal value, you must escape it by preceding it with a backslash, as illustrated in many places in the code in this thread. The same is true for periods, spaces, "+", "*", backslashes themselves, and several other characters.
Jim
Right now I tried implementing the above solutions and I get a 500 server error. I'm going to have to wait till later tonight to try some more.
Wish there was some sort of test server somewhere to try these redirects out on.
If I have a link that has /subdir/ in it, it still reveals /subdir/
Here is the .htaccess:
AddHandler server-parsed .htm .html
Options +FollowSymLinks
RewriteEngine on
#
# Redirect direct client requests for /index.php or /index.shtml in
# any subdirectory back to www.example.com/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+/)*index\.(php¦shtml)\ HTTP/
RewriteRule ^([^/]+/)*index\.(php¦shtml)$ http://www.example.com/ [R=301,L]
#
# Redirect direct client requests for /subdir/ back to www.example.com/
RewriteCond %{THE_REQUEST} ^/subdir/[^\ ]*\ HTTP/
RewriteRule ^subdir/(.*)$ http://www.example.com/$1 [R=301,L]
#
# Redirect non-canonical hostname to canonical host
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
#
# Rewrite Web root directory requests to /subdir
RewriteCond %{REQUEST_URI}!^subdir/
RewriteRule (.*) /subdir/$1 [L]
redirect 301 /oldfilename.html http://www.example.com/newfilename.php
URL=http://example.com/subdir/
Result code: 301 (MovedPermanently / Moved Permanently)
Date: Wed, 15 Nov 2006 04:21:15 GMT
Server: Apache
Location: http://www.example.com/subdir/
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1
New location: http://www.example.com/subdir/
URL=http://www.example.com/subdir/
Result code: 200 (OK / OK)
So it should be easy for me to figure out right? ;)
As I stare at it, I'm thinking $1 in the rewrite rule containes /subdir/ so it's not really redirecting.
So the correct way is giving me a 500 error. Does this need to be different for different servers maybe?
Actually I see my script above does not have extra slash.
This gives 500 error:
# Rewrite Web root directory requests to /subdir
RewriteCond %{REQUEST_URI}!^subdir/
RewriteRule (.*) /subdir/$1 [L]
This does not give 500 error but of course does not work:
# Rewrite Web root directory requests to /subdir
RewriteCond %{REQUEST_URI}!^/subdir/
RewriteRule (.*) /subdir/$1 [L]
Actually I think the last rule is working, the problem is that any requests to /subdir/filename.php gets redirected to /subdir/filename.php instead of filename.php
So this isn't working?:
# Redirect direct client requests for /subdir/ back to www.example.com/
RewriteCond %{THE_REQUEST} ^/subdir/[^\ ]*\ HTTP/
RewriteRule ^subdir/(.*)$ http://www.example.com/$1 [R=301,L]
I think I'm just redirecting it to itself because $1 contains /photo/.
Anyway, I just thought I'd share what worked.
AddHandler server-parsed .htm .html
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.+/)?index\.(php¦shtml)$ http://www.example.com/ [R=301,L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^subdir(/(.*))?$ http://www.example.com/$2 [R=301,L]
RewriteCond %{HTTP_HOST}!^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
RewriteRule!^subdir(/.*)?$ /subdir%{REQUEST_URI} [QSA,L]
Redirect 301 /oldfilename.html http://www.example.com/newfilename.php