Forum Moderators: phranque

Message Too Old, No Replies

index.$ to www.domain.com

index.php and index.shtml to www.domain.com

         

babushka

1:48 pm on Nov 13, 2006 (gmt 0)

10+ Year Member



What is the best way to write this so that both the current index.php and the older index.shtml all point to the root domain? Should I use a index\.$ or do I write this for each index type?

# 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]

sandyk20

3:17 pm on Nov 13, 2006 (gmt 0)



RewriteEngine on
RewriteCond %{THE_REQUEST} index\.php
RewriteCond %{QUERY_STRING} ^$
RewriteRule index\.php [domain.com...] [L,R=301]

that should work

babushka

3:58 pm on Nov 13, 2006 (gmt 0)

10+ Year Member



Hi Sandy,

I'm not sure I understand. If I understand correctly, what you are saying is that if someone requests www.domain.com/index.shtml, they will be redirected to www.domain.com/subdir/. Correct?

Thanks for your help!

sandyk20

7:55 pm on Nov 13, 2006 (gmt 0)



Hello,
Nope if someone requests www.domain.com/subdir/index.php they will be redirected back to www.domain.com/subdir/?

I think this is what you need to acheive?

jdMorgan

8:10 pm on Nov 13, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member




# 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]

Replace the broken pipe "¦" characters in the code above with solid pipe characters before use; Posting on this forum modifies the pipe characters.

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

babushka

8:19 pm on Nov 13, 2006 (gmt 0)

10+ Year Member



Hi 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!

babushka

10:57 pm on Nov 13, 2006 (gmt 0)

10+ Year Member



Hmmm, I tried the suggestion, I did replace the bar, and the index.php redirects fine but the index.shtml does not. Do I have to put some addhandler in there?

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]

jdMorgan

3:38 am on Nov 14, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Are you sitting comfortably?

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]

Change the rule order to avoid exposing the /subdir and to avoid chained (multiple) redirects. Internally rewrite -- not externally redirect -- the root folder requests to the /subdir. Be sure that the (now) first rule will recognize index page requests made to /subdir, as well as the root or any other folder. Fix missing/incorrect [L] and [NC] flags. Standardize capitalization and remove superfluous anchors and flags.

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

babushka

2:04 pm on Nov 14, 2006 (gmt 0)

10+ Year Member



Wow thanks! I am off to study this and hope to get to it tonight. Then we'll see how well I've done my homework. ;)

babushka

3:56 pm on Nov 14, 2006 (gmt 0)

10+ Year Member



ok due to rain I have more time now than I expected.

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]

jdMorgan

6:53 pm on Nov 14, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



A few tweaks:

# 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]

Read up on regular expressions -- See the links in our forum charter (charter link at top left of this page). Regular expressions is a powerful pattern-matching "language" than is responsible for much of the usefulness of mod_rewrite, other Apache directives, and many currently-popular programming and scripting languages.

".*" 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:

  • RewriteRule sees "subdir/foo.html"
  • %{REQUEST_URI} is "/subdir/foo.html" (note leading slash, not visible to RewriteRule in .htaccess)
  • %{HTTP_HOST} is "example.com"
  • %{HTTP_METHOD} is "GET"
  • %{THE_REQUEST} is "GET /subdir/foo.html HTTP/1.1"

    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

  • babushka

    2:15 am on Nov 15, 2006 (gmt 0)

    10+ Year Member



    Thanks for all your help. I've been perusing the docs the best I can but for some reason have a hard time grasping this.

    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.

    babushka

    3:08 am on Nov 15, 2006 (gmt 0)

    10+ Year Member



    Well I've pretty much narrowed it down to this as nothing else seems to be a problem.

    # Rewrite Web root directory requests to /subdir
    RewriteCond %{REQUEST_URI}!^/subdir/
    RewriteRule (.*) /subdir/$1 [L]

    babushka

    3:29 am on Nov 15, 2006 (gmt 0)

    10+ Year Member



    Well crap.

    I set up a subdomain to test, and it worked perfectly. Only thing I left out was:

    # Redirect non-canonical hostname to canonical host
    RewriteCond %{HTTP_HOST} ^example\.com [NC]
    RewriteRule (.*) http://www.example.com/$1 [R=301,L]

    Now I'm really confused. :(

    babushka

    3:55 am on Nov 15, 2006 (gmt 0)

    10+ Year Member



    Ok, not sure why it wasn't working before (I swear I was religiously flushing my cache) but this is not giving a 500 error now. There is still one issue.

    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

    babushka

    4:23 am on Nov 15, 2006 (gmt 0)

    10+ Year Member



    Funny when I check the headers for example.com/subdir/ I get this:

    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.

    jdMorgan

    6:39 am on Nov 15, 2006 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    Your last rule has an error in it:

    # Rewrite Web root directory requests to /subdir
    RewriteCond %{REQUEST_URI} !^subdir/
    RewriteRule (.*) /subdir/$1 [L]

    Compare this very carefully to the one I posted above, and re-read the bulleted list of what each server variable contains.

    Jim

    babushka

    1:12 pm on Nov 15, 2006 (gmt 0)

    10+ Year Member



    ok I see the extra slash I put in. So that is why it wasn't working for me before, I did not have the extra slash and I got a 500 error.

    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/.

    babushka

    2:28 pm on Nov 15, 2006 (gmt 0)

    10+ Year Member



    Ok reading through more docs I take it $1 should contain .*

    jdMorgan

    7:25 pm on Nov 15, 2006 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    > So the correct way is giving me a 500 error. Does this need to be different for different servers maybe?

    No. It needs to be correct on all servers.

    What is the log entry in your server error log when you get the 500-Server Error?

    Jim

    babushka

    10:04 pm on Nov 15, 2006 (gmt 0)

    10+ Year Member



    Hmmm, looks like it is picking up the forward slash and nothing else if I read this correctly. I've tried removing and adding slashes before subdir but haven't found a combination that works.

    "GET / HTTP/1.1" 500 1005 "-"

    jdMorgan

    10:32 pm on Nov 15, 2006 (gmt 0)

    WebmasterWorld Senior Member 10+ Year Member



    What is the log entry in your server error log when you get the 500-Server Error?

    Jim

    babushka

    2:25 am on Nov 16, 2006 (gmt 0)

    10+ Year Member



    This is the error message:

    "mod_rewrite: maximum number of internal redirects reached. Assuming configuration error. Use 'RewriteOptions MaxRedirects' to increase the limit if neccessary."

    So for some reason it goes into an endless loop.

    babushka

    1:53 pm on Nov 16, 2006 (gmt 0)

    10+ Year Member



    Another modrewrite guru provided this code to use and it works. I am not sure why though. My brain is having trouble parsing the second rule there. The only thing it doesn't do is give me back my max toolbar pagerank whereas the code you were providing was giving me my max. Not a big deal I guess since it has no bearing on my actual search standings.

    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