Forum Moderators: phranque

Message Too Old, No Replies

Redirecting index.php and all query strings back to "/"?

Trying to remove index.php along with any possible query strings.

         

internet tuff guy

11:02 am on Jan 18, 2008 (gmt 0)

10+ Year Member



Hi folks,

I'm trying to rewrite www.mydomain.com/index.php back to www.mydomain.com/, and am using the current solution:

#Rewrite index.php back to /
RewriteCond %{THE_REQUEST} ^[^/]*/index\.php [NC]
RewriteRule . / [R=301,L]

However if the request contains a query string, that query string is appended to the domain, for example www.mydomain.com/index.php?foo=bar rewrites to www.mydomain.com/?foo=bar

I would like to have index.php write back to / regardless of bogus query strings appended, for SEO purposes. My custom CMS produced a few links to index.php with query strings that had no effect on script execution, but were indexed in Google - I'd rather not let that happen again!

Thanks for any help. I've been reading through Apache mod_rewrite files and tutorials to no avail, but have picked up a couple of concepts that were a little enlightening.

jdMorgan

1:42 pm on Jan 18, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Easy to miss in the RewriteRule documentation, but it's there: You must add a "?" to the substitution URL to clear the requested query string:

RewriteCond %{THE_REQUEST} ^[^/]+/index\.php(\?[^\ ]*)?\ HTTP/ [NC]
RewriteRule index\.php$ [b]/?[/b] [NC,R=301,L]

This question mark is a mod_rewrite functional token in this case; It will clear the query string, but will NOT appear as part of the new URL.

The seemingly-redundant "index\.php$" RewriteRule pattern is not; It actually improves efficiency in most cases, since the RewriteCond will not be processed unless the RewriteRule pattern is matched (see docs).

The more-complex RewriteCond pattern prevents redirection of URLs containing "index.php" in the query string only, independent of any previously-executed internal redirects.

Jim

[edit] Fixed per following post to prevent future copy-and-paste errors. [/edit]

[edited by: jdMorgan at 2:25 pm (utc) on Jan. 18, 2008]

internet tuff guy

2:03 pm on Jan 18, 2008 (gmt 0)

10+ Year Member



Your elaborate response and working solution (Sans an open bracket for the NoCase flag :D) were very helpful. Thank you.

I will be re-reading it for hours, no doubt, trying to get mod_rewrite under my belt.

jdMorgan

2:24 pm on Jan 18, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Oops -- I fixed it for future readers of this thread.
(If you want to catch all case variations on "index.php" then you'll need [NC] on the RewriteRule as well.)

Jim

[edited by: jdMorgan at 2:26 pm (utc) on Jan. 18, 2008]

Pfui

4:48 pm on Jan 19, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Jim, might your code work similarly for index.pl kinds of URIs? For example, I want all requests in certain directories to pass through to posts --

/disc/topic1/index.pl?read=01234
/disc/topic2/index.pl?read=56789
(etc.)

-- but I want only on-site referrers and/or specific hosts to access the script proper. In other words, what do you think of the following, please? Apologies if it's more mixed up than not.

Placed in /disc/.htaccess:


# If not on the server (its Host or IP):
RewriteCond %{HTTP_REFERER}!^http://(www\.)?example.com/.*$ [NC]
RewriteCond %{HTTP_REFERER}!^http://98\.76\.654\.321/.*$ [NC]
# And/or hailing from a certain Host or IP:
RewriteCond %{REMOTE_HOST}!^server\.example\.com$
RewriteCond %{REMOTE_ADDR}!^987\.654\.321$
# Send all requests for ALL base index.pl files to intro:
RewriteCond %{THE_REQUEST} ^[^/disc/topic1]+/index\.pl(\?[^\ ]*)?\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[^/disc/topic2]+/index\.pl(\?[^\ ]*)?\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[^/disc/topic3]+/index\.pl(\?[^\ ]*)?\ HTTP/ [NC]
RewriteRule index\.pl$ http://www.example.com/disc/intro.html [NC,R=301,L]

(Note: There should be spaces before every exclamation mark.)

jdMorgan

7:01 pm on Jan 19, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



What is the intent of this subpattern: "[^/disc/topic1]+"?

Right now, it says, "one or more characters not equal to a '/' or 'd' or 'i' or 's' or 'c'" etc. Square brackets define grouped *character alternatives*, and not strings...

We need to know whether it is your intent to redirect (or to not redirect) those particular "discussion topic" index.php requests.

Jim

Pfui

10:06 pm on Jan 19, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Sorry for the confusion. I made the mistake of plugging things a bit willy-nilly into your original example:) --

RewriteCond %{THE_REQUEST} ^[^/]+/index\.php(\?[^\ ]*)?\ HTTP/ [NC]

-- so when I saw the "^[^/]+/index\.php" part, I thought I could specify directories by name because I have some directories with index.pl scripts that are okay to access directly, and some not.

My intent is to redirect all off-site (& not host-specified) requests to just "index.pl" ( e.g.: ^/disc/topic1/index\.pl$) in certain directories. Requests to individual posts (?read=01234) would be allowed.

Sheesh. That sounds clear as mud. Maybe this will help...

Okay ONLY if referrer is on the same server and/or MY hostname makes the request:
http://www.example.com/disc/topic1/index.pl

Okay for everyone:
http://www.example.com/disc/topic1/index.pl?read=01234

Pfui

10:17 pm on Jan 19, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Heeding your brackets info and noting placement, is this how the A-OK directories would be identified?

Placed in /disc/.htaccess:

...continued...


# Send all requests for ALL base index.pl files to intro:
RewriteCond %{THE_REQUEST} ^[^/]+/disc/topic1/index\.pl(\?[^\ ]*)?\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[^/]+/disc/topic2/index\.pl(\?[^\ ]*)?\ HTTP/ [NC,OR]
RewriteCond %{THE_REQUEST} ^[^/]+/disc/topic3/index\.pl(\?[^\ ]*)?\ HTTP/ [NC]
RewriteRule index\.pl$ http://www.example.com/disc/intro.html [NC,R=301,L]

(P.S. In that last line, do we need a ^ as in: RewriteRule ^index\.pl ...?)

[edited by: Pfui at 10:18 pm (utc) on Jan. 19, 2008]

jdMorgan

12:31 am on Jan 20, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That's much better.

But no, do not start-anchor the rule pattern, since that would redirect only a requested URL-path exactly equal to "index.pl", thus defeating your rule.

Jim

Pfui

8:49 pm on Jan 21, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Aw, shoot. That didn't work, Jim. Neither did the umpteen variations I tried before a seriously obsessive testing streak ran out.

FWIW, in addition to a Comcast account, I tested using an AOL account (w/ a no-cache UA pref). I also alternated including, and commenting-out, the on-server and specific-host conditions. But no matter what I did/tried, I either redirected everyone OR I let everyone in; never just-me-to-index.pl, dangit.

If you're game to carry on, would you prefer a clean slate? :)

[edited by: jdMorgan at 9:12 pm (utc) on Jan. 21, 2008]
[edit reason] speeling. [/edit]

jdMorgan

9:13 pm on Jan 21, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Post all lines of your current rule again. The initial RewriteConds could use some work as well, we just hadn't got to them yet.

Jim