homepage Welcome to WebmasterWorld Guest from 54.237.78.165
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
[mod rewrite] i don't understand this rule
Oxaguian



 
Msg#: 4596053 posted 12:56 pm on Jul 24, 2013 (gmt 0)

Hello,

I don't understand why i have this problem.
I created a rule in the htaccess file
RewriteEngine On
RewriteRule ^([^/]*)/([^/]*)/([^/]*)\.html$ page1.php?c=$1&cat_id=$2&cat_name=$3 [L]


and this works normally. Then I added a new rule for another page:
RewriteRule ^([^/]*)/([^/]*)\.html$ page2.php?id_sede=$1&nome_sede=$2 [L]

Although viewing the url correctly written, when I click on the link to go to page2.php, always opens page1.php ... why?

Thanks for help

 

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4596053 posted 9:25 pm on Jul 24, 2013 (gmt 0)

Tangential:
Here you should use + rather than *, or else your rule will accept empty file/directory names. Or it will treat doubled slashes as empty names, depending on how you look at it.

Also tangential:
The target should begin with a / directory slash. If it doesn't, the Rule will use whatever you've set as your RewriteBase; if you haven't set one, the default is / (root). (If you have set a RewriteBase, this may not be tangential after all.)

You've correctly got [^/] rather than . so we can exclude that explanation. And both rules have opening anchors. So far so good.

So the first rule is for
/blah/blah/blah.html

and the second is for
/blah/blah.html

Although viewing the url correctly written

This wording is a little obscure. Does the same thing happen if you explicitly type in an URL that is intended for page2.php? Or does it only show the wrong content when you click on a link? What about when you type in garbage URLs that fit one pattern or the other?

Tangential again:
This pair of rules means that anything in the form
example.com/dir1/name.html
or
example.com/dir1/dir2/name.html
will get a 200 from the server and will then be passed along to a php page. I hope both php pages are set up to return a 404 if the parameters are bad.

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4596053 posted 12:43 am on Jul 25, 2013 (gmt 0)

Change all * to +, clear your cache and see if that alters anything.

Do you really need ".html" on the end of your friendly URLs? Isn't this the time to "go extensionless"?

Oxaguian



 
Msg#: 4596053 posted 9:37 am on Jul 25, 2013 (gmt 0)

Thanks for your replies lucy24 and g1smd.


I used + rather than * but i can't use a / directory slash because
already have set it on my global php $var:

define('WEB_ROOT', 'http://www.mysite.com/');

so, on my php page:

<?php echo WEB_ROOT . $var1."/".$var2; ?>.html"><?php echo $name; ?>

and the htaccess rule:

RewriteRule ^([^/]+)/([^/]+)\.html$ page2.php?id_sede=$1&nome_sede=$2 [L]

The link seems correct

www.mysite.com/9/file-name.html

But the problem remains. When I click on the link, instead of
opening page2.php opens page1.php

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4596053 posted 11:20 am on Jul 25, 2013 (gmt 0)

When I click on the link, instead of
opening page2.php opens page1.php

Hence my questions. Does the problem happen only when you click on the link, or also when you type in the URL? What about typing in some made-up garbage URLs that fit one of your two patterns? If you comment-out one rule or the other or both, what happens to the request?

but i can't use a / directory slash

Things that happen within a php page have no effect on what happens in mod_rewrite.

g1smd

WebmasterWorld Senior Member g1smd us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4596053 posted 11:38 am on Jul 25, 2013 (gmt 0)

The RewriteRule target path should have a leading slash.

Use the
Live HTTP Headers extension for Firefox and see if that gives any clues as to what is going on.
Oxaguian



 
Msg#: 4596053 posted 2:15 pm on Jul 25, 2013 (gmt 0)

I tried to comment on the rule on page 1. The links on page 2 work perfectly...
So it must be a conflict between the first and the second rule?
Does the problem happen only when you click
on the link, or also when you type in the URL? What about typing
in some made-up garbage URLs that fit one of your two patterns?
I'm sorry but I do not understand, what does this mean? I'm newbie

I tried to enter a url like localhost/bla/im-newbie.html
and the result is always the same: page2.php


The RewriteRule target path should have a leading slash.


return a 404 error

I'm working on localhost with WAMP

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4596053 posted 11:36 pm on Jul 25, 2013 (gmt 0)

Your server only sees the request. It doesn't know and doesn't care what the browser did in order to send in that request. If you are testing a rule by clicking on links, then there are two completely unrelated ways things can go wrong:
--the link itself might point to the wrong URL
--the RewriteRule might do the wrong thing

At this point in testing, you should not be clicking links at all. FIRST test your rule by manually typing URLs into your browser's address bar.

I'm working on localhost with WAMP

Good. It's helpful to get things sorted out locally before you bring them live. The practical differences are:
--If a rule creates a redirect to some other page on your own site, the "target" can only begin with a leading slash, not with a full "http://www.example.com". Sure, you could express the target as "localhost:whatever-the-port-number-is" but there's no point because you still have to edit it for the live site.
--Nobody is going to sneak into your own computer and inject Bad Stuff, so it isn't really essential to have a leading slash in the target. But it does no harm, and it's one less thing to edit when you go live.

I tried to enter a url like localhost/bla/im-newbie.html
and the result is always the same: page2.php

Now you need something like LiveHeaders so you can easily track the requests your browser is sending in. Note that LiveHeaders will NOT give a record of server rewrites, only redirects. Requests are also tracked in your server logs, if they exist. (My MAMP setup doesn't seem to keep ordinary logs, only error logs.)

If I'm reading your reply correctly, typing in an URL leads to the intended rewrite. Things only go wrong when you're clicking on a link. That means the problem is not in your RewriteRule at all and you can stop worrying about it. Whew.

JD_Toims

WebmasterWorld Senior Member Top Contributors Of The Month



 
Msg#: 4596053 posted 1:14 am on Jul 29, 2013 (gmt 0)

I can't quite figure out why that would happen the way the rules are written, unless this is really in the httpd.conf file rather than the .htaccess, then it should happen... My best guess is there's some "oddity" in the greediness of the [^/] as the end pattern when there should not be a / to break on or since this is on a localhost (it sounds like) somehow the preceding / is present in the .htaccess file, unlike most situations.

I'd try:

RewriteEngine on
RewriteRule ^([^/]+)/([^/]+)/([^/.]+)\.html$ page1.php?c=$1&cat_id=$2&cat_name=$3 [L]
RewriteRule ^([^/]+)/([^/.]+)\.html$ page2.php?id_sede=$1&nome_sede=$2 [L]

ADDED:

If that doesn't work, then reverse the patterns...

RewriteEngine on
RewriteRule ^([^/]+)/([^/.]+)\.html$ page2.php?id_sede=$1&nome_sede=$2 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/.]+)\.html$ page1.php?c=$1&cat_id=$2&cat_name=$3 [L]

* Also, I noticed you said you tested with an empty cache, make sure and maybe even use a different browser if you're using FireFox... It's gotten so bad with not re-requesting sometimes I've almost had to quit using it for work, because I can dump the cache (twice), refresh on a page with an iFrame that has a value in the query_string changed and if the query_string is the same length (say I change i=3 to i=8) it Refuses to re-request the iFrame from the source and display the correct information... The only way I can get it to re-request the iFrame from the source in that situation is to go into the inspector, view the source, double click to edit the iFrame URL then click off of it and for some reason that triggers a reload even though I don't change anything in the iFrame URL that way.

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4596053 posted 2:08 am on Jul 29, 2013 (gmt 0)

or since this is on a localhost (it sounds like) somehow the preceding / is present in the .htaccess file, unlike most situations

Not unless WAMP behaves differently from MAMP. I use essentially the same htaccess for live site and MAMP, minus all the ### about hotlinking and so on that I don't need.

If you want to split hairs, the leading / isn't a config vs. htaccess difference, it's directory-level vs. whole-thing. That means anything in a <Directory> section comes down on the htaccess side, not the config side. Unless I'm reading the Apache docs sideways, which has been known to happen.


Here's one thing you can do in MAMP/WAMP that you can't do on your live site:
ExpiresActive On
ExpiresByType text/html "access"

Where I have "html" put in any extension you use for pages. Ideally this will force the browser to put in a new request to the server every single time you ask for a page. It doesn't always work, but it can't hurt.

At least with WAMP you know for sure that there's no intervening ISP shoving its remote-caching oar in. It's just you and the server.

Can you set up a RewriteLog? I've just been wrestling with this in another venue; turns out it's a bit of a pain and SQL is furious with me, but in the end you do get some information. You don't need to crank the LogLevel all the way up to 9; 3 or 4 should do it. In 4000+ lines of log, I found only a dozen or so (4) and nothing higher.

JD_Toims

WebmasterWorld Senior Member Top Contributors Of The Month



 
Msg#: 4596053 posted 2:15 am on Jul 29, 2013 (gmt 0)

Not unless WAMP behaves differently from MAMP.

Yeah, I have MAMP running too and can't figure out why that would happen, but when someone's "running their own thing" and there's some "oddity" I usually go with the "anything's possible" line of thinking... I can't see why the posted URL (www.mysite.com/9/file-name.html) would "qualify" for the first rule even with the * on the pattern, other than the preceding / being present when it's tested, because 2 slashes in the path should be required for there to be a match, but there's only 1 if it's in the .htaccess and the first / is dropped like it should be...

Unless! maybe the .htaccess is "on a higher level" than normal? I can't recall testing to see if that makes a difference, but what just "popped into my head" is if the .htaccess is on the same level as the "public_html" (in generic terms) rather than within the "host directory" maybe then the preceding / is present when the .htaccess is processed?

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4596053 posted 3:48 am on Jul 29, 2013 (gmt 0)

The trailing directory slash is always dropped. Where the location of htaccess makes a difference is in anchors:

filename.html
matches anything that meets the htaccess, but

^filename.html
only matches if it's in the same directory as htaccess (not necessarily the root)

The target always works from the / root; only the pattern is location-specific.

By the usual yawn-provoking coincidence I have just come from poring over my first attempt at RewriteLogs in MAMP. (First conclusion: I have no idea what triggers a level 5 or higher log entry, because I never saw any!) RewriteLogs are a pain if your RewriteRules are located in htaccess-- or any <Directory> section-- because every single action is preceded by "strip per-dir prefix" like this (adding line breaks and one blank space):

strip per-dir prefix:
/Users/myname/Documents/www_example/directories /paintings/pending/blowups/largephotograph.jpg
->
paintings/pending/blowups/largephotograph.jpg

You'd think they would strip it once when you switch on the RewriteEngine, and put it back at the end. But no, every single time. To further clutter the logs, any "pass through" action is (1). This may be important when the rules are located in the config file, but it's a bit gratuitous in htaccess when everything is a pass-through.

So if you're looking at a RewriteLog based on htaccess the first thing you have to do is delete two-thirds of the entries so you can see what's really been happening :)

I also note with interest that internal requests resulting from mod_dir activity simply ignore all rules with the [R] flag-- something I'd stumbled across earlier in a different context, but now it comes into sharper focus.

JD_Toims

WebmasterWorld Senior Member Top Contributors Of The Month



 
Msg#: 4596053 posted 4:05 am on Jul 29, 2013 (gmt 0)

I also note with interest that internal requests resulting from mod_dir activity simply ignore all rules with the [R] flag-- something I'd stumbled across earlier in a different context, but now it comes into sharper focus.

Interesting, and...

I don't think the other should matter according to the docs and how things are supposed to work, but there's still no reason I can see for the ruleset initially posted to not work the way it's intended if things are working "the way they should" and how we understand they're supposed to... Do you see one? [If not I'm still in "anything is possible, especially when running one's own box", territory]

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4596053 posted 6:17 am on Jul 29, 2013 (gmt 0)

Oxaguian, still with us?

Go back to your two RewriteRule patterns:
^([^/.]+)/([^/.]+)/([^/.]+)\.html
and
^([^/.]+)/([^/.]+)\.html

Now pick two ordinary static html pages that really exist on your WAMP site. For example:

RewriteRule ^([^/.]+)/([^/.]+)/([^/.]+)\.html /onepage.html [R=301,L]

RewriteRule ^([^/.]+)/([^/.]+)\.html /otherpage.html [R=301,L]

DON'T CLICK ANY LINKS. If you type in random URLs-- any old garbage, so long as it's got one or two directories and then a filename in html-- do you get redirected to the two different pages?

If yes, continue to step 2.

Don't change anything, but delete the R=301 part of each flag, leaving only the [L]. Again try some random type-ins. Do you see the content of the two pages?

Oxaguian



 
Msg#: 4596053 posted 8:50 am on Jul 29, 2013 (gmt 0)

Oxaguian, still with us?

Yes, again here...

Excuse me, I made a big error of assessment of the rule. Commenting the lines one by one, I found that the rule in conflict is not
^([^/]+)/([^/]+)/([^/]+)\.html$ page1.php?c=$1&cat_id=$2&cat_name=$3 [L]

but

^([^/]+)/([^/]+)\.html$ new-page.php?c=$1&ncat=$2 [L]

so these are the two rules:

^([^/]+)/([^/]+)\.html$ new-page.php?c=$1&ncat=$2 [L] // works

^([^/]+)/([^/]+)\.html$ page2.php?id_sede=$1&nome_sede=$2 [L] // not works

lucy24,
I did not understand what you mean for
If you type in random URLs-- any old garbage, so long as it's got one or two directories and then a filename in html-- do you get redirected to the two different pages?

Can you give me an example?
Thanks and sorry again for my mistake :-)

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4596053 posted 9:06 am on Jul 29, 2013 (gmt 0)

Can you give me an example?

Fire up your WAMP site. Now instead of clicking on a link, type into the address bar. After the first slash:

info.html
or
directory/filename.html
or
abc/def/ghi.html
or
... et cetera. You will either get redirected, or not.

BUT WAIT.

so these are the two rules:

^([^/]+)/([^/]+)\.html$ new-page.php?c=$1&ncat=$2 [L] // works

^([^/]+)/([^/]+)\.html$ page2.php?id_sede=$1&nome_sede=$2 [L] // not works

Uhm. Uh. Yeah. Oh. Yes. That would make a difference. Now we all understand.

Those are the same rule twice. Anything that would potentially fit the pattern of #2 has already been captured by #1.

What is supposed to be the difference between the two patterns?

Hey, don't feel too bad. It's only a few hours since I discovered, while looking into something else, that the reason my Log Headers requests don't get intercepted in MAMP... is that I've got an earlier RewriteRule intercepting everything in the directory that contains logheaders.php and slapping down a [L] so the request never reaches the rule that's supposed to rewrite it. Oh, ouch. Oh, ouch.

Oxaguian



 
Msg#: 4596053 posted 9:13 am on Jul 29, 2013 (gmt 0)

I added the new rules as you say

RewriteRule ^([^/.]+)/([^/.]+)/([^/.]+)\.html /onepage.html [R=301,L]
RewriteRule ^([^/.]+)/([^/.]+)\.html /otherpage.html [R=301,L]


I created 2 pages: onepage.html and otherpage.html
Then I opened the dir of the project: locahost / site / and without click any links, i typed the url to html pages
localhost/site/onepage.html and localhost/site/otherpage.html

Both Work regularly . I did it right?

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4596053 posted 4:19 pm on Jul 29, 2013 (gmt 0)

That's the first step. Now try typing in some nonsense URLs like

/abc/def.html
/jkl/mno.html
/bbz/bbz.html

et cetera. Do you get redirected?

Oxaguian



 
Msg#: 4596053 posted 9:07 am on Jul 30, 2013 (gmt 0)

Do you get redirected?


If i try nosense URL like localhost/site/abc.html, i get 404 error.

If i try a real URL like localhost/site/onepage.html, works

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4596053 posted 9:48 pm on Jul 30, 2013 (gmt 0)

Any request that fits the pattern

^([^/.]+)/([^/.]+)/([^/.]+)\.html
or
^([^/.]+)/([^/.]+)\.html

should be getting redirected. Did you accidentally comment-out the line RewriteEngine On? Unlike most things in apache, mod_rewrite is not inherited, so you need to enable it separately in each htaccess that uses it. (Normally just once per site.) Technically you also need Options +FollowSymLinks, but this has almost certainly been set in the server already. (It's inherited.)

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved