dynamicproxy_pass与地图和正则expression式

我试图让下面的模式工作。 我需要在我的客户端代码中指定一个dynamicpath,以便能够切换到几个预定义的主机。 我通过将他们的别名附加到/ fwd / url来映射这些主机。 别名映射到nginx中的真实服务器,如下所示:

map $uri $repoUrl { default invalid; ~^/fwd/foo/.* http://foo.domain.nl/; ~^/fwd/bar/.* http://bar.domain.nl/; } 

然后在服务器configuration部分,我捕捉任何以fwd开头的url,并应用映射的别名值。 别名之后的url的其余部分也应附加到url。

 location /fwd/(\w+)/(.*)$ { add_header X-FwdHost "$repoUrl$2"; add_header Access-Control-Allow-Origin "*"; proxy_pass "$repoUrl$2"; proxy_redirect off; access_log on; } 

如果我testing这个:

 curl -i http://localhost:8080/fwd/foo/something/else 

我得到:

 X-FwdHost: http://foo.domain.nl/ 

但是,当从正则expression式testing结果时,我得到:

  $1: foo $2: something/else 

所以整体来看,它似乎在工作。 正则expression式似乎是好的,但我不能把它连接成一个string? 任何想法还是有一个更容易/更好的方式来实现相同?

[编辑]

我发现使用一个名为forward的查询参数可能更简单。 首先将查询参数映射到正确的主机:

 map $arg_forward $repo_forward { default http://invalid_repo_forward/; foo http://foo.domain.nl/; bar http://bar.domain.nl/; 

}

然后使用要转发的path中的参数:

 location /fwd/ { add_header X-FwdHost $repo_forward; add_header Access-Control-Allow-Origin "*"; proxy_pass $repo_forward; proxy_redirect off; access_log on; } 

我期望和url一样:

 http://localhost:8080/fwd/?forward=foo 

以导致:

 http://foo.domain.nl/ 

…但这仍然行不通。 我得到一个404返回。 我错过了什么?

我最终回到了第一种方法,因为向这个URL添加一个查询参数是不方便的。 这使得客户端逻辑不必复杂。

我找到了解决方案,我的第一个方法。 位置声明中的正则表达式是错误的。 你需要通过使用?捕获变量名中的正则表达式? 喜欢这个:

 location ~ ^/fwd/(?<fwd_alias>\w+)/(?<fwd_path>.*)$ 

那么$ fwd_alias将包含像foo或bar这样的别名。 $ fwd_path包含之后的整个路径。

要传递包括可选查询参数的完整路径,可以将proxy_pass指定为:

 proxy_pass http://$repo_url$fwd_path$is_args$args; 

而已!

所以,现在,包括第一个例子中的映射,并添加解析器,它归结为:

 location ~ ^/fwd/(?<fwd_alias>\w+)/(?<fwd_path>.*)$ { resolver 8.8.8.8; add_header Access-Control-Allow-Origin "*"; proxy_pass http://$repo_url$fwd_path$is_args$args; proxy_redirect off; access_log on; } 

并用以下路径请求:

 http://localhost:8080/fwd/foo/something/else?with=query 

映射到:

 http://foo.domain.nl/something/else?with=query 

我在正确的轨道上。

如果你想用一个可变参数来使用proxy_pass,你需要做两件事:

  1. 添加一个解析器语句来解析主机名。 据我了解,在启动nginx查找配置中的所有域名,并映射到IP地址。 由于我们使用的是变量主机名,因此在加载配置时,nginx无法查找,我们需要指定DNS解析器。

  2. 在proxy_pass中使用变量时,您需要添加http://。 不知道这是为什么。

所以这导致:

 location /fwd/ { resolver 8.8.8.8; add_header X-FwdHost $repo_forward; add_header Access-Control-Allow-Origin "*"; proxy_pass http://$repo_forward; proxy_redirect off; access_log on; } 

它的工作原理! 🙂