How to prevent ReweiteRules to match subdomains - apache

How can I limit my mod_rewrite RewriteRules to only apply to the www and no-subdomain?
The subdomains are in different folders -- rather website root folder, however all of my RewirteRules apply to all of the subdomains, which is not what I want.
I know that it's possible to match every RewriteRule by a RewriteCond that only matches www and no-subdomain, but then I have to repeat the same thing for all the RewriteRules, which is not what I want again.
So I was wondering if there is any way to globally prevent RewriteRules to apply to other subdomains? I can also place .htaccess files in each subdomain as well to prevent matching, if that's a possibility.
Here is part of what I have in .htaccess right now:
options -Indexes -MultiViews +FollowSymLinks
Header set Access-Control-Allow-Origin *
RewriteEngine On
RewriteBase /
RewriteRule ^city/([^/].+)/([^/].+)/([^/].+)/$ index.php?page=$3&city=$1 [L]
RewriteRule ^city/([^/].+)/([^/].+)/$ index.php?city=$1 [L]
RewriteRule ^flights/([^/].+)/$ index.php?page=flights&mode=$1 [L]
RewriteRule ^health/([^/].+)/$ index.php?page=health&view=$1 [L]
# so on ...
RewriteRule ^([^/].+)/$ index.php?page=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . index.php [L]
Update #1
Just to explain the problem better, right now sub.domain.com shows domain.com instead of it's actual content.

You can insert this single rule below RewriteBase line to ignore all sub-domains from rest of the rules:
# ignore all sub domains
RewriteCond %{HTTP_HOST} !^(www\.)?example\.com$ [NC]
RewriteRule ^ - [L]
Replace example.com with your actual domain.

Related

.htaccess 301 redirect with exclusion does not work

I try to use a simple 301 redirect
from domain1.com/folder/ to domain2.com/
but excluding domain1.com/folder/subfolder
I use the following code in .htaccess:
RedirectMatch 301 ^/folder/((?!subfolder).*)$ https://domain2.com/$1
but it simply redirects all the requests, including the requests to subfolder.
Please, help to fix the line to make it work as described. Thank you!
here is the complete code of .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /folder/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /folder/index.php [L]
</IfModule>
RedirectMatch 301 ^/folder/((?!subfolder).*)$ https://domain2.com/$1
Try it like this using mod_rewrite instead:
(NB: This assumes the .htaccess file is located in the document root.)
# /.htaccess
# Redirect all direct requests, except "subfolder"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond $1 !^subfolder($|/)
RewriteRule ^folder/(.*) https://domain2.com/$1 [R=301,L]
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /folder/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /folder/index.php [L]
</IfModule>
It is important that the redirect goes before the rewrite to your front-controller.
You will need to ensure your browser cache is cleared before testing and test with a 302 (temporary) redirect to avoid potential caching issues.
UPDATE:
Yes, /folder has it's own .htaccess (this is the file I am working at all this time). Yes, /folder is where Wordpress is installed.
In that case you would need to change the above redirect to read as follows (it won't do anything otherwise):
# /folder/.htaccess
# Redirect all direct requests, except "subfolder"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond $1 !^subfolder($|/)
RewriteRule (.*) https://domain2.com/$1 [R=301,L]
Basically, you need to remove folder/ from the start of the regex that matches the URL-path. The URL-path that the RewriteRule pattern matches against is relative to the directory that contains the .htaccess file.
The addition of the check against the REDIRECT_STATUS env var is to ensure that rewritten requests to the WP front-controller (when subfolder is requested) are not redirected.
You can also "simplify" the WordPress directives that follow (although if these are enclosed in # BEGIN WordPress / # END WordPress comment markers then you should leave the directives as they are since they are maintained by WordPress). For example:
RewriteEngine On
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
The RewriteBase directive is not required. And neither is the <IfModule> wrapper. (But as I said above, only change this if you are hand-coding the .htaccess and not letting WordPress maintain it.)

.htaccess RewriteRule with existing file and folder

My web structure looks like this:
public_html/
/images/
/user/
/userimage1.jpg
/userimage2.jpg
/userimage3.jpg
/icons/
/index.php
/user.php
...
I have 2 domains: example.com and images.example.com and I want to use a .htaccess RewriteRule that the images.example.com subdomain leads to the /images/-folder but also to use URLs without the file extension.
My .htaccess looks like this:
<IfModule mod_rewrite.c>
Options +FollowSymLinks +MultiViews
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} ^images\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/images/
RewriteRule ^(.*)$ /images/$1 [NC,L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.php -f
RewriteRule ^(.*)$ $1.php [L]
</IfModule>
Now, https://example.com/user/ works fine, but when I try to open https://images.example.com/user/userimage1.jpg it says that %{REQUEST_URI} is /images/redirect:/images/user.php/userimage1.jpg
Unfortunately, both, the domain and the subdomain have to be installed with public_html as the root folder.
How do I have to adept my .htaccess file so that both URLs, https://example.com/user/ and https://images.example.com/user/userimage1.jpg work fine?
You have a conflict with MultiViews (which you've enabled at the top). The fact that "https://example.com/user/ works fine" (with a trailing slash) is because of MultiViews, not because of your mod_rewrite directives. (The mod_rewrite directives as written would only "work" with /user - no trailing slash.)
When you request https://images.example.com/user/userimage1.jpg, MultiViews triggers an internal subrequest for /user.php/userimage1.jpg (/user.php with additional path-info /userimage1.jpg), but mod_rewrite has also tried to rewrite the request (an internal "redirect") - hence the seemingly malformed rewrite.
Generally, you need to avoid using MultiViews with mod_rewrite rewrites - a common cause of conflict.
Try the following instead:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Rewrite images subdomain
RewriteCond %{HTTP_HOST} ^images\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/images/
RewriteRule ^(.*)$ /images/$1 [L]
# Append .php file extensions
RewriteCond %{DOCUMENT_ROOT}/$1 !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^(.*)/$ $1.php [L]
Note that I've included the trailing slash in the RewriteRule pattern and taken this out of the capturing subpattern - this is assuming that the trailing slash is mandatory on your URLs (as in your example).
You don't need the <IfModule> wrapper unless mod_rewrite really is optional? (It's not.)

How to redirect all subdomains to main domain using htaccess?

I have looked through and tried many different suggestions all to no avail. please help!
I want to redirect all subdomains to main domains. I have pointed the DNS for wildcard subdomains to my IP with A zone and currently any subdomain entered will lead to 404. My eventual result would be that for any subdomain and their URLS, it will be redirected to the main domain. i.e.
blog.my-domain.com -> my-domain.com (yes my domain has a dash)
test.my-domain.com/testing -> my-domain.com
example.my-domain.com -> my-domain.com
my current .htaccess file is as below:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# DO NOT REMOVE THIS LINE AND THE LINES BELOW SSL_REDIRECT:my-domain.com
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^my-domain.com$
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# DO NOT REMOVE THIS LINE AND THE LINES ABOVE SSL_REDIRECT:my-domain.com
I tried adding this piece of code at the bottom but didnt work
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.+)\.my\-domain\.com$ [NC]
RewriteRule (.*) https://my-domain.com%{REQUEST_URI} [L,R=301]
please help thanks!!
1) Add this rule before line "# BEGIN WordPress"
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^my-domain.com$ [NC]
RewriteRule ^(.*)$ https://my-domain.com/$1 [R=301,L]
It's 1:1 rewrite example:
(http or https)://any-subdomain.my-domain.com/link <> https://my-domain.com/link
2) Another possibility is add only rule for subdomains, add it before line "# BEGIN WordPress"
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^(.*)\.my-domain\.com$ [NC]
RewriteRule ^(.*)$ https://my-domain.com/ [R=301,L]
It's rewrite all subdomains requests to my-domain.com, example:
(http or https)://any-subdomain.my-domain.com/link <> https://my-domain.com/
Check the option that you prefer more.

Rewrite rule for opening a different page

I'm stuck with some .htaccess rules.
I've got the page /module/slug. I want, when I type slug to see content of /module/slug/ but not redirect to this page. Is it possible? I've tried this rule, but had no luck:
RewriteRule ^slug/$ /module/slug/ [L]
My .htaccess content:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteRule ^calculator/$ /sample-page/ [R=301,L]
</IfModule>
# END WordPress
That happens because you don't tell Apache to redirect (R=301).
Add the redirect flag R, and it should work. Also make sure that:
You have set the RewriteBase correctly.
There are not any other rules earlier in the file that match the same URL.
.
RewriteEngine On
RewriteBase /
RewriteRule ^slug/$ /module/slug/ [R=301,L]

Rewrite only root without redirect not working

I have a problem that I can't get to rewrite only root to file. For example example.com to example.com/landing-page/mypage.html but keep all other addresses like example.com/something/ intact.
Currently for test purposes I have managed to redirect /test/ and my .htaccess looks like this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/test/.*$
RewriteRule . /wp-content/themes/mytheme/landing_page.html [L]
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
But now if I try to redirect only root and replace RewriteCond with
RewriteCond %{REQUEST_URI} ^/$
it doesn't work and it loads my Wordpress site.
UPDATE:
I tested on another server using just simple rule RewriteRule ^/?$ /mypage/landing-page.html [L] also keeping WordPress lines and it works there, but the same lines do not work on this server. So now the question arises what server settings might be preventing this simple rule.
Looks like you forgot to turn on the RewriteEngine in your second example .
RewriteEngine On
RewriteRule ^$ /landing-page/mypage.html [NC,L]