12

In nginx I can use set to define a variable, but is it possible to define a default?

e.g.

set $foo bar if $foo is not defined
Howard
  • 2,135
  • 13
  • 48
  • 72

4 Answers4

19
map $foo $new_foo {
    default  $foo;
    ''       bar;
}

or

if ($foo = '') {
    set $foo bar;
}
VBart
  • 8,309
  • 3
  • 25
  • 26
  • 4
    Using the if method I got `using uninitialized "foo" variable` warning in my log. Can I avoid it? – hiroshi Feb 18 '18 at 06:04
0

map $foo $foo {} gives me cycle while evaluating variable "foo" error message in the nginx error log.

Now,

map $foo $foo_with_default {
  default 'bar';
  ~. $foo;
}

does work and it's also semantically correct: if the regular expression matches anything then the result will be $foo if it doesn't then there are no characters to match so it becomes bar. I do not think the configuration syntax for nginx makes it possible to distinguish between an empty string and an undefined variable. I believe you need openresty and a nil check for that.

chx
  • 1,705
  • 2
  • 16
  • 25
0

As of the current Nginx versions in 2023 (v1.20+), the above approaches do not seem to work and all create either a warning or failure to start up in my usage when adding these into nginx.conf.

In my case I needed to overwrite the Host header, conditionally, in an included general configuration file shared by many sites, whilst only setting that for the sites that needed it.

In this case, in your http block (e.g. nginx.conf):

map '' $proxied_host {
  default '';
}

map "$proxied_host" $resolved_host {
  default $host;
  ~. $proxied_host;
}

and in the included configuration file in every location:

proxy_set_header            Host $resolved_host:$server_port;

then in the sites that need to overwrite it, in the location block:

set $proxied_host your.example.com;

This is the only way I found to avoid:

  1. Floods of warnings in error.log saying using uninitialized "proxied_host" variable
  2. Errors related to using uninitialized variables in the map like nginx: [emerg] unknown "proxied_host" variable
  3. Errors relating to cycles in variables cycle while evaluating variable "proxied_host"
NGT
  • 1
0

This also works:

map $foo $foo {
    default '';
}
map $foo $bar {
    default '';
    'bar' 'bar';
    'foo' $foo;   <----- nginx: [emerg] unknown "foo" variable
}

map $foo $foo {} solves error nginx: [emerg] unknown "foo" variable - just doesn't look right - but it works.

Note: map must be in block http {} (nginx/conf.d)

hrvoj3e
  • 133
  • 1
  • 6