been searching for 2 days and can't quite get the right solution due to my lack of understanding of mod_rewrite and time constraints on this project so hoping someone can help.
The aim
To rewrite all requests to the root index.php if the client doesn't have the correct cookie.
If the client has the correct cookie allow them to browse as they wish.
The problem
The htaccess in my subdirectory is taking precendence over my root htaccess, so requests such as www.mydomain.com/subdir/index.php arn't getting redirected.
My root .htaccess
Options FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_COOKIE} !^.*pass.*$
RewriteCond %{REQUEST_URI} !^/index.php$
RewriteRule ^(.*)$ http://www.mydomain.com/index.php?url=$0 [NC]
My subdir htaccess
RewriteEngine On
RewriteBase /
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
Additional info
Ideally I'm trying to create a password protected area, so all requests are routed to index.php where a password can be entered and when verified a cookie is created, allowing free browsing of contents and sub directories. So if there is a better way to accomplish this then please let me know, and I havn't gone for .htpasswd since I need custom login, error and splash pages.
Also, the subdir .htaccess is an ExpressionEngine URL handler.
Thanks.
To allow execution of rewrite rules from parent .htaccess (htaccess from parent folder), you need to explicitly allow it (Apache will treat rewrite rules in current .htaccess as the only one that need to be executed, as long as rewritten URL remains in the same subfolder).
You need to add this line to your .htaccess in sub-folder:
RewriteOptions inherit
Apache manual: http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteoptions
Related
I am developing the website in my local server in a root folder, the problem is that when my client told me to upload the website in to their server, it is located in the subfolder. So the url has been like this. http://example.com/myproject
The problem with that format is that all my css,js, ajax calls are messed up because when I tried to check Firebug/chrome console, I am seeing a http://example.com/assets/css/main.css , where in fact it should be http://example.com/myproject/assets/css/main.css
All my scripts are coded to be like this:
<link rel="stylesheet" href="/assets/css/main.css"> since that works perfectly when the project is not in a subfolder.
My question now is that, is there a trick, maybe in the .htaccess or mod_rewrite that would allow me to tell the browser that always add a /myproject in all my script calls?
The reason for this is that I don't want to change all my script calls and add a /myproject/...
This is the sample of my .htaccess:
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Allow asset folders through
RewriteRule ^(fuel/modules/(.+)?/assets/(.+)) - [L]
# Protect application and system files from being viewed
RewriteRule ^(fuel/install/.+|fuel/crons/.+|fuel/data_backup/.+|fuel/codeigniter/.+|fuel/modules/.+|fuel/application/.+) - [F,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php/$0 [L]
# Prevents access to dot files (.git, .htaccess) - security.
RewriteCond %{SCRIPT_FILENAME} -d
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\." - [F]
</IfModule>
Options -Indexes
Your help will be greatly appreciated! Thanks!
If you are unable/unwilling to edit your site then you will need to edit the .htaccess file (or server config) in the site's document root. To rewrite all requests for non-existent files to your project's subdirectory:
For example, something like:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/myproject%{REQUEST_URI} -f
RewriteRule !^myproject/ /myproject/$0 [L]
For all requests for files not in the /myproject subdirectory, that don't exist, but do exist in the /myproject subdirectory then internally rewrite the request to the /myproject subdirectory.
This assumes that your (sub)site consists of real files that exist on the filesystem.
This will make it look as though your project is hosted in the document root. You could externally redirect (R=301) - but that would result in every page triggering multiple redirects which is to be avoided!
However, whether this works at all will depend on what else your client is hosting on their site.
I think the best solution is to edit your files.
UPDATE: Since your site has a front controller (ie. you are routing all requests for non-existent files through index.php) then the above directives won't quite work.
However, if the client is simply hosting a site that consists of real files on the filesystem then this could probably be simplified to:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !^myproject/ /myproject/$0 [L]
In Unix based filesystems (which the web path is based on), the / at the beginning of a path is an absolute path to the root level.
For web addresses, this means it goes directly to the document root of your website.
You will need to remove the beginning / from your href attributes
<link rel="stylesheet" href="assets/css/main.css">
I have a specific problem with my mod_rewrite configuration that I cannot resolve. I am no admin, therefore I'm kindly asking for a collective advice :) Please note - it's not a general question about redirection, but very specific one.
Story
I have a shared hosting with access to FTP and ability to create my own .htaccess files. This shared hosting had plenty of files and directories before I created the website, so logical step for me was to place everything inside new-site folder.
Then I had to create custom rewrite rules so that everything under example.com points to new-site.
CONFIG
So I came up with the following config.
# (...) other rules
# 1. Make sure that /new-site/ is not a duplicated content
RewriteCond %{REQUEST_URI} ^/new-site/
RewriteRule ^/new-site/(.*)$ /$1 [R=301,L]
# 2. Make sure that example.com is internally handled by files in '/new-site'
RewriteCond %{REQUEST_URI} !^/new-site/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /new-site/$1
RESULTS
Rule marked with 2. works fine, my site is accessible as I want. However I didn't want https://example.com/new-site/ to be found on the server by bots and treated by a duplicated content, so I added rule 1..
This rule, however, doesn't seem to have any effect! I looked it up with CURL and request is handled immediately with a 200 status. I'm banging my head against the wall and experimenting with other variants of it, but everything fails.
What I'm after is pretty darn simple:
Make every request to the root domain be handled by website which is stored in /new-site/
Make sure that direct call to https://example.com/new-site/(.*) is redirected with 301 status back to the domain root.
What am I doing wrong?
EDIT
I've noticed that my setup seems to be doing far better if I remove a child .htaccess file under /new-site/ subfolder. I didn't mention it in my original question because there is nothing special about it (just some SEO rewrites).
RewriteEngine on
DirectoryIndex index.php
RewriteRule ^products$ products.php
# (...) similar rewrites
Old answer: RewriteRule does not accept leading slash. Try to change to
RewriteRule ^new-site/(.*)$ /$1 [R=301,L]
Edit:
Version that is provided by you will forward to the cyclic redirection. To avoid it, I think, you can use such .htaccess
RewriteEngine on
RewriteRule ^new-site/ - [R=404,L]
# 2. Make sure that example.com is internally handled by files in '/new-site'
RewriteCond %{REQUEST_URI} !^/new-site/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /new-site/$1 [L]
Direct asking /new-site/* wil receive 404 error, while url exaple.com/* wil be redirected to /new-site
And notice that if there are files with the same name, for example, /r.jpg and /new-site/r.jpg, the last never be achieve
Your first rule never matches because it must not begin with a leading slash.
With RewriteRule, you only need a leading slash if you're directly in httpd.conf or before Apache v2.4 i think.
While you have a good idea, your first rule will cause an infinite redirection loop if it's working. You have to use THE_REQUEST to match direct user request only.
You can put this code in /.htaccess
# 1. Make sure that /new-site/ is not a duplicated content
RewriteCond %{THE_REQUEST} \s/new-site/([^\s]*)\s [NC]
RewriteRule ^ /%1 [R=301,L]
# 2. Make sure that example.com is internally handled by files in '/new-site'
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^((?!new-site/).*)$ /new-site/$1 [L]
Also, you'll have to add this line in /new-site/.htaccess (to avoid automatic override)
RewriteOptions InheritBefore
I just created and uploaded a website using free hosting from byet.com.
Everything works fine except that typing the mere domain name in the browser does not redirect the user to my index.php file (an ads page is displayed instead).
After googling mod_rewrite and browsing a dozen different pages, I tried adding the following in my .htaccess file :
DirectoryIndex index.php
or
RedirectMatch ^/$ /index.php
or also (from this Stackoverflow answer )
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/index.php$
RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png|css|js)$
RewriteRule .* /index.php [L,R=302]
None of which changed anything, or sometimes caused my index.php page to be inaccessible, with the error message "The script does not redirect properly".
Perhaps this behavior is implemented at the level of the httpd.conf file (to which I do not have access), so I will never be able to change that.
I asked the support center of byte.com about it, but unfortunately the person who answered me did not seem to really understand English or my question.
Any suggestions appreciated.
If your index.php is under your tld (e.g. http://domain.com/index.php) you can try this;
RewriteEngine On
RewriteRule ^.*$ /index.php [L]
Otherwise, if your index.php is in a subfolder (e.g. http://domain.com/my/folder/index.php), you will have to add the path to the RewriteRule;
RewriteEngine On
RewriteRule ^.*$ /my/folder/index.php [L]
If this doesn't work, there is a slight possibility that your host has disabled the mod_rewrite module (although the redirection error message you get suggests otherwise). Have you checked apache's error_log file for relevant messages?
Try this rule in root .htaccess:
RewriteEngine on
RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png|css|js)$ [NC]
RewriteRule ^(?!index\.php).*$ /index.php [L,NC,R=302]
I am trying to write a .htacess file such that:
The site runs php 5.4
Requests to domain.com run index.php first
Requests to http://domain.com/checkout are redirected to https://domain.com/checkout
All requests to domain.com are redirected to www.domain.com
So here is my attempt:
<IfModule mod_rewrite.c>
# Use PHP 5.4
AddType application/x-httpd-php54 .php
Options -MultiViews
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
RewriteCond %{HTTP_HOST} !^www\.domain\.com
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=permanent,L]
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} ^(/checkout|/order)
RewriteRule ^(.*)$ https://www.domain.com/$1 [R,L]
</IfModule>
But when I make a post to domain.com/cart the user is automatically redirected to domain.com/index.php
Please let me know where I am going wrong...
First off, you need to understand that such rules in .htaccess files are run on a first-come, first-serve basis. Also, you are using the L flag for each of them.
So, you should make sure that the two conditions and rule for silent-mapping to index.php should come last. Move those down to below the https and www-on rules.
Now, of course a request to /cart will be mapped to index.php; that's what it's programmed to do. However, you say "redirected"... Does that mean that it shows index.php in the address bar? If that is the case, the fix I've mentioned should sort that out (always check for redirects first, and then do the necessary mapping).
Like #scotsninja said in the comments, these things should be handled by Laravel itself. Your .htaccess file should only be used to map anything that is not a file or directory to the index file, or Laravel bootstrap.
I am using kohana 3.2
My site is www.mysite.com/best, kohana is installed on best.
I am using the default htaccess file with rewritebase /best
so what is the best way to redirect users that go to www.mysite.com?
Right now if someone puts www.mysite.com/helo (www.mysite.com/best/helo)
It loads but apache gives 404 not found.
I hope my question makes sense.
EDIT
If a user goes to main domain (www.mysite.com) I want it to load kohana located at mysite/best.
but if a user right now types the full thing and omits best, site will load but my forms wont work because it is posting to www.mysite.com/helo not www.mysite.com/best/helo
instead of loading the fake helo controller, it must show a page not found.
EDIT
Ok I added this to htaccess file and it works perfectly
RewriteCond %{REQUEST_URI} !^/best/
RewriteRule ^(.*)$ /best/$1
You can't have multiple rewritebase in htaccess so...
rewrite your rules to fit you need in /best
or put an other htaccess in / to rewrite your needs.
Try this .htaccess instead:
# Turn on URL rewriting
RewriteEngine On
# Installation directory
RewriteBase /best/
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs to index.php/URL
#RewriteRule .* index.php?kohana_uri=$0 [PT,L,QSA]
RewriteRule .* index.php?/$0 [PT,L,QSA]
Note that the trailing / on RewriteBase is required.