htaccess redirect in joomla WITHOUT landing on index.php - apache

I've added an redirect from an old domain to my new domain in the .htaccess file of my Joomla 3.x site, running on Apache.
This is the code I'm trying to get working;
RewriteCond %{HTTP_HOST} !newdomain\.co\.uk$ [NC]
RewriteRule ^(.*)$ http\:\/\/www\.newdomain\.co\.uk/$1 [R=301,L]
This succeeds in redirecting any incorrect domain to my new domain, but does NOT put me on the corresponding sub-page.
So, for example, I type in the following address ..;
http:\\old.com\calendar
... and I WANT to end up at;
http:\\newdomain.co.uk\calendar
But instead, I get directed to;
http:\\newdomain.co.uk\index.php
Can anyone help me get the redirect working to land me on the corresponding sub-page?
For the record, the Joomla site's SEO settings are as follows (and work as you would expect - site pages do not generally include index.php in the URL and correspond to the menu item alias);
Search Engine Friendly URLs - YES
Use URL rewriting - YES
Adds Suffix to URL - NO
Unicode Aliases - NO
The COMPLETE .htaccess file looks like this - I don't know if Joomla's .htaccess definitions are affecting the redirect that I've put in place;
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule .* index.php [F]
RewriteBase /
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]
suPHP_ConfigPath /whatever/php.ini
RewriteCond %{HTTP_HOST} !newdomain\.co\.uk$ [NC]
RewriteRule ^(.*)$ http\:\/\/www\.newdomain\.co\.uk/$1 [R=301,L]
Header set X-UA-Compatible "IE=10"
Thanks in advance to anyone who can provide some insight!

You are rewriting a lot of stuff to index.php before already – so when your new Rules you added below that are evaluated, the (internal) request URI most likely is index.php already.
So move those new rules further up.

Related

.htaccess redirect facebook crawlers except privacy policy

I have a SPA app with dynamic content for sharing on Facebook so I am redirecting Facebook crawlers to a nice static page using the following rule in htaccess:
<IfModule mod_rewrite.c>
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit.*$
RewriteRule ^(.*)$ https://sharing.mysite.tld/api/share/$1 [L]
This works great! But there is one problem... I can't make my app live because Facebook requires a link to privacy policy, terms and conditions etc - and these get redirected too!!
I need to ignore a certain URLs - anything requested in /docs/ - from the above rule EDIT: so that urls containing /docs/ are followed as normal (no redirect, just served normally). I can't get .htaccess to pick up on the ignore rule. I would have thought this would do it (with thanks to https://stackoverflow.com/a/1848579/4881971):
RewriteRule ^(docs)($|/) - [L]
so I would have thought my .htaccess file would look like this :
<IfModule mod_rewrite.c>
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit.*$
RewriteRule ^(docs)($|/) - [L]
RewriteRule ^(.*)$ https://sharing.mysite.tld/api/share/$1 [L]
but when I use Facebook Object Debugger on https://mysite.tld/docs/privacy I get a 404! It redirecting to https://sharing.mysite.tld/api/share/docs/privacy
How do I retain the rule but ignore requests from mysite.tld/docs/* ? Thanks.
Could you please try following, please make sure you clear your browser cache before testing your URLs. This considers your uri starts from docs.
<IfModule mod_rewrite.c>
RewriteEngine ON
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit.*$ [NC]
RewriteCond %{REQUEST_URI} ^/docs [NC]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ https://sharing.mysite.tld/api/share/$1 [L]
In case you want to pass URLs where docs could come anywhere in uri(not from starting what 1st solution looks for), then try following Rules.
<IfModule mod_rewrite.c>
RewriteEngine ON
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit.*$ [NC]
RewriteCond %{REQUEST_URI} docs [NC]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ https://sharing.mysite.tld/api/share/$1 [L]
Have it like this with a negated comdition:
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit [NC]
RewriteRule %{THE_REQUEST} !\s/+docs [NC]
RewriteRule ^ https://sharing.mysite.tld/api/share%{REQUEST_URI} [L,R=301,NE]

Re-writing url - apache - htaccess

I am migrating an existing website to a Codeigniter one so need a help with re-writing of the urls.
I need to map old URLs with new URLs so that people visiting site from search engine results get redirected to matching new URLs as otherwise they would get page not found errors.
Most of the old urls in this format e.g.
/page.php?id=5 or /page.php?id=180&t=78
/data.php?token=GH45LK
/faqs.php?k=98#section2
Their matching new URLs are
/page/5 or I will be happy with /page?id=5&whatever=xyz too
/data/GH45LK
/faqs/98#section2
This is my current .htaccess of CodeIgniter
# Turning on the rewrite engine is necessary for the following rules and features.
# FollowSymLinks must be enabled for this to work.
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
# If you installed CodeIgniter in a subfolder, you will need to
# change the following line to match the subfolder you need.
# http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
RewriteBase /
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Rewrite "www.example.com -> example.com"
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
# Checks to see if the user is attempting to access a valid file,
# such as an image or css document, if this isn't true it sends the
# request to the front controller, index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
# Ensure Authorization header is passed along
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
I tried something like this after RewriteBase / line
RewriteRule ^data\.php\?token=(.*)?$ data/=$1 [R=301,L]
but not sure if I got that right as it's not working.
Could you help me getting it right? Thx
RewriteRule does not work that way: it only test the path part of an URL. For all the other parts (domain, query string, ...), you need to use RewriteCond and the corresponding variable (%{QUERY_STRING}, for the query string/here).
RewriteCond %{QUERY_STRING} (?:^|&)id=(\d+)
RewriteRule ^page\.php$ /page/%1 [L,R=permanent]
RewriteCond %{QUERY_STRING} (?:^|&)token=([^&]+)
RewriteRule ^data\.php$ /data/%1? [L,R=permanent]
RewriteCond %{QUERY_STRING} (?:^|&)k=(\d+)
RewriteRule ^faqs\.php$ /faqs/%1? [L,R=permanent]
And I think there is an error with RewriteCond %{HTTPS} !=on as you redirect on http://, not https://, this should result in an infinite loop.
Also note that the anchor (#section2 in your example), is not sent to the server (so it can't be rewritten).

htaccess redirect all subdomains to the same directory

I want to be able to redirect all subdomains to a folder:
RewriteCond %{HTTP_HOST} ^([^/.]+)\.example\.com$
RewriteRule (.+)$ "http://example.com/subdomains/%1" [L,P]
for example, if some visits sub1.example.com it will keep the URL but show example.com/subdomains/sub1 and if the sub1 directory does not exist, it will show example.com/404
Is this possible?
I tried the above code but its showing me:
Forbidden
You don't have permission to access /index.php on this server.
Wordpress says:
# 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
and at the top of my htaccess file, is:
RewriteEngine On
DirectoryIndex index.php
RewriteCond %{HTTP_HOST} admin.domain.com$
RewriteRule ^(.*)$ /admin/system/$1 [L]
Your above .htaccess would externally redirect the calls, as you use a full URL as the target.
In your question you say you want to keep the hostname, so I will assume that is the requirement.
0) Enable rewrite engine
RewriteEngine On
1) Rewriting known subdomains to their directory in /subdomains
# Rewrite known subdomains to /subdomains/{subdomain}/
RewriteCond %{HTTP_HOST} ^([^/.]+)\.example\.com$
RewriteCond %{REQUEST_URI} !^/subdomains [NC]
RewriteCond %{REQUEST_URI} !^/404 [NC]
RewriteRule ^(.+)$ /subdomains/%1/ [L]
When we encounter a request with a subdomain,
and we have not rewritten it to /subdomains
and we have not rewritten it to /404
then rewrite it to /subdomains/{subdomain}/
So, if the request was
http://foo.example.com/hello
the URL in the browser would stay the same, but internally be mapped to
/subdomains/foo/
2) Rewriting unknown subdomains to /404
# Rewrite missing unknown subdomains to /404/
RewriteCond %{HTTP_HOST} ^([^/.]+)\.example\.com$
RewriteCond %{REQUEST_URI} ^/subdomains [NC]
RewriteCond %{REQUEST_URI} !^/404 [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ /404/ [L]
When we encounter a request with a subdomain,
and we have already rewritten it to /subdomains
and we have not rewritten it to /404
and it is not existing as a file
and it is not existing as a directory
and it is not existing as a symlink
then rewrite it to /404
So, if the request was
http://bar.example.com/hello
the URL in the browser would stay the same, but internally be mapped to
/subdomains/bar/
by the first RewriteRule from 1).
If /subdomains/bar/ does not exist, the second RewriteRule from 2) will kick in and internally map it to
/404/
3) Test-Environment
I actually tested all of this with exemplary code, available here: https://github.com/janpapenbrock/stackoverflow-36497197
I'd say you are experiencing a permission issue. I guess your Apache server runs as apache user. Use chmod to give apache access to this path.

Apache, url rewrite

I have the following .htaccess file inside my root directory:
RewriteEngine On
<If "%{SERVER_NAME} = 'example.com'">
# The actual condition is really long one so I replaced it for illustration.
RewriteCond %{HTTP_USER_AGENT} (iPhone|Blackberry|Android) [NC]
RewriteRule .* http://m.example.com%{REQUEST_URI} [R,L]
RewriteCond %{REQUEST_URI} ^/([a-z-]+)/$ [NC]
RewriteRule .* %{REQUEST_SCHEME}://%{SERVER_NAME}/?title=%1 [L]
</If>
<Else>
RewriteCond %{REQUEST_URI} ^/([a-z-]+)/$ [NC]
RewriteRule .* %{REQUEST_SCHEME}://%{SERVER_NAME}/?title=%1 [L]
DirectoryIndex /m/index.htm /m/index.php /m/index.html
</Else>
So as you can see its a pretty much simple way to redirect users of mobile devices to m.example.com and if that is the case I change the DirectoryIndex, few notes:
The reason I duplicate the same RewriteCond/RewriteRule is because I can't use them outside <If>/<Else> blocks.
The way I redirect(if/else) is not the question and I'm pretty sure not the best way, but if anyone have suggestions I'm all ears.
The problem:
If I access example.com/Article-Name on desktop browser there will be internal redirection to: example.com/?title=articleName but I won't see example.com/?title=articleName at my url bar as expected.
The exception:
If I access m.example.com/Article-Name my url bar is now m.example.com/?title=articleName.
I was expecting the same behavior as the desktop (internal redirection not redirection I can see on my url bar), I'm pretty sure its because the DirectoryIndex but I don't how to prove it or solve this issue, if anyone have a solution I will be very thankful.
The main issue with your code is that you're feeding it with an URL that is not the same as the current URL then, what happens is that it ignores the internal and make it an external redirect.
Another very important thing is that you forgot %{HTTP_USER_AGENT} to match against the mobile browsers.
Here is an idea to resolve your issue:
RewriteEngine On
# First we verify if its a mobile device and
# if its not already on the mobile subdomain
RewriteCond %{HTTP_HOST} !^m\.domain\.com$ [NC]
RewriteCond %{HTTP_USER_AGENT} (iPhone|Blackberry|Android) [NC]
RewriteRule ^ http://m.example.com%{REQUEST_URI} [R,L]
# here we deal with all the internal redirects for
# the mobile subdomain
RewriteRule ^m/index\.php$ - [L]
RewriteCond %{HTTP_HOST} ^m\.domain\.com$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ /m/index.php?title=$1 [L]
# here we deal with the normal website
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ /index.php?title=$1 [L]
Your doing internal redirects, if you want to redirect to a new URL use external ones
Replace [L] with [L,R=302]
or 301 if you want the result to be cached

.htaccess rewrite to simultaneously change domain and remove path

My URL structure is currently as follows:
http://domain.com/folder/filename (CURRENT)
I want to change this so that I can use the following URL instead:
http://sub.domain.com/filename (NEW)
So accessing the CURRENT or the NEW url, should load the file located at the CURRENT url, but show the NEW url in the address bar. It should only apply to the "/folder/" path.
sub.domain.com is a mirror of domain.com, ie. they share the same file system and root directory.
This is what I have so far:
Options +FollowSymLinks
RewriteBase /
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$ [NC]
RewriteCond %{REQUEST_URI} ^/folder/?(.*)$ [NC]
RewriteRule ^(.*)$ http://sub.domain.com/$1 [R=301,L]
This is working, but is missing the rule to remove the "/folder/" from the path. I've tried combining multiple RewriteRule's with no luck. Any ideas? Thanks.
UPDATE: Thanks again #Gerben - I understand what your rules are doing now, but the second one isn't working for me. I suspect because it's conflicting with some other rewrite rules, in particular those of WordPress, which are lower down in my .htaccess file:
# BEGIN WordPress
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Because of this the page ends up in a redirect loop, ie (from Chrome):
"The webpage at http://sub.domain.com/folder/index.php has resulted in too many redirects." - while the url I was originally trying to access was, for example, http://sub.domain.com/page
Any ideas?
Try:
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$ [NC]
RewriteRule ^(folder/)?(.*)$ http://sub.domain.com/$2 [R=301,L]
This will redirect everything to sub.domain.com, and remove the /folder part of the URI if it is there. If not, it redirects and leaves the URI untouched.
RewriteCond %{THE_REQUEST} /folder/
RewriteRule ^folder/(.*)$ http://sub.domain.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^sub\.domain\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/folder/
RewriteRule ^(.*)$ folder/$1 [L]
# WordPress rules here
edit the second R=301 should not have been there
But this won't work, as wordpress has no way of knowing you want folder. You could add the Proxy flag to the rewrite, but then you need to change the rule above to not redirect on this internal proxy request.