Auto-append dummy folder name to end of base URL - .htaccess

Take a look at this sample vhost snippet:
<VirtualHost *:80>
DocumentRoot /web/content
ServerName me.example.com
</VirtualHost>
Say /web/content contains 2 files, index.html and page.html, and a subdirectory colors containing yellow.html. index.html contains links like href="/page.html" and href="/colors/yellow.html", using / to refer to the web root.
Is there a way to internally use me.example.com/test/ as the root of the site? In other words, when a user goes to http://me.example.com/test/, I want to fetch /web/content/index.html. So, the /test/ in the URL would essentially be a dummy "folder".
Basically, I'd like me.example.com/test to function exactly how a subdomain (say, test.me.example.com) would. Something like setting ServerName me.example.com/test (but I know that doesn't work).
I know I could simply make a REAL folder /web/content/test and put everything in there, but that would break my links beginning with a /, as they would still refer to /web/content as the web root. The same problem arises when adding a directive like Alias /test /web/content.
Do I have any options here? Maybe using RewriteBase somehow? (I've tried a few things with no luck.)

Try putting this in the htaccess file in your document root
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/test/(.*)$
RewriteCond %{DOCUMENT_ROOT}/%1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1 -d
RewriteRule ^ /%1 [L]
This maps the /test/ URI path to the document root. If you want to say, map it to the colors folder, you'd do:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/test/(.*)$
RewriteCond %{DOCUMENT_ROOT}/colors/%1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/colors/%1 -d
RewriteRule ^ /colors/%1 [L]

Related

Redirect a domainA.com/dir/file -> domainB.com/dir/file keeping URL structure

I am able to achieve what I want partially by doing the following...
Putting this (see below) on DomainA .htaccess will do what I want. But I have to be specific at to what the folder name is... How would I wildcard it so that the folder name is captured and passed on to forwarding domain?
RewriteEngine On
RewriteRule ^folderA/(.*)$ http://domainB.com/folderB/$1 [L,R=301]
trying to achieve
domainA.com/folder/123 -> domainB.com/folder/123
Edit: I noticed an issue after implanting a solution. IF the redirecting domain i.e. DomainA.com does not have the folder on the site then the rewrite does not work.
trying to achieve domainA.com/folder/123 -> domainB.com/folder123
You can use a pattern instead of using folderA:
RewriteEngine On
RewriteRule ^([^/]+)/(.*)$ http://domainB.com/$1$2 [L,R=301,NC]
In the case when domainA and domainB are on same host and same DocumentRoot then you must add a RewriteCond to check for domainA being the original request's domain like this:
RewriteCond %{HTTP_HOST} ^(?:www\.)?domainA\.com$ [NC]
RewriteRule ^([^/]+)/(.*)$ http://domainB.com/$1$2 [L,R=301,NC]

htaccess multi language site with sub directories, and default 301

I am having some issues setting up my htaccess to allow multiple languages utilising the sub directory method eg:
http://www.domain.com/en/
http://www.domain.com/sw/
http://www.domain.com/ie/
Also to complicate things, the project isn't currently live, its on a dev server. For example, I am currently accessing the project at:
http://dev.domain.com/devname/projectname/
And I want the above to automatically 301 redirect to:
http://dev.domain.com/devname/projectname/en/
Here is my htaccess:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# ----------------------------------------------------------------------
# MULTI LANGUAGE SUB DIRECTORY
# ----------------------------------------------------------------------
RewriteCond %{REQUEST_URI} !^/(en|sw)/
RewriteRule ^(.*)$ en/$1 [R=301,L]
# ----------------------------------------------------------------------
# Rewrite rules
# ----------------------------------------------------------------------
## CASE STUDIES ##
RewriteRule ^casestudies/([^/\.]+).html$ index.php?controller=contents&method=viewCasestudy&link=$1 [L,QSA]
## PRODUCTS ##
RewriteRule ^products/([^/\.]+).html$ index.php?controller=contents&method=viewProduct&link=$1 [L,QSA]
RewriteRule ^([a-z{2}]+)(/)?$ index.php?controller=contents&method=viewHome&lang=$1 [L,QSA] # Default load
RewriteRule ^(/)?$ index.php?controller=contents&method=viewHome [L,QSA] # Default load
The above will actually redirect to:
http://dev.domain.com/home/webserver_dir/devname/projectname/en/
..and if I use RewriteBase it seems to just goto...
http://dev.domain.com/en/
So my question: How do I get the language URLs working correctly relative to the directory its in on my dev server, and then ideally will work when it goes live without any environment specific rules.
Bonus question: Do I need to add the ([a-z{2}]+) bit in front of all my subsequent rewrite rules or can I have a catch all that will effect all further rules?
EDIT -----------------------------
I have reduced it down to the following as suggested...
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /devname/projectname/
RewriteCond %{REQUEST_URI} !^/(en|sw)(/|$) [NC]
RewriteRule ^(.*)$ en/$1 [R=301,L]
RewriteRule ^([a-z]{2})/?$ index.php?controller=contents&method=viewHome&lang=$1 [NC,L,QSA] # Default load
... but now its redirecting to http://dev.domain.com/devname/projectname/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/, any ideas?
Have you tried the answer in the following link? It should do what you're trying to achieve.
Endless Redirect Loop by htaccess rules multi language
RewriteEngine On
RewriteBase /
# empty url -> redirect to en/
RewriteCond %{QUERY_STRING} !lang=(en|de)
RewriteRule ^$ en/ [R=301,L]
# url is ONLY '/en' or '/de' -> redirect to /en/ or /de/ (adding slash)
RewriteRule ^(en|de)$ $1/ [R=301,L]
# now all urls have en/ de/ -> parse them
RewriteRule ^(en|de)/(.*)$ $2?lang=$1&%{query_STRING} [L]
If .htaccess must not change
Change your <VirtualHost> configuration for your DEV server project as
<VirtualHost *:80>
ServerName dev.domain.com
ServerAlias project.domain.com
DocumentRoot "/home/webserver_dir/devname/projectname"
</VirtualHost>
These changes would typically go in your httpd-vhosts.conf file. Your .htaccess files would now have
RewriteBase /
to mark root as your base directory for both your development and live servers.
If you're trying to version your projects or test multiple projects on the same dev host, then you would have to incorporate the naming scheme into the domain names instead of the URL path. For example,
<VirtualHost *:80>
ServerName dev1.domain.com
ServerAlias project1.domain.com
DocumentRoot "/home/webserver_dir/dev1/project1"
</VirtualHost>
<VirtualHost *:80>
ServerName dev2.domain.com
ServerAlias project2.domain.com
DocumentRoot "/home/webserver_dir/dev2/project2"
</VirtualHost>
The bottom line is that you can not have the same .htaccess file rules working untouched with different deployment directories unless you resort to mod-rewrite way of if-else mumbo jumbo which would just be added clutter once you've gone live.
For the rules to work transparently, Apache must only see and apply the rules on what's going live (the content that comes after /devX/projectX/ directories) which is what shifting the DocumentRoot does here for us.
If minimal mods to .htaccess are okay
Not everyone has access to Apache's .conf files. Certain hosts out-rightly reject requests to modify them. Which is why, if they have at least kept mod-rewrite enabled, a lot of website's settings can be tinkered with. One of them is to use RewriteBase to handle the different deployment directories.
So, if you keep RewriteBase / on live but change it to RewriteBase /devX/projectX/ for development, most of your RewriteRules should work as is. So, /devname/projectname/ should correctly redirect to /devname/projectname/en/.
Your use of ([a-z{2}]+) is incorrect. You probably meant ([a-z]{2}) to capture exactly two letters. If you meant to capture two or more, it would become ([a-z]{2,}). So, your default load rewrite would become
RewriteRule ^([a-z]{2})/?$ index.php?controller=contents&method=viewHome&lang=$1 [NC,L,QSA] # Default load
You're correct to assume that you would need this regex for all subsequent rules or they would fail to match. So, your RewriteRule for casestudies won't work. A simpler way to not care about the language prefix is to drop the ^ start of URL path anchor as
RewriteRule /casestudies/([^/\.]+).html$ index.php?controller=contents&method=viewCasestudy&link=$1 [NC,L,QSA]
RewriteRule /products/([^/\.]+).html$ index.php?controller=contents&method=viewProduct&link=$1 [NC,L,QSA]
Your last RewriteRule matching ^(/)?$ isn't required because you're already doing a 301 redirect for all URLs with no language directory prefix to /en/$1 above, which should ideally be
RewriteCond %{REQUEST_URI} !^/(en|sw)(/|$) [NC]
RewriteRule ^(.*)$ en/$1 [R=301,L]
Otherwise, /en would get redirected as well to /en/en.

how to add a sub domain .htaccess pointing to a folder outside the root

I want to have a sub domain that points to a folder outside the normal public root folder.
httpdocs/
sub_dom/
So say "admin.domain.com" points to "sub_dom" while "domain.com" points to the regular httpdocs folder.
is this possible
is there a better solution (for example would it be better/more advisable to do it another way)
Currently the htaccess file contains this but it does not seem to do the trick:
RewriteCond %{HTTP_HOST} ^admin\.domain\.com$
RewriteRule ^/(.*) /var/www/vhosts/domain.com/sub_dom/admin/ [redirect,last]
There is most probably something very wrong with the second line maybe?
is this possible
It is in vhost or server config. It is not possible using an htaccess file unless you can already access the /sub_dom/ directory via your regular domain. You can't access any directory outside of your document root using your htaccess file.
is there a better solution (for example would it be better/more advisable to do it another way)
The correct way to do it is to create a new vhost. Your old vhost should have server names something like this:
ServerName domain.com
ServerAlias www.domain.com
In your new vhost, you have:
ServerName admin.domain.com
And a:
DocumentRoot /path/to/sub_dom/
The Apache documentation has a tutorial for setting up vhosts.
Alternatively, you can create an alias from your regular domain, something like:
Alias /sub_dom /path/to/sub_dom
Then you can use mod_rewrite in your domain.com document root (httpdocs):
RewriteEngine On
RewriteCond %{HTTP_HOST} ^admin\.domain\.com$ [NC]
RewriteCond %{DOCUMENT_ROOT}/sub_dom%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/sub_dom%{REQUEST_URI} -d [OR]
RewriteCond %{DOCUMENT_ROOT}/sub_dom%{REQUEST_URI} -s
RewriteRule ^ /sub_dom%{REQUEST_URI} [L]
But, you may as well just move /sub_dom/ into httpdocs, it'll achieve the same thing.

URL-rewriting with index in a "public" folder

I’m a newcomer in the development world. I desperately try to get the good URL. I checked the site for similar problems but I can’t find exactly what I need. Or I do it badly.
Here is the situation: I set up a project for a site whose the index.php file is in a folder named Public.
To be clearer, here is the URL I have now to reach the homepage of the built site:
http:// Domain Name.com/ Folder / Name of the site/public
My concern is about the folder Public: I don’t want it appears in the URL.
Here is the URL I’d like to get:
http:// Domain Name.com/ Folder / Name of the site
In fact, I’d like this URL permits to get the index file placed in the folder "Public".
I can’t access the Apache configurations (shared host) so I have a .htaccess I placed in the project (i.e: www/ Folder /Name of the site /.htaccess). Here is its content:
Options -Indexes +FollowSymLinks +Multiviews
RewriteEngine On
RewriteBase /public/
RewriteRule ^(.*)$ index.html [NC,L]
I made something very simple for now because I tried lots of things without efficient result.
Not really sure what you are trying to do, but if you want to remove the /public/ path that appears in the URL, you need to remove it from all your links, second, turn off multiviews, it's not what you want, third, you need a rule to externally redirect the browser when a request is made for /public/, then you need to internally rewrite requests to point to public.
Options -Indexes +FollowSymLinks -Multiviews
RewriteEngine On
# externally redirect, must match against %{THE_REQUEST}
RewriteCond %{THE_REQUEST} ^(GET|HEAD|POST)\ /public/
RewriteRule ^/?public/(.*)$ /$1 [L,R=301]
# internally rewrite it back, but we must first check that it's pointing to a valid resource:
RewriteCond %{DOCUMENT_ROOT}/public%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/public%{REQUEST_URI} -d [OR]
RewriteCond %{DOCUMENT_ROOT}/public%{REQUEST_URI} -s
RewriteRule ^(.*)$ /public/$1 [L]

Point External Domain and Sub Directories to Site's Folder

A lot of pages in our site uses an old subdomain for images, css and javascript files. I inherited the project from newbie developers and they didn't use any common design template. The result are hundreds of pages with static references to contents an examples are:
http://static.foo.bar/css/sample.css
http://static.foo.bar/brochure/css/sample.css
http://static.foo.bar/company/newsletter/js/common.js
http://static.foo.bar/images/version2/header.jpg
...and hundreds of other locations. I need to point them all to the main domain instead of the subdomain without creating rules for each of these on the .htaccess file. So:
http://static.foo.bar/css/sample.css
should point to:
http://www.foo.bar/css/sample.css
http://static.foo.bar/brochure/css/sample.css
should point to:
http://www.foo.bar/brochure/css/sample.css
http://static.foo.bar/company/newsletter/js/common.js
should point to:
http://www.foo.bar/company/newsletter/js/common.js
http://static.foo.bar/images/version2/header.jpg
should point to:
http://www.foo.bar/images/version2/header.jpg
I know this is possible only I'm not a server guy. Any help would be very much appreciated.
Create an .htaccess file in the document root with this content:
Add this to your server configuration, %{HTTP_HOST} check does not work from .htaccess:
<IfModule mod_rewrite.c>
# bad matching: RewriteCond %{HTTP_HOST} !^static\.foo\.bar [NC]
#
# correction, matching everything other than www.foo.bar :
RewriteCond %{HTTP_HOST} !^www\.foo\.bar$ [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://www.foo.bar/$1 [L,R]
</IfModule>
See http://httpd.apache.org/docs/2.0/misc/rewriteguide.html#url
UPDATE:
Giving it a second though, if it's hosted on the same server, just add
ServerAlias static.foo.bar
to the www.foo.bar configuration to serve up the static content, too.
UPDATE #2 based on feedback:
This should work (works on my pc) in the .htaccess file, this redirects all requests coming to static.foo.bar/* to www.foo.bar/* :
RewriteCond %{HTTP_HOST} ^static\.foo\.bar [NC]
RewriteRule ^(.*)$ http://www.foo.bar/$1 [R,L]
And no, the ServerAlias command only works from a VirtualHost configuration:
http://httpd.apache.org/docs/2.2/mod/core.html#serveralias

Resources