Commit 0aebb10e authored by Terence Lee's avatar Terence Lee Committed by GitHub

Merge pull request #63 from heroku/proxy_resolver

Fixes #44. Respect DNS TTL for proxies.
parents d03c2716 a26fb057
...@@ -8,7 +8,8 @@ class NginxConfig ...@@ -8,7 +8,8 @@ class NginxConfig
encoding: "UTF-8", encoding: "UTF-8",
clean_urls: false, clean_urls: false,
https_only: false, https_only: false,
worker_connections: 512 worker_connections: 512,
resolver: "8.8.8.8"
} }
def initialize(json_file) def initialize(json_file)
...@@ -18,20 +19,23 @@ class NginxConfig ...@@ -18,20 +19,23 @@ class NginxConfig
json["port"] ||= ENV["PORT"] || 5000 json["port"] ||= ENV["PORT"] || 5000
json["root"] ||= DEFAULT[:root] json["root"] ||= DEFAULT[:root]
json["encoding"] ||= DEFAULT[:encoding] json["encoding"] ||= DEFAULT[:encoding]
index = 0
json["proxies"] ||= {} json["proxies"] ||= {}
json["proxies"].each do |loc, hash| json["proxies"].each do |loc, hash|
evaled_origin = NginxConfigUtil.interpolate(hash['origin'], ENV) evaled_origin = NginxConfigUtil.interpolate(hash['origin'], ENV)
if evaled_origin != "/"
json["proxies"][loc].merge!("origin" => evaled_origin + "/")
end
uri = URI(evaled_origin) uri = URI(evaled_origin)
json["proxies"][loc]["path"] = uri.path
uri.path = "" json["proxies"][loc]["name"] = "upstream_endpoint_#{index}"
json["proxies"][loc]["host"] = uri.to_s cleaned_path = uri.path
redirect_scheme = uri.scheme == "https" ? "http" : "https" cleaned_path.chop! if cleaned_path.end_with?("/")
json["proxies"][loc]["redirect"] = uri.dup.tap {|u| u.scheme = redirect_scheme }.to_s json["proxies"][loc]["path"] = cleaned_path
json["proxies"][loc]["redirect"] += "/" if !uri.to_s.end_with?("/") json["proxies"][loc]["host"] = uri.dup.tap {|u| u.path = '' }.to_s
%w(http https).each do |scheme|
json["proxies"][loc]["redirect_#{scheme}"] = uri.dup.tap {|u| u.scheme = scheme }.to_s
json["proxies"][loc]["redirect_#{scheme}"] += "/" if !uri.to_s.end_with?("/")
end
index += 1
end end
json["clean_urls"] ||= DEFAULT[:clean_urls] json["clean_urls"] ||= DEFAULT[:clean_urls]
...@@ -47,6 +51,17 @@ class NginxConfig ...@@ -47,6 +51,17 @@ class NginxConfig
json["error_page"] ||= nil json["error_page"] ||= nil
json["debug"] ||= ENV['STATIC_DEBUG'] json["debug"] ||= ENV['STATIC_DEBUG']
nameservers = []
if File.exist?("/etc/resolv.conf")
File.open("/etc/resolv.conf", "r").each do |line|
next unless md = line.match(/^nameserver\s*(\S*)/)
nameservers << md[1]
end
end
nameservers << [DEFAULT[:resolver]] unless nameservers.empty?
json["resolver"] = nameservers.join(" ")
json.each do |key, value| json.each do |key, value|
self.class.send(:define_method, key) { value } self.class.send(:define_method, key) { value }
end end
......
...@@ -28,12 +28,17 @@ module NginxConfigUtil ...@@ -28,12 +28,17 @@ module NginxConfigUtil
def self.match_proxies(proxies, uri) def self.match_proxies(proxies, uri)
return false unless proxies return false unless proxies
proxies.each do |proxy| matched = proxies.select do |proxy|
return proxy if Regexp.compile("^#{proxy}") =~ uri Regexp.compile("^#{proxy}") =~ uri
end end
# return the longest matched proxy
if matched.any?
matched.max_by {|proxy| proxy.size }
else
false false
end end
end
def self.match_redirects(redirects, uri) def self.match_redirects(redirects, uri)
return false unless redirects return false unless redirects
......
...@@ -41,6 +41,9 @@ http { ...@@ -41,6 +41,9 @@ http {
<% if error_page %> <% if error_page %>
error_page 404 500 /<%= error_page %>; error_page 404 500 /<%= error_page %>;
<% end %> <% end %>
<% if proxies.any? %>
resolver <%= resolver %>;
<% end %>
location / { location / {
mruby_post_read_handler /app/bin/config/lib/ngx_mruby/headers.rb cache; mruby_post_read_handler /app/bin/config/lib/ngx_mruby/headers.rb cache;
...@@ -78,11 +81,15 @@ http { ...@@ -78,11 +81,15 @@ http {
<% end %> <% end %>
<% proxies.each do |location, hash| %> <% proxies.each do |location, hash| %>
set $<%= hash['name'] %> <%= hash['host'] %>;
location <%= location %> { location <%= location %> {
proxy_pass <%= hash['origin'] %>; rewrite ^<%= location %>/?(.*) <%= hash['path'] %>/$1 break;
proxy_pass $<%= hash['name'] %>;
proxy_ssl_server_name on; proxy_ssl_server_name on;
proxy_redirect default; # handle Location rewrites from the proxy properly
proxy_redirect <%= hash["redirect"] %> <%= location %>; <% %w(http https).each do |scheme| %>
proxy_redirect <%= hash["redirect_#{scheme}"] %> <%= location %>;
<% end %>
} }
<% end %> <% end %>
...@@ -94,11 +101,13 @@ http { ...@@ -94,11 +101,13 @@ http {
# fallback proxy named match # fallback proxy named match
<% proxies.each do |location, hash| %> <% proxies.each do |location, hash| %>
location @<%= location %> { location @<%= location %> {
rewrite ^<%= location %>(.*)$ <%= hash['path'] %>/$1 break; rewrite ^<%= location %>/?(.*)$ <%= hash['path'] %>/$1 break;
proxy_pass <%= hash['host'] %>; # can reuse variable set above
proxy_pass $<%= hash['name'] %>;
proxy_ssl_server_name on; proxy_ssl_server_name on;
proxy_redirect default; <% %w(http https).each do |scheme| %>
proxy_redirect <%= hash["redirect"] %> <%= location %>; proxy_redirect <%= hash["redirect_#{scheme}"] %> <%= location %>;
<% end %>
} }
<% end %> <% end %>
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment