1

I am very new to apache and I have two services one for read and one for writes and both services support same locations. But this routing does not seem to work. Is there anyway I can restrict these based on Http methods

 <VirtualHost *:1000>
     ServerAdmin me@example.com
     DocumentRoot "C:/Apache24/htdocs"
     ServerName localhost:1000
     ErrorLog "logs/example.com-error.log"
     CustomLog "logs/example.com-access.log" common
     ForensicLog "logs/forensic-log.log"
     ProxyRequests Off
     ProxyPreserveHost On
  LogLevel debug
     <Proxy *>
        Require all granted
         
     </Proxy>

     #ReadService only supports GET
     <Location /api/users>
         ProxyPass        http://localhost:5000/api/users connectiontimeout=5 timeout=300
         ProxyPassReverse hhttp://localhost:5000/api/calls
     </Location>
     
     #WriteService anything other than GET
 
     <Location /api/users>
         ProxyPass        http://localhost:7000/api/users connectiontimeout=5 timeout=300
         ProxyPassReverse http://localhost:7000/api/users
     </Location>
     
     
 </VirtualHost>
  • You may want to try using mod_allowmethods. – tinkertwain Oct 8 at 13:28
  • @tinkertwain thanks for the suggest. but it does not seem to work. Last location match does not allow to pass through other location. In above conf, only POST gets successful and GET is rejected. – Sameer Oct 8 at 13:56
  • hmm. How about trying mod_proxy_balancer with mod_headers. Use %{REQUEST_METHOD} to set a Header and then route using balancer. – tinkertwain Oct 8 at 14:31
  • @tinkertwain thanks I will try that out. Though I could achieve the routing I wanted using RewriteCond but not sure how it plays out in load balancer situation. Also there is recommendation to favor ProxyPass instead of RewriteCond when possible, so will resort to using that only when I can't see any options available. :) – Sameer Oct 8 at 14:36
  • @tinkertwain can you let me know how to route based on header using balancer – Sameer Oct 8 at 16:23
0

I haven't tested, but you can try something like below. You'll need to tweak with the conditional setting of ROUTEID. If the header does not work, you will have to try cookies as outlined in various examples.

<IfModule mod_headers.c>
    <If "%{REQUEST_METHOD} =GET">
        Header set ROUTEID: "1"
    </If>
    <Else>
        Header set ROUTEID: "2"
    </Else>
</IfModule>

ProxyPass        "/api/users" "balancer://mycluster"
ProxyPassReverse "/api/users" "balancer://mycluster"

<Proxy "balancer://mycluster">
    BalancerMember "http://localhost:5000/api/users" route=1
    BalancerMember "http://localhost:7000/api/users" route=2
    ProxySet stickysession=ROUTEID
</Proxy>

Let us know how it goes.

| improve this answer | |
  • Thanks for putting this out! Could not edit the answer as it has complaining edit should be at least 6 chars. <If "%{REQUEST_METHOD} == 'GET' "> But fixing that it did not work. load balancer picks routes in pretty much round robin fashion. So I get success, and method not allowed error consecutively – Sameer Oct 9 at 5:22
  • Also stickysession seems to only work with cookies or querysrtring and not with header stickiness details pache. Not sure how to add a querystring though – Sameer Oct 9 at 7:23
  • 1
    Let me create an environment similar to yours and test. Stay tuned. – tinkertwain Oct 9 at 14:48
0
RewriteCond %{REQUEST_METHOD} ^(GET)$
RewriteCond %{REQUEST_URI} ^/api/users(.*)$
RewriteRule ^/api/users(.*)$  http://localhost:5000/api/users$1  [P]

RewriteCond %{REQUEST_METHOD} !^(GET)$
RewriteCond %{REQUEST_URI} ^/api/users(.*)$
RewriteRule ^/api/users(.*)$  http://localhost:7000/api/users$1  [P]
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.