How to write htaccess rewrite for subdirectories recursively? - .htaccess

I have an Apache server, hosting a number of websites for my company. I plan to use htaccess, and rewrite the URLs from the "root" directory to a subfolder.
Here is my real folder structure:
/www (root)
/www/beamstyle (beamstyle.com.hk, CodeIgniter framework)
/www/beamcard (beamcard.com.hk, Static files)
/www/beamcard/app (beamcard.com.hk/app, CodeIgniter framework)
====================================================================
The beamstyle website works using the following code:
ReWriteCond %{HTTP_HOST} ^(www.)?beamstyle.com.hk [NC]
RewriteCond %{REQUEST_URI} !^/beamstyle/.*$
RewriteRule ^(.*)$ /beamstyle/$1 [L]
The above works, because my framework (CodeIgniter) is inside /www/beamstyle.
Therefore, I can access http://beamstyle.com.hk, and it will get redirected without any issues.
====================================================================
However, here is the problem. When I do the beamcard website, it doesn't work because actually, the directory "/www/beamcard/" actually stores ONLY static .html files. My CodeIgniter framework is inside app/.
When I use the same code:
ReWriteCond %{HTTP_HOST} ^(www.)?beamcard.com.hk [NC]
RewriteCond %{REQUEST_URI} !^/beamcard/.*$
RewriteRule ^(.*)$ /beamcard/$1 [L]
Here are the results using the above code:
(a) http://beamcard.com.hk/ <-- OK no problem, because this is the immediate folder after rewrite (and contain static files only)
(b) http://beamcard.com.hk/app <-- NOT OK, because it steps one directory beyond the immediate folder after rewrite.
If I type this, the location bar (on the top) gets un-disguised and redirected to http://beamcard.com.hk/beamcard/app/ (I confirmed that this redirect not done by Codeigniter files because the same result happens when I apply on an empty directory)
====================================================================
I've tried everything I could, and did so many Google searches, but failed to fine an htaccess snippet that works on subdirectories BEYOND the directory after rewrite. It loses it's "disguise" functionality when I step further in the subdirectories.
Any help on this is greatly appreciated!
Cheers,
Thomas
====================================================================
Update 1
In order to describe my situation better, I've put together some use cases.
[ Case Scenarios ]
** To simplify things, let's assume the "app" directory is empty **
(1) If I type in http://beamcard.com.hk, the page "/www/beamcard/index.html" inside the server should get loaded. After finish loading the page, the location bar should write "http://beamcard.com.hk/".
(2) If I type in http://beamcard.com.hk/contact_us.html, the page "/www/beamcard/contact_us.html" inside the server should get loaded. After finish loading the page, the location bar should write "http://beamcard.com.hk/contact_us.html".
(3) If I type in http://beamcard.com.hk/app, an "empty file listing" should be loaded. After finish loading the page, the location bar should write "http://beamcard.com.hk/app/".
(4) If I type in http://beamcard.com.hk/app/, an "empty file listing" should be loaded. After finish loading the page, the location bar should write "http://beamcard.com.hk/app/".
========================================================================
Currently, (1) and (2) works.
However, for (3) and (4), after finish loading the page, the location bar got redirected to "http://beamcard.com.hk/beamcard/app/", which "reveals" the "/beamcard/" portion, which ideally should be hidden from the site visitor.

Try adding NS at the end (to prevent the rule from being applied to sub-requests):
ReWriteCond %{HTTP_HOST} ^(www.)?beamcard.com.hk [NC]
RewriteCond %{REQUEST_URI} !^/beamcard/.*$
RewriteRule ^(.*)$ /beamcard/$1 [L,NS]

Related

Subdomain in .htaccess file only works with index

I have a subdomain setup in my .htaccess, which only seems to work with the default index.html page. I'd LIKE it to work for ANY page in the folder corresponding to the subdomain. Edited for privacy, assume my domain is example.org. The pertinent parts of the file look like this...
#subdomain
RewriteCond %{HTTP_HOST} ^subname\.example\.org$ [OR]
RewriteCond %{HTTP_HOST} ^www\.subname\.example\.org$
# (a few lines added by my hosting company deleted -- see below)
RewriteRule ^/?$ "http\:\/\/example\.org\/subname\/" [R=301,L]
So the result of the above is that if I have an index.html page in my 'public-html' (root?), http://example.org and a different index.html stored in a sub-folder (having the same name as the subdomain), I will get this expected result, which works...
browse to: http://example.org results in viewing http:// example.org/index.html
browse to: http://subname.example.org results in viewing http:// example.org/subname/index.html
Great so far. This is what I expected when I created the domain name. However, given a specific file myfile.html stored in the subname folder, I would expect this to work also, and it doesn't...
browse to: http://subname.example.org/myfile.html results in a 404 error.
This despite the fact that browsing to http://example.org/subname/myfile.html works fine. In that case myfile.html is displayed. So is there anything I can do to modify the subdomain code to get the result I'm looking for? Namely, browsing to http://subname.example.org/ANYFILE should work as well as browsing to http://example.org/subname/ANYFILE, regardless of what 'ANYFILE' is. This, after all, is one of the main reasons I set up the subdomain to begin with!
Note: I confess that I relied on my hosting company's cPanel utility to create the subdomain code, so I asked for their tech support for help first. Long story short they didn't. Maybe what I hoped for is not actually possible?
Also, the lines I deleted' from the code had to do with something called "well-known/acme-challenge", added by my hosting company at some point. Since removing them had no effect on the behavior I've described, I left it out to avoid clouding the issue.
RewriteRule ^/?$ "http\:\/\/example\.org\/subname\/" [R=301,L]
This only "redirects" the document root. To redirect all URLs you need to change the above to read something like:
RewriteRule (.*) http://example.org/subname/$1 [R=301,L]
The $1 backreference refers to the URL-path captured in the RewriteRule pattern, ie. (.*).
No need to backslash-escape the colons, slashes and dots in the substitution string (that's typical of cPanel).
Also, the lines I deleted' from the code had to do with something called "well-known/acme-challenge", added by my hosting company at some point.
Those lines will likely be required when the (Let's Encrypt?) SSL cert auto-renews. (Although the above redirects to "http" - are you not using HTTPS?)
UPDATE:
RewriteCond %{HTTP_HOST} ^subname\.example\.org$ [OR]
RewriteCond %{HTTP_HOST} ^www\.subname\.example\.org$
Just as an aside, these two conditions could be reduced to a single condition if you wanted. For example, the above is equivalent to:
RewriteCond %{HTTP_HOST} ^(www\.)?subname\.example\.org$

htaccess: act as if files were in another directory, but RewriteRules seem to be mutually exclusive

For files in several subdirectories of /data/, I would like to treat them (and the files inside them) as if they were in the root directory.
So,
1) a request to
/data/foobar/file.png
should redirect the browser to
/foobar/file.png
2) any requests to
/foobar/file.png
should respectively deliver the file /data/foobar/file.png, but without redirection.
For 1) I got the following rule working
:
RewriteCond %{REQUEST_URI} ^(.*)?data/((foobar|and|some|other|subdirs)/.*)$
RewriteRule .* %1%2 [R=301,L,qsappend]
(I took this approach usind a RewriteCond with %x references in order to be subdirectory-agnostic, as in my dev environment the page is located in a subdirectory as opposed to the live system where it's in the root of the domain.)
And for 2) the following rule does the trick:
RewriteRule ^((foobar|and|some|other|subdirs)/.*)$ data/$1 [L,qsappend]
However, these rules only work if I enable one at a time. If I enable both of them at the same time, the browser will abort the request with a "too many redirects" error. The redirect from /data/* to /* will work, but then end in the aborted request just the same as calling the URL without /data/*.
I'm having a hard time understanding why this is happening. It would be totally logical if both rules actually triggered a redirect. But as far as my understanding of htacccess goes (and the Network tab of the dev console seems to confirm that conception), the client shouldn't even know for case 2) that the file is not actually there. So why does this apparently still count towards the redirection limit?
Is there something fundamental I'm missing? And how can I achieve what I'm trying to achieve?
This is because you first redirect and then rewrite the same Uri . Your second rule is conflicting with with the first one.
You need to match against %{THE_REQUEST} instead of %{REQUEST_URI} to avoid the redirect loop
RewriteCond %{THE_REQUEST} \s(.*)?data/((foobar|and|some|other|subdirs)/.*)\s
RewriteRule .* %1%2 [R=301,L,qsappend]
RewriteRule ^((foobar|and|some|other|subdirs)/.*)$ data/$1 [L,qsappend]

.htaccess url redirect from one an old page to a new one keeping the root directory same

I have an application whose codebase is deployed inside a folder shop . The URL to the main application is http://myapp/shop/.
One of the links on my page reads
http://myapp/shop/website-design/design-urself.php
which I want to redirect to http://myapp/shop/website-design/index.php
The rule which I am using in my .htaccess file is :
RewriteEngine On
RewriteBase /
RewriteRule ^/website-design/design-urself.php /website-design/index.php [R=301]
But the link is wrongly being getting redirected to http://myapp/website-design/index.php
I tried by removing the leading slash (/) from the urls as :
RewriteRule ^website-design/design-urself.php website-design/index.php [R=301]
but still it doesn't work.
I can understand that probably changing the RewriteBase to shop will solve my problem.
However , the thing here is - going further, the folder name ("shop" in my case) can change . So , in that case I have to again go and modify the .htaccess , which is not desirable.
What is the appropriate RewriteRule I should use in this case?
UPDATE : I have my .htaccess file located at my document root , i.e, inside the folder shop and outside of all other folders residing inside shop.

CakePHP: Can you globally modify all links to point to another directory?

My CakePHP app lives inside a subdirectory to keep it from crashing into a Wordpress installation that powers part of the website:
example.com/ <--root
/_wp <--Wordpress installed here
/page1
/page2
/_cake <--CakePHP installed here
/page3
/page4
To maintain consistency, I'm using mod_rewrite rules to rewrite URLs from example.com/_cake/pageX to example.com/pageX etc. This basically works, but CakePHP still creates links with /_cake/pageX. So if a user hovers over a link, the "_cake" will show up in the bottom of the browser and of course in the source code.
Is there a way to configure CakePHP to think it's actually in the site root so it creates the desired URLs for links etc?
I haven't found a way to configure CakePHP the way you want.
If you create your links with HtmlHelper::link or Router::url, you can add a member $url['base'] = false to the $url array argument. This prevents the _cake prefix being inserted in front of the URL.
As an alternative, you can create your own link() or url() function, which calls HtmlHelper::link and always adds base = false.
For this to work, you must also have a .htaccess in the document root, which rewrites the requests to their real destination
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /_cake/$0 [L]
You must also pay attention to requests destined for the _wp directory.

htaccess rewriterule for directory is changing the url in a undesireable way

EDIT
After a comment from Seth below, and heading to a helpful apache page here, I have found that VirtualHosts are the way to go for the following issue.
/edit
--ORIGINAL POST--
First, a little background on file setup. I am running a LAMP server that hosts multiple domains. I have staging and live sites on this server, under different directories under the web root.
examples
/webroot/live/site1/[public files]
/webroot/live/site2/[public files]
/webroot/stage/site1/[public files]
/webroot/stage/site2/[public files]
The domains for each of these go to the IP of the server, which points at the webroot directory. I have an .htaccess file there to load the appropriate content based on the http_host.
examples
RewriteCond %{HTTP_HOST} ^www.site1-live.com [NC]
RewriteRule ^(.*)$ /live/site1/$1 [PT,L,QSA]
RewriteCond %{HTTP_HOST} ^www.site1-stage.com [NC]
RewriteRule ^(.*)$ /stage/site1/$1 [PT,L,QSA]
These work great for hitting the home page and any of the internal pages, even with the specific pages being like site1-live.com/view/123. Each site's htaccess handles those.
My issue (sorry it took so long to get here):
When I head to any subdirectory within a site, like www.site1-live.com/rss, the content loads just fine, but the URL changes to something like the following
http://www.site1-live.com/live/site1/rss/
Essentially showing the path from the webroot to the files.
How can I avoid this? I obviously want the url to remain www.site1-live.com/rss. Do I need an htaccess file inside the rss directory to block this somehow?
Thanks in advance!
replace ^www with ^(.*)
then have the whole url in the second line www.yourdomain.com/live/...
Doug,
why do you need the QSA flag?
Anyway, what is happening to you is that mod_index (or whatever is serving you directories) is redirecting you www.site1-live.com/rss (without the ending /) to the equivalent URL with the ending /.
If you don't use mod_alias or something list that on the rewritten URLs, removing the PT should work as you expect.

Resources