.htaccess cross-domain redirect - apache

I'm trying to create a redirect from http://example.com/links/AAA to http://links.example.net/l/AAA (where AAA is a variable). I've got that working. The problem is that both http://example.com/links/ and http://example.com/links should redirect to http://links.example.net (without the /l/).
At the moment http://example.com/links/ redirects to http://links.example.net/l/, and example.com/links redirects to http://links.example.net/l//hsphere/local/home/username/example.com/links.
Current .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} (.+)$ [NC]
RewriteRule ^(.*)$ http://links.example.net/l/$1 [R=301,L]
</IfModule>
Pseudocode:
if ($path) {
goto(http://links.example.net/l/${path}/); // Adding the trailing slash is not necessary, but would be handy. Obviously, don't add if it already exists.
} else {
goto(http://links.example.net/);
}
I have looked through a bunch of other .htaccess questions here (good grief there are so many), but have yet to find anything equivalent.
If necessary, I can do this a different way:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php/$1
</IfModule>
And then do the redirection in PHP, where I'm a bit more at home. But that would be (a) less efficient, (b) less fun, and (c) less educational. So I'm going to try to do this the proper way.

Here is one way, assuming that your .htaccess file is in the root directory of your site.
RewriteEngine on
RewriteBase /
#if /links or links/ (path empty)
RewriteCond %{REQUEST_URI} ^/links/?$ [NC]
RewriteRule ^ http://links.example.net [R=301,L]
#otherwise
RewriteRule ^links/(.*)$ http://links.example.net/l/$1 [R=301,NC,L]

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 language based RewriteRule like example.com/en/

I'm trying to write redirect directives in the .htaccess to forward internally all user requests like this:
Every request in a language folder should redirect to the requested file with the language query string:
example.com/en/contact.php -> example.com/contact.php?lang=en
Redirect any request without language path to a default language folder like this:
example.com -> example.com/en
Remove trailing slash if the address is entered with it:
example.com/en/ to example.com/en
For the folder projects, every request should lead to the view-project.php file with the respective query strings:
example.com/en/projects/test -> example.com/view-project.php?lang=en&path=test
Here is my attempt, but it's not working without trailing slash on a request like: http://www.example.com/de and is not redirecting http://www.example.com to a default language folder.
RewriteEngine On
RewriteRule ^(en|de)/(.*)$ $2?lang=$1 [L,QSA,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^projects/([^/\.]+)/?$ view-project.php?path=$1 [QSA,L]
How can I achieve this?
This is possible a duplicate and I apologize for that. I searched everywhere and read about 100 posts, but I did't found what I'm looking for.
after struggling a while and with the help of someone else, here is the .htaccess file that works for me:
RewriteBase /example.com/
DirectorySlash Off
RewriteEngine On
RewriteOptions AllowNoSlash
RewriteRule ^$ de [R=301,L]
RewriteRule ^(de|en)/$ $1 [R=301,L]
RewriteRule ^(de|en)$ index.php?lang=$1 [L]
RewriteRule ^(de|en)/projects/(.+) view-project.php?lang=$1&path=$2 [L,QSA]
RewriteRule ^(de|en)/(.+) $2?lang=$1 [L,QSA]
Try:
RewriteEngine On
RewriteBase /mysite.com/
RewriteCond %{HTTP:Accept-Language} (en|de) [NC]
RewriteRule ^ /%1/index.php [L]
RewriteCond %{HTTP:Accept-Language} (en|de)
RewriteCond %{DOCUMENT_ROOT}%1%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule ^(en|de)/(.+)$ $2&lang=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^projects/([^/\.]+)/?$ view-project.php?path=$1 [QSA,L]
Edit:
The above was before the detailed explanation: After the detailed explanation, I've come up with this solution which is very similar to the solution the author has come up with while I was not aware about the edit explaining the situation:
DirectorySlash Off # disables mod_dir slash redirect
RewriteEngine On
RewriteBase /mysite.com/ # rewrites inside /mysite.com/
RewriteOptions AllowNoSlash # stops ignoring the directory redirects that redirect directories without slash, so by default: example.com/dir1 -> example.com/dir2 would be ignored. This is used because DirectorySlash is off
RewriteRule ^(en|de)\/projects\/(.+)$ view-project.php?lang=$1&path=$2 [QSA,L] # rule 4
RewriteRule ^(en|de)\/(.*)$ $2?lang=$1 [QSA,L] # rule 1
RewriteRule ^$ en [R=302,L] # rule 2
RewriteRule ^(en|de)\/$ $1 [R=302,L] # rule 3

.htaccess RewriteRule Exception

I have the following rules in my .htaccess file. The problem is when I try to navigate to site.com/news/wp-admin/, it ends up in a redirect loop. From other questions/answers I've read, you can create an exception by using RewriteCond %{REQUEST_URI} !^/news/wp\-admin/ but this does not resolve the issue. It still redirects. I'm not sure what I'm doing wrong.
The below .htaccess is in my root.
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteOptions inherit
RewriteCond %{REQUEST_URI} !^/news/wp\-admin/
RewriteRule ^([a-z0-9\-]+)/?$ index.php?p=$1 [L,NC,QSA,B]
RewriteRule ^([a-z0-9\-]+)/(option1|option2|option3)/?$ index.php?p=$1&type=$2 [L,NC,QSA,B]
RewriteRule ^([a-z0-9\-]+)/(option1|option2|option3)/(.+)$ index.php?p=$1&type=$2&q=$3 [L,NC,QSA,B]
If I comment out RewriteRule ^([a-z0-9\-]+)/?$ index.php?p=$1 [L,NC,QSA,B] it works, but breaks the rest of my site.
This is the .htaccess in /news/ where my WordPress is.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /news/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /news/index.php [L]
</IfModule>
# END WordPress
I assume you have Apache 2 so that mean you have to do it that way:
RewriteCond %{REQUEST_URI} !^/?news/wp-admin/
In Apache 2 there is no leading / so we make it optional with /?
and there is no need to escape the - because it have no special meaning.
Edit
Additional removing RewriteOptions inherit will do it, because with this option you apply the same rules to subdirectory and this will cause your loop

Apache .htaccess RewriteRule not including subdirectory when redirecting non-www to www url

I've setup a rewrite rule in order to direct domain.com traffic to www.domain.com using the following rule:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
From my limited understanding, the $1 in the RewriteRule should match anything after domain.com/ and then be placed at the end of my rewritten url www.domain.com/.
For example domain.com/abc should become www.domain.com/abc.
However this is not working. If I browse to domain.com/abc then this path isn't rewritten at all and I just get domain.com/abc without the www.
I've done lots of reading just to figure out that the $1 should be taking care of this, from my understanding.
Can anyone explain why it isn't working as I suspect it should be? Thanks.
It turns out that because I was using Wordpress AND W3 Cache plugin that I was simply putting the code in the wrong place in my .htaccess file.
The code should be placed within the # BEGIN Wordpress codeblock and before the existing rules that Wordpress already has in place.
The existing code should look something like this:
# 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
I added my original code to this as follows:
# BEGIN Wordpress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
#END Wordpress
This fixes the issue I was describing above. Thanks to the commenters for sparking my thought process.

Folder control with .htaccess

I have a directory /public_html/myfolder/ and I want my domain www.example.com to point to /public_html/myfolder/ as my root folder.
I figured that out, but problem is, my images are not showing.
Here's my .htaccess file:
Options -Indexes
RewriteEngine on
Options +FollowSymLinks
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule .* https://www.example.com/$1 [L,R=301]
RewriteRule ^$ myfolder/index.php [L]
# Require SSL
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST} [L]
# Rewrite rules
<IfModule mod_rewrite.c>
#RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ myfolder/index.php?q=$1 [L,QSA]
</IfModule>
The issue may be that you have relative paths specified for your images on pages and after the URL is rewritten the links get broken. To fix this cosider using root-relative paths for the resources.
You will need to make sure the images are ignored by using RewriteCond's.
Try something like
RewriteCond %{REQUEST_FILENAME} !\.(jpg|png|gif)$
(not sure if the . should be escaped, but i think it should be)
You can also try adding
RewriteLog
RewriteLogLevel 3 (or maybe greater)
I'm not sure if this works if it is inserted into a .htaccess, it might be that it has to be in the server conf, but it is worth a try. It is easier to debug rewrite if you have the log.