Apache ProxyPass error - apache

I have to redirect all apache requests on 80 to tomcat on 8080, except one path.
So, if a receive http://example.com/anything --> tomcat:8080.
But, if the url is that: http://example.com/site --> apache should serve and no redirect is needed.
Currently, there is a folder named site inside /var/www/html/.
This is my current configuration file:
site.conf (this file contains only the following and is inside the conf.d folder)
<LocationMatch "/*">
Allow from all
ProxyPass /site !
ProxyPass http://127.0.0.1:8080
ProxyPassReverse http://127.0.0.1:8080
</LocationMatch>
I think this is a simple thing to accomplish with apache, but I have tried everything that I could find and I am still getting the error:
ProxyPass|ProxyPassMatch can not have a path when defined in a location.
The thing is that the root website is running on tomcat, but the other runs on apache (the one that I called site in this question).
If anyone can help, I appreciate.
Thanks!
Update 1 - 09/06/2017
I get it to work if I remove the LocationMatch and put the ProxyPass
direct in the .conf file:
ProxyPass /site !
ProxyPassReverse /site !
ProxyPass / http://127.0.0.1:8080
ProxyPassReverse / http://127.0.0.1:8080
But, I would like to know, why is that? What is the impact of putting this directives outside the LocationMatch tag? And, most important, why I cannot accomplish the same result using the LocationMatch?

I think the error is pretty clear:
ProxyPass|ProxyPassMatch can not have a path when defined in a location.
According to the documentation, inside a context block like Location or LocationBlock the ProxyPass directive does not accept a path:
When used inside a <Location> section, the first argument is omitted and the local directory is obtained from the <Location>. The same will occur inside a <LocationMatch> section; however, ProxyPass does not interpret the regexp as such, so it is necessary to use ProxyPassMatch in this situation instead.
You're getting the error because you were trying to use a path:
ProxyPass /site !
You could try to resolve this in theory by using multiple <Location> sections, like this:
<Location />
ProxyPass http://backend/
</Location>
<Location /site>
ProxyPass !
</Location>
The ordering of these sections is important.
Your solution of using ProxyPass directives outside of a LocationMatch block is probably the simplest solution.
As a side note, your LocationMatch directive is incorrect. The argument to LocationMatch is a regular expression, and /* would only match URLs consisting only of / characters. That is, it would match / or // or /////////, etc. I think you really meant /.*. The * in a regular expression means "the previous character, zero or more times".

Related

ProxyPass Exclude path

i configured an apache proxy to forward all calls to another web server. I need to exclude the path http://my-server/{var1}/api/{all-path} (where var1 is variable) from this rule.
How can I do?
Thanks
I tried with:
ProxyPassMatch ^/(.*)/api/(.*)$ !
ProxyPass / http://127.0.0.1:8080/
but not working.
I'd say you need a negative lookahead in your matching pattern and only a single proxy directive:
ProxyPassMatch ^/[^/]+/(?!api/) http://127.0.0.1:8080/
That should match any path starting with something and a following slash, followed by anything that is NOT "api/".

ProxyPass ! directive not working

I am in the middle of migrating a server and my old virtual host config was like this
ProxyPass /images !
ProxyPass / ajp://domain.tld:8010/ nocanon
It passes ok to Tomcat but the ! directive is being ignored. There are no errors thrown. What might be causing this?
If the /images rule matches but the path is not valid, e.g. cannot be found, Apache will try the next rule.
Only if all other rules are failing too, the first matched rule is used (and the corresponding error is shown, e.g. 404 instead of proxy error).

Apache as proxy with "catch-all"

I want to have Apache proxy to different servers and also have a "catch everything else that doesn't fit" to a server.
I want the following cases where ProxyPass is configured in the proxy's Apache conf file:
ProxyPass / - The "catch-all" where everything else that doesn't fit will go here
ProxyPass /sub1 - going to /sub1 takes me to sub1.domain.com...
ProxyPass /sub2 - going to /sub2 takes me to sub2.domain.com...
I tried the following:
<Location /sub1>
ProxyPass http://sub1.domain.com/
</Location>
<Location /sub2>
ProxyPass http://sub2.domain.com/
</Location>
<Location />
ProxyPass http://sub1.domain.com/
</Location>
This doesn't seem to work as everything defaults to <Location />.
I tried using LocationMatch and wasn't successful in getting sub1 or sub2 to return content. Referred from here: https://serverfault.com/questions/591591/apache-locationmatch-regex-behaviour-does-not-seem-correct
With the above LocationMatch, the headers were working but no content was returned. Going to /A or /B resulted to "Not found".
Does anyone know how I can get this working for Apache or is it even possible?
Try proxypassmatch instead of location directive.

How to server static files + proxy context

I am wondering how to configure my httpd server to serves the following pages:
My need is to serve static content located in my /var/www/static when url is /context/static and to proxy the remaining to a tomcat server
In this order:
/context/static/* --> files served by httpd
/context/* --> resources served by tomcat
I have tried to rewrite /context/static/* to a folder pointing to my /var/www/static and added the ProxyPath directive for the remaining but I can't get it working.
What are the best practices and how to achieve that ?
Thanks in advance
Well, in fact it is quiet easy...
Having such folders configured:
/var/www/static/
|- css/*
|- js/*
\ medias/*
The following httpd configuration will redirect static/* to the /var/www and the rest will be proxied
# first rewrite for statics
RewriteEngine On
RewriteRule ^/context/static/(.+)$ /static/$1
# then proxy remaining...
ProxyPass /context http://127.0.0.1:8080/context
ProxyPassReverse /context http://127.0.0.1:8080/context
I've found the following approach that works and is quite general. (4/12/2018)
Location/Proxypass expressions always take priority over any other location block, so you have to Exclude the paths that you don't want to be proxied. the "?!" does that in the regex. Since static content is, um, static, it is not so bad to require that the apache configuration be updated if another directory is needed to be served directly for a different media type.
The following was taken from a server that was proxying a Python Flask application.
<LocationMatch "^/(?!js|css|media)" >
ProxyPass http://127.0.0.1:5000
ProxyPassReverse http://127.0.0.1:5000
</LocationMatch>
<Location "/">
Require all granted
</Location>
Both of the existing answers rely on Regular Expressions. While they work, it is possible to do this without such complicated constructs. ProxyPass can take "!" as a second parameter, in which case it doesn't proxy the matching URL. For example
ProxyPass /context/static/ !
ProxyPass /context http://127.0.0.1:8080/context
ProxyPassReverse /context http://127.0.0.1:8080/context
or, with multiple exclusions,
ProxyPass /js !
ProxyPass /css !
ProxyPass /media !
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
These exceptions need to come before the more general rule in order to take precedence.
Thanks to freenode user "thumbs" in #httpd.

Stuck with apache,mod-ajp weird redirection

hi all i have a redirection problem with mod ajp, that it always adds the application name before the desired page, for example:
if i requested the page:
http://myapp.com/mypage
it is converted to
http://myapp.com/myapp/mypage, and i get a 404 error
i don't know why such behaviour occurs, this is the configuration:
<Proxy *> AddDefaultCharset Off Order deny,allow Allow from all </Proxy>
ProxyPass / ajp://127.0.0.1:8009/myapp/
ProxyPassReverse /
ajp://127.0.0.1:8009/myapp/
ProxyPassReverseCookiePath /myapp/
this strange redirection occurs exaclty when an inside application redirection occurs meaning after registration the user is redirected(application side) to the login page using response.sendRedirect , any ideas ?
The ProxyPassReverse directive is possibly wrong. I guess it should be
ProxyPassReverse / http://myapp.com
See The Mystery of ProxyPassReverse.
You can resolve problems like this with this approach:
Install LiveHTTPHeaders and enable it
Access the application directly
Access the application via your reverse proxy
Compare the HTTP traffic of the previous cases
Most likely your application redirects user using relative URL. However your ProxyPassReverse only rewrites absolute versions. The relative version gets redirected with the page load according to your ProxyPass rule, causing the doubling of the path.