Apache Reverse Proxy - Stop Trailing Slash Redirection - apache

I'm migrating a site running static HTML on a Sun One (iPlanet) 6.1 to a Drupal site on Apache.
There is a requirement to keep the old server running and serving old content until it can be moved into Drupal. I figured the easiest way is to have some reverse proxy entries in Apache that point to this old content.
Here is what I have in the httpd.conf at the server context level.
RewriteEngine On
RewriteLogLevel 9
RewriteLog "/var/log/httpd/rewrite_log"
RewriteRule offices/ist/?(.*)$ http://oldserver/offices/ist/$1 [P]
<Location /offices/ist/>
ProxyPassReverse /
</Location>
When I make a request like this everything works OK.
http://newserver/offices/ist/somedir/
If I make the same request (without the trailing slash) it 302 redirects using the old server's name.
http://newserver/offices/ist/somedir => Redirect to http://oldserver/offices/ist/somedir/
Shouldn't Apache catch this redirect before it's sent back to the client?
Can I get Apache to rewrite these requests before they're sent to the old server?

I'm not sure, but may be (.*) it too greedy.
I had a look at the Apache mod_rewrite but I did not find an example with ?.
I would suggest to try it without the /? or with something similar to the Apache mod_proxy example.
ProxyPass /foo http://foo.example.com/bar
ProxyPassReverse /foo http://foo.example.com/bar

The problem is a result of Sun One's redirection headers.
Proxying Apache to another Apache server, the problem goes away. Apache is able to catch the redirection sent by the backend Apache server before it is sent to the client.

Related

Redirection https to https within same Apache

I have a requirement where I have to redirect my hostname to particular application which is again hosted on same Apache. Let's take an example, When I hit on host(https://domain1.example.com), It should internally redirect me to Apache Web Application (https://domain1.example.com/application1) without changing the browser URL.
I am not sure how to achieve SSL to SSL redirection. Thanks in Advance..!!!
This should work. This will redirect all incoming urls that are going to domain1.example.com/ to domain1.example.com/application1
RewriteEngine On
RewriteCond %{HTTP_HOST} ^domain1.example.com$
RewriteRule ^$ https://domain1.example.com/application1 [L,R=301]
If without changing browsing URL is your goal then PROXY is your way.
Put following in your apache vhost or global file,
ProxyPass https://domain1.example.com/ https://domain1.example.com/application1
ProxyPassReverse https://domain1.example.com/ https://domain1.example.com/application1
PS shibboleth has nothing to do with this, at least you have not mentioned any case.
EDIT
ProxyPass should come to virtural host not in location
Ideally all the location tag should be out of virtual host

Apache http server rewrite or redirect

I have a functioning environment with an apache http server (load balancer) with a cluster of tomcat servers at the back end. I am stumped by one problem though, I am not able to redirect or rewrite the request url to what I need. for example,
request url - http://www.yyy.com
i would like to redirect or rewrite it to
http://www.yyy.com/mycontext
I tried redirect and rewrite with no luck.
RewriteRule ^/$ http://www.yyy.com/mycontext/ [L] - Error (can't fine the url)
AND then I tried this,
Redirect / http://www.yyy.com/mycontext/ - this results in the following,
http://www.yyy.com/mycontext/mycontext/mycontext/mycontext/mycontext/........... repeats.
I am not able to figure out the right condition statement. I tried using the server variables to write a rewritecond but I am doing something wrong and it gets ignored.
Any assistance is appreciated. I have not had much experience in this area.
And this ProxyPass / http://www.yyy.com/mycontext/ is in the config for www.yyy.com?
yes in the virtualhost
Not sure how your load balancer could ever possibly work. You are proxying requests back to yourself, and it's going to instantly run out of threads because each proxied request runs on its own thread.
Request for / arrives at your virtual host
ProxyPass reverse proxies it to http://www.yyy.com/mycontext/, which is itself
Request for /mycontext/ arrives at your virtual host
ProxyPass reverse proxies it to http://www.yyy.com/mycontext/mycontext/
Request for /mycontext/mycontest/ arrives at your virtual host
ProxyPass reverse proxies it to http://www.yyy.com/mycontext/mycontext/mycontext/
etc.
I think what you're probably looking for is:
RewriteCond %{REQUEST_URI} !^/mycontext/
RewriteRule ^(.*)$ /mycontext/$1 [L]
But this has nothing to do with your load balancer or your tomcat server.

Tomcat, Mod_rewrite, Mod_proxy: how do I keep the original URI path in a proxied request?

I'm using the following configuration to proxy requests and rewrite urls from Apache to Tomcat using mod_rewrite, mod_proxy.
# In apache virtual hosts
ProxyRequests Off
ProxyPreserveHost On
...
# In .htaccess file
#forward non-resource URL to jsp
RewriteRule ^([^\.]+)/?$ http://localhost:8080/mycontext/$1.jsp [P]
My question: is it possible to instruct Tomcat to keep the original URI so that I can read it using a request.getRequestURI()? Is this configuration possible or do I have to resort to mod_jk or some other proxy Connector?
The host name is retained currently... not the request path. I'm also using Apache 2.2 and Tomcat 6.
A not too cumbersome solution:
RewriteRule ^([^\.]+)/?$ http://localhost:8080/mycontext/$1.jsp&_requri_=%{REQUEST_URI}
Then read the request uri from the _requri_ query parameter.
If there's a better way, please let me know.

Correctly setup Tomcat behind Apache with mod_proxy_ajp

I've been tinkering with Apache + Tomcat so that I can serve multiple tomcat apps (in different machines) through apache (clean & crisp urls rock). I've succesfully configured mod_proxy_ajp & mod_rewrite to the point where I can serve two tomcat apps in different machines with almost no troubles.
The only issue I've found is that one of the apps (which I'm developing in Struts2) has a lot of links and forms, which are generated with <s:a />, <s:url /> and <s:form /> tags. The urls generated by these tags generally are like this:
/WebApp/path/to/some.action
Thanks to the magic of ModRewrite, this is generally not a big issue and hyperlinks poiting to such urls are quickly rewriten & redirected to /app/path/to/some.action (although I do get tons of 302 responses).
The real problem occurs when performing POST requests. As you all might know, I cannot redirect POST requests with mod_rewrite... so in the end... all of my POST requests don't work because mod_rewrite redirects to the correct url but as a GET request.
I have already read a bit about mod_proxy_html and how it can help me rewrite the urls returned by the Tomcat web application... but it feels troublesome.
This is my current apache configuration:
## HACKING BEGINS RIGHT HERE
# cookies
ProxyPassReverseCookiePath /WebApp /app
# this is for CSS, IMGs, JS and redirecting urls with /WebApp*
RewriteRule ^/WebApp(.*)$ /app$1 [R,L]
<Location /app>
ProxyPass ajp://localhost:8009/WebApp
ProxyPassReverse ajp://localhost:8009/WebApp
Order allow,deny
Allow from all
</Location>
# the other app
ProxyPassReverseCookiePath /WebApp2 /other
<Location /other>
ProxyPass ajp://200.9.4.6:8009/WebApp2
ProxyPassReverse ajp://200.9.4.6:8009/WebApp2
Order allow,deny
Allow from all
</Location>
There must be a solution to my POST requests problem... Any ideas? Can I somehow configure something that will allow Struts2 to output correct urls?
Thanks for your help.
There may be a couple ways to go about this.
If you are able to deploy your app to Tomcat under the same name that you are using in the URL, that would be the easiest. So your application app would be /webapps/app[.war] instead of /webapps/WebApp, this would avoid the rewrite altogether.
Otherwise, the following should work, and should go before your current rewrite rule. The [PT] should allow Apache to still proxy the request (this works when using mod_jk, not sure I've used/tested it with mod_proxy_ajp):
RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^/WebApp(.*)$ /app$1 [PT,L]
Once your bean has processed the POST request, you could then send the request to a URL that would be redirected. In the end, the POST URL doesn't matter to the user, so it doesn't have to be a pretty URL.
Edits Below:
I saw on the Apache mod_proxy, that ProxyPassReverse should work with the [PT] flag. And I was able to replicate the issue you're having, and the below config worked for me with a basic JSP page with a form that posted to another JSP page.
<VirtualHost *:80>
ServerName localhost
RewriteEngine On
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule /WebApp/(.*) /app/$1 [R,L]
RewriteCond %{REQUEST_METHOD} POST
RewriteRule /WebApp/(.*) /app/$1 [PT,L]
<Location /app>
ProxyPass ajp://localhost:8109/WebApp
ProxyPassReverse ajp://localhost:8109/WebApp
</Location>
</VirtualHost>
This is a problem with the webapp setup; there may be a way to work around it in httpd config, but it's cleaner to fix the original inconsistency vs. hacking around it.
Also worth mentioning that Struts is trying to help you by giving you context-aware, non-relative URLs; if you just make the paths match, you can rely on that (instead of fighting it...).
So, just deploy the Struts webapp to /app and /other, instead of /WebApp and /WebApp2. (There might be some reason this isn't possible -- like if you don't actually control those other servers -- but it sounds like that doesn't apply).
I would avoid URL rewriting. It just opens cans of worms like this, makes you look into mod_proxy_html, etc, which of course are just yet more worms. Instead just deploy your apps in Tomcat with real URLs you can live with as being visible externally.

Configuring mod_rewrite and mod_jk for Apache 2.2 and JBoss 4.2.3

My problem is as follows: I have JBoss 4.2.3 application server with AJP 1.3 connector running on one host under Windows (192.168.1.2 for my test environment) and Apache 2.2.14 running on another FreeBSD box (192.168.1.10). Apache acts as a "front gate" for all requests and sends them to JBoss via mod_jk. Everything was working fine until I had to do some SEO optimizations. These optimizations include SEF urls, so i decided to use mod_rewrite for Apache to alter requests before they are sent to JBoss. Basically, I nedd to implement 2 rules:
Redirect old rules like "http://hostname/directory/" to "http://hostname/" with permanent redirect
Forward urls like "http://hostname/wtf/123/" to "http://hostname/wtf/view.htm?id=123" so that end user doesn't see the "ugly" URL (the actual rewrite).
Here is my Apache config for test virtual host:
<VirtualHost *:80>
ServerAdmin webmaster#dummy-host.example.com
DocumentRoot "/usr/local/www/dummy"
ServerName 192.168.1.10
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule /directory/(.*) /$1 [R=permanent,L]
RewriteRule ^/([^/]+)/([0-9]+)/?$ /$1/view.htm?id=$2
</IfModule>
JkMount /* jsp-hostname
ErrorLog "/var/log/dummy-host.example.com-error_log"
CustomLog "/var/log/dummy-host.example.com-access_log" common
</VirtualHost>
The problem is that second rewrite rule doesn't work. Requests slip through to JBoss unchanged, so I get Tomcat 404 error. But if I add redirect flag to the second rule like
RewriteRule ^/([^/]+)/([0-9]+)/?$ /$1/view.htm?id=$2 [R,L]
it works like a charm. But redirect is not what I need here :) . I suspect that the problem is that requests are forwarded to the another host (192.168.1.2), but I really don't have any idea on how to make it work. Any help would be appreciated :)
The reason your second rewrite rule doesn't work is that you use the '?' in your URI definition and the URI definition never contains the separator '?'.
So simply use the rewrite rules without it. eg.
RewriteRule ^/([^/]+)/([0-9]+)/$ /$1/view.htm?id=$2 [R,L]
Simply, doesn't works because the first RewriteRule has the [L] at the end, which means is the last rule to process.