Delegate specific URL request to specific Directory - apache

Taking forward from my last question i.e. Mapping domains to Tomcat Apps. Now I want that if a particular request came i.e.
http://www.app1.com/blog
then this would be redirected to a specific folder on my server. I did tried below code
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^/blog/ /path_to_my_site/app1_com/blog/ [L]
but that has gone horribly wrong as that has become redirect loop, so I removed it immediately.
Note: My site www.app1.com is hosting java application and www.app1.com/blog would be php application blog.
Update 1
for the sake of clarity below is my virtual host configuration
<virtualhost *:80>
ServerName app1.com
ServerAlias app1.com www.app1.com
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^blog(/.*)?$ /path_to_my_site/blog/ [L,NC]
ProxyPass / ajp://127.0.0.1:8009/app1/
ProxyPassReverse / ajp://127.0.0.1:8009/app1/
</virtualhost>
Update 2
contents of .htaccess in blog folder is
# Pretty Permalinks
RewriteRule ^(images)($|/) - [L]
RewriteCond %{REQUEST_URI} !^action=logout [NC]
RewriteCond %{REQUEST_URI} !^action=login [NC]
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /blog/
RewriteCond %{REQUEST_URI} !index\.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?filename=$1 [NC,QSA,L]

You can use:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^blog(/.*)?$ /path_to_my_site/app1_com/blog/ [L,NC]
/path_to_my_site/app1_com/blog/ should be a valid path under DocumentRoot.
Change your ProxyPass line to this:
ProxyPass /blog !
ProxyPassMatch ^/(?!blog).*$ ajp://127.0.0.1:8009/app1/
ProxyPassReverse / ajp://127.0.0.1:8009/app1/

Related

Apache vhost double slash on redirects

I was trying to force the FQDN and HTTPS via Apache Vhost redirects in a Laravel application behind a reverse Proxy. My problem now is that the user sometimes gets redirected to a URL with double slash e.g. https://exampledomain.xy//test instead of https://exampledomain.xy/test and I'm not sure why.
Here is my apache vhost configuration:
<VirtualHost *:80>
ServerName localhost
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html/public
<Directory /var/www/html>
AllowOverride All
</Directory>
ErrorLog /dev/stderr
TransferLog /dev/stdout
RewriteEngine on
RewriteCond %{HTTP_HOST} !=localhost
RewriteCond %{HTTP_HOST} !=127.0.0.1
RewriteCond %{REMOTE_ADDR} !=127.0.0.1
RewriteCond %{REMOTE_ADDR} !=::1
RewriteRule (.*) https://exampledomain.xy/$1 [L,R=301]
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot "/var/www/html/public"
ServerName exampledomain.xy
</VirtualHost>
And my .htaccess file (default .htacces file that comes with Laravel)
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Okay looks like I fixed the issue. I changed the following in my config:
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://stk-support.ukl.uni-freiburg.de$1 [R=301,L]
The extra slash in the rewrite rule was causing the issue and I also added a HTTPS rewrite condition.

With two rewrite rules for different directories, only one works

Background
I'm trying to add another rewrite rule for my Apache server but am having a strange issue.
This new rule which I'm creating causes the original rule to break (as in, not work... I don't get any errors). Only one or the other rule will run.
It's easier to explain by showing the code...
Code
Rule #1:
# Redirect hits from non-existent page to link shortener
<Directory /var/www/html/lnf>
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . - [L]
RewriteRule ^/?([^/]+)/?$ link/link.php?a=$1 [L]
</Directory>
Rule #2:
# Deny disallowed user agents (when adding this, it causes the first one to break)
<Directory ~ "/var/www/html/*">
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} "(netscape|\.ru)" [nocase]
RewriteRule ^.*$ – [forbidden,last]
</Directory>
Question
Why is this happening, and how do I fix it?
PS: Excuse my lack of knowledge, I still feel like a beginner when it comes to Apache.
Update
I have 4 vhosts for HTTP and 4 for HTTPS.
The four in both /etc/apache2/sites-enabled/000-default.conf and /default-ssl.conf are:
1. A catch-all for denying all hits to the public IP which are usually bots (This is on the top of the vhosts file to catch if nothing else does):
<VirtualHost *:80 (and 443 in ssl)>
ServerName catchall
<Location />
Require all denied
</Location>
</VirtualHost>
2. 3 different vhosts for 3 different domains
<VirtualHost _default_:80 (and 443 in ssl)>
ServerName (my domain)
### REDIRECT HTTP TO HTTPS (this is only in the 000-default.conf)
RewriteEngine On
RewriteCond %{HTTPS} off
#only change when using [mydomain.com] domain (the only public domain)
RewriteCond %{HTTP_HOST} ^mydomain\.com
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
# doc roots, error logs, ssl certificates (I omitted this to save space)
</VirtualHost>
Have it this way:
# default rule applied to all locations
<Location />
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} "(netscape|\.ru)" [NC]
RewriteRule ^ – [F,L]
</Location>
# catch all virtual host
<VirtualHost _default_:*>
DocumentRoot "/var/www/html"
ServerName catchall
<Location />
Require all denied
</Location>
</VirtualHost>
# rules specific to mydomain.com placed here
<VirtualHost _default_:80>
DocumentRoot "/var/www/html/lnf"
ServerName mydomain.com
DirectoryIndex index.php
### REDIRECT HTTP TO HTTPS (this is only in the 000-default.conf)
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTPS} off
#only change when using [mydomain.com] domain (the only public domain)
RewriteCond %{HTTP_HOST} ^mydomain\.com$
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^/?([^/]+)/?$ /link/link.php?a=$1 [L,QSA]
</VirtualHost>

Combining Rewrite Rules - http to https AND all links to one file while maintaining clean URL

Over the past few days, I have read quite a few forums and StackOverflow answers on rewriting URLs in apache.conf and converting http to https using rewrites. Thanks to StackOverflow, I have figured out how to do both separately. Unfortunately, I haven't found a solution that can combine the two while allowing me to keep my clean URL appearance AND while letting me pass a variable to page in a hidden manner.
Here is the current directory part of my apache.conf file:
<Directory /home/tim/example>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ sort-url.php?rt=$1
</Directory>
I currently pass of "https://example.com/CA/Los-Angeles" to a file called "sort-url.php", where I get the "rt" variable, explode it into an array using the "/", and then use the variables like $route_array[0] for "CA" and $route_array[1] = "Los-Angeles". Right now, the user will never see "sort-url.php", so my URLs always look clean. I want to keep this same effect, but convert http to https for all sites.
I found this code to convert to https if I substitute this rewrite rule for the other rewrite rule:
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{SERVER_NAME}/sort-url.php?rt=$1 [R,L]
But, this causes "sort-url.php?rt=CA/Los-Angeles" to show up in the URL. If I get rid of the "sort-url.php in the rewrite rule like this:
RewriteRule ^(.*)$ https://%{SERVER_NAME}/$1 [R,L]
It won't know to route all requests to the sort-url.php file, but it will look like the clean link I want with https.
Am I going about it the wrong way? Is it possible to combine the two rules while maintaining a clean URL?
Thank you in advance,
Tim
ADDITION - Here are my virtual hosts:
<VirtualHost XXX.XXX.XX.XXX:12345>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
<VirtualHost XXX.XXX.XX.XXX:80>
ServerName example.com
Redirect / https://example.com/
</VirtualHost>
<VirtualHost XXX.XXX.XX.XXX:443>
ServerName example.com
DocumentRoot /home/tim/example
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/certs/example.key
SSLCertificateChainFile /etc/ssl/certs/sf_bundle.crt
</VirtualHost>
Enable .htaccess if not already enabled.
Try this code in your DOCUMENT_ROOT/.htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ sort-url.php?rt=$1 [L,QSA]
I suggest suppressing Directory clause (COMMENT), and this in vhosts:
<VirtualHost XXX.XXX.XX.XXX:80>
ServerName example.com
ServerAlias *.example.com
DocumentRoot /home/tim/example
Redirect / https://example.com/
</VirtualHost>
<VirtualHost XXX.XXX.XX.XXX:443>
ServerName example.com
ServerAlias *.example.com
DocumentRoot /home/tim/example
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/certs/example.key
SSLCertificateChainFile /etc/ssl/certs/sf_bundle.crt
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} !-f
RewriteRule ^(.*)$ /sort-url.php?rt=$1 [L,QSA]
</VirtualHost>
Ok, it appears my load balancer configuration (SSL termination on LB, port 80, etc.) was throwing me for a loop and "X-Forwarded-Proto" was the answer I needed. Here is my updated directory part:
<Directory /home/tim/example>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=permanent]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ sort-url.php?rt=$1 [L,QSA]
</Directory>

How go to home page correctly?

I enable mod_rewrite but when I go to home page the browser try download something. When I go to app_dev.php the browser show error:
The requested URL /app_dev.php/ was not found on this server.
My locale host was configurated to web directory.
the output of 'app/console router:debug _welcome' is:
[router] Route "_welcome"
Name _welcome
Path /
Host ANY
Scheme ANY
Method ANY
Class Symfony\Component\Routing\Route
Defaults _controller: Acme\DemoBundle\Controller\WelcomeController::indexAction
Requirements NO CUSTOM
Options compiler_class: Symfony\Component\Routing\RouteCompiler
Path-Regex #^/$#s
my httpd-vhosts.conf:
<VirtualHost *:80>
ServerAdmin myemail#email.com
DocumentRoot "/var/www/symfony/hz.dev/web"
ServerName hz.dev
ServerAlias www.hz.dev
ErrorLog "/var/log/apache2/hz.dev-error_log"
CustomLog "/var/log/apache2/hz.dev-access_log" common
</VirtualHost>
My web/.htaccsess
DirectoryIndex app.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{CONTEXT_PREFIX}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule .? %{ENV:BASE}app.php [L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
RedirectMatch 302 ^/$ /app.php/
</IfModule>
</IfModule>
Try this .htaccess instead. It's very simple, I use it during development.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app_dev.php [QSA,L]
</IfModule>
You should then be able to access Symfony at http://example.com/ without app_dev.php in the URL

RewriteRule to cause subdomain to load another DocumentRoot?

Apache (mostly) noob here... could sure use a little help with what I am trying to do with a RewriteRule in .htaccess:
...to causes URLs using our sharpedge. subdomain to auto-load from the Internet_IE directory - one level deeper than the site root.
I have this in httpd.conf:
[snip]
NameVirtualHost 11.22.33.44
<VirtualHost 11.22.33.44>
Options All +ExecCGI
ServerAdmin hostmaster#ourhost.com
DocumentRoot /var/www/html/ourdomain.com
ServerName ourdomain.com
ServerAlias www.ourdomain.com
DirectoryIndex index.htm index.html index.dna
#---------------------------------
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
</IfModule>
#---------------------------------
</VirtualHost>
<VirtualHost 11.22.33.44>
Options All +ExecCGI
ServerAdmin hostmaster#ourhost.com
DocumentRoot /var/www/html/ourdomain.com
ServerName sharpedge.ourdomain.com
DirectoryIndex index.htm index.html index.dna
#---------------------------------
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
</IfModule>
#---------------------------------
</VirtualHost>
[snip]
...and this in .htaccess (in the site root, here: /var/www/html/ourdomain.com/)
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^sharpedge\.ourdomain\.com$
# years ago this next line was used here, but in httpd.conf: (I don't know what it was supposed to do)
# RewriteRule ^(.+) %{HTTP_HOST}$1 [C]
RewriteRule ^sharpedge\.ourdomain\.com(.*) /var/www/html/ourdomain.com/Internet_IE/$1 [L]
</IfModule>
..but nothing happens from the RewriteRule; it is as if the RewriteRule was not there.
I'd much appreciate any suggestions.
Edits:
I would just change the DocumentRoot to the directory I actually want to serve, but I need to be able to call (include) files from within files in that directory with a prefixing / in the include path, where those files are located in the site root. Those files are also similarly called from other files that are in the site root.
You don't want to put any part of your host in the RewriteRule, but you got the HTTP_HOST right, try:
RewriteCond %{HTTP_HOST} ^sharpedge\.ourdomain\.com$ [NC]
# to prevent looping
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /Internet_IE/$1 [L]
Try changing the !-f and !-d checks:
RewriteCond %{HTTP_HOST} ^sharpedge\.ourdomain\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/Internet_IE/
RewriteRule ^(.*)$ /Internet_IE/$1 [L]