7

I need to redirect the traffic to one backend or another according to the user-agent. Is that the right thing to do ?

server {
    listen      80;
    server_name my_domain.com;

    if ($http_user_agent ~ iPhone ) {
        rewrite     ^(.*)   https://m.domain1.com$1 permanent;
    }
    if ($http_user_agent ~ Android ) {
        rewrite     ^(.*)   https://m.domain1.com$1 permanent;
    }
    if ($http_user_agent ~ MSIE ) {
        rewrite     ^(.*)   https://domain2.com$1 permanent;
    }
    if ($http_user_agent ~ Mozilla ) {
        rewrite     ^(.*)   https://domain2.com$1 permanent;
    }
}
Luc
  • 518
  • 3
  • 5
  • 20

2 Answers2

14

If you're using 0.9.6 or later, you can use a map with regular expressions (1.0.4 or later can use case-insensitive expressions using ~* instead of just ~):

http {
  map $http_user_agent $ua_redirect {
    default '';
    ~(iPhone|Android) m.domain1.com;
    ~(MSIE|Mozilla) domain2.com;
  }

  server {
    if ($ua_redirect != '') {
      rewrite ^ https://$ua_redirect$request_uri? permanent;
    }
  }
}
kolbyjack
  • 7,854
  • 2
  • 34
  • 29
  • Nice - that's much more elegant. – Shane Madden Sep 28 '11 at 19:56
  • 1
    Thanks! nginx's map module doesn't often get the attention it really deserves. – kolbyjack Sep 28 '11 at 19:59
  • The user agent for Android contains both 'Android' and 'Mozilla'. Will both checks be done or does the process exit just after the first rewrite ? – Luc Sep 29 '11 at 09:05
  • I'm not positive, but I would guess the regex entries will be checked in order and the first match used. That's how regex location selection is done, so it will probably be the same for a map. – kolbyjack Sep 29 '11 at 10:57
  • ok, thanks. In the case of the multiple "if" I used at the beginning, can several be executed or as soon as a rewrite is done the process ends ? – Luc Sep 29 '11 at 11:26
  • With your original ifs, having that 'permanent' flag on the rewrite statements should immediately end rewrite processing (and request processing, actually) as soon as an if matches and return the redirection immediately. – kolbyjack Sep 29 '11 at 11:56
1

Yup, that'd be the way to do it. If your patterns are going to stay that simple, you can probably combine them to reduce the volume of expression comparisons:

if ($http_user_agent ~ (iPhone|Android) ) {
    rewrite     ^(.*)   https://m.domain1.com$1 permanent;
}
if ($http_user_agent ~ (MSIE|Mozilla) ) {
    rewrite     ^(.*)   https://domain2.com$1 permanent;
}
Shane Madden
  • 112,982
  • 12
  • 174
  • 248