Forum Moderators: phranque

Message Too Old, No Replies

Struggling with a RewriteRule

I need help getting this working

         

stoveboltgeek

5:58 pm on Jul 6, 2022 (gmt 0)

Top Contributors Of The Month



I manage, on a volunteer basis, a busy hobby website with about 5600 pages, both static and dynamic content. About 860 pages have links on them to a bulletin board that we used to use before it was changed by the vendor (utlimatebb - changed to ubbthreads).

I'm trying to figure out how to redirect those links to the new bulletin board so that they will no longer generate 404 errors.

Here's the old link.
https://www.example.com/bboard/cgi-bin//ultimatebb.cgi?ubb=get_profile;u=00009498

And here's the new link.
https://www.example.com/ubbthreads/ubbthreads.php?ubb=showprofile&User=00009498

I've been doing a ton of reading trying to figure this out. If I understand the docs correctly, I have to have a RewriteCond that looks for the query string, the a RewriteCond that looks for the REQUEST_URI, and then put the two together for the RewriteRule.

I'm really unsure how to do this, but this is what I wrote. (It doesn't work.)
RewriteCond “%{REQUEST_URI}” “/bboard/cgi-bin/ultimatebb.cgi”
RewriteCond “%{QUERY_STRING}” “ubb=showprofile&User=(\d*)”
RewriteRule ^/bboard.*.cgi$ /ubbthreads/ubbthreads.php?ubb=showprofile&User=%1”

Have I completely misunderstood how this works? Or did I just write the conditions or rules incorrectly?

[edited by: phranque at 9:18 pm (utc) on Jul 6, 2022]
[edit reason] Please Use example.com For Domain Names in Posts Apache Web Server forum [/edit]

phranque

9:41 pm on Jul 6, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



welcome to WebmasterWorld [webmasterworld.com], stoveboltgeek!

(It doesn't work.)

what did you try and what was the result?
did you look for clues in the web server access and error files?

RewriteCond “%{REQUEST_URI}” “/bboard/cgi-bin/ultimatebb.cgi”
RewriteCond “%{QUERY_STRING}” “ubb=showprofile&User=(\d*)”
RewriteRule ^/bboard.*.cgi$ /ubbthreads/ubbthreads.php?ubb=showprofile&User=%1”

if you can specify the Request URI in the Pattern of the RewriteRule, you should do so and then you don't need the additional conditional.
the conditional looks at the request, so the condition pattern should reflect the "old link".
also, you want a 301 redirect in this case and the way you have specified the Substitution string (without a hostname specified) means it will internally rewrite the request.
finally, you haven't specified where these directives are used (.htaccess or server config files) so i am assuming .htaccess in my suggestion below. (i.e. the leading slash is stripped from the URI in directory context)
i would try something like this:
RewriteCond %{QUERY_STRING} ^ubb=get_profile;u=(\d+)$
RewriteRule ^bboard/cgi-bin/ultimatebb\.cgi$ https://www.example.com/ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]

lucy24

11:43 pm on Jul 6, 2022 (gmt 0)

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



Is this a typo or the actual URL?
https://www.example.com/bboard/cgi-bin//ultimatebb.cgi?ubb=get_profile;u=00009498
A quirk of mod_rewrite is that RewriteRules ignore extra slashes, but RewriteConds take them as written. (I know this only because I once made an error that led to links containing // in the middle. I had to redirect them just so search engines would stop asking.)

stoveboltgeek

3:09 am on Jul 7, 2022 (gmt 0)

Top Contributors Of The Month



Sorry. I should have been more specific. These rules are in the server config file. That's what apache docs recommend. I also have logging for rewrites enabled. But I'm not seeing much that's helpful in the logs.

 LogLevel alert rewrite:trace3

For example.
[Wed Jul 06 22:55:09.804734 2022] [rewrite:trace3] [pid 15176] mod_rewrite.c(470): [client 157.55.39.87:43010] 157.55.39.87 - - [example.com/sid#55fb03b7d378][rid#55fb03e6b750/initial] applying pattern '^bboard/cgi-bin/ultimatebb\\.cgi$' to uri '/ubbthreads/ubbthreads.php/topics/1456461/possible-grand-piano-for-free.html'
[Wed Jul 06 22:55:09.804846 2022] [rewrite:trace3] [pid 15176] mod_rewrite.c(470): [client 157.55.39.87:43010] 157.55.39.87 - - [example.com/sid#55fb03b7d378][rid#55fb03e7aed0/subreq] applying pattern '^bboard/cgi-bin/ultimatebb\\.cgi$' to uri '/topics/1456461/possible-grand-piano-for-free.html'
[Wed Jul 06 22:55:09.824370 2022] [rewrite:trace3] [pid 15176] mod_rewrite.c(470): [client 157.55.39.87:43010] 157.55.39.87 - - [example.com/sid#55fb03b7d378][rid#55fb03eadd50/subreq] applying pattern '^bboard/cgi-bin/ultimatebb\\.cgi$' to uri '/topics/1456461/possible-grand-piano-for-free.html'
[Wed Jul 06 22:55:09.824585 2022] [rewrite:trace3] [pid 15176] mod_rewrite.c(470): [client 157.55.39.87:43010] 157.55.39.87 - - [example.com/sid#55fb03b7d378][rid#55fb03eadd50/subreq] applying pattern '^bboard/cgi-bin/ultimatebb\\.cgi$' to uri '/topics/1456461/possible-grand-piano-for-free.html'

So, it appears that apache is testing the QUERY_STRING against urls, however, when I tail the log grepping for my IP, I don't see anything, even though I'm accessing a broken link and getting a 404.
# tail -f /var/log/httpd/example/error.log | grep "70.121.63.82"

# tail -f /var/log/httpd/example/ssl_access_log | grep "70.121.63.82"
70.121.63.82 - - [06/Jul/2022:23:07:19 -0400] "GET /bboard/cgi-bin//ultimatebb.cgi?ubb=get_profile;u=00012520 HTTP/1.1" 404 227
70.121.63.82 - - [06/Jul/2022:23:07:26 -0400] "-" 408 -

I'm beginning to wonder if it's possible to redirect a dynamic link to another dynamic link. I even tried AliasMatch with no success.

[edited by: phranque at 7:50 am (utc) on Jul 7, 2022]
[edit reason] Please Use example.com For Domain Names in Posts Apache Web Server forum [/edit]

stoveboltgeek

3:10 am on Jul 7, 2022 (gmt 0)

Top Contributors Of The Month



That must be something the board does, because I posted the actual links.

lucy24

4:17 am on Jul 7, 2022 (gmt 0)

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



That must be something the board does, because I posted the actual links.
Welcome to WebmasterWorld ;-)

All links are turned into active links, as in [w3.org...]

When referring to your own site, you have to change it to example.com (or example dot any tld if it is necessary to use more than one hostname). This is a general rule having to do with not marketing yourself--but here in the Apache subforum, there's a second reason: people need to be able to see what you actually wrote. Sometimes it helps to put everything inside [ code ] markup, but then Reason #1 kicks in again.

The htaccess vs. config question was simply to make sure the RewriteRule pattern is right: with or without leading / depending on where the rule is located. If you have access to the config file, then of course that's where you should be putting your rules ... except that it's sometimes convenient to Allow Overrides in one carefully selected directory, so you can experiment in htaccess without having to remember to reload the config file every time.

Now then. In the first post
RewriteCond “%{REQUEST_URI}” “/bboard/cgi-bin/ultimatebb.cgi”
RewriteCond “%{QUERY_STRING}” “ubb=showprofile&User=(\d*)”
why is everything inside quotation marks? And, equally important, are they really curly quotes, or is that an artifact of copy-paste for posting?

stoveboltgeek

5:19 am on Jul 7, 2022 (gmt 0)

Top Contributors Of The Month



That must be something the board does, because I posted the actual links.

stoveboltgeek

5:25 am on Jul 7, 2022 (gmt 0)

Top Contributors Of The Month



why is everything inside quotation marks? And, equally important, are they really curly quotes, or is that an artifact of copy-paste for posting?

Yes, those are double quotes. I've seen examples done without quotes, but the Apache docs use quotes [httpd.apache.org ], so I assumed that was the preferred method.

BTW, this is what I have currently in the virtualhost conf file.
RewriteCond "%{QUERY_STRING}" "ubb=.*u=(\d*)"
RewriteRule "^bboard/cgi-bin/ultimatebb\.cgi$" "https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1" [L,R=301]

[edited by: phranque at 7:50 am (utc) on Jul 7, 2022]
[edit reason] Please Use example.com For Domain Names in Posts Apache Web Server forum [/edit]

stoveboltgeek

6:58 am on Jul 7, 2022 (gmt 0)

Top Contributors Of The Month



I tested my RewriteCond and RewriteRule on https://htaccess.madewithlove.com. This was the result.
The new url is /ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 (I removed the https:// and www.example.com so it would be visible.)
Test are stopped, a redirect will be made with status code 301

So apparently I've done something wrong in the capture group? Or I need to escape %1? Or there's something about it that I don't understand. The RewriteCond should be capturing the member id which is what I need to have inserted into the new query string.

I though %1 was how I represented the capture group. Back to the docs.....

[edited by: phranque at 7:51 am (utc) on Jul 7, 2022]

[edited by: not2easy at 4:42 pm (utc) on Jul 8, 2022]
[edit reason] Please Use example.com For Domain Names in Posts Apache Web Server forum [/edit]

stoveboltgeek

7:26 am on Jul 7, 2022 (gmt 0)

Top Contributors Of The Month



I just did some testing on https://htaccess.madewithlove.com.
This passed with flying colors.
RewriteCond %{QUERY_STRING} ubb=.*u=(\d*)
RewriteRule ^bboard/.*$ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]

Notice that I had to remove the quotes to get it working, so the Apache docs deceived me.
Here's the results.
1 RewriteCond %{QUERY_STRING} ubb=.*u=(\d*)
This condition was met.
2 RewriteRule ^bboard/.*$ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]
The new url is https://www.example.com/ubbthreads/ubbthreads.php?ubb=showprofile&User=00009498
Test are stopped, a redirect will be made with status code 301

Perfect! Just what I needed! Except...it doesn't work on my server....?
Here's what's in the conf file now. And yes, I restarted Apache. After confirming that there were no errors using apachectl configtest.
# grep Rewrite /etc/httpd/conf.d/example.conf
RewriteEngine On
RewriteOptions Inherit
RewriteCond %{QUERY_STRING} ubb=.*u=(\d*)
RewriteRule ^bboard/.*$ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]

So, something else is wrong.
So, I reenabled logging of rewrites.
# tail -f /var/log/httpd/example/error.log | grep rewrite | grep bboard
[Thu Jul 07 03:31:16.017080 2022] [rewrite:trace3] [pid 623] mod_rewrite.c(470): [client 157.55.39.49:2688] 157.55.39.49 - - [example.com/sid#55f21d4d12f8][rid#55f21d7d0ec0/initial] applying pattern '^bboard/.*$' to uri '/ubbthreads/ubbthreads.php/topics/1457572/installing-gauges.html'
[Thu Jul 07 03:32:03.541122 2022] [rewrite:trace3] [pid 626] mod_rewrite.c(470): [client 157.55.39.87:41921] 157.55.39.87 - - [example.com/sid#55f21d4d12f8][rid#55f21d7ceeb0/initial] applying pattern '^bboard/.*$' to uri '/ubbthreads/ubbthreads.php/topics/1457113/re-just-a-quick-heads-up.html'

I'm gettting comparisons against the pattern in the rewrite rule to urls that don't meet the RewriteCond. How is that even possible? The rewrite condition should prevent the processing of the rule unless the pattern is matched, so apparently my regex is not specific enough. So, I rewrote it like this.
RewriteCond %{QUERY_STRING} ubb=get_profile.*u=(\d*)
and now I'm testing some more.

[edited by: phranque at 7:52 am (utc) on Jul 7, 2022]

[edited by: not2easy at 4:43 pm (utc) on Jul 8, 2022]
[edit reason] Please Use example.com For Domain Names in Posts Apache Web Server forum [/edit]

phranque

8:11 am on Jul 7, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



I'm gettting comparisons against the pattern in the rewrite rule to urls that don't meet the RewriteCond. How is that even possible?

the RewriteRule Pattern is matched before any RewriteCond directives withing the ruleset.

Here's what's in the conf file now. And yes, I restarted Apache. After confirming that there were no errors using apachectl configtest.

# grep Rewrite /etc/httpd/conf.d/example.conf
RewriteEngine On
RewriteOptions Inherit
RewriteCond %{QUERY_STRING} ubb=.*u=(\d*)
RewriteRule ^bboard/.*$ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]



So, something else is wrong.

since this is in config context rather than directory context, the RewriteRule Pattern must start with the leading slash (i.e. specifying the document root directory):
RewriteRule ^/bboard/ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]

also note that if you aren't capturing the trailing .*, it and the end anchor are unnecessary in the Pattern specification.

i would also suggest using the most specific RewriteRule and conditional Pattern specifications possible:
RewriteCond %{QUERY_STRING} ^ubb=.+;u=(\d+)$

phranque

8:14 am on Jul 7, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



The RewriteCond directive defines a rule condition. One or more RewriteCond can precede a RewriteRule directive. The following rule is then only used if both the current state of the URI matches its pattern, and if these conditions are met.

source:https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritecond

stoveboltgeek

12:56 pm on Jul 7, 2022 (gmt 0)

Top Contributors Of The Month



Several things this morning. I checked the logs and found this.
[Thu Jul 07 08:26:18.183738 2022] [rewrite:trace3] [pid 17347] mod_rewrite.c(470): [client 157.55.39.98:35008] 157.55.39.98 - - [example.com/sid#55d672bca2f8][rid#55d672eb46f0/initial] applying pattern '^bboard/.*$' to uri '/ubbthreads/ubbthreads.php/topics/1457624/re-how-to-troubleshoot-truck-not-turning-over.html'
[Thu Jul 07 08:26:29.798420 2022] [rewrite:trace3] [pid 17183] mod_rewrite.c(470): [client 207.46.13.184:31360] 207.46.13.184 - - [example.com/sid#55d672bca2f8][rid#55d672f06bc0/initial] applying pattern '^bboard/.*$' to uri '/ubbthreads/ubbthreads.php/users/8659.html'
[Thu Jul 07 08:26:40.013497 2022] [rewrite:trace3] [pid 17534] mod_rewrite.c(470): [client 207.46.13.184:31360] 207.46.13.184 - - [example.com/sid#55d672bca2f8][rid#55d672eb46f0/initial] applying pattern '^bboard/.*$' to uri '/ubbthreads/ubbthreads.php/topics/1457553/pto-needed-sm420.html'

But this is what I have in the conf file.
RewriteCond %{QUERY_STRING} ubb=get_profile.*u=(\d*)
RewriteRule ^bboard/.*$ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]

So the pattern Apache is trying to match, according to the error log, is not the pattern in the conf file. Yet I have restarted Apache since making that change. I restarted Apache again this morning (I use systemctl restart httpd), and the logs are still showing the old patttern being matchied.
tail -f /var/log/httpd/stovebolt/error.log | grep rewrite | grep bboard
[Thu Jul 07 08:32:12.115951 2022] [rewrite:trace3] [pid 17279] mod_rewrite.c(470): [client 207.46.13.184:32000] 207.46.13.184 - - [example.com/sid#55d672bca2f8][rid#55d672eb8710/initial] applying pattern '^bboard/.*$' to uri '/ubbthreads/ubbthreads.php/topics/1457454/ad-wiper-blade.html'
[Thu Jul 07 08:33:14.696501 2022] [rewrite:trace3] [pid 17945] mod_rewrite.c(470): [client 157.55.39.49:8384] 157.55.39.49 - - [example.com/sid#55881ce3e2f8][rid#55881d128730/initial] applying pattern '^bboard/.*$' to uri '/ubbthreads/ubbthreads.php/topics/1457548/re-1937-chevy-1-5-ton-dually-disc-brake-conversion.html'

I looked into how to clear apache's cache and where it's located. Supposedly it's in /var/cache/httpd. but there's nothing in there.

This is making no sense at all.


[edited by: not2easy at 6:23 pm (utc) on Jul 7, 2022]
[edit reason] Please Use example.com For Domain Names in Posts Apache Web Server forum [/edit]

stoveboltgeek

1:23 pm on Jul 7, 2022 (gmt 0)

Top Contributors Of The Month



@phranque, thanks for your response. You wrote
the RewriteRule Pattern is matched before any RewriteCond directives within the ruleset.

Are you saying that Apache tests the rule before it tests the Condition? If so, that's contrary to my understanding. And it seems contradictory to what you wrote in your second response.
The RewriteCond directive defines a rule condition. One or more RewriteCond can precede a RewriteRule directive. The following rule is then only used if both the current state of the URI matches its pattern, and if these conditions are met.

Unless what you are saying is that Apache first looks for a pattern match from the Rule, then checks to see if the Cond is met before proceeding with applying the rule. And now that I reread what you quoted, it seems that's what it's saying. It first tests the Rule pattern, then checks the Cond, and if both match, it proceeds with applying the Rule substitution. Is my understanding correct?

since this is in config context rather than directory context, the RewriteRule Pattern must start with the leading slash (i.e. specifying the document root directory):
RewriteRule ^/bboard/ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301

When I tested the pattern on https://htaccess.madewithlove.com adding the leading forward slash breaks the rule. It's my understanding that not including the leading forward slash means the match could be anywhere in the uri. I don't have a problem with that, because no other links use that pattern.

also note that if you aren't capturing the trailing .*, it and the end anchor are unnecessary in the Pattern specification.
I am capturing the trailing .*. The entire point of this is to capture the member ID and reuse it in a different URI.

i would also suggest using the most specific RewriteRule and conditional Pattern specifications possible:
That's good advice, because the pattern I was using was matching other uris that I wouldn't want to match. Thus the errors in my logs that I posted previously.

I have since discovered that I have a complete set of logs in /etc/httpd/logs/ that I didn't know about. I'm going to have to investigate that. CentOS is so completely different from FreeBSD that it's sometimes befuddling to me.


[edited by: not2easy at 4:44 pm (utc) on Jul 8, 2022]
[edit reason] delinked unrelated tool [/edit]

lucy24

4:09 pm on Jul 7, 2022 (gmt 0)

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



I am capturing the trailing .*. The entire point of this is to capture the member ID and reuse it in a different URI.
You're confusing two different .*

The one in the RewriteRule is unnecessary, and hence so is the closing anchor $ In fact, trailing .* or .+ is never necessary in a RewriteRule unless you are capturing; otherwise it's just extra work for the server.

The one that IS necessary is the one in the RewriteCond, because it is being captured for reuse.

One might here insert editorial comments about Apache's examples. They are particularly fond of .* or .+ in the middle of a pattern, which is a hideously bad idea. In other words, don't take their syntax as divine guidance.

mod_rewrite works on a “two steps forward, one step back” system. A RewriteRule is evaluated first. If and only if the pattern in the Rule matches, then and only then are the RewriteCond belonging to that rule evaluated.

If you don't want to deal with the opening-slash issue, then leave off the beginning anchor ^ and it will match regardless. This is, of course, assuming you don't have URLs that happen to contain the element "bboard" at some other random spot.

Quotation marks are not necessary. The sole exception is some rare cases involving THE_REQUEST where you need to catch a literal space, which otherwise would have syntactic meaning, and some situations involving whole-string matches that don't apply here.

When I tested the pattern on [htaccess.madewithlove.com ] adding the leading forward slash breaks the rule.
Well, yeah. That's because yours is a config file rule and the tool is made to test htaccess. Even then, htaccess testers aren't perfect, as shown by the literal "%1" in the result. This string should have been replaced by either some content, or none, depending on whether there was a successful capture--and if the rule isn't applied at all, then there wouldn't be a target of any kind.

stoveboltgeek

4:21 pm on Jul 7, 2022 (gmt 0)

Top Contributors Of The Month



@lucy24, if I understand you correctly. I currently have this:
RewriteCond %{QUERY_STRING} ubb=get_profile.*u=(\d*)
RewriteRule /bboard/cgi-bin/.* https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]

but I should have this?
RewriteCond %{QUERY_STRING} ubb=get_profile.*u=(\d*)$
RewriteRule /bboard/cgi-bin/ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]

I added the /cgi-bin/ just to be on the safe side.


[edited by: not2easy at 6:29 pm (utc) on Jul 7, 2022]
[edit reason] Please Use example.com For Domain Names in Posts Apache Web Server forum [/edit]

lucy24

5:08 pm on Jul 7, 2022 (gmt 0)

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



I added the /cgi-bin/ just to be on the safe side.

Add as much as is necessary to ensure that the pattern only matches what you are trying to match. As long as we are purely dealing with literal text, the change in server workload is insignificant.

And oh, yuk, I only just noticed the .* in the middle of the RewriteCond. Can this be avoided? In the opening post, the old URL was given as

ubb=get_profile;u=00009498
meaning that the pattern would be

ubb=get_profile;u=(\d+)
It may seem trivial, but any time a Regular Expression meets a .* or .+ it then gobbles up* everything to the end--and then, if there is something after the .* or .+ it has to backtrack until it finds a match for the remaining bit.

Edit: The difference between .* and .+ in the query string may be significant. Is it ever possible for this element to be entirely empty? If so, where would you want it redirected to?


* For reasons I don't want to inquire into, the vocabulary of Regular Expressions revolves around food: they are greedy by default, they come in different flavors and so on.

stoveboltgeek

5:30 pm on Jul 7, 2022 (gmt 0)

Top Contributors Of The Month



Well, I finally gave up in frustration and opened a ticket with the hosting company. They had it working in about five minutes. They commented out the conf file and put this in a ..htacess file.

RewriteCond %{QUERY_STRING} ubb=get_profile.*u=(\d*)
RewriteRule ^bboard/.*$ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]

Then changed AllowOverride from None to All in the main server conf file (httpd.conf). And it worked. {{sigh}}

I should give up trying to do this stuff and just ask the support staff to take care of it.

In any case, the problem is solved, so you can close this ticket.

Update: I did some additional testing. I backed up the .htacess file and removed it, and edited the virtualhost conf file. It now looks like this.
RewriteCond %{QUERY_STRING} ubb=get_profile;u=(\d*)
RewriteRule /bboard/cgi-bin/ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]

I took your advice and eliminated the .* in the QUERY_STRING and used the entire string instead. And, instead of trying to get fancy with regex, I made the pattern in the RewriteRule a simply match to the known pattern before the query string. That should not match anything but those bad links.

After restarting Apache, the redirect works as expected. I thought perhaps setting AllowOverride to All in the main httpd.conf file was what fixed the problem, but I tested that by setting it to None and restarting Apache, and the redirect still works. I give up. I'll never understand computers. :-)


[edited by: not2easy at 6:32 pm (utc) on Jul 7, 2022]
[edit reason] Please Use example.com For Domain Names in Apache Web Server forum [/edit]

phranque

9:19 pm on Jul 7, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



RewriteCond %{QUERY_STRING} ubb=get_profile;u=(\d*)
RewriteRule /bboard/cgi-bin/ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]

i would still use more precise pattern specifications where appropriate.
for example, \d* means zero or more numeric digits, while \d+ means one or more numeric digits.
i would also add beginning and/or end anchors where appropriate.
RewriteCond %{QUERY_STRING} ^ubb=get_profile;u=(\d+)$
RewriteRule ^/bboard/cgi-bin/ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]

phranque

9:26 pm on Jul 7, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



It first tests the Rule pattern, then checks the Cond, and if both match, it proceeds with applying the Rule substitution. Is my understanding correct?

yes

lucy24

10:10 pm on Jul 7, 2022 (gmt 0)

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



I thought perhaps setting AllowOverride to All in the main httpd.conf file was what fixed the problem
The AllowOverride directive applies to one thing and one thing only: the use of htaccess files. The directive really means what it sounds like: allow some other file to override the rules laid out in the config file. It has no effect whatsoever on things that are in config anyway. But if you don't need or want htaccess files, leave AllowOverride set at None, because then the server does not have to take the time to look for htaccess files on every ... single ... request.

stoveboltgeek

10:57 pm on Jul 7, 2022 (gmt 0)

Top Contributors Of The Month



Thanks for all your help @lucy24 and @phranque.

phranque

2:41 am on Jul 8, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



...the server does not have to take the time to look for htaccess files on every ... single ... request.

in fact for each directory level for each resource requested, including internal/subrequests.

lucy24

3:27 am on Jul 8, 2022 (gmt 0)

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



... multiple times, depending on how many mods are allowed to operate in htaccess :)

stoveboltgeek

4:06 am on Jul 8, 2022 (gmt 0)

Top Contributors Of The Month



Can you tell me what the required differences are between RewriteCond and RewriteRule in .htaccess versus conf file? The rules are working fine in the .htacess file but don't work in the conf file.

phranque

4:42 am on Jul 8, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Can you tell me what the required differences are between RewriteCond and RewriteRule in .htaccess versus conf file?

for RewriteRule directives:
What is matched?

  • In VirtualHost context, The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html"). This is the (%-decoded) URL-path.

  • In per-directory context (Directory and .htaccess), the Pattern is matched against only a partial path, for example a request of "/app1/index.html" may result in comparison against "app1/index.html" or "index.html" depending on where the RewriteRule is defined.

    The directory path where the rule is defined is stripped from the currently mapped filesystem path before comparison (up to and including a trailing slash). The net result of this per-directory prefix stripping is that rules in this context only match against the portion of the currently mapped filesystem path "below" where the rule is defined.

    Directives such as DocumentRoot and Alias, or even the result of previous RewriteRule substitutions, determine the currently mapped filesystem path.

source:https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule

stoveboltgeek

3:17 pm on Jul 8, 2022 (gmt 0)

Top Contributors Of The Month



@phranque, that's not exactly what I wanted to know. These rules work in the .htacess file but do not work in the conf file. What do I have to change to get them to work in the conf file? It is my understanding that it's preferable to put rewrite rules in the conf file.
RewriteEngine On
RewriteOptions Inherit
RewriteRule ^links/ /links.html [L,R=301]
RewriteCond %{QUERY_STRING} ubb=get_profile;u=(\d+)\b
RewriteRule ^bboard/.*$ https://www.example.com/ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]
RewriteCond %{QUERY_STRING} page=get_profile;u=(\d+)\b
RewriteRule ^bboard/.*$ https://www.example.com/ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]
RewriteCond %{QUERY_STRING} page=editprofile;u=(\d+)\b
RewriteRule ^bboard/.*$ https://www.example.com/ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]
RewriteCond %{REQUEST_URI} /bboard/cgi-bin/ultimatebb.cgi
RewriteRule (.*)$ https://www.example.com//ubbthreads/ubbthreads.php [L,R=301]
RewriteCond %{QUERY_STRING} page=getprofile;u=(\d+)\b
RewriteRule (.*)$ https://www.example.com//ubbthreads/ubbthreads.php?ubb=showprofile&User=%1 [L,R=301]







[edited by: not2easy at 3:56 pm (utc) on Jul 8, 2022]
[edit reason] Please see TOS [webmasterworld.com] [/edit]

lucy24

4:10 pm on Jul 8, 2022 (gmt 0)

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



When posting, remember to use example.com.

The key difference between htaccess and config is very often the ^ opening anchor. (The closing anchor is unaffected.)

In htaccess, patterns start with the current directory, so

^thisname

means the URL example.com/thisname
(assuming the htaccess is located at the root, as they usually are)
corresponding to the physical filepath (for example) servername/public/users/example.com/thisname

In config, patterns start with the whole server. So you have to either omit the opening anchor, or include the full physical filepath.

Pro tip: Leave a blank line between each ruleset (RewriteRule plus attached Conditions). This has no syntactic meaning, but will make it vastly easier for you, the human site administrator, to keep track.

As previously noted, there is never any reason for the non-capturing element
.*$
since it simply means “there might or might not be more stuff after the pattern” which is understood anyway. May as well let the server get out of there a few picoseconds sooner.

When you are capturing, there is still no need for the closing anchor in
blahblah(.*)
because, as noted a few posts back, Regular Expressions are greedy by default; they will continue capturing until something impels them to stop.

phranque

8:02 pm on Jul 8, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



These rules work in the .htacess file but do not work in the conf file. What do I have to change to get them to work in the conf file?

read the Apache doc re:Context and then you will understand why and how patterns will differ between .htaccess directives and config file directives:
https://httpd.apache.org/docs/current/mod/directive-dict.html#Context

stoveboltgeek

8:13 pm on Jul 8, 2022 (gmt 0)

Top Contributors Of The Month



@lucy24
In config, patterns start with the whole server. So you have to either omit the opening anchor, or include the full physical filepath.

For clarification, I should change this .htaccess rule.
RewriteRule ^links/ /links.html [L,R=301]

to this if I move it to the conf file?
RewriteRule /links/ /links.html [L,R=301]

Are conf rules always referenced from DocumentRoot?
Pro tip: Leave a blank line between each ruleset (RewriteRule plus attached Conditions). This has no syntactic meaning, but will make it vastly easier for you, the human site administrator, to keep track.
I did this immediately after I read this, and I added comments regarding what the purpose of each rule was.
As previously noted, there is never any reason for the non-capturing element
.*$
since it simply means “there might or might not be more stuff after the pattern” which is understood anyway. May as well let the server get out of there a few picoseconds sooner.

I have removed the closing anchor $ from all my rules now.

Thanks for all your help.
@phranque
read the Apache doc re:Context and then you will understand why and how patterns will differ between .htaccess directives and config file directives:
[httpd.apache.org...]
I'm headed there now. I confess that Apache docs are often too technical for me to understand, but I try my best.
This 36 message thread spans 2 pages: 36