I have configured server with lucee tomcat and apache2 for virtual host on ubuntu. I have enabled rewrite rule and my virtual host is as followes.
<VirtualHost *:80>
ServerAdmin admin#example.com
ServerName example.com
ServerAlias example.com www.example.com
DocumentRoot /var/www/html/example.com/
<Directory /var/www/html/example.com/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error_main_example.log
CustomLog ${APACHE_LOG_DIR}/access_main_example.log combined
DirectoryIndex index.cfm
</VirtualHost>
redirect from htaccess file is working good but rewrite rule is not working. Here is the htaccess file that i am trying.
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^(.*)/abc/([0-9]+)$ /test-404.cfm [L]
Here are the example URLs:
https://www.example.com/example.cfm/abc/2
https://www.example.com/example.cfm/abc/8
https://www.example.com/example.cfm/abc/15
It is showing me tomcat 404 error that
HTTP Status 404 – Not Found
Type Status Report
Message The requested resource [/example.cfm/abc/2] is not available
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
Apache Tomcat/9.0.35
Can any body help me about this issue. By the way, site is configured using classic load balancer on AWS.
I'm posting a working solution here also, because you didn't answer to our posts of this cross post at the Lucee forum. This solution might also help others with the same problem.
The issue is that mod_proxy will always preced urlrewrite, unless you invoke mod_proxy with a special urlrewrite rule. To make urlrewrite work and use mod_proxy, you need to flag the rewrite rule with [P] (for proxy). Here is a working example that should work for you:
Step: Set everything in apache2.conf in mod_proxy.c as comment, just leaving ProxyPreserveHost and ProxyPassReverse, like so:
<IfModule mod_proxy.c>
ProxyPreserveHost On
#ProxyPassMatch ^/(.+\.cf[cm])(/.*)?$ http://127.0.0.1:8888/$1$2
#ProxyPassMatch ^/(.+\.cfml)(/.*)?$ http://127.0.0.1:8888/$1$2
# optional mappings
#ProxyPassMatch ^/flex2gateway/(.*)$ http://127.0.0.1:8888/flex2gateway/$1
#ProxyPassMatch ^/messagebroker/(.*)$ http://127.0.0.1:8888/messagebroker/$1
#ProxyPassMatch ^/flashservices/gateway(.*)$ http://127.0.0.1:8888/flashservices/gateway$1
#ProxyPassMatch ^/openamf/gateway/(.*)$ http://127.0.0.1:8888/openamf/gateway/$1
#ProxyPassMatch ^/rest/(.*)$ http://127.0.0.1:8888/rest/$1
ProxyPassReverse / http://127.0.0.1:8888/
</IfModule>
Step: In your virtual host configuration set the following rewrite rules ( that may work also in your .htaccess, but I’m not sure).
...
<Directory /var/www/html/example.com/>
...
...
RewriteEngine On
RewriteBase /
# Catch non-existing files/directories and pass them via proxy to a 404 cfml errorpage
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule "^(.*)$" "http://127.0.0.1:8888/my-404.cfm" [P]
# Catch https://www.example.com/example.cfm/abc/2
# Catch https://www.example.com/example.cfm/abc/7 etc.
RewriteRule "^example.cfm(/abc/[0-9]+)$" "http://127.0.0.1:8888/my-404.cfm" [P]
# Pass request for cfm/cfc files to proxy with mod_rewrite rule
RewriteRule "^(.+\.cf[cm])(/.*)?$" "http://127.0.0.1:8888/$1$2" [P]
...
</Directory>
I’ve tested it and the solution above works fine.
Related
I have installed Codeigniter 4 on Raspbian and everything seems to be working fine.
My web directory is /var/www/html
Inside there are two folders containing two different Codeigniter-4 apps that I would like to invoke with:
blue.ddns.net -> /var/www/html/blue/public/index.php
black.ddns.net -> /var/www/html/black/public/index.php
So I'm creating a .htaccess file to put in the folder /var/www/html/ to handle the two requests
Well, I'm still at step 0 because I can't get the .htaccess file to work properly.
Below I attach a copy of the file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /var/www/html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ blue/public/index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
ErrorDocument 404 /index.php
</IfModule>
The Rewrite module is activated
the error that appears in /var/log/apache2/error.log is:
/var/www/html/.htaccess: Expected </IfModule> before end of configuration, referer: https://blue.ddns.net/
That shouldn't really be done in your htaccess. You should setup that in your apache virtual hosts.
Go into your sites-avaiable folder.
$ cd /etc/apache2/sites-available
Create a new virtual host called blue.ddns.net.conf
$ touch blue.ddns.net.conf
Open that file with nano or any other text editor you might like and add the following.
<VirtualHost *:80>
ServerAdmin your#email.com
DocumentRoot /var/www/html/blue/public
ServerName blue.ddns.net
ServerAlias blue.ddns.net
<Directory "/var/www/html/blue/public">
allow from all
AllowOverride All
Options None
Require all granted
</Directory>
RewriteEngine on
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteCond %{SERVER_NAME} =blue.ddns.net
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Save and close the file.
Then add this to your apache with the following:
$ sudo micro blue.ddns.net.conf
Repeat the same process for the other codeigniter install and reboot apache.
$ sudo service apache2 restart
That should do it.
Now if you want to override some config that would be something that you might do in your htaccess file for each codeigniter 4 install.
I've always worked in hosting and never had to do Apache configurations.
But now I'm discovering the Raspberry/Linux world.
Thanks to your answers I was able to better understand the problem and solve it (for the moment) in the following way:
Now my configuration files 000-default.conf (port 80) and 000-default-le-ssl.conf (port 443) both contain the following code:
<Directory "/var/www/html">.
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
in /var/www/html instead I created a .htaccess file with the following code:
# Disable directory browsing
Options All -Indexes
<IfModule mod_rewrite.c>.
RewriteEngine On
RewriteCond "%{HTTP_HOST}" "black\.ddns\.net"
RewriteRule ^(.*)$ black/public/index.php?/$1 [L]
RewriteCond "%{HTTP_HOST}" "blue\.ddns\.net"
RewriteRule ^(.*)$ blue/public/index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
ErrorDocument 404 /index.php
</IfModule>
apps are located in
/var/www/html/blue
and
/var/www/html/black
It's a very simple solution that serves my purposes.
Although I think it's not very elegant
What do you think about it?
I am writing a .htaccess rule that sends a subdomain request to a specific login page file. My current rule is:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^subdomain.name.com$
RewriteRule ^ https://name.com/app/login [R=302,L,NE]
This works as I would expect. I now want to build on this so as to keep the original url displayed. The RewriteRule would continue to redirect to https://name.com/app/login but still display https://subdomain.name.com as the URL within the web browser.
Is this possible within .htacess file? I cannot find a solution.
You could use:
RewriteCond %{HTTP_HOST} ^subdomain.name.com$
RewriteRule ^ https://name.com/app/login [P]
For this to work, you need to
1) enable apache proxy module
2) enable SSLProxyEngine in the VirtualHost definition:
<VirtualHost subdomain.name.com:80>
...
SSLProxyEngine on
</VirtualHost>
<VirtualHost subdomain.name.com:443>
...
SSLProxyEngine on
</VirtualHost>
3) If the certificate is not "trusted", e.g. is self signed, you could disable the proxy `s verification by adding:
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
to the virtualHost definitions above.
References
Redirect website but keep the original url in the address bar
Disable proxy ssl verification
I'm trying to get this RewriteRule working, but the Proxy flag [P] is behaving like a redirect:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ - [E=MAPTO:${domainmap:%1}]
RewriteCond %{ENV:MAPTO} !=""
RewriteRule ^.*$ https://mywebsite.com/%{ENV:MAPTO}/$0/ [P,NC]
</IfModule>
I enabled rewrite logging by using LogLevel alert rewrite:trace6, which confirmed that a match is being found in my map, but from my log:
RewriteCond: input='proxiedwebsite.com' pattern='^(?:www\\.)?(.+)$' [NC] => matched
map lookup OK: map=domainmap key=proxiedwebsite.com -> val=path/to/dynamic-content
setting env variable 'MAPTO' to 'path/to/dynamic-content'
strip per-dir prefix: /var/www/mywebsite.com/html/ ->
applying pattern '^.*$' to uri ''
RewriteCond: input='path/to/dynamic-content' pattern='!=""' => matched
rewrite '' -> 'https://mywebsite.com/path/to/dynamic-content/'
escaped URI in per-dir context for proxy, https://mywebsite.com/path/to/dynamic-content/ -> https://mywebsite.com/path/to/dynamic-content/
forcing proxy-throughput with https://mywebsite.com/path/to/dynamic-content/
go-ahead with proxy request proxy:https://mywebsite.com/path/to/dynamic-content/ [OK]
What ends up happening is I get https://mywebsite.com/path/to/dynamic-content/ in my address bar instead of the intended https://proxiedwebsite.com.
And here's what my Apache config looks like:
<Directory "/var/www/mywebsite.com/html">
DirectoryIndex disabled
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<VirtualHost *:443>
ServerName www.mywebsite.com
ServerAlias mywebsite.com proxiedwebsite.com www.proxiedwebsite.com
DocumentRoot /var/www/mywebsite.com/html
UseCanonicalName Off
ProxyRequests On
SSLEngine On
SSLProxyEngine On
SSLCertificateFile /path/to/cert/fullchain.pem
SSLCertificateKeyFile /path/to/cert/privkey.pem
LogLevel alert rewrite:trace6
</VirtualHost>
I've also tried doing this without https on port 80, but I get the same issue.
UPDATE
I added ProxyPreserveHost On to my VirtualHost configuration and it seems to be responding to my rewrite conditions — however, it's creating a loop. After several seconds I'm getting a 403 Forbidden error with the %{ENV:MAPTO} variable repeated over and over again. Not sure why.
UPDATE 2
Okay, now I understand why ProxyPreserveHost On is creating a loop. But I still don't understand why my Proxy [P] flag is resulting in a 301 Redirect. So, back to the original problem.
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.
My problem is that my .htaccess file on my local server is not being read. The settings in the VirtualHost file seem to always take precedence.
I have tried the following:
Enabled mod_rewrite
Changed the AllowOverride to All but this causes a HTTP Error 500 Internal server error. I have tried it with various options but it always causes a 500 error.
I am using a VirtualHost file on Ubuntu which looks like the following:
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /web/website
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /web/website>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
</VirtualHost>
In my .htaccess file under /web/website I have the following rules (which are not being read):
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [L]
RewriteCond %{HTTP_USER_AGENT} ^facebookexternalhit
RewriteRule ^(.*)$ ogtags.php?$1 [L,QSA]
ErrorDocument 404 /404
ErrorDocument 401 /401
One thing I tried which did work was appending these rules directly into the VirtualHost file, but I would like my .htaccess file to work! Is that such a big ask? :(
Edit: So I looked in my apache error.log and it says Invalid command 'Action', perhaps misspelled or defined by a module not included in the server configuration referring to my .htaccess file. There doesn't seem to be a module called Action which I can enable. Any ideas?
Edit 2: I noticed that my httpd.conf file is blank. Should this matter since I am using VirtualHost files?
After looking at my apache error.log I realised I just had to enable the Apache actions module:
sudo a2enmod actions
And no more 500 Internal Server Errors!
Hope this helps somebody down the line :)
You miss the RewriteBase / directive
Add it after the RewriteEngine directive :
RewriteEngine On
RewriteBase /