redirect additional subdomain in htaccess - apache

I have a problem with an redirect.
I have this code in my htaccess file.
RewriteCond %{HTTP_HOST} ^frutasadomicilio.cl
RewriteRule ^ http://www.frutasadomicilio.cl%{REQUEST_URI} [L,R=301]
Redirect 301 /index.html http://www.frutasadomicilio.cl/venta-de-verduras
Redirect 301 http://frutasadomicilio.cl http://www.frutasadomicilio.cl/venta-de-verduras
This code is working fine. This code redirects all requests without www to www.
But my problem is when I try to access resources.frutasadomicilio.cl that is a subdomain, I am redirected to www.frutasadomicilio.cl/venta-de-verduras.

I assume your subdomain points to a subdirectory off the document root of the main domain (a common setup)? eg. resources. -> /resources/...?
The problem in this case is that the .htaccess file from the parent directory on the filesystem is inherited. So, a request for resources.example.com will result in a redirect (Redirect 301 /index.html ...).
Also, you should not mix mod_alias redirects (ie. Redirect) with mod_rewrite redirects (ie. RewriteRule). If you are using mod_rewrite then only use mod_rewrite.
Redirect 301 http://frutasadomicilio.cl http://www.frutasadomicilio.cl/venta-de-verduras
This line actually does nothing and should be removed. Redirect takes a root-relative path (starting with a slash) as the source path, not an absolute path, so this will never match.
The last two Redirects can be rewritten as the following (using mod_rewrite) to avoid your unwanted redirection:
RewriteCond %{HTTP_HOST} ^www\.
RewriteRule ^(index\.html)?$ /venta-de-verduras [R=301,L]
Now, the redirection only occurs when the host starts www. (so excludes resources.).
Alternatively, you can omit the above RewriteCond directive and include an .htaccess file in the /resources subdirectory with the following directive.
RewriteEngine On
mod_rewrite directives are not inherited by default, so by simply enabling the rewrite engine in the subdirectory prevents the mod_rewrite directives in the parent .htaccess from being executed (note that other modules in the parent .htaccess file are still processed). This might be preferable if you have a lot of redirects in the parent .htaccess file that need to be excluded.

Related

.htaccess redirect not redirecting

I am trying to Redirect pages to new location on the same website using .htaccess
the physical file name is displayitems.php but there is a rule in .htaccess
RewriteRule ^buy-online-(.*) ./displayitems.php?url=$1
which is to handle the user friends URLs and works well.
Now i want to redirects these user friendly urls to new location which is on the same website for eg.
redirect https://example.com/buy-online-alhabib-rings4-sku-1658906163 https://example.com/products/jewelry/buy-online-alhabib-rings4-sku-1658906163 [R=301]
redirect https://example.com/buy-online-alhabib-rings3-sku-1658906162 https://example.com/products/jewelry/buy-online-alhabib-rings3-sku-1658906162 [R=301]
redirect https://example.com/buy-online-alhabib-rings2-sku-1658906161 https://example.com/products/jewelry/buy-online-alhabib-rings2-sku-1658906161 [R=301]
redirect https://example.com/buy-online-alhabib-rings1-sku-1658906160 https://example.com/products/jewelry/buy-online-alhabib-rings1-sku-1658906160 [R=301]
these user friendly url doesn't have any extensions like ".php" ".htm" etc
but nothing happening.
I have added this code in php file to check if url doesn't contain \products\ than redirect it to new location with the same name, for testing i just redirect it with 302 once all tested i will change it to 301
if (strpos($_SERVER['REQUEST_URI'], "/products/") === false) { $NewAddress = strtolower("Location:". $ini['website_address_https'] . "products/".$Product['categoriesname']."/".$Product['BrandName'].$_SERVER['REQUEST_URI']); header("$NewAddress",TRUE,302); }
redirect https://example.com/buy-online-alhabib-rings4-sku-1658906163 https://example.com/products/jewelry/buy-online-alhabib-rings4-sku-1658906163 [R=301]
There are 3 main issues here:
The mod_alias Redirect directive takes a root-relative URL-path (starting with a slash) as the source URL, not an absolute URL. So the above will never match.
You have mixed syntax with mod_rewrite. [R=301] is a RewriteRule (mod_rewrite) flags argument and has nothing to do with the mod_alias Redirect directive. Redirect takes the HTTP status code as an optional second argument. eg. Redirect 301 /buy-online-alhabib-rings4-sku-1658906163 ...
Since you are using mod_rewrite (ie. RewriteRule) for your internal rewrite, you should use mod_rewrite for external redirects as well to avoid potential conflicts. These redirects then need to go before your internal rewrite.
Additionally,
In the 4 redirects you have posted it looks like you are simply injecting /products/jewelry at the start of the URL-path. This does not need 4 separate rules, providing you are wanting to redirect all URLs that following this particular format.
Try the following instead:
RewriteEngine On
# Inject (redirect) "/product/jewelry" at the start of the URL-path
RewriteRule ^buy-online-alhabib-rings\d-sku-\d+$ /products/jewelry/$0 [R=301,L]
# Internal rewrite
RewriteRule ^buy-online-(.*) displayitems.php?url=$1 [L]
The $0 backreference in the first rule contains the entire URL-path that is matched by the RewriteRule pattern.
Note that I also removed ./ from the start of the substitution string in the last rule. This is unnecessary here.

Redirect all requests to subdirectory without changing the url _and_ remove subdirectory from url

For a seamless deployment of new website versions I'm using following directives to transparently redirect all requests to a specific subdirectory (v2 in this snippet).
DirectorySlash Off
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !v2/
RewriteRule (.*) /v2/$1 [L]
The next step is, that I need another rewrite rule to ensure, that requests to that subdirectory will be redirected the corresponding root url (e.g. https://example.com/v2/foo.html should redirect to https://example.com/foo.html).
All my attempts in creating this rule by myself resulted in an redirect loop.

htaccess 301 redirect not redirecting

tried several ways to make redirect, but not successfull
Redirect 301 /ru/pages/portfolio/ /ru/pages/portfolio/3/ [END,R=301]
or
Redirect 301 http://myssite/en/pages/portfolio http://myssite/en/pages/portfolio/3
and many others from internet, but all of them not working.
Need to redirect pages/portfolio to pages/portfolio/3 (for all languages - en, ru)
This is content of file
<IfModule mod_rewrite.c>
# Turn Off mod_dir Redirect For Existing Directories
DirectorySlash Off
# Rewrite For Public Folder
RewriteEngine on
Redirect 301 /ru/pages/portfolio/ /ru/pages/portfolio/3/ [END,R=301]
RewriteCond $1 !^(pma)
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
Since you are already using mod_rewrite (for an internal rewrite) you should also use mod_rewrite for this redirect, rather than using a mod_alias Redirect. Different modules execute at different times during the request, despite the apparent order of the directives in the config file.
However, your example is unclear. The first example includes a trailing slash; the second does not? Is there a trailing slash or not?
Try something like the following instead after the RewriteEngine directive:
RewriteRule ^(en|ru)/pages/portfolio$ /$1/pages/portfolio/3 [R,L]
This excludes the trailing slash. And assumes "all languages" are just en and ru. This is also a temporary (302) redirect. Change to a permanent (301) redirect (if that is the intention) only when you are sure it's working OK, since 301s are cached by the browser. You will need to clear your browser cache before testing.
Redirect 301 /ru/pages/portfolio/ /ru/pages/portfolio/3/ [END,R=301]
:
Redirect 301 http://myssite/en/pages/portfolio http://myssite/en/pages/portfolio/3
Aside: Neither of these would have worked anyway. End flags like [END,R=301] are a mod_rewrite syntax, and do not relate to mod_alias (Redirect). And the URL-path matched by the Redirect directive should be a root-relative path beginning with a slash, not an absolute URL. See the Apache docs... https://httpd.apache.org/docs/current/mod/mod_alias.html#redirect

.htaccess to redirect the root to a subfolder

Using .htaccess I am trying to redirect requests for the root of a site to a subdir. The three approaches I have tried either fail or leave something to be desired.
This fails with indefinite recursion:
Redirect / http://example.org/sub
These don't seem to work for a defaulted index.html:
Redirect / http://example.org/sub/index.html
Redirect /index.html http://example.org/sub/index.html
This works, but leaves the directory at the top level, which necessitates rewriting relative links in the html file:
DirectoryIndex http://example.org/sub/index.html
So, is there any straightforward way just redirect the root totally to a subfolder and have everything work there? I am trying to avoid the fancier features of .htaccess -- I'd probably just prefer the third alternative if it gets too complicated.
In the DocumentRoot of old site have this rule:
RewriteEngine On
RewriteCond %{HTTP_HOST} !example\.org$ [NC]
RewriteRule ^ http://example.org/sub%{REQUEST_URI} [L,NE,R=301]

Apache mod_rewrite - want a file system redirect not a 301 redirect

I have example1.com on a shared web host running Apache. It has a directory example1.com/foo. I now want example2.com to serve the same content from example1.com/foo, except at the example2.com root without the intervening directory in the URL. Like example2.com/bar.html should serve the same content as example1.com/foo/bar.html .
RewriteEngine on
RewriteCond %{HTTP_HOST} example2.com$ [NC]
RewriteRule ^(.*)$ foo/$1 [NC]
This simple rewrite rule takes any request intended for example2.com and inserts the foo/ to point to the content which is in that directory. Problem is this keeps doing an external 301 redirect. I don't want that, I want the browser to stay on example2.com without redirecting while Apache serves up the content from /foo in the filesystem.
Been over the Apache mod_rewrite docs several times, which say how to force a 301 redirect with the [R] flag but don't say how to force it NOT to happen. What am I missing here? It is behaving the same on both my Linux shared host and a local test with Apache on Windows.
Thanks!
I figured this out. The 301 was happening because I had the directory name wrong in the rule. So the result of the rule pointed to a path that didn't exist, which makes Apache try to fallback from the file system redirect to a 301 redirect.
Then I had to fix an infinite loop, since that above rule always adds "foo" to the URL even if it's already present so I'd get foo/foo/foo/foo/... . We need to add it only if it's not already there. Had to do it with this two-step rule, because you can't use wildcards in a capturing group of a negative rule. But this seems to work, adding "foo" when the host is example2.com and the URL does not already contain "foo".
RewriteEngine on
RewriteCond %{HTTP_HOST} example2.com$ [NC]
RewriteRule !^foo - [C]
RewriteRule ^(.*)$ foo/$1 [NC,PT]