mod_rewrite failing on uppercase dir - .htaccess

I have a very basic mod_rewrite in a .htaccess file which I'm sure worked last time I looked at it, but now it is doing strange things with the case of the REQUEST_URI. It's intended purpose is to rewrite sub-domains to a given file, passing the subdomain as a php var of bnurl. Here is my code:
RewriteCond %{REQUEST_URI}= "RSDEV/location/" [NC]
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.mydomain\.co\.uk(:80)? [NC]
RewriteRule ^RSDEV/location/$ RSDEV/newmain.php?bnurl=%1&accesstype=new [NC,L]
Now, typing joebloggs.mydomain.co.uk/RSDEV/location/ into my web browser comes back with the response "The requested URL /RSDEV/location/ was not found on this server" which is a correct statement because /RSDEV/location/ is not a real directory, but why did it not rewrite to RSDEV/newmain.php?bnurl=joebloggs&accesstype=new as expected?
Now, the really strange thing here is that if I enter joebloggs.mydomain.co.uk/rsdev/location/ into my browser (note rsdev is now lowercase), it correctly rewrites as expected. The script newmain.php is in dir RSDEV (uppercase) so if it was going to fail, I would have expected it to fail the other way round with the lowercase rsdev.
As you can see, I have [NC] on each line. Is this my mod_rewrite code failing or some other mystical server force keeping me up all night?

Get rid of the line:
RewriteCond %{REQUEST_URI}= "RSDEV/location/" [NC]
The check is already being made in the rewrite rule's pattern. Not just that, the = is connected to the %{REQUEST_URI} variable, so the string ends up with a = at the end (it should really be next to the pattern).

Related

friend url on wildcard subdomains htacces, not working

i have wildcard subdomains sets already and works fine, now i wish have friends url for the content in thats subdomains, the structure of my site is if the user type subdomain.maindomain.com and the .htaccess redirect to
blogs/index.php?user=subdomain
where blogs/index.php receive the param and show the correct content
now i try to make the url function like this
subdomain.maindoamin.com/24/title-of-content
and then .htaccess must result
blogs/index.php?id_content=24&title=title-of-content
i have the next .htaccess
Options +FollowSymLinks
#this force to server the content always without www.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*)$
RewriteRule ^(.*)$ http://%1/$1 [R=301]
#this is to pass the subdomain like param and show the right content of the user
RewriteCond %{HTTP_HOST} !^www\.misite\.com [NC]
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.misite\.com
RewriteRule ^(.*)$ blogs/index.php?url=%1 [QSA,L]
#the next line i can't make work to make nice url
RewriteRule ^/(.*)/(.*)$ blogs/index.php?idP=$1&name=$2 [L]
not working because when i make in index.php
echo $_SERVER['REQUEST_URI'];
don't show idP=24 show /24/title-of-content and i need $_GET(idP)
i really apreciate some light on this stuff i am not expert on htaccess, thanks in advance to everybody.
There are two problems:
The first argument of RewriteRule matches against everything after the slash of the directory .htaccess is in, and before the query string. If .htaccess is in your www-root, and you get the url http://www.example.com/shiny/unicorns.php?are=shiny, you match against shiny/unicorns.php. It will never start with a slash, so ^/ will never match.
Rules are executed in order. If you go to http://sub.example.com/10/unicorns, the second rule will match first and rewrite the request to /blogs/index.php?url=10/unicorns. If you removed the leading slash the third rule would match, but normally you wouldn't want that. You want to have the third rule only match
You want to move the third rule up so it is the second rule. You want to make it more specific to only match with subdomains. You also know the first part contains only numbers, so use that knowledge to prevent blogs/index.php from matching your now second rule. You also need to prevent blogs/index.php from matching the now third rule to prevent it from matching itself. Last but not least I removed [L] from the now second rule, since the third rule will match anyway.
#the next line i can't make work to make nice url
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^([0-9]+)/([^/]+)$ blogs/index.php?idP=$1&name=$2
#this is to pass the subdomain like param and show the right content of the user
RewriteCond %{HTTP_HOST} !^www\.misite\.com [NC]
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.misite\.com
RewriteCond %{REQUEST_URI} !/blogs/index\.php
RewriteRule ^ blogs/index.php?url=%1 [QSA,L]

htaccess ReWriteCond ReWriteRule - redirect occurs even when URL includes nonsense characters

We've just finished a major re-structuring our website and I'm trying to write a set of redirect rules of varying specificity. The redirects are half working:
They correctly re-route old URLs
They incorrectly also allow and re-route URLs that include text not specified in the
ReWriteCond statements (when instead I would expect to see a "Not Found" error message displayed in the browser.)
Statements in the .htaccess file (located in the root of the web site) include:
RewriteBase /
RewriteCond %{REQUEST_URI} /company/company-history.html
RewriteRule (.*)$ http://www.technofrolics.com/about/index.html
RewriteCond %{REQUEST_URI} /press
RewriteRule (.*)$ http://www.technofrolics.com/gallery/index.html
The above correctly executes the desired redirect
but also works when I enter the following after the domain name:
/youcanenteranytext/hereatall/anditstillworks/press
In other words, any text following the domain and preceding the conditional string seems to be allowed/ignored. Any advise on how to restrict the condition or rewrite rule to prevent this would be much appreciated!
Thanks, Margarita
You need to including bounds in your regular expressions when you try to match against %{REQUEST_URI}, the ^ indicates the beginning of the match.
RewriteCond %{REQUEST_URI} ^/company/company-history\.html
Will make it so requests for /garbage/stuff/comapny/company-history.html won't match. And likewise:
RewriteCond %{REQUEST_URI} ^/press
Will make it so requests for /youcanenteranytext/hereatall/anditstillworks/press won't match. You can additionally employ the $ in your regular expression to indicate the end of the match, so something like this:
RewriteCond %{REQUEST_URI} ^/press$
Will ONLY match requests for /press and not /something/press or /press/somethingelse or /press/.

Rewrite htaccess old oscommerce links

I am trying to rewrite all the old oscommerce links to a new website. But I am having trouble with part of the URL I need to rewrite.
The link looks like this:
http://www.domain.com/product_info.php?cPath=3_72&products_id=129&osCsid=6j3iabkldjcmgi3s1344lk1285
This rewrite works for the above link:
RewriteCond %{REQUEST_URI} ^/product_info\.php$
RewriteCond %{QUERY_STRING} ^cPath=3_72&products_id=129&osCsid=([A-Za-z0-9-_]+)$
RewriteRule ^(.*)$ http://www.domain.com/apple/air.html? [R=301,L]
But will not work for:
http://www.domain.com/product_info.php?cPath=3_72&products_id=129
My problem is that I want the rewrite to work no matter if the &osCsid=6j3iabkldjcmgi3s1344lk1285 part is included or not.
I think you can achieve this by not specifying the closing delimiter ($)
Give this a try:
RewriteCond %{REQUEST_URI} ^/product_info\.php$
RewriteCond %{QUERY_STRING} ^cPath=3_72&products_id=129
RewriteRule ^(.*)$ http://www.domain.com/apple/air.html? [R=301,L]
By not putting the $ at the end of the regex string you are basically saying: match any string that starts with ..., no matter what comes after
Hope this helps :)
This should do the job just fine:
RewriteCond %{QUERY_STRING} ^cPath=3_72&products_id=129
RewriteRule ^product_info\.php$ http://www.domain.com/apple/air.html? [R=301,L]
There is no need for separate condition RewriteCond %{REQUEST_URI} ^/product_info\.php$ -- this part can be (actually, SHOULD BE, for better performance) moved to RewriteRule.
This is enough ^cPath=3_72&products_id=129 -- it tells "When query strings STARTS with ...". No need to include optional/non-important parameters osCsid=([A-Za-z0-9-_]+).
This rule is to be placed in .htaccess file in website root folder. If placed elsewhere some small tweaking may be required.

htaccess subdomain script redirection

I'm having problems understanding how htaccess redirects work:
Can I do a background redirect, so that the user sees [subdomain].mydomain.com/?p1=v1..., but the server delivers mydomain.com/?sid=[subdomain]&p1=v1... without actual redirection, only server side.
This is what I have so far, it doesn't work:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^([^./]+)\.localhost\.com/(.+) [NC]
RewriteRule (.+) localhost.com/index.php?supplier=$1&$2 [L]
I doesn't change anything.
Edit
I got this halfway working:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^([^./]+)\.localhost\.com$ [NC]
RewriteRule /(.+)$ http://localhost\.com/eshop/?supplier=%1 [QSA,P]
Now I get a nice forbidden warning, if I remove the P flag it'll redirect, so the URL shows http://localhost.com/eshop/?supplier=[subdomain]&p1=v1... like it should, but the user must still see http://[subdomain].localhost.com/eshop/?p1=v1..., now how the remove that forbidden part...
(Notice my website is actually in a folder under www, but the eshop part will go away).
EDIT 2
IT WORKS, so as clmarquart said I needed mod_proxy. On WAMP you have to enable it by clicking on the tray icon->Apache->Apache modules and I enabled proxy_module and proxy_http_module, whatever they are.
Use the "P" flag to force use of the internal proxy. The RewriteURL target must be a full URL when using the proxy module. Use "%1" to "%9" as the captured data from the RewriteCond expression, and "$1" to "$9" for the captured data from the RewriteRule expression.
The following should work better (not tested though)
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^([^./]+)\.localhost\.com$ [NC]
RewriteRule (.+) http://localhost.com/index.php?supplier=%1&$1 [L,P]

mod_rewrite regex (too many redirects)

I am using mod_rewrite, to convert subdomains into directory urls. (solution from here). When I explicity write a rule for one subdomain, it works perfectly:
RewriteCond %{HTTP_HOST} ^[www\.]*sub-domain-name.domain-name.com [NC]
RewriteCond %{REQUEST_URI} !^/sub-domain-directory/.*
RewriteRule ^(.*) /sub-domain-directory/$1 [L]
However, if I try to match all subdomains, it results in 500 internal error (log says too many redirects). The code is:
RewriteCond %{HTTP_HOST} ^[www\.]*([a-z0-9-]+).domain-name.com [NC]
RewriteCond %{REQUEST_URI} !^/%1/.*
RewriteRule ^(.*) /%1/$1 [L]
Can anyone suggest what went wrong and how to fix it?
Your second RewriteCond will never return false, because you can't use backreferences within your test clauses (they're compiled during parsing, making this impossible since no variable expansion will take place). You're actually testing for paths beginning with the literal text /%1/, which isn't what you wanted. Given that you're operating in a per-directory context, the rule set will end up being applied again, resulting in a transformation like the following:
path -> sub/path
sub/path -> sub/sub/path
sub/sub/path -> sub/sub/sub/path
...
This goes on for about ten iterations before the server gets upset and throws a 500 error. There are a few different ways to fix this, but I'm going to chose one that most closely resembles the approach you were trying to take. I'd also modify that first RewriteCond, since the regular expression is a bit flawed:
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$ [NC]
RewriteCond %1 !=www
RewriteCond %1#%{REQUEST_URI} !^([^#]+)#/\1/
RewriteRule .* /%1/$0 [L]
First, it checks the HTTP_HOST value and captures the subdomain, whatever it might be. Then, assuming you don't want this transformation to take place in the case of www, it makes sure that the capture does not match that. After that, it uses the regular expression's own internal backreferences to see if the REQUEST_URI begins with the subdomain value. If it doesn't, it prepends the subdomain as a directory, like you have now.
The potential problem with this approach is that it won't work correctly if you access a path beginning with the same name as the subdomain the request is sent to, like sub.example.com/sub/. An alternative is to check the REDIRECT_STATUS environment variable to see if an internal redirect has already been performed (that is, this prepending step has already occurred):
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$ [NC]
RewriteCond %1 !=www
RewriteCond %{ENV:REDIRECT_STATUS} =""
RewriteRule .* /%1/$0 [L]

Resources