Question

I am creating a reverse proxy with nginx that is being used to proxy between an existing legacy system and a new application based on Rails. We are by default sending all traffic to the Rails site, unless they match certain URLs or if the request body does not contain certain parameters. However, there are cases where the URL matches the legacy conditions, but we need to redirect to the new system if certain parameters are present. So, for example, we have a URL of /index.cfm?fuseaction=search, which would normally be sent to the legacy system, but since it contains fuseaction=search, I need that to redirect to the new system at /search/events. I have written the following configuration.

upstream legacy  { 
    server 10.0.0.1:80;
}

upstream rails {
 server 10.0.0.2:80; 
}

server { 
    listen       0.0.0.0:80; 
    server_name  mydomain.com
    root   /usr/share/nginx/html; 
    index  index.html index.htm; 

    location / { 

         proxy_pass  http://rails; 
         if ($request_body ~* fuseaction(?!=public\.search(_all(_by_type)?)?)) 
            { 
                    proxy_pass http://legacy; 
            } 

         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; 
         proxy_redirect off; 
         proxy_buffering off; 
         proxy_set_header        Host            $host; 
         proxy_set_header        X-Real-IP       $remote_addr; 
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for; 
       } 


    location ~* /(index.cfm|images|uploads|admin|htmlArea|innovastudio|js|scripts|w3c)*$ { 
         proxy_pass  http://legacy; 

         if ($request_body ~* fuseaction=public\.search(_all(_by_type)?)?) 
            { 
                    proxy_pass http://rails/search/events; 
            } 

         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; 
         proxy_redirect off; 
         proxy_buffering off; 
         proxy_set_header        Host            $host; 
         proxy_set_header        X-Real-IP       $remote_addr; 
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for; 
       } 
} 

However, when I try to start nginx, I get the following error:

"proxy_pass" may not have URI part in location given by regular expression, or inside named location, or inside the "if" statement, or inside the "limit_except" block in /etc/nginx/sites-enabled/default:56

I understand what the error is saying, but I am not sure how to fix it. Maybe proxy_pass is not what I need? Maybe I need to use proxy_redirect? Any help on how I can solve this problem is appreciated.

Was it helpful?

Solution 2

In the process of trying to understand this issue, I realized that what I actually needed was to redirect instead of trying to proxy. In addition to many things that I eventually changed, I checked the $args variable instead of $request_body. Here is what the rewrite blocks looked like when I was finished

if ($args ~ fuseaction\=public\.race_search(_all(_by_type)?)?)
{
  rewrite ^(.*)$ /search/events? permanent;
}

if ($args ~ fuseaction\=public\.tools)
{
  rewrite ^(.*)$ /directors? permanent;
}

if ($args ~ fuseaction\=public\.contact)
{
  rewrite ^(.*)$ /contact? permanent;
}

if ($args ~ fuseaction\=public\.spotlight)
{
  rewrite ^(.*)$ /search/events? permanent;
}

if ($args ~ fuseaction\=public\.results)
{
  rewrite ^(.*)$ /search/results? permanent;
}

The first argument matches the entire path, the second tells it what to rewrite to, with the trailing ? to remove any query parameters from the rewrite, and the third to do a 301 (permanent) redirect.

OTHER TIPS

proxy_pass should be fine, but I don't know why it is complaining about that line, is "//rails" definitely an accessible URI?

I would have thought the issue to be related to using $request_body, I would switch to using $args if you know that they are GET parameters that you need to match against.

Something like:

     if ($args ~ "fuseaction(?!=public\.search(_all(_by_type)?)?)" ) 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top