Exclude addon domain from rewrite rule? - .htaccess

I am trying to redirect all files in the folder mydomain.com/es to mydomain.com/
This works using
RedirectMatch 302 ^/es/ /index.php
However this is also redirecting the folder es/ in one of my addon domains.
So myaddondomain.com/es/ is going to mydomain.com/
How do I stop this? I have searched through the forum and found these rules that people have posted, but neither of them work
RewriteRule ^myaddondomain.com/?$ - [L]
or
RewriteCond %{REQUEST_URI} !^/myaddondomain.com/$

RedirectMatch 302 ^/es/ /index.php
If this should only apply to a particular domain (ie. hostname) then you need to use mod_rewrite (RewriteRule / RewriteCond) instead and check the HTTP_HOST in a condition. For example:
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com [NC]
RewriteRule ^es/ /index.php [R,L]
Note that the URL-path matched by the RewriteRule pattern (1st argument) in a directory context does not start with a slash.
This also allows for an optional www subdomain. Remove (www\.)? in the CondPattern if that is not required.
Note that this redirects to /index.php, not strictly mydomain.com/ as you stated in your description. Maybe you should be redirecting to / instead?
Aside: As far as SEO is concerned, many-to-one redirects to the homepage will likely be seen as a soft-404.
Aside:
I have searched through the forum and found these rules that people have posted, but neither of them work
RewriteRule ^myaddondomain.com/?$ - [L]
or
RewriteCond %{REQUEST_URI} !^/myaddondomain.com/$
I would be curious where you saw these (on StackOverflow?) as they are obviously incorrect in this context.
The RewriteRule pattern (first rule) matches against the URL-path only, so the first rule will never match.
Again, the REQUEST_URI server variable (second rule) contains the URL-path only so the "negated" condition will always be successful.

Related

.htaccess redirect rule only root-domain [duplicate]

I am not a programmer of .htaccess code, I read the other related posts but do not understand them. Non of them do what I need.
I have a Wordpress site that runs on http://example.com/main but want to redirect http://example.com to http://otherexample.com/page.php. Also need that http://example.com/anyfile not be redirected.
Assuming example.com and otherexample.com point to different places then try something like the following in the root .htaccess file at example.com:
RedirectMatch 302 ^/$ http://otherexample.com/page.php
The regex ^/$ matches / only, ie. the root directory.
^ asserts the start-of-string (ie. URL-path)
/ matches a literal slash
$ asserts the end-of-string
UPDATE: I found that secondary.com also is redirected.
If you have multiple domains pointing to the same place and you only want to redirect one of them then you'll need to use mod_rewrite to check the hostname first before redirecting.
For example, the following would need to go at the top of the .htaccess file before the WordPress front-controller:
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com [NC]
RewriteRule ^$ http://otherexample.com/page.php [R=302,L]
Note that the RewriteRule pattern matches against the URL-path less the slash prefix, hence the regex ^$ (different to the RedirectMatch directive), which matches an empty URL-path (ie. the root directory only).

HTACCESS How to "cut" URL at one point

I am new to .htaccess and I don't understand it well. Recently I have built the following code:
RewriteEngine On
RewriteCond %{HTTP_HOST} (.*)
RewriteCond %{REQUEST_URI} /api/v2/
RewriteRule ^api/v2(.*) /api/v2/api.php?input=$1
This was in the root public folder (example.com/.htaccess). But now I have to create second Rewrite and I want to make .htaccess file in example.com/api/v2/ folder. I tried to remove /api/v2/ part in each Rewrite Rule, but only thing I got was error 500.
What I want to achieve:
If someone uses this link: https://example.com/api/v2/test/test/123, I'd like to make it into https://example.com/api/v2/api?input=test/test/123 with .htaccess located in example.com/api/v2 folder.
Addressing your existing rule first:
RewriteCond %{HTTP_HOST} (.*)
RewriteCond %{REQUEST_URI} /api/v2/
RewriteRule ^api/v2(.*) /api/v2/api.php?input=$1
The first RewriteCond (condition) is entirely superfluous and can simply be removed. The second condition simply asserts that there is a slash after the v2 and this can be merged with the RewritRule pattern. So, the above is equivalent to a single RewriteRule directive as follows:
RewriteRule ^api/v2(/.*) /api/v2/api.php?input=$1 [L]
This would internally rewrite the request from /api/v2/test/test/123 to /api/v2/api.php?input=/test/test/123 - note the slash prefix on the input URL parameter value.
However, unless you have another .htaccess file in a subdirectory that also contains mod_rewrite directives then this will create a rewrite loop (500 error).
Also note that you should probably include the L flag here to prevent the request being further rewritten (if you have other directives).
If someone uses this link: https://example.com/api/v2/test/test/123, I'd like to make it into https://example.com/api/v2/api?input=test/test/123 with .htaccess located in example.com/api/v2 folder.
I assume /api? is a typo and this should be /api.php?. Note also that the slash is omitted from the start of the URL parameter value (different to the rule above).
I tried to remove /api/v2/ part in each Rewrite Rule, but only thing I got was error 500.
This is the right idea, however, you need to be careful of rewrite loops (ie. 500 error response) since the rewritten URL is likely matching the regex you are trying to rewrite.
Try the following instead in the /api/v2/.htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_URI} !api\.php$
RewriteRule (.*) api.php?input=$1 [L]
The preceding RewriteCond directive checks that the request is not already for api.php, thus avoiding a rewrite loop, since the pattern .* will naturally match anything, including api.php itself.
You could avoid the additional condition by making the regex more specific. For example, if the requested URL-path cannot contain a dot then the above RewriteCond and RewriteRule directives can be written as a single directive:
RewriteRule ^([^.]*)$ api.php?input=$1 [L]
The regex [^.]* matches anything except a dot, so avoids matching api.php.
Alternatively, only match the characters that are permitted. For example, lowercase a-z, digits and slashes (which naturally excludes the dot), which covers your test string test/test/123:
RewriteRule ^([a-z0-9/]*)$ api.php?input=$1 [L]
Or, if there should always be 3 path segments, /<letters>/<letters>/<digits>, then be specific:
RewriteRule ^([a-z]+/[a-z]+/\d+)$ api.php?input=$1 [L]

Redirect Each Page of Old Domain to Same Page URL on the New Domain

I know this question has been asked with all variations but I still cannot find the exact answer. I have changed my domain name. All website files and urls are still the same. old domain still points so the same server and I have the following code in htaccess file.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^olddomain\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.olddomain\.com$
RewriteRule ^(.*)$ "https\:\/\/www\.newdomain\.com\/$1" [R=301,L]
Problem is that this only redirects the old domain home page. What can I do so I don't have to add individual redirects for each page.
It sounds like you've put these directives in the wrong place in your .htaccess file. They need to go at the beginning of the file, not at the end.
These directives look typical of cPanel generated redirects. cPanel always places redirects at the end of the .htaccess file (which is often incorrect).
If you have a front-controller before this (such as that used by WordPress) then you will find that these directives will only get processed for requests to the document root (ie. the "homepage"), as all other requests will be stopped by the front-controller.
These directives can also be simplified:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?olddomain\.com [NC]
RewriteRule (.*) https://www.newdomain.com/$1 [R=301,L]
I've removed the $ from the end of the CondPattern so as to match a FQDN (that ends in a dot).
There is also no need to backslash escape colons, slashes and dots in the RewriteRule substitution, as these characters carry no special meaning here (it's not a regex). (This unnecessary escaping is very typical of cPanel.)

Redirect All Unused Link on a subdomain to a domain

I want to redirect all the unused link in my subdomain.olddomain.com to newdomain.com
i tried this but it doesn't seem to work for subdomain
RewriteCond %{HTTP_HOST} !^subdomain\.olddomain\.com [NC]
RewriteRule ^/(.*) http://www.newdomain.com/$1 [L,R=301]
I manage to make the code below but the issue is it does not redirect or catch all the unused like. It only redirects the root and returns page error when accessing unused link(e.g. tag) An example url look like below (OsCommerce)
sub.domain.com/product_info.php?products_id=999&osCsid=29f8a9504d1c4de90a1a1e4106344280
RewriteCond %{HTTP_HOST} !^www\.newdomain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
Additional Info:
What I am trying to do is redirect all the link coming from subdomain.olddomain.com to newdomain.com so for example when someone visit subdomain.olddomain.com/tags/vanilla or subdomain.olddomain.com/product_info.php?products_id=999&osCsid=29f8a9504d1c4de90a1a1e4106344280m they will automatically be redirected to newdomain.com , the newdomain.com is located in another server server
From the documentation (emphasis mine):
Per-directory Rewrites
The rewrite engine may be used in .htaccess files and in sections, with some additional complexity.
To enable the rewrite engine in this context, you need to set "RewriteEngine On" and "Options FollowSymLinks" must be enabled. If
your administrator has disabled override of FollowSymLinks for a
user's directory, then you cannot use the rewrite engine. This
restriction is required for security reasons.
When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is
automatically removed for the RewriteRule pattern matching and
automatically added after any relative (not starting with a slash or
protocol name) substitution encounters the end of a rule set. See the
RewriteBase directive for more information regarding what prefix will
be added back to relative substitutions.
If you wish to match against the full URL-path in a per-directory (htaccess) RewriteRule, use the %{REQUEST_URI} variable in a
RewriteCond.
The removed prefix always ends with a slash, meaning the matching occurs against a string which never has a leading slash. Therefore, a
Pattern with ^/ never matches in per-directory context.
Although rewrite rules are syntactically permitted in and sections (including their regular expression counterparts),
this should never be necessary and is unsupported. A likely feature to
break in these contexts is relative substitutions.
The .htaccess-file is per-directory context, so your rule will never ever match anything. Your rule should look like:
RewriteCond %{HTTP_HOST} !^subdomain\.olddomain\.com [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [L,R=301]
This is assuming that newdomain.com does not use this .htaccess file, as that would cause an infinite redirect.

htacces redirect and mask

How would I redirect from the root folder to a sub folder and then mask that folder?
So instead of http://root.com/sub_folder
It would be just http://root.com
I have tried:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^root\.com$
RewriteRule (.*) http://root.com/$1 [R=301,L]
RewriteRule ^$ /sub [L]
However, that does not work. Any help will be welcome.
To clarify what I think you're looking for:
You want users who enter http://root.com with no trailing path to be rewritten silently to http://root.com/sub.
If a user directly enters http://root.com/sub, however, you want them to be redirected to http://root.com.
Any other path within root.com should be left alone.
The following two rules accomplish this. If you have more than one domain and only want this to apply to one domain, add your original RewriteCond in front of each RewriteRule.
RewriteRule ^sub/?$ http://root.com/ [R=301,L]
RewriteRule ^$ /sub [END]
First rule redirects /sub with or without trailing slash to root.com. Second rule rewrites base domain to /sub.
EDIT: Per Jon Lin's comment, below, the [L] flag only stops the current round of processing and internal rewrites are sent through the rules once more (I always forge that part). So, you can terminate the second line with [END] instead, which stops all rewrite processing. The catch is that [END] is only available in Apache 2.4 or higher, so if you're on an older version something trickier will need to be done.

Resources