2013-08-26 10 views
5

我試圖讓下面的模式工作。我需要在客戶端代碼中指定一個動態路徑才能切換到幾個預定義的主機。我通過將他們的別名附加到/ fwd/url來映射這些主機。別名被映射到真實服務器在nginx的是這樣的:動態proxy_pass與地圖和正則表達式

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

然後在服務器配置部分,我發現任何開頭的網址FWD和應用映射的別名值。別名之後的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; 
} 

如果我測試這個用:

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

我得到:

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

但是,當測試從正則表達式的結果我得到:

$1: foo 
$2: something/else 

所以整體它似乎在工作。正則表達式似乎是好的,但我不能把它連接成一個字符串?任何想法或有更容易/更好的方式來實現相同?

[編輯]

我發現了一個可能是更容易的方式來做到這一點,使用名爲前進的查詢參數。首先查詢參數映射到正確的主機:

map $arg_forward $repo_forward { 
default   http://invalid_repo_forward/; 

foo    http://foo.domain.nl/; 
bar    http://bar.domain.nl/; 

}

然後用參數的路徑轉發:

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

我希望和網址,如:

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

產生於:

http://foo.domain.nl/ 

...但這仍然無效。我得到一個404返回。我錯過了什麼?

回答

6

我最終回到了第一種方法,因爲爲此添加查詢參數到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 
+0

任何機會,您可以發佈一個「完整」的解決方案的副本,請。我遵循這個(儘可能),但仍然得到404的。 Alstublieft。 – Guy

1

我在正確的軌道上。

如果你想與你需要做兩件事情變量參數使用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; 
} 

和它的作品!:)