CodeIgniter on subdomain and htaccess - apache

I'm trying to setup a website based on CodeIgniter.
For developing I want to have the domain dev.XXX.com
I changed my structure so I've got a no_www and a public_www folder.
Both are in the root of dev.XXX.com
So my idea was to rewrite url's form
dev.XXX.com/index.php/test
to
dev.XXX.com/public_www/index.php/test
So I just want add public_www to all the requests
In my htaccess file I've got:
RewriteRule ^(.*)$ /public_www/$1 [L]
But I always get 500 - Internal Server Error

Try adding the following to the .htaccess file in the root directory (public_www) of your site.
RewriteEngine on
RewriteBase /
#if its on dev.xxx.com
RewriteCond %{HTTP_HOST} ^dev\.XXX\.com$ [NC]
#if its not already public_www/ rewrite to public_www/
RewriteRule ^(?!public_www/)(.*)$ /public_www/$1 [L,NC]
The rule you had would lead to an infinite rewrite and subsequent 500 error. The one above should prevent that.
EDIT
could you maybe explain why my version leads into a infinite loop
I am likely incorrect about the infinite loop, but below is what will happen
Start with any input
^(.*)$ pattern will match any input
It will rewrite to /public_www/$1
.htaccess rules will be run again
^(.*)$ pattern will match rewritten input /public_www/$1
It will rewrite to /public_www/public_www/$1
At this point it will likely fail as the directory does not exist...
Your RewriteRule pattern ^(.*)$ will match all input and will rewrite to . The .htaccess rules will then be run again

Related

htaccess rewrite subdomain to some folder if exists else another

I know there are some similar questions about subdomain -> folder htaccess, but I already have a setup that works for me for that simple case.
What I want to add, is "rewrite to projects/subdomain/current/public/ if that current/public exists, else rewrite to projects/subdomain/"
It's because I'm hosting a laravel application, which is in 'public/', and I deployed it using a tool that symlinks 'current/' to its latest release.
My current setup is:
# Redirect everything non-www to /projects/...
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www.* [NC]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.mydomain\.com
RewriteCond /var/www/mydomain.com/projects/%1 -d
RewriteRule ^(.*) /projects/%1/$1 [L]
Which is something like:
if it doesn't start with www
get the subdomain in a var
if the /projects/subdomain folder exists
rewrite the request to look into that folder
else 404
How would I update this to have an "IF /projects/subdomain/current/public exists, then that, ELSE IF /projects/subdomain exists, then that, ELSE 404"?
Thanks in advance!
Just create another rule before the existing one. For example, following the same pattern as your existing rule:
RewriteEngine on
# Redirect to /projects/<subdomain>/current/public/
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.mydomain\.com
RewriteCond /var/www/mydomain.com/projects/%1/current/public -d
RewriteRule (.*) /projects/%1/current/public/$1 [L]
# Redirect everything non-www to /projects/...
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.mydomain\.com
RewriteCond /var/www/mydomain.com/projects/%1 -d
RewriteRule (.*) /projects/%1/$1 [L]
I removed the ^ from the RewriteRule pattern (^(.*)) since it was superfluous.
I also changed !^www.* (matches any hostname that simply starts "www") to !^www\. (any hostname that starts "www." - the subdomain only) to avoid potentially spurious matches.
Presumably /var/www/mydomain.com is the document-root, so you could use the DOCUMENT_ROOT server variable instead in the RewriteCond TestString. For example:
RewriteCond %{DOCUMENT_ROOT}/projects/%1/current/public -d
However, by themselves, these directives will result in a rewrite-loop (500 error), so I assume you already have directives in place that prevent this. eg. Another .htaccess file in the directory that you are rewriting to that contains mod_rewrite directives (relevant to the individual projects)? If not then you can either add another condition to each rule that checks against the REDIRECT_STATUS environment variable, or include an exception at the top of the file that prevents further processing after the request is rewritten. For example:
RewriteEngine On
# Stop further processing if the request has already been rewritten
RewriteCond %{ENV:REDIRECT_STATUS} !^$
RewriteRule ^ - [L]
: Remaining directives follow...
UPDATE: If you are on Apache 2.4 you can instead simply change the L flag to END to halt all processing by the rewrite engine, to prevent a rewrite loop. The END flag is a relatively recent addition and consequently often gets overlooked - but it's not strictly necessary as there are always other (perhaps more complex) ways to do this.
Why would it loop?
The L flag does not stop all processing. It simply stops the current round of processing and then the rewrite engine effectively starts over, passing the rewritten URL back into the rewrite engine. In the above example, the rewritten URL also matches the same rules, so the URL would be rewritten again, and again, and again, ....
For example (for simplicity, just using your original rule that rewrites to /projects):
Request subdomain.mydomain.com/foo
<doc-root>/projects/subdomain directory exists
URL rewritten to /projects/subdomain/foo
Rewriting process starts over... passing in the rewritten URL, essentially subdomain.mydomain.com/projects/subdomain/foo, back into the rewrite engine.
<doc-root>/projects/subdomain directory exists (as previous)
URL rewritten to /projects/subdomain/projects/subdomain/foo
Rewriting process starts over... etc. etc.
The Rewriting process loops in this fashion until the URL passes through unchanged, unless something else steps in the way... for example, as mentioned above, if you have another .htaccess file located at /projects/subdomain/.htaccess that also contains mod_rewrite directives then control would pass to this .htaccess file after the first round of rewrite processing and prevent further rewrites (since mod_rewrite directives are not inherited by default).

having trouble writing htaccess redirects

I'm having trouble writing redirect rules in my website's htaccess file.
Basically, i want to write two rules:
1 - When i write the base URL, like http://www.example.com, i want it to automatically redirect the user to http://www.example.com/someDirectory.
2 - However, when i write http://www.example.com/Admin, i want it to redirect the user to http://www.example.com/Admin.
Here's what i've managed to do so far:
# This allows you to redirect index.html to a specific subfolder
Redirect http://www.example.pt http://www.example.pt/MainFolder
# This allows you to redirect index.html to a specific subfolder
Redirect http://www.example.pt/Admin http://www.example.pt/Admin
However this does not work... Any idea on how to do this?
Try it like this,
When there is no request for specific file or directory it will redirect you to your directory mention in rule and for the rest it will work without any rule.
Please check.
RewriteEngine on
RewriteCond %{REQUEST_URI} ^$
RewriteRule ^ %{HTTP_HOST}/someDirectory [R,L]
After a long research i was able to find a solution to my problem. I'll leave it here, in case anyone's having the same problem:
#Rewrite everything to subfolder
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/MainFolder
RewriteCond %{REQUEST_URI} !^/Admin
Rewriterule ^(.*)$ MainFolder/$1 [L]

.htaccess and rewrite from subdirectories inside unknown parent directory

So I have an htaccess file in a subdirectory and whenever I try to rewrite the url, it redirects to the document_root and not the subdirectory where the htaccess resides. Now, under normal circumstances, I'd rewrite it with the path to the subdirectory with path/to/subdirectory, but I won't know what the exact path will be. Is there a way either, through an Apache environment variable or something else, to write out that path?
Edit:
Here's the .htaccess file so far.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule (.*-file) a/b/c/$1.file
RewriteRule (.*-file) $1.file
So, I'm trying to, if the request contains the word file, I want to match the entire request prior to the word file and redirect there. This is so that if a request is to
example.com/a/b/c/file[any characters here].file
the request will be redirected to the right file. To reiterate, the problem is that I am trying to redirect within the subdirectory. So when I say Rewrite $1, I want that to include the entire request and not just what matched in the REQUEST_FILENAME. And the reason I need it to do that is because I can't simply put a/b/c/$1.file since I won't know for absolute certainty the a/b/c part.
Edit 2: Examples:
So, an example is that I'd send a request like:
example.com/a/b/c/fileacs.file
And want to redirect to:
example.com/a/b/c/file.file
Where I do not know a/b/c/. I have an actual regex and set of rules for the real-world use of this redirect, so don't mind the ridiculous nature of this example.
But currently it's redirecting to:
example.com/file.file
Which does not exist and even if it did, I do not want to redirect there. I've read about Rewrite Context, but can't find out anything substantial about it nor if it's the cause for this. Thank you, in advance.
You can use this rule to capture any path before fileacs.file and use that as bach-reference in RewriteRule:
RewriteEngine On
RewriteCond ^(.*)/file[^.]+\.file$ [NC]
RewriteRule ^ %1/file.file [L,R=302]
The solution is to use the a RewriteCond on the %{REQUEST_URI} (thanks anubhava!) that checks matches the entire request except for the %{REQUEST_FILENAME} without capturing it, using a lookahead. Write out this with the %1 followed by the desired filename. See the following:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} (.*)-file(?!\.file) [NC]
RewriteRule ^ %1.file [L,R=301]
The %1 now holds the path up to the directory that the .htaccess is stored, plus any prefix to the filename. This doesn't match the remainder of the request, but rather looksahead to ensure you're not actually requesting the file you would like to redirect to (causing a loop).

Apache mod-rewrite rule not working

I am facing issue with apache rewrite rule. i am expecting the below result
If URL is
http://www.mysite.co/testWeb/query1/guery2/3
Then Result
http://www.mysite.co/testWeb/index.html/#/query1/guery2/3
(index.html/# - has to be added in URL, it the path contains testWeb)
The rule i added is as follow
RewriteEngine On
RewriteRule ^testWeb/(.*)$ http://%{HTTP_HOST}/testWeb/index.html/#/$1 [L]
this rule is working fine in the rewrite rule online tester. But not in my apache. Any idea?
It looks like the Rule is creating a Redirect loop error on your server because your Regex pattern also matches the target url /testweb/index.html .
You need to use a negitive RewriteCond to prevent this .
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/testWeb/index\.html$ [NC]
RewriteRule ^testWeb/(.*)$ http://%{HTTP_HOST}/testWeb/index.html/#/$1 [NC,L,NE]

mod_rewrite loops even with L flag

I've got a problem with rewriting a URL to a fastcgi dispatcher. If I leave only:
RewriteRule ^(.*)$ dispatch.fcgi/$1 [L,QSA]
I expected L (last rule) to cause only a single rewrite. Instead, it keeps prepending dispatch.fcgi until apache reports an error.
I know it can be fixed with:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.fcgi/$1 [L,QSA]
But what is the reason for multiple rewrites? Does L do something else than I think it does?
I know it's an old question, but to others searching for the REAL answer, here it is:
The [L] flag DOES work in .htaccess files. It tells the rewrite module to skip all of the following rules in that particular .htaccess file. It does its job, Apache rewrites the url and exits the .htaccess file.
However, at the end of the .htaccess file if the request url has been rewritten, the whole url matching process starts again with the new url.
This is what happens above, ^(.*)$ will always match the current url, it causes an infinite loop, only the maxredirect rewrite option (10 by default) stops it.
The !-f file attribute test (as mentioned by the questioner) would solve the problem, since the url will match a real filename:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.fcgi/$1 [L,QSA]
now, if we request http://example.com/toappend, .htaccess rewrites it to dispatch.fcgi/toappend and no rewrite loop will happen.
Hy , add this after RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule .* - [L]
.. and it should work stoping loops .
Apparently -- and I only read this here, I have no first hand knowledge -- the [L] directive does not work in .htaccess files, only if its in your .conf file.
See: Hidden features of mod_rewrite
within the .htaccess context, [L] will
not force mod_rewrite to stop. it will
continue to trigger internal
Faced the same problem, and it turns out that the best solution in Apache 2.3.9+ is to use END flag instead of L as it prevents mod_rewrite from looping over rules.