Need Proxy?

BotProxy: Rotating Proxies Made for professionals. Really fast connection. Built-in IP rotation. Fresh IPs every day.

Find out more


How to write regex for apache ProxyPassMatch to reverse proxy API calls

Question

I have an angular 4 web application which is hosted on apache 2.4. The application makes use of an API written in nodejs javascript running over express. Both the website and the API service are running on the same machine but on different ports. The website is on port 80 and the API service is listening on port 9000.

I would like to set up apache to do reverse proxy for all the API calls.

For example, any url that contains /api/ I want it rewritten by apache to point to the API url:port. If I use ProxyPass like the following lines, the redirect works fine:

ProxyPass        "/api/V1/systeminfo" "http://localhost:9000/api/V1/systeminfo"
ProxyPassReverse "/api/V1/systeminfo" "http://localhost:9000/api/V1/systeminfo"

What I do not know how to do, is to use the ProxyPassMatch directive and create a regular expression so that any url that contains /api/ is redirected to http://localhost:9000/api/.....

I tried the following but it does not work:

ProxyPassMatch    "^/api.*$" "http://localhost:9000/$1"
ProxyPassReverse  "^/api.*$" "http://localhost:9000/$1"

Neither does the following:

ProxyPassMatch    "^/.*?/api.*?/v[0-9]+/(.*)$" "http://localhost:9000/$1"
ProxyPassReverse  "^/.*?/api.*?/v[0-9]+/(.*)$" "http://localhost:9000/$1"

Any help would be appreciated. My regex skills are lacking!

Note: obviously 'localhost' can be an IP address or a domain, I am using it in the example for simplicity.

Many thanks!

Edit: I corrected the first example to use .* instead of just * as per Alex's comment.

Answer

I solved the problem. The correct way to do reverse proxy with apache on the above example is the following:

ProxyPassMatch    "/api(.*)" "http://localhost:9000/api$1"
ProxyPassReverse  "/api(.*)" "http://localhost:9000/api$1"

I knew the multiple regex examples I was trying were correct, as I was testing them with https://regex101.com/, but I was hard coding the second part of to a particular route in order to eliminate the issue of the second part being incorrect, but for some reason it does not like that. Once I understood that the (.*) part of the regex is the first capture group and used it as $1 in the second part, it all worked.

I hope I clarified the answer enough and it is useful to someone else.

cc by-sa 3.0