Forum Moderators: phranque

Message Too Old, No Replies

mod rewrite internal rewrite works as external redirect

         

chrisman

3:30 pm on Mar 14, 2012 (gmt 0)

10+ Year Member



hello,

i've a problem with mod_rewrite. apache redirects user, but it should just rewrite the url internally, not visible for user.

this is the rewriterule (first):
RewriteRule ^([a-zA-Z0-9_-]*)/(.*?)\.html(.*?)$ phpfile.php?file=$2&lang=$1$3 [L]


this rewriterule works so far. but when i extend my ruleset to use ssl subject to .html-file in url it does not work anymore in special cases:

ruleset extension (in .htaccess before the other rule):
RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} !^.*?lang/usessl.html*
RewriteRule ^(.*) http://%{HTTP_HOST}/$1 [L,R=301]



user request:
[domain.com...]

though this user request is not matched by the rewrite condition the first rewriterule is executed as a redirect instead a (internal) rewrite.

any ideas?

kind regards,
chris

g1smd

3:46 pm on Mar 14, 2012 (gmt 0)

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



There are a lot of errors in your code.

Never use .* at the beginning or in the middle of a RegEx pattern.

Escape literal periods in RegEx patterns.

html(.*?)$ will never match a query string. RewriteRule can see only the path part of the request.

By using ^([a-zA-Z0-9_-]*)/(.*?)\.html you allow a request for
example.com//.html
to be a valid request. Use + in place of * in the first pattern and ([^/.]+) in place of (.*?) in the second pattern.

.html* matches .htm and .html and htmllllllll alike.

Put the rules in the right order, correct the errors above and let's take another look.

chrisman

4:40 pm on Mar 14, 2012 (gmt 0)

10+ Year Member



g1smd, thanks for your fast reply.

i corrected the errors:

#SSL
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_URI} ^/lang/usessl\.html(.*)$
RewriteRule ^(.+) https://%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} !^/lang/usessl\.html(.*)$
RewriteRule ^(.+) http://%{HTTP_HOST}/$1 [R=301,L]

RewriteRule ^([a-zA-Z0-9_-]+)/(.+)\.html(.*)$ phpfile.php?file=$2&lang=$1$3 [L]


unfortunately the problem still exists.

>RewriteRule can see only the path part of the request.
I guess, that's not true. $3 is not empty in last rewriterule (tested).

take another look?

thank you!

g1smd

6:03 pm on Mar 14, 2012 (gmt 0)

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



In the final rewrite (.+) is still the wrong pattern to use here.


>RewriteRule can see only the path part of the request.
I guess, that's not true.

It certainly is true. RewriteRule patterns can match only the PATH part of the request.

What do your URLs look like?
-
example.com/foo/bar.html/somestuff

-
example.com/foo/bar.html?somestuff


The first URL may work if using AcceptPathInfo.

The latter URL format cannot be matched by your pattern. The query string is separate and need a RewriteCond looking at the QUERY_STRING parameter. The QSA flag will re-appened the original query string.

chrisman

6:48 pm on Mar 14, 2012 (gmt 0)

10+ Year Member



the following rule does not work because of missing query data:
RewriteRule ^([a-zA-Z0-9_-]+)/(.+)\.html phpfile.php?file=$2&lang=$1 [QSA,L]


URLs look like:
example.com/lang/file.html&query=data

maybe i should mention this command on the beginning of .htaccess:
RewriteBase /


the rule is working for all non-ssl pages, but not for the usessl.html

any ideas?

thank you and kind regards,
chris

lucy24

7:08 pm on Mar 14, 2012 (gmt 0)

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



Objection ;) The pattern
html(.*?)$

--with or without anchor --will always match but the capture will always be empty. "Zero or more".

RewriteCond %{REQUEST_URI} ^/blahblah

If this were in the Rule itself, it would always fail, except for malformed requests with // double slash after the domain name.

the following rule does not work because of missing query data:

That's right. So you need to add a RewriteCond looking at the %{QUERY_STRING}. afaik, only two Conditions can "see" the query string; the other one is the complete %{THE_REQUEST}. If you are uncertain, do a Forums search for "query string boilerplate". I post it every month or so.