Apache Rewrite rule with decode url - apache

I have a basic rewrite rule
RewriteRule ^/v1/(.*)$ http://127.0.0.1:8000/v1/$1 [P,L,QSA]
Rewrite is working fine, but I have a issue with a request which is coming to the apache.
https://example.com/v1/test/bd95f52d72942198eb84e1b6998a6259/phone_numbers/%2B61180087654
Apache is decoding this URL to
https://example.com/v1/test/bd95f52d72942198eb84e1b6998a6259/phone_numbers/+61180087654
I want apache should pass the same request to my code. I don't want + with number. What should I change to get the expected result.
Thanks

Unless you have some other reason to use rewrite, try this instead of RewriteRule ...
ProxyPass /v1/ http://127.0.0.1:8000/v1/ nocanon
ProxyPassReverse /v1/ http://127.0.0.1:8000/v1/
(ProxyPass should also have performance benefits over rewrite, in some cases)

Related

How to add a trailing slash to this one particular url in apache

When a user types in www.example.co.uk/beta, I want the traffic to be sent to www.example.co.uk/beta/. But only for that url ie, when the url ends /beta.
How do I accomplish this in apache?
I have tried:
<Location /beta>
DirectorySlash Off
ProxyPass http://testserver.co.uk
ProxyPassReverse http://testserver.co.uk
</Location>
With no success
Please note the proxypass directives are for my reverse proxy
Maybe it would be easier using .htaccess?
RewriteEngine On
RewriteRule beta$ /beta/ [NC]
I offer no promises that this won't loop, but it's worth a try. Add a [R=301] flag if you want to inform the visitor/search engine that they should use the trailing-slash version. Add a ? after /beta/ if you want to suppress any Query String that comes with it.

ProxyPass and RewriteRule [P] acting differently in regard to http/https

I have a working configuration that looks like
ProxyPass /roundcube protocol://127.0.0.1:8080/roundcube
ProxyPassReverse /roundcube protocol://127.0.0.1:8080/roundcube
when I go to
http://www.example.com/roundcube
or
https://www.example.com/roundcube
both or properly proxied to the server on 127.0.0.1:8080, as expected.
However, I would like to have more control over when the proxying happens, so I would like to use mod_rewrite's [P] option rather than the ProxyPass directive shown above. I tried the following:
RewriteEngine On
RewriteRule ^/roundcube$ /roundcube/ [R]
RewriteRule ^/roundcube/(.*) protocol://127.0.0.1:8080/roundcube/$1 [P]
ProxyPassReverse /roundcube protocol://127.0.0.1:8080/roundcube
With that configuration, when I go to
http://www.example.com/roundcube
the request proxies correctly as expected.
BUT when I go to
https://www.example.com/roundcube
the request 404's.
So my question is, why does the mod_rewrite proxy not work the same way as the ProxyPass version, in regard to both http and https requests? My two examples above should be functionally equivalent based on my understanding, but that does not seem to be the case. What am I missing? I haven't been able to track down any documentation that would explain this. Thanks!
Although it might be too late, I'm posting this answer in case someone comes to this page with the same problem.
The syntax for ProxyPass is different from that of RewriteRule. In RewriteRule, in order to refer to the protocol, you should use %{SERVER_PROTOCOL} as explained at http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html

Proper ProxyPassReverse with rewrite

I'm trying to do something similar to the Coral cache.
For example if a client/browser looks up google.com.foo.com, it gets passed to a proxy by apache and serves a proxied/cached version of google.com to the client/browser.
My configuration for this so far is this:
ProxyRemote * http://localhost:8080
RewriteEngine on
RewriteCond %{http_host} ^(.*)\.foo\.com [NC]
RewriteRule ^(.*)$ http://%1$1 [P]
This actually works well as long as the website does not redirect to another site, but as soon as it redirects, it "bursts" out of the proxy and simply goes to the redirected site (oviously).
ProxyPassReverse should, as far as I understand it, prevent this, but I simply can't piece together how my ProxyPassReverse directive should look. After all, the hostname could be everything in this case...
Is this even possible?

How to rewrite urls that go through apaches mod_proxy

I have configured my apache 2.2 server as a simple forward proxy using mod_proxy and mod_proxy_http.
When the client requests a URL of the following format:
http://specific.host.com/specific?specificarg1=(.+)&specificarg2=(.+)&specificarg3=specificvalue
to be requested in a rewritten form where the values for specificarg1 and specificarg2 get replaced by values defined in my server config.
It would be also possible not to use regex but to rewrite a specific url to another specific url, but i would prefer with regex matching.
So after reading the documentsations for mod_rewrite, mod_proxy and so I tried something like the following to get some sort of rewrite working at all:
RewriteRule .* http://www.google.com/ [P,L]
just like that in the server config, nothing gets rewriten when surfing over the proxy
<VirtualHost *:80>
ServerName domain-i-tried-to-surf-to.com
`RewriteRule .* http://www.google.com/ [P,L]
</VirtualHost>
no luck either
ProxyPass(Reverse) / http://www.google.com
ProxyPass(Reverse) /path/i/tried/to/surf/to http://www.google.com
no luck with that too
ProxyRemote * http://www.google.com
no luck as well
I also tried to put rewrite rules into proxymatch directives but I am just unable to rewrite a url. Can somebody point me in the right direction?
You first need to add a RewriteEngine on statement at the very beginning to even get mod_rewrite to process any rules.

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.