lib/slinky/proxy_server.rb in slinky-0.4.2 vs lib/slinky/proxy_server.rb in slinky-0.5.0
- old
+ new
@@ -2,27 +2,32 @@
module ProxyServer
HTTP_MATCHER = /(GET|POST|PUT|DELETE|HEAD) (.+?)(?= HTTP)/
HOST_MATCHER = /Host: (.+)/
def self.process_proxies proxy_hash
- proxy_hash.map{|from, to|
+ proxy_hash.map{|from, h|
begin
- [from, URI::parse(to)]
+ to, opt = h.is_a?(Hash) ? [h.delete("to"), h] : [h, {}]
+ a = [from, URI::parse(to), opt]
rescue
$stderr.puts "Invalid proxy setting: #{from} => #{to}".foreground(:red)
end
}.compact
end
def self.process_proxy_servers proxies
- proxies_servers = proxies.map{|p| [p[1].host, p[1].port]}
+ proxies.map{|p| [p[1].host, p[1].port]}
end
def self.find_matcher proxies, path
proxies.find{|p| path.start_with?(p[0])}
end
+ def self.rewrite_path path, proxy
+ path.gsub(/^#{proxy[0]}/, "")
+ end
+
def self.replace_path http, old_path, new_path, addition
# TODO: This may fail in certain, rare cases
addition = addition[0..-2] if addition[-1] == "/"
http.gsub(old_path, addition + new_path)
end
@@ -34,21 +39,24 @@
def self.run proxy_hash, port, slinky_port
proxies = process_proxies proxy_hash
proxy_servers = process_proxy_servers proxies
Proxy.start(:host => "0.0.0.0", :port => port){|conn|
+ proxy = nil
+ start_time = nil
conn.server :slinky, :host => "127.0.0.1", :port => slinky_port
proxy_servers.each{|p|
conn.server p, :host => p[0], :port => p[1]
}
conn.on_data do |data|
begin
_, path = data.match(ProxyServer::HTTP_MATCHER)[1..2]
proxy = ProxyServer.find_matcher(proxies, path)
+ start_time = Time.now
server = if proxy
- new_path = path.gsub(/^#{proxy[0]}/, "")
+ new_path = ProxyServer.rewrite_path path, proxy
data = ProxyServer.replace_path(data, path, new_path, proxy[1].path)
new_host = proxy[1].select(:host, :port).join(":")
data = ProxyServer.replace_host(data, new_host)
puts [data, [proxy[1].host, proxy[1].port]].inspect
[proxy[1].host, proxy[1].port]
@@ -60,10 +68,21 @@
conn.send_data "HTTP/1.1 500 Ooops...something went wrong\r\n"
end
end
conn.on_response do |server, resp|
- resp
+ opt = proxy && proxy[2]
+ if opt && opt["lag"]
+ # we want to get as close as possible to opt["lag"], so we
+ # take into account the lag from the backend server
+ so_far = Time.now - start_time
+ time = opt["lag"]/1000.0-so_far
+ EM.add_timer (time > 0 ? time : 0) do
+ conn.send_data resp
+ end
+ else
+ resp
+ end
end
conn.on_finish do |name|
unbind
end