2013-08-26 100 views
5

Tôi đang cố gắng làm cho mẫu sau hoạt động. Tôi cần phải chỉ định một đường dẫn động trong mã phía máy khách của tôi để có thể chuyển sang một vài máy chủ định sẵn. Tôi ánh xạ các máy chủ này bằng cách thêm bí danh của chúng vào a/fwd/url. Bí danh được ánh xạ tới máy chủ thực trong nginx như sau:Proxy_pass động với bản đồ và regexp

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

Sau đó, trong phần cấu hình máy chủ, tôi bắt bất kỳ url bắt đầu bằng fwd và áp dụng giá trị bí danh được ánh xạ. Phần còn lại của url, sau khi bí danh cũng nên được thêm vào 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; 
} 

Nếu tôi thử nghiệm này với:

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

tôi nhận được:

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

Nhưng khi kiểm tra các kết quả từ regexp tôi nhận được:

$1: foo 
$2: something/else 

Vì vậy, tổng thể Nó dường như được làm việc. Regex dường như là ok, nhưng tôi không thể có được nó để nối vào một chuỗi? Bất kỳ ý tưởng hoặc là có một cách dễ dàng hơn/tốt hơn để thực hiện như vậy?

[EDIT]

Tôi đã tìm thấy cách dễ dàng hơn để thực hiện việc này bằng cách sử dụng tham số truy vấn có tên chuyển tiếp. Đầu tiên lập bản đồ các tham số truy vấn tới một máy chủ phải:

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

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

}

Sau đó, sử dụng tham số trong đường dẫn được chuyển tiếp:

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

tôi mong chờ và url như:

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

Để có kết quả:

http://foo.domain.nl/ 

... nhưng vẫn không hiệu quả. Tôi nhận được một 404 trả lại. Tôi đang thiếu gì?

Trả lời

6

Tôi cuối cùng đã quay lại phương pháp đầu tiên, vì không thuận tiện khi thêm thông số truy vấn vào url cho điều này. Nó làm cho logic khách hàng không cần thiết phức tạp.

Tôi đã tìm ra giải pháp cho cách tiếp cận đầu tiên của mình. Regex trong tuyên bố vị trí đã sai. Bạn cần phải nắm bắt regex trong tên biến bằng cách sử dụng? như thế này:

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

Sau đó $ fwd_alias sẽ chứa bí danh như foo hoặc bar. $ fwd_path có chứa toàn bộ đường dẫn sau đó.

Để vượt qua trên con đường đầy đủ bao gồm các thông số truy vấn tùy chọn bạn chỉ định proxy_pass như:

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

Vậy là xong!

Vì vậy, bây giờ, bao gồm các bản đồ trong ví dụ đầu tiên, và thêm các bộ giải quyết, nó đi xuống đến:

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; 
} 

Và một yêu cầu với đường dẫn sau:

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

bản đồ để:

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

Bất kỳ cơ hội nào bạn có thể đăng bản sao "đầy đủ" của giải pháp. Tôi đang theo dõi điều này (theo như tôi có thể) nhưng vẫn nhận được 404. Alstublieft. – Guy

1

Tôi đã đi đúng hướng.

Nếu bạn muốn sử dụng proxy_pass với một đối số biến bạn cần phải làm hai việc:

  1. Thêm một tuyên bố giải quyết để giải quyết tên máy chủ. Khi tôi hiểu nó, khi khởi động nginx tìm kiếm tất cả các tên miền trong cấu hình và ánh xạ chúng vào các IP. Vì chúng tôi đang sử dụng một tên máy chủ biến nginx không thể tìm kiếm nó khi tải cấu hình và chúng tôi cần phải chỉ định trình phân giải DNS.

  2. Khi sử dụng biến trong proxy_pass, bạn cần phải thêm http: // vào đó. Không chắc sao lại thế.

Vì vậy, kết quả này trong:

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; 
} 

Và nó hoạt động!:)