Forum Moderators: phranque

Message Too Old, No Replies

Redirect URL with Search String Query

         

tfweb

5:58 pm on Jul 4, 2014 (gmt 0)

10+ Year Member



I am looking to redirect this URL:
www.mysite.com/catalogsearch/result/?q=RED+SHOES

To:
www.mysite.com/red-shoes

I tried the following and it didnt seem to work

RewriteCond %{QUERY_STRING} ^q=RED+SHOES$ [NC]
RewriteRule ^catalogsearch/result$ red-shoes[R=301,L]

Please help

lucy24

8:53 pm on Jul 4, 2014 (gmt 0)

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



Two mistakes. The most obvious one is here
result$

when you've explicitly said the URL ends in
result/


Second mistake involves Regular Expressions. The + plus sign is a special character meaning "one or more of the preceding" so
RED+SHOES

doesn't mean
RED+SHOES
it means
REDSHOES
or
REDDSHOES
or
REDDDDDDDSHOES

et cetera. For a literal plus sign you need to escape it as
\+


:: detour to test site to check something ::

Yes, that's OK. By the time a request reaches htaccess, the plus sign + is seen as-is. (I had to make sure it isn't percent-encoded as %2B)

Final issue: Why does the condition have an [NC] flag? Do you ever get wrongly cased requests? When you're writing the rule, [NC] looks trivial-- it's just a few more letters to type. But it means the server has to do more work, looking for two characters every single time. So a term with nine alphabetics gives 2^9 (512) possibilities, as if you'd said
[Qq]=[Rr][Ee][Dd]
et cetera.

penders

1:39 am on Jul 6, 2014 (gmt 0)

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



RewriteRule ^catalogsearch/result$ red-shoes[R=301,L]


Also... is it OK to redirect to a relative URL (ie. "red-shoes") here? Should this not at least be root-relative eg. "/red-shoes"? (Or some even prefer absolute?)

There's also a space missing before the RewriteRule flags.

lucy24

3:17 am on Jul 6, 2014 (gmt 0)

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



is it OK

Ugh, no it isn't, and I'm glad you homed in on it because I entirely overlooked that detail. It's not just a bad idea; it genuinely won't work. The target URL is then appended to the physical path which in turn is attached to the hostname. For example (quick experimenting here):

RewriteRule foobar widget.html [R=301,L]


>>
(on my shared-hosting setup)

http://www.example.com/home/lucy24/example.com/widget.html


Details may be different if you've got the rule lying loose in your config file, but clearly it's not something you want to do.

Quick edit:
The difference between root-relative in / vs. full protocol-plus-hostname only kicks in if the original request was for the "wrong" form of the name, like with/without www or wrong protocol or appended port number. If you send out the full correct package, there's no chance of someone having to be redirected twice. And, of course, the server doesn't have to look anything up.

There's also a space missing before the RewriteRule flags.

That's got to be a typo in the post. Otherwise the flags would be treated as part of the redirect target. I checked this, too, in my test site because I wasn't sure if it would simply lead to a universal 500 error. You really do get
http://www.example.com/a.html[R=301,L]

in browser's address bar, accompanied in my case by the 404 page.

penders

12:43 pm on Jul 6, 2014 (gmt 0)

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



Great info (as usual) lucy24! Much appreciated.

In the case of a (hypothetical) relative path substitution, presumably a RewriteBase directive would always be required here? However (bit of an aside), I'm just a bit confused by the Apache docs regarding RewriteBase [httpd.apache.org]... the docs do indeed state that "[RewriteBase] is required when you use a relative path in a substitution in per-directory (htaccess) context unless..." ... "The original request, and the substitution, are underneath the DocumentRoot"? But even if the original request, and the substitution, are underneath the DocumentRoot (as they are in this case) you'd probably still need a RewriteBase directive (as you've shown above)?

There's also a space missing before the RewriteRule flags.


That's got to be a typo in the post.


... it didnt seem to work


Quite possibly, but maybe not? :)

lucy24

8:22 pm on Jul 6, 2014 (gmt 0)

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



Oops, forgot about RewriteBase.

And, dammit, I also forgot to put my keyboard in the front window to recharge overnight. So it will probably die at midday.

:: detour to check ::

Double dammit, I've been saying all along that / is the default, and it isn't. Where did I get that from? For 2.x the default is "none", for 1.3 it's, well, looks like it's the physical filepath-- which boils down to "none". Crap.

The original request, and the substitution, are underneath the DocumentRoot

g1? You out there? I don't understand how the original request can be anywhere but under the document root. Otherwise how would it ever see the htaccess? And if you don't do any funny business with ../../ -- which you'd be demented to use in mod_rewrite anyway -- then the target will end up in the same place.

:: detour for further testing ::

Yup, a RewriteBase makes all the difference.

Wonder what, exactly, they mean by
per-directory (htaccess)

It makes it sound as if the two are synonymous, when obviously they aren't. You can also have RewriteRules in <Directory> sections of a config file. It should say something like "per-directory (including htaccess)".

Oh, here's the part I overlooked. A RewriteBase isn't needed if
The filesystem path to the directory containing the RewriteRule, suffixed by the relative substitution, is also valid as a URL path on the server (this is rare).

Clearly that's what kicked in here.

I think if I stare at the docs long enough I will understand. ("This is rare" haha.)


tfweb, still with us?

lucy24

10:52 pm on Jul 6, 2014 (gmt 0)

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



Follow-up because I missed the Edit deadline:

I went back and checked a detail I'd forgotten earlier. If your RewriteRule is configured as a rewrite alone (no R flag) then targets without leading / are treated as if they did have a /. (Technically this may not be what's happening at all-- maybe they're just using filepaths on both sides, so it comes out even-- but it's the easiest visual explanation.) So it's one of the rare and confusing cases where mod_rewrite behavior varies according to whether it's an external redirect or an internal rewrite. I've met these once or twice before.

And then hilarity ensues, because in the particular rule I was experimenting with

RewriteRule widget hoosegow/test-one.html [L]


(here I had to use a real page so I could see if the rewrite worked) I'd forgotten that the page "test-one.html" was made to test php includes, hence its name. And the included file happens to be named ... drumroll ... "widget.php". Very interesting nested effect!

penders

5:03 pm on Jul 7, 2014 (gmt 0)

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



I've been saying all along that / is the default, and it isn't. Where did I get that from?


If it's any consolation, this is what I thought too - if the .htaccess file is in the document root. Which is why I wondered whether it might work, possibly by chance, depending on the setup. I too tried this on my local test server and live (shared) server and I get the same results as you (when redirecting).

The original request, and the substitution, are underneath the DocumentRoot


There is another bit to that quotation that I omitted, since I didn't think it was relevant here, "...(as opposed to reachable by other means, such as Alias)". If an Alias was used then presumably either the original request and/or the target could be somewhere other than "underneath the DocumentRoot". Would the .htaccess file be seen if an Alias is used? But both are underneath the DocumentRoot in our examples and we are not using an Alias.(?)

Wonder what, exactly, they mean by ...
... You can also have RewriteRules in <Directory> sections of a config file.


In fact, their example uses a <Directory> section.


If your RewriteRule is configured as a rewrite alone (no R flag) then targets without leading / are treated as if they did have a /.


Interesting, yes, I see that too.

lucy24

8:46 pm on Jul 7, 2014 (gmt 0)

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



Maybe when they say "under the document root" they mean "physically located in the directory that contains the root"? Even on shared hosting, there are other possible configurations. For example, my /stats/ directory is located in a completely different area, although its URL is example.com/stats/. And I used to have one of my directories aliased to my son's userspace, so its physical location was
home/son's-name/blahblah
Took me ages to understand why my htaccess directives seemed to have no effect on requests for files in this directory :(

:: looking vaguely around for someone who speaks Apache ::

tfweb, we're not trying to scare you. We just got sidetracked :)