apache htaccess - rewriting query string with no equal sign - apache

This has been driving me insane. Any help appreciated!
I have a site that has a bunch of dynamic entries in the format:
http://example.com/foo?item-1
http://example.com/foo?item-2
etc.
Noting there is no equal sign / parameter post the ?, just a single string per the above.
I want to clean up the URL's so that we get to:
http://example.com/foo/item-1
So basically, I just want to remove that pesky question mark for foo pages and replace it with a slash. I haven't seen anyone address this case previously. I have tried the following with no success:
RewriteRule ^foo/([^/]*)\$ /foo?$1 [L]
There are two other rules in use already (both of which work). These remove the php from the end of the URL and the http from the start, per the below.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteCond %{HTTP_HOST} ^www.example.com
RewriteRule (.*) http://example.com/$1 [R=301,L]
Thanks again in advance.

You have a problem with your regex. The \ before the $ symbol means you literally want to match a dollar sign there. Try without the \.
Also, you probably want that before your php rule but after the redirect. You want your external redirects before your internal rewrites:
RewriteCond %{HTTP_HOST} ^www.example.com
RewriteRule (.*) http://example.com/$1 [R=301,L]
RewriteRule ^foo/([^/]*)$ /foo?$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]

Related

How do I combine these two .htaccess rules?

I want to combine these two rules, but not sure how
RewriteRule ^([^\.]+)$ $1.html [L]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
when I put both, I get the error "too many redirects"
My goal here is to combine them both,
the first rule is to remove file extensions (ex. html)
the second rule is: make every URL go to https://www.example.com, rather than https://example.com
With the additional information you now gave I would suggest this approach:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.example\.com$
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,END]
RewriteRule ^/?(.+)\.html$ /$1 [R=301,END]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^ %{REQUEST_URI}.html [END]
In general it is a good diea to start using a R=302 temporary redirection and only change that to a R=301 permanent redirection once everything works as expected. That prevents nasty caching issues ...

Apache RewriteRule fails on question mark

We had a typo when creating URLs, so
/wasserh?hne/wasserhahn-1-2-zoll-dg11040-e+1281
should be redirected to
/wasserhaehne/wasserhahn-1-2-zoll-dg11040-e+1281
the .htaccess starts with
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.kull-design.com$1 [R,L=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) index.php [L]
RewriteRule ^eng/deu index.php
and normally sth like this works
Redirect 301 /blog/tag/wasserhaehne-aus-messing/ https://www.kull-design.com/wasserhahn-classic/wasserhahn-13cm-40-593+631
but this fails
RewriteRule /wasserh?hne/wasserhahn-1-2-zoll-dg11040-e+1281 https://www.kull-design.com/wasserhaehne/wasserhahn-1-2-zoll-dg11040-e+1281
I tried to escape the ?, but that doesn't help. I suspect that the part after the ? is seen as query string, so I attempted
RewriteCond %{QUERY_STRING} hne/wasserhahn-1-2-zoll-kurz-dg11040m+1277
RewriteRule ^/wasserh https://www.kull-design.com/wasserhaehne/wasserhahn-1-2-zoll-kurz-dg11040m+1277 [R=301,L]
but that doesn't do the trick. There are similar questions, but they deal with real query strings.
Update:
I tested PanamaJacks solution using htaccess.madewithlove.be. It seems any url starting with wasserh is redirected to the same product. So i tried this instead
https://www.kull-design.com/wasserh?hne/wasserhahn-gebogen-dg110h76870+1295
RewriteEngine On
RewriteCond %{QUERY_STRING} ^hne/wasserhahn-gebogen-dg11010+1295
RewriteRule ^wasserh(.*)$ https://www.kull-design.com/wasserhaehne/wasserhahn-gebogen-dg11010+1295 [R=301,L]
but it doesn't match the condition. Again escaping - or + has no effect.
Update:
Note that you have to put these redirects before the RewriteRule, that sends anything to index.php or it won't work in spite of the rewrite-conditions being correct.
Actually this should work kinda. Give this rule a try and see if it works for you.
RewriteEngine On
RewriteCond %{QUERY_STRING} ^.+$
RewriteRule ^wasserh(.*)$ https://www.kull-design.com/wasserhaehne/wasserhahn-1-2-zoll-kurz-dg11040m+1277? [R=301,L]
Edit:
Then just try matching part of it that is unique to that URL.
RewriteCond %{QUERY_STRING} ^hne(.+)1281$
RewriteRule ^wasserh(.*)$ https://www.kull-design.com/wasserhaehne/wasserhahn-1-2-zoll-kurz-dg11040m+1277? [R=301,L]

Check URL and stop processing using htaccess

I want to check URL using htaccess. Developer might want run special file - specialfile.php. I use htaccess:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /specialfile\.php$
RewriteRule .* [L] #don't change adress
RewriteRule ^$ public/index.html [NC,L]
RewriteRule (.*) public/$1 [NC,L]
My idea was: if rewriteCond %{REQUEST_URI} !/specialfile.php$ true than htaccess should use RewriteRule .* [L] - that should mean that specialfile.php will be run and this all. But it doesn't work because it runs next rule: RewriteRule (.*) public/$1 [NC,L].
I think you are using the RewriteCond not correctly. The conditions only affect the next RewriteRule that follows.
Check out the example on the Apache Homepage. Since your 2nd RewriteRule is evalutated, I think your conditions are not correct. To get a litte bit more information about the rewriting, you should increase the log level. This is also documented here.
Your 2nd rule ^$ matches only an empty request btw. That's why it probably does not work as you expect it to.

How can I math a regular expression to write an htaccess rule

I want this URL
http://rebateninja.com/index.php?page=home
To be previewed like this via htaccess
http://rebateninja.com/home
I know it is not that hard and I have done that before, but for some reason it is not working now at all. My .htaccess contains the following:
RewriteEngine On
RewriteRule (index.php\?page=)(.*) /$2 [NC,R=301,L]
What I am doing wrong? Perhaps it is related to my Apache version? I have lost my entire morning without success!!! Thanks for your answers.
You can't match against the query string in a RewriteRule, you need to use a RewriteCond with either %{THE_REQUEST} or %{QUERY_STRING} and use a % to backreference groupings:
RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /index\.php\?page=([^&\ ]+)
RewriteRule /%2? [L,R=301]
That externally redirects the browser so that the URL in the address bar changes. In order to internally rewrite it back you need to do:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.phjp?page=$1 [L]
Try this.
RewriteRule ^index.php\?page=(.*)$ /$1 [NC,R=301,L]

Simulating a 2-level If-Else using RewriteCond

I'm trying to get my head around RewriteCond, and want to rewrite any requests either to a static html page (if it exists), or to a specific index.php (so long as the requested file doesn't exist).
To illustrate the logic:
if HTTP_HOST is '(www\.)?mydomain.com'
if file exists: "/default/static/{REQUEST_URI}.html", then
rewrite .* to /default/static/{REQUEST_URI}.html
else if file exists: {REQUEST_FILENAME}, then
do not rewrite
else
rewrite .* to /default/index.php
I don't seem to have much trouble doing it when I don't need to test for the HTTP_HOST. Ultimately, this one .htaccess file will be handling requests for several domains.
I know I could get around this with vhosts, but I'd like to figure out how to do it this way.
I'm not too familiar with some of the other flags, will any of them be of use here (like chain|C, next|N or skip|S)?
Thanks in advance!
UPDATE: I've managed to do it, but would appreciate alternatives:
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..* [NC]
RewriteCond %{DOCUMENT_ROOT}/%1/static/%{REQUEST_URI}.html -f
RewriteRule (.*)? /%1/static/$1.html [NC,L]
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..* [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* /%1/index.php [L,QSA]
UPDATE #2: With help from Gumbo's answer, came up with another. I like that this would would require less maintenance in the case of added domains. (Thanks Gumbo!)
Are there any reasons why I shouldn't set ENV variables?
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..*$ [NC]
RewriteRule ^ - [E=APP:%1]
RewriteCond %{DOCUMENT_ROOT}/%{ENV:APP}/static/%{REQUEST_URI}.html -f
RewriteRule (.*)? /%{ENV:APP}/static/$1.html [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* /%{ENV:APP}/index.php [L,QSA]
I would probably do it like this:
RewriteCond %{HTTP_HOST} !^(www\.)?example\.com$
RewriteRule ^ - [S=2]
RewriteCond %{DOCUMENT_ROOT}/default/static%{REQUEST_URI}.html -f
RewriteRule !^default/static/ default/static%{REQUEST_URI}.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^default/static/ default/index.php [L]
This is similar to your updated example. Except that the first rule will skip the following two rules if the host is not appropriate. And the RewriteRule patterns exclude any path that starts with /default/static/. But your rules are already pretty good.