It's my first time deploying a web app on a hosting and they give me this .htaccess but i've never configured one, i have a root directory then a public_html and at the same level my webpage. i'll show you the directory tree and the content of the .htaccess
root
|
|---project
|---public_html
|---.htaccess
The content of the .htaccess is:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
And when I enter the website it's showing me a http 403 error: Server or website configuration is blocking you from viewing this page.
I have never configured a website on a hosting so I don't know what i'm doing most of the time...
Thx!!
root
|
|---project
|---public_html
|---.htaccess
Assuming public_html is the document root (where your public facing files and index.php are located) then the .htaccess file should be in the public_html directory itself (not above it).
That is...
root
|
|---project
|---public_html
|------.htaccess
By placing the .htaccess file in the root directory (above the document root) then it would attempt to rewrite the request to /root/index.php (as opposed to /root/public_html/index.php) which is inaccessible (from rewriting in .htaccess) and does not exist anyway, so would likely result in a 403, 400, etc.
Related
I have a subdomain called test.mysite.com and I have a CI4 installation inside a folder there called project. So the actual url for the CI4 installation is test.mysite.com/project/public/index.php. I want to remove the public/index.php portion from the url but continue to use the public folder to have my files, as they should.
I'm using this .htaccess on the project folder root:
DirectoryIndex /public/index.php
RewriteEngine on
RewriteCond $1 !^(index\.php|images|assets|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./public/index.php/$1 [L]
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
But it's not working. When I access test.mysite.com/project it leads me to a server list of files. I know the .htaccess file is being properly read because when I add an error there it gives me a warning
EDIT:
CI4 already comes with an htaccess inside the public folder:
# Disable directory browsing
Options All -Indexes
<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...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
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 ^([\s\S]*)$ index.php/$1 [L,NC,QSA]
# Ensure Authorization header is passed along
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
ErrorDocument 404 index.php
</IfModule>
# Disable server signature start
ServerSignature Off
# Disable server signature end
When I access test.mysite.com/project it leads me to a server list of files
Because your DirectoryIndex is set to /public/index.php (which presumably does not exist, as the index document is located at /project/public/index.php) and directory indexes (mod_autoindex) is presumably enabled (it should be disabled, so that such a request results in a 403 Forbidden).
the difference is that the other website that is working is not on a subdomain and it’s on the root, so it’s not the same htaccess
I'm not sure why it would be any different?
With the .htaccess file in the /project subdirectory, arrange your mod_rewrite (and mod_dir) directives like this instead:
DirectoryIndex index.php
Options -Indexes
RewriteEngine on
RewriteCond $1 !^public/(index\.php|images|assets|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) public/index.php/$1 [L]
The presence of robots\.txt and favicon\.ico in the first condition implies you are rewriting requests from the document root. Since search engines request /robots.txt (in the document root), not /project/robots.txt (or /project/public/robots.txt). The same applies to /favicon.ico. If you are not rewriting these two requests then these two entries are not required.
This also assumes you are linking directly to your static resources using the public subdirectory. eg. /projects/public/images/foo.jpg. This isn't necessarily desirable since it exposes /public in the URL path. Users won't necessarily see this as it's not directly visible in the browser's address bar, but search engines and anyone who views the HTML source / network traffic will see it.
Just to add, that first condition (ie. RewriteCond directive) is "just" an opimisation. If it's set incorrectly, your site will probably work OK and you won't see a difference, except that it will be performing many more filesystem checks than it needs to do.
Alternative structure
An alternative approach is to have two .htaccess files. A basic /project/.htaccess file that simply rewrites everything to the public subdirectory and a more comprehensive (CI) .htaccess file at /project/public/.htaccess that actually routes the request to CI. This then allows you to omit public from all URLs, including URLs to your static resources.
For example:
/project/.htaccess
DirectoryIndex index.php
Options -Indexes
RewriteEngine On
# Unconditionally rewrite everything to the "public" subdirectory
RewriteRule (.*) public/$1 [L]
/project/public/.htaccess
The presence of mod_rewrite directives in the subdirectory .htaccess file naturally prevent a rewrite loop from the RewriteRule directive in the parent directory. (Assuming mod_rewrite inheritance has not been enabled.)
RewriteEngine on
RewriteCond $1 !^(index\.php|images|assets|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php/$1 [L]
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
Working for years with Codeigniter 3 I had this issue too. First I tried the .htaccess road but after realizing Codeigniter 3 could also benefit from a more secure structure, I applied the same experience to Codeigniter 4.
The basic idea is to move the whole framework to a folder off the web root. And move the public folder to the root (WEBROOT can also be a subfolder under the public html folder)
PRIVATEFOLDER
\codeigniter:
\app
\vendor
\writable
WEBROOT
assets\
index.php
.htaccess
Then I'll modify index.php (and spark and preload.php if used). This will do in index.php:
// This is the line that might need to be changed... etc
define('ENGINEPATH', 'PRIVATEFOLDER/codeigniter');
require ENGINEPATH . '/app/Config/Paths.php';
And /app/Config/Paths.php to this:
namespace Config;
class Paths
{
public $systemDirectory = ENGINEPATH . '/vendor/codeigniter4/framework/system';
public $appDirectory = ENGINEPATH . '/app';
public $writableDirectory = ENGINEPATH . '/writable';
public $testsDirectory = ENGINEPATH . '/tests';
public $viewDirectory = ENGINEPATH . 'app/Views';
}
Now, set the $baseURL to the WEBROOT url and you should be able to navigate without index.php and public, and the app code is protected outside the public folder.
I have looked at a good few similar questions on stack overflow but what I have tried doesn't seem to work.
'quotes' is a subfolder with a wordpress installation in it. So, the main root has a wordpress site in it and the 'quotes' subfolder also has a wordpress installation in it.
I have a path something like
https://example.com/quotes/uk/travel-packages
https://example.com/quotes/us/travel-packages
But I don't want 'quotes' to be in the url, it should just be
https://example.com/uk/travel-packages
I currently have this
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /example/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /example/index.php [L]
RewriteRule ^quotes/(.*)$ /$1 [L,NC,R]
RewriteRule ^uk/(.*) /quotes/$1 [L]
RewriteRule ^us/(.*) /quotes/$1 [L]
</IfModule>
EDIT: I was trying this on my localhost hence the rewrite base being /example/ so I understand the confusion there now.
Here is the live server .htaccess file for both the root directory and the quotes subfolder in the root directory.
ROOT:
# 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 /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
QUOTES SUBDIRECTORY
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /quotes/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /quotes/index.php [L]
</IfModule>
# END WordPress
If /quotes is a subdirectory that contains the WordPress installation and you have already removed /quotes from the URL in WordPress itself then you need to configure two .htaccess files:
One in the document root that internally rewrites (unconditionally) all requests to the /quotes subdirectory.
And another .htaccess file in the /quotes subdirectory that routes the request to WordPress - containing the "standard" WordPress front-controller.
In the (root) /.htaccess file:
RewriteEngine On
# Internally rewrite all requests to WordPress subdirectory
RewriteRule ^ quotes%{REQUEST_URI} [L]
In the /quotes/.htaccess file:
RewriteEngine On
# OPTIONAL...
# Redirect any direct requests for "/quotes/<anything>" back to root
# NB: WP itself *must* already be correctly configured to omit "/quotes" from the URL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) /$1 [R=301,L]
# WordPress front-controller
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
The check against the REDIRECT_STATUS environment variable is to ensure only direct requests are redirected and not rewritten requests by the WP front-controller - which would otherwise cause a redirect loop.
Alternatively, you have just a single .htaccess file in the document root (and remove the .htaccess file in the /quotes - WordPress - subdirectory). For example:
RewriteEngine On
RewriteBase /quotes
# OPTIONAL...
# Redirect any direct requests for "/quotes/<anything>" back to root
# NB: WP itself *must* already be correctly configured to omit "/quotes" from the URL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^quotes/(.*) /$1 [R=301,L]
# WordPress front-controller
RewriteRule ^quotes/index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
It seems from your question update that you also have a 2nd WordPress installation in the document root. It's not possible to have two separate WordPress installations and make them appear as a single WP site in the document root (ie. without specifying the subdirectory as part of the URL) unless there is some discernable difference in the URL structure between the two sites. Otherwise, you don't know which URLs should be routed to the WP installation in the subdirectory and which to the site in the document root.
Any with /us or /uk or any country extension in future should go to /quotes otherwise it should go to the route or whatever page is being called from the root site like for instance, https://example.com/contant-us should go to the root contact us page.
Yes, this is possible. For "any" country extension I assume a string of 2 lowercase letters a-z. Although this does mean that the WP site in the document root cannot have any URLs that start with a 2 letter path segment.
Ordinarily, you would modify the existing directives (as above). However, since this is WordPress, the directives in the # BEGIN WordPress code block should not be modified (unless you prevent WP from modifying this). Instead, we will just add some directives before the WP front-controller.
In the (root) /.htaccess file:
# Rewrite any URLs that contain a language code prefix to the subdirectory
RewriteRule ^[a-z]{2}/ quotes%{REQUEST_URI} [L]
# BEGIN WordPress
# : (Remainder of existing .htaccess file goes here)
In the /quotes/.htaccess file:
# OPTIONAL...
# Redirect any direct requests for "/quotes/<anything>" back to root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) /$1 [R=301,L]
# BEGIN WordPress
# : (Remainder of existing .htaccess file goes here)
This assumes you will be accessing your static resources directly. eg. Using the /quotes subdirectory for resources that are contained within this site, so the /quotes subdirectory is not entirely hidden.
See my answer to part two of this question with regards to missing static resources (images, CSS and JS) for the second WordPress installation in the subdirectory that could result from implementing the above rewrites/redirects.
wordpress site missing images after htaccess change
I have an application with its UI accessible at subdomain.example.com/subdir1/subdir2/ and would like for this to load for a user who goes to subdomain.example.com/subdir1/. I believe this is called a subdirectory alias, but I am not entirely certain about this. When I search for other questions/examples here, all I can find are explanations of how to 'hide' subdir1 or subdir1/subdir2 and I have been unable to figure out how to change those examples to work for my case.
The file structure is
subdomain root
public_html
subdir1
(a bunch of application folders and files)
subdir2
(a bunch of UI-related application files)
.htaccess
The .htaccess file in subdir2/ contains the following:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
#RewriteBase #add base url ex: www.website.com[/this part is your base url for this file up to "public"]
#RewriteBase /your_base_url
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
There are no other .htaccess files at the moment.
How would I go about having someone who visits URL subdomain.example.com/subdir1 to load the content of ...subdir1/subdir2 (while the address bar URL remains ...subdir1)? Is it possible from within this one .htaccess file, or will I need to create another one at some other location?
I'm using the micro framework Silex on my website hosted on a VPS.
So, the site files are in the /site_name/public_html/ folder but, with Silex, the site must point to the /site_name/public_html/web/ folder.
In the public_html directory, I have the following .htaccess file :
Options -Indexes -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Redirect to https & www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L,NE]
# Redirect incoming URLs to web folder
RewriteCond %{REQUEST_URI} !web/
RewriteRule (.*) /web/$1 [L]
</IfModule>
And, in the /public_html/web/ folder, the following .htaccess :
<IfModule mod_rewrite.c>
# Redirect incoming URLs to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
</IfModule>
Now, everything works fine but my pages are accessible with three different patterns :
example.com/page/ (the one I want to keep)
example.com/web/page/
example.com/web/index.php/page/
I have used the meta canonical to avoid duplicate content but I still want these last two options to not exist.
I guess I have something to change in both .htaccess files but I can't find what it is.
I would actually remove the .htaccess file in the /web subdirectory altogether and rewrite directly to /web/index.php in the root .htaccess file. By having two .htaccess files you are seemingly creating extra work. The mod_rewrite directives in the subdirectory will completely override the parent directives (by default), so your canonical HTTPS and www redirects are also being overridden.
(Presumably you had a RewriteEngine On directive in the /web/.htaccess file?)
Having removed the /web/.htaccess file, try something like the following in your root .htaccess file:
Options -Indexes -MultiViews
RewriteEngine On
RewriteBase /web
# Redirect to https & www
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=302,L,NE]
# If /web or /index.php is present at the start of the requested URL then remove it (via redirect)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(?:web|index\.php)/(.*) /$1 [R=302,L]
# Front-controller...
# Internally rewrite all requests to /web/index.php (uses RewriteBase set above)
RewriteRule index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
The check against the REDIRECT_STATUS environment variable ensures we only test initial requests and not requests that have been later rewritten.
The <IfModule> wrapper is not required, unless your site is intended to work without mod_rewrite.
Note that a request like /web/index.php/page/ would result in two redirects. First to /index.php/page then to /page. Since this is an edge case I would consider a double redirect to be acceptable.
UPDATE: I've removed the "directory" check in the above as this would have prevented the document root (example.com/) from being rewritten to the /web subdirectory. This would have consequently resulted in a 403 if you didn't have a directory index document (eg. index.php) in the document root of your site. (However, requests for example.com/page/ should have still worked OK.)
Test with 302 (temporary) redirects and only change to 301 (permanent) when you are sure it's working OK - to avoid any caching issues in the browser. Be sure to clear the browser cache before testing.
I have a Laravel 5.4 project under the folder www of Wampserver64.
The project folder name is AxilogicV2.
When I visit localhost/AxilogicV2 it will take me to the login screen, but after login succeeds it takes me to 'localhost/'. (The form should make a post request to itself ('/') and will be redirected to ('/view').
Every redirection ignores 'AxilogicV2'.
Example: localhost/AxilogicV2/view/9408 => localhost/view/9408.
Here is my .htaccess file. I tried a bunch of redirect rules but didn't work.
Options -MultiViews
RewriteEngine On
RewriteBase /AxilogicV2
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
In httpd.conf file Rewrite is enabled and Override is set to All.
Edit: I took out the index.php from public folder and made appropriate corrections so that it will find the right bootstrap folder and access autoload.php and app.php