On my server I have a two directories, both with php/css/jpg/png files. One directory is named devel and the second is release. Both directories contains the same page, but with different version. release is used to expose stable content it to a customer, and devel is my working directory. Right now, both pages are available through addresses like: http://example.com/devel/index.php and http://example.com/release/index.php.
Is it is possible to have an .htaccess file which for a request like http://example.com/index.php will load http://example.com/devel/index.php when users IP is 123.123.123.123 and http://example.com/release/index.php otherwise?
This is my current .htaccess file:
# Disable directory browsing
Options All -Indexes
# Enable rewrite engine
RewriteEngine on
# Force non-www
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^(.*)$ http://example.com/ [L,R=301]
# For not specified files extensions redirect to Entry.php
RewriteRule !^.*\.(css|js|jpg|png)$ Entry.php
# Force trailing slash
RewriteCond %{REQUEST_URI} /+[^\.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
Related
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 difficulties to understand how htaccess rewrite / redirect is working. I have been trough already more than 20 article about it but I don't catch the logic and the syntax of how to write rules properly.
I currently have a server with public_html folder
We have our main site under the subfolder /site , this is a wordpress site
We have other site (also a wordpress site) we use for e-learning under the subfolder /training
I need to make our site (domain.com) to point to /public_html/site while having domain.com/learning to point to public_html/training
I have tried to understad how queries in htaccess are working such as RewriteCond or RewriteRule
Here is my current code:
# Use PHP5.4 Single php.ini as default
AddHandler application/x-httpd-php54s .php
# File modified on Sun Mar 30 01:22:23 2014 by server
# For security reasons, mod_php is not used on this server. Use a php.ini file for php directives
# php_value max_execution_time 90
# BlueHost.com
# .htaccess main domain to subdirectory redirect
# Do not change this line.
# For security reasons, Option followsymlinks cannot be overridden.
#Options +FollowSymLinks
Options +SymLinksIfOwnerMatch
RewriteEngine on
#RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
# Change 'subdirectory' to be the directory you will use for your main domain.
#RewriteCond %{REQUEST_URI} !^/site/
# Don't change the following two lines.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Change 'subdirectory' to be the directory you will use for your main domain.
RewriteRule ^(.*)$ /site/$1
# Change example.com to be your main domain again.
# Change 'subdirectory' to be the directory you will use for your main domain
# followed by / then the main file for your site, index.php, index.html, etc.
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
RewriteRule ^(/)?$ site_en/index.html [L]
# .htaccess main domain to subdirectory redirect
# Do not change this line.
RewriteEngine on
# Change domain.com to be your main domain.
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
# Change 'site to be the directory you will use for your main domain.
RewriteCond %{REQUEST_URI} !^/learning/
# Don't change the following two lines.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Change 'site' to be the directory you will use for your main domain.
RewriteRule ^(.*)$ /learning/$1
# Change domain.com to be your main domain again.
# Change 'site' to be the directory you will use for your main domain
# followed by / then the main file for your site, index.php, index.html, etc.
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
RewriteRule ^(/)?$ learning/index.html [L]
The following code will need to be added to the .htaccess file in the public_html folder of your hosting account.
You will need to insert the following code block and make modifications as noted in the (#) comments.
# .htaccess main domain to subdirectory redirect
# Do not change this line.
RewriteEngine on
# Change domain.com to be your main domain.
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
# Change 'site to be the directory you will use for your main domain.
RewriteCond %{REQUEST_URI} !^/site/
# Don't change the following two lines.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Change 'site' to be the directory you will use for your main domain.
RewriteRule ^(.*)$ /site/$1
# Change domain.com to be your main domain again.
# Change 'site' to be the directory you will use for your main domain
# followed by / then the main file for your site, index.php, index.html, etc.
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
RewriteRule ^(/)?$ site/index.html [L]
Repeat Same for Learning domain .
Visitors to your Web site will not be able to tell that your main domain is using a subdirectory, they will still see the Web site address as
http://www.domain.com/index.html.
Note :
Please note that this will not work with some website software. You
may also need to modify the $base_url, $live_site or other
configuration settings to finish the process.
Since you mentioned that your case is WordPress , don't forget to have a look at this too
https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory
Update :
RedirectMatch 301 /learning/(.*) /training/$1
# .htaccess main domain to subdirectory redirect
# Do not change this line.
RewriteEngine on
# Change domain.com to be your main domain.
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
# Change 'site to be the directory you will use for your main domain.
RewriteCond %{REQUEST_URI} !^/site/
# Don't change the following two lines.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Change 'site' to be the directory you will use for your main domain.
RewriteRule ^(.*)$ /site/$1
# Change domain.com to be your main domain again.
# Change 'site' to be the directory you will use for your main domain
# followed by / then the main file for your site, index.php, index.html, etc.
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$
RewriteRule ^(/)?$ site/index.php [L]
In my "public_html" directory I have the following structure:
- root
- index.html
- blog
- index.html
- lab
- index.html
- wp
- (WORDPRESS FILES)
The "lab" and "wp" directories are just subdomain directories ("http://lab.tomblanchard.co.uk" and "http://wp.tomblanchard.co.uk") which work fine.
Basically I want the main domain ("http://tomblanchard.co.uk") to point to the "root" directory without any actual redirecting, for example, I want "http://tomblanchard.co.uk" to point to the "index.html" file within the "root" directory, I want "http://tomblanchard.co.uk/blog" to point to the "index.html" file within the "root/blog" directory and so on.
I have kind of achieved this with the following code in my ".htaccess" file:
# Add directives
RewriteEngine on
# Remove ".html" extension from URLs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
# Change root directory to "root" folder
Options +FollowSymLinks
RewriteCond %{REQUEST_URI} !(.*)root
RewriteRule ^(.*)$ root/$1 [L]
The only problem is that things like "http://tomblanchard.co.uk/root/" and "http://tomblanchard.co.uk/root/blog/" still work when really they shouldn't even be able to be accessed (404).
If anyone has any idea on how to sort this or has a stronger method of doing this it would be greatly appreciated.
Update
Finally got it working how I wanted it after hours of researching, I used the following:
# Add directives
RewriteEngine on
# Change root directory to "root" folder
RewriteCond %{THE_REQUEST} ^GET\ /root/
RewriteRule ^root/(.*) /$1 [L,R=301]
RewriteRule !^root/ root%{REQUEST_URI} [L]
The order of directives in mod_rewrite is important, as each rule sees the output of the previous rule as its input to test. You need to do 3 (or possibly 4) things, in order:
Deny access to any URL beginning /root/ (we have to do this first, else everything will be denied!)
It's generally good practice to ensure each URL has only one valid form, so URLs which do specify .html should cause a browser redirect to the non-.html form. This needs to happen before other rewrites, otherwise you can't tell the difference between a .html from the browser and one you've added virtually.
Look up any URL not denied above in the /root/ directory, rather than the configured DocumentRoot
Look up any URL not pointing at a directory under the URL + .html, if that file exists. This has to come after other rewrites, or the "file exists" check will always fail.
# General directives
Options +FollowSymLinks
RewriteEngine on
# Deny URLs beginning /root/, faking them as a 404 Not Found
RewriteRule ^root/ [R=404]
# Additional rule to strip .html off URLs in the browser
RewriteRule ^(.*)\.html$ $1 [R=permanent,L]
# Rewrite everything remaining to the /root sub-directory
# (Host condition was in your post originally, then edited out; this is where it would go)
RewriteCond %{HTTP_HOST} ^(www\.)?tomblanchard\.co\.uk$
RewriteRule ^(.*)$ root/$1
# Handle "missing" ".html" extension from URLs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
PS: Note my careful language to describe (internal) rewrites, as opposed to (browser) redirects: the rule you have is not removing .html from anything, it is adding it, thus allowing the page to be accessed if someone else removes it. Since you are often modifying both within a set of rules, it's important to keep clear in your head the distinction between the URL the browser has requested, and the virtual URL Apache will ultimately serve.
You are not defining any rule to block /root address so how do you want to block it when there is nothing to do that?
Try this:
# Add directives
RewriteEngine on
RewriteCond %{REQUEST_URI} .root [NC]
RewriteRule (.*) / [L,R=404]
# Remove ".html" extension from URLs
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
# Change root directory to "root" folder
RewriteCond %{HTTP_HOST} ^tomblanchard.co.uk$ [NC,OR]
RewriteCond %{HTTP_HOST} ^www.tomblanchard.co.uk$
RewriteCond %{REQUEST_URI} !.root
RewriteRule (.*) /root/$1 [L,R=301,QSA]
This is not tested so if it wouldn't work, play around with it to get your need.
I have the following on my .htaccess file:
Options +FollowSymlinks
#+FollowSymLinks must be enabled for any rules to work, this is a security
#requirement of the rewrite engine. Normally it's enabled in the root and we
#shouldn't have to add it, but it doesn't hurt to do so.
RewriteEngine on
#Apache scans all incoming URL requests, checks for matches in our #.htaccess file
#and rewrites those matching URLs to whatever we specify.
#allow blank referrers.
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?site.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?site.dev [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?dev.site.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
site.com is the production site.
site.dev is a localhost dev environment.
dev.site.com is a subdomain where we test live.
I'm aware that this will avoid the site to be indexed:
Header set X-Robots-Tag "noindex, nofollow"
cf. http://yoast.com/prevent-site-being-indexed/
My question is however, fairly simple perhaps:
Is there a way to apply this line ONLY on dev.site.com, so that it doesn't get indexed ?
Is there a way to apply this line ONLY on dev.site.com, so that it doesn't get indexed ?
Yes, you need to put the Header line in the vhost config for dev.site.com. There's no way you can make a host check tied to a Header set directive from within an htaccess file.
The other possibility is if you want to block bots via useragent, you can remove the Header set and add some rules:
# request is for http://dev.site.com
RewriteCond %{HTTP_HOST} ^dev.site.com$ [NC]
# user-agent is a search engine bot
RewriteCond %{HTTP_USER_AGENT} (Googlebot|yahoo|msnbot) [NC]
# return forbidden
RewriteRule ^ - [L,F]
Note that the list of user agents isn't complete. You can try to go through the massive list of User-Agents and look for all of the index robots, or at least the more popular ones.
I have run into a problem which is that my web host doesn't appear offer addon domains.
I currently have a domain name pointing to my name servers.
I went into cPanel to add an addon domain that points to a sub-directory, but all that is available in cPanel is to park domain at the document root which is 'public_html/'.
So traffic coming from the parked domain would get the wrong content, which is obviously not good.
I get the feeling that this isn't possible, but can I change the parked domain document root from 'public_html/' to 'public_html/sub-directory' ?
Or perhaps can I edit the .htaccess file to redirect traffic from the parked domain to the sub-directory?
Basically I want this address; www.parked-domain.com/
To show the content of this sub-directory; www.first-domain.com/parked-directory
I hope this is possible otherwise I need to look at a new web host.
Regards,
Dean.
Add the following to your .htaccess file:
RewriteRule ^parked-directory - [L]
RewriteCond %{HTTP_HOST} ^(www\.)?parked-domain\.com$ [NC]
RewriteRule ^(.*)$ parked-directory/$1 [L]
While frowned upon, it is possible to dynamically set up your parked domain sub-hosts using mod_rewrite.
Here's a .htaccess sample for multihosting via mod_rewrite using a dynamic format that requires parked-domain-name = sub-folder-name, and covers other parked domains on your site being redirected or ignored.
# tell mod_rewrite to activate and give base for relative paths
RewriteEngine on
RewriteBase /
# permanent redirect of unused parked domains so they do not try to resolve.
# only use this redirect if you want multiple names to point to another.
# otherwise, replace the rewrite rule with: RewriteRule . - [F,L]
RewriteCond %{HTTP_HOST} ^(www\.)?parked-domain1\.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^(www\.)?parked-domain2\.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^(www\.)?parked-domain3\.com$ [NC,OR]
RewriteCond %{HTTP_HOST} ^(www\.)?parked-domain4\.com$ [NC]
RewriteRule ^(.*)$ http://main-site.com/$1 [L,R=301]
# if you have an active site in hosting root folder,
# then tell it not to look for a subfolder by skipping next rule
RewriteCond %{HTTP_HOST} ^(www\.)?main-site\.com [NC]
RewriteRule ^(.*)$ - [S=1]
# the domain-name = sub-folder automation
# thus parked-domain5.com in /parked-domain5/
RewriteCond %{HTTP_HOST} ([^.]+)\.com
RewriteCond %{REQUEST_URI} !^/%1
RewriteRule ^(.*)$ %1/$1 [L]
# if you're hosting wordpress sites, this is a tweaked variant of the WP code.
# add the rest of this example only if:
# 1. main-site.com is a WP site
# 2. you remove .htaccess in subfolders
# if (1.) true, yet keeping subfolder .htaccess, uncomment next 2 lines:
# RewriteCond %{HTTP_HOST} !^(www\.)?main-site\.com [NC]
# RewriteRule ^(.*)$ - [S=1]
#### BEGIN WordPress, improved
# if this request is for "/" or has already been rewritten to WP
RewriteCond $1 ^(index\.php)?$ [OR]
# or if request is for image, css, or js file
RewriteCond $1 \.(gif|jpg|jpeg|png|css|js|ico)$ [NC,OR]
# or if URL resolves to existing file
RewriteCond %{REQUEST_FILENAME} -f [OR]
# or if URL resolves to existing directory
RewriteCond %{REQUEST_FILENAME} -d
# then skip the rewrite to WP
RewriteRule ^(.*)$ - [S=1]
# else rewrite the request to WP
RewriteRule . /index.php [L]
# END WordPress
instead of using "parked domain", use the addon domain - and here just the root directory to public_html/sub-directory where you want to point your new "parked" domain...