Redirect to https and sub dir on apache2 - apache

I have a bolt application installed and want to do 2 things with my .htacces:
1st) Redirect to the /public/ folder, since bolt displays an error otherwise.
2nd) Change all incoming requests to https://
Seperatly I get them to work, individually I get either: 404, installation error or missing files on the site since the path differs.
I now have the following that redirects to /public/:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule cache/ - [F]
# Some servers require the RewriteBase to be set. If so, set to the correct directory.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^mydomain.ch$ [OR]
RewriteCond %{HTTP_HOST} ^www.mydomain.ch$
RewriteRule ^(.*)$ /public/$1 [PT,L,QSA]
</IfModule>
In an attempt to switch to https:// I tried:
RewriteCond %{REQUEST_URI} /public/$1
RewriteCond %{HTTPS} =off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [PT,L,QSA]
How can I solve it and why is this not working?

Related

RewriteRule not doing the job on blog subfolder

The following code, which was discussed recently on another post here, works as a charm on my website and subdomain:
RewriteEngine On
# Force www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
# Force https (SSL)
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
However, on the /blog subfolder, where I have my WordPress-based blog, it doesn't work. What do I mean that it doesn't work? When opening a page on my blog, a secure page (using https) is opened, and that is good. No issues there.
But if on the website or subdomain I manually enter a non-secure link (using just http, without the "s"), it automatically gets redirected to a secure one (https, with the "s"), but on the blog that doesn't happen, even though the same RewriteRule is used .htaccess of the blog subfolder as in the main domain and subdomain subfolder.
The full text of the blog's subfolder's .htaccess file is:
# BEGIN WordPress
# The directives (lines) between `BEGIN WordPress` and `END WordPress` are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress
RewriteEngine On
# Force www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
# Force https (SSL)
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]
# Use PHP70 as default
AddHandler application/x-httpd-php70 .php
<IfModule mod_suphp.c>
suPHP_ConfigPath /opt/php70/lib
</IfModule>
On a sidenote, I wasn't sure if I need the second RewriteEngine On, or if perhaps it even makes trouble, so I tried both with and without, with the same result.

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.

generic non-www to www, and non-http to https

I have the following code for my .htaccess file that I've picked up from here and tried adapting it as I understand from .htaccess, yet I can't seem to get it to work (or maybe the browser has cached it but I can't seem to clear it).
Options -Indexes
Options +FollowSymlinks
<IfModule mod_rewrite.c>
########## FORCE SSL ##########
RewriteEngine On
RewriteBase /
# Non-secure requests to www.domain.com should redirect to https://www.domain.com
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^www\.%{HTTP_HOST} [NC]
RewriteRule ^(.*)$ https://www\.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# All secure (HTTPS) traffic should redirect to https://www.domain.com
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !^www\.%{HTTP_HOST} [NC]
RewriteRule ^(.*)$ https://www\.%{HTTP_HOST}/$1 [L,R=301]
</IfModule>
I want to make it as generic a possible so I can simply copy and paste it to any site I make so no need to edit it each time - I guess I could also do this in PHP but I think it would be good if .htaccess is also there.
Another point is, can .htaccess be read if i were to go to www.domain.com/.htaccess or do I need to cover that in a 'deny all' kind of thing?
The second argument to the RewriteCond must be a regex, so it cannot contain a variable.
Try adding the following to your .htaccess file in place of the rules you had
#capture top level domain (.com or .co.uk)
RewriteCond %{HTTP_HOST} ([-_a-zA-Z0-9]+\.([a-zA-Z]{2,5}|co\.uk))$ [NC]
RewriteCond %{HTTP_HOST} (www\.)?(.+)$ [NC]
RewriteRule ^ - [E=MY_TLD:%2]
# Non-secure requests to www.domain.com should redirect to https://www.domain.com
RewriteCond %{HTTPS} off
RewriteRule ^ https://www\.%{ENV:MY_TLD}%{REQUEST_URI} [L,R=301]
# All secure (HTTPS) traffic should redirect to https://www.domain.com
RewriteCond %{HTTPS} on
#if host does not start with www
RewriteCond %{HTTP_HOST} !^www\.[-_a-zA-Z0-9]+\.([a-zA-Z]{2,5}|co\.uk)$ [NC]
RewriteRule ^ https://www\.%{ENV:MY_TLD}%{REQUEST_URI} [L,R=301]
Shortest version would be:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} (www\.)?(.+)$ [NC]
RewriteRule ^ https://www\.%2%{REQUEST_URI} [L,R=301]
Only (somewhat) downside would be that subdomain.example.com gets redirected to www.subdomain.example.com

How do i force www subdomain on both https and http

For whatever reason I can't seem to get this right, I've looked at many examples on here and apache's website. I'm trying to force www.domain.com instead of domain.com on EITHER http or https but I am not trying to force https over http.
the following code seems to work for all https connections but http will not redirect to www.
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteRule ^ https://www.domain.com%{REQUEST_URI} [R=301]
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteRule ^ http://www.domain.com%{REQUEST_URI} [R=301]
You don't need the second RewriteEngine directive. That may or may not be causing a parse issue making the second set of rules not work. To test whether this is the case, try switching the order of the two blocks you have.
It's good practice to use L to modify requests that are definitely the last. So, change [R=301] to [R=301,L] both times it appears.
Largely as a matter of style, I would consider changing the RewriteRule directives to something like (using http or https as appropriate):
RewriteRule ^(.*)$ http://www.domain.com$1 [R=301,L,QSA]
Your rules seem to be fine. You can combine them as follows:
RewriteCond %{HTTP_HOST} !^www\.example\.com$
RewriteCond %{HTTPS}s on(s)|
RewriteRule ^ http%1://www.example.com%{REQUEST_URI} [L,R=301]
Also note the additional L flag to stop the rewriting process after this rule has been applied.
In case anyone still need an answer to this. Use another .htaccess. Get guide from here, I found it and it looks good: http://www.farinspace.com/codeigniter-htaccess-file/
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
### Canonicalize codeigniter URLs
# If your default controller is something other than
# "welcome" you should probably change this
RewriteRule ^(welcome(/index)?|index(\.php)?)/?$ / [L,R=301]
RewriteRule ^(.*)/index/?$ $1 [L,R=301]
# Removes trailing slashes (prevents SEO duplicate content issues)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [L,R=301]
# Enforce www
# If you have subdomains, you can add them to
# the list using the "|" (OR) regex operator
RewriteCond %{HTTP_HOST} !^(www|subdomain) [NC]
RewriteRule ^(.*)$ http://www.domain.tld/$1 [L,R=301]
# Enforce NO www
#RewriteCond %{HTTP_HOST} ^www [NC]
#RewriteRule ^(.*)$ http://domain.tld/$1 [L,R=301]
###
# Removes access to the system folder by users.
# Additionally this will allow you to create a System.php controller,
# previously this would not have been possible.
# 'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php/$1 [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 index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# Without mod_rewrite, route 404's to the front controller
ErrorDocument 404 /index.php
</IfModule>
Remember, once you have your CodeIgniter htaccess file setup, you will want to go into your “/system/application/config/config.php”, find the following:
$config['index_page'] = "index.php";
and change it to:
$config['index_page'] = "";