nginx map指令:为什么只允许在http级别?

时间:2014-12-08 13:11:58

标签: nginx

nginx map中有一个非常有用的指令。

但是只能在http级别使用它(请参阅此处的文档http://nginx.org/en/docs/http/ngx_http_map_module.html#map)。

例如我定义了server,我想使用$url变量在此服务器中使用一些条件重定向。在server中使用此指令会非常方便,但这是不可能的。的为什么吗

是的我也可以在http级别上执行此操作,但server级别可能会定义不同的http,我希望将此条件保留在server内他们被定义为。

4 个答案:

答案 0 :(得分:5)

很旧的帖子,但我真的想给黑暗带来一些光明。答案本身很简单。

DR;TL NGINX 中的变量始终是全局的,并且一旦定义就可以从配置中的任何位置访问。因此,在 serverlocation 块中定义地图没有任何意义。

map 创建一个新变量,其值取决于第一个参数中指定的一个或多个源变量的值。

示例配置:

map $host $myvar {
example.com "test";
foo.com     "for";

}

因为 NGINX 中的变量总是全局的,并且一旦定义就可以在配置中的任何其他地方使用。因此,将地图移动到某个位置或服务器块没有任何意义。我们的 map 指令有趣的事实是变量 myvar 何时会收到其值或何时会被赋值?

一旦变量将在您的配置中使用,map 就会将值分配给变量

这意味着您可以在 http 上下文中定义映射,但该值将在您访问 nginx 配置中的 $myvar 时分配。

回到你的问题: 由于 NGINX 变量始终是全局的,因此每个 map 块都有一个 server 是有意义的,因为它们无论如何都是全局的。

答案 1 :(得分:0)

我认为如果您使用map进行重定向-在nginx配置中这不是好方法。也许重写可以解决您的问题? SMT。像https://www.nginx.com/blog/creating-nginx-rewrite-rules/

答案 2 :(得分:-1)

我认为这实际上是关于开发人员构建模块的内容与实际如何

我查看了源代码的内幕,为了更清晰,我建议这样做。我还使用以下指南来了解该代码的含义:https://www.evanmiller.org/nginx-modules-guide.html

ngx_http_map_module 的源代码是 here

如果我查看定义模块指令static ngx_command_t ngx_http_map_commands[] = {...},特别是以下代码段:

 { ngx_string("map"),
  NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2,
  ngx_http_map_block,
  NGX_HTTP_MAIN_CONF_OFFSET,
  0,
  NULL },
  1. 第一个参数只是定义了指令字符串
  2. 第二个参数很有趣。它的 type 字段是:
<块引用>

type 是一组标志,指示指令在哪里合法以及指令需要多少个参数。

我们在这里看到定义的字段是 NGX_HTTP_MAIN_CONF,这使得指令在 http 级别有效。但是我们没有看到相应的标志 NGX_HTTP_SRV_CONF - 用于 serverNGX_HTTP_LOC_CONF 用于 location 级别。

因此,ngx_http_map_module 的这种特定实现仅适用于 http 级别。

现在,它可以在服务器/位置级别工作吗?理论上应该。但它需要在源代码中做出一些贡献。如果你认为它会成为一个有用的功能,请贡献 :)

答案 3 :(得分:-2)

可以使用map的范围在nginx源代码中修复。以下是ngx_http_map_module.c的代码的一部分。您可以看到map只能在NGX_HTTP_MAIN_CONF中使用,仅表示http级别。

static ngx_command_t  ngx_http_map_commands[] = {                                                                                                      

    { ngx_string("map"),                                                                                                                               
      NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2,                                                                                                
      ngx_http_map_block,                                                                                                                              
      NGX_HTTP_MAIN_CONF_OFFSET,                                                                                                                       
      0,                                                                                                                                               
      NULL },