class Invoker::Power::Balancer
Attributes
connection[RW]
http_parser[RW]
protocol[RW]
session[RW]
upgraded_to[RW]
Public Class Methods
new(connection, protocol)
click to toggle source
# File lib/invoker/power/balancer.rb, line 41 def initialize(connection, protocol) @connection = connection @protocol = protocol @http_parser = HttpParser.new(protocol) @session = nil @upgraded_to = nil @buffer = [] end
run(options = {})
click to toggle source
# File lib/invoker/power/balancer.rb, line 27 def self.run(options = {}) start_http_proxy(InvokerHttpProxy, 'http', options) start_http_proxy(InvokerHttpsProxy, 'https', options) end
start_http_proxy(proxy_class, protocol, options)
click to toggle source
# File lib/invoker/power/balancer.rb, line 32 def self.start_http_proxy(proxy_class, protocol, options) port = protocol == 'http' ? Invoker.config.http_port : Invoker.config.https_port EventMachine.start_server('0.0.0.0', port, proxy_class, options) do |connection| balancer = Balancer.new(connection, protocol) balancer.install_callbacks end end
Public Instance Methods
append_for_http_parsing(data)
click to toggle source
# File lib/invoker/power/balancer.rb, line 92 def append_for_http_parsing(data) http_parser << data rescue HTTP::Parser::Error http_parser.reset connection.close_connection_after_writing end
backend_data(backend, data)
click to toggle source
# File lib/invoker/power/balancer.rb, line 99 def backend_data(backend, data) @backend_data = true # check backend data for websockets connection. check for upgrade headers # - Upgarde: websocket\r\n if data =~ /Upgrade: websocket/ @upgraded_to = "websocket" end data end
complete_message_received(full_message)
click to toggle source
# File lib/invoker/power/balancer.rb, line 58 def complete_message_received(full_message) connection.relay_to_servers(full_message) http_parser.reset end
frontend_disconnect(backend, name)
click to toggle source
# File lib/invoker/power/balancer.rb, line 111 def frontend_disconnect(backend, name) http_parser.reset unless @backend_data return_error_page(503) end @backend_data = false connection.close_connection_after_writing if backend == session end
headers_received(headers)
click to toggle source
# File lib/invoker/power/balancer.rb, line 63 def headers_received(headers) if @session return end @session = UUID.generate() if !headers['Host'] || headers['Host'].empty? return_error_page(400) return end dns_check_response = UrlRewriter.new.select_backend_config(headers['Host']) if dns_check_response && dns_check_response.port connection.server(session, host: dns_check_response.ip, port: dns_check_response.port) else return_error_page(404) http_parser.reset connection.close_connection_after_writing end end
install_callbacks()
click to toggle source
# File lib/invoker/power/balancer.rb, line 50 def install_callbacks http_parser.on_headers_complete { |headers| headers_received(headers) } http_parser.on_message_complete { |full_message| complete_message_received(full_message) } connection.on_data { |data| upstream_data(data) } connection.on_response { |backend, data| backend_data(backend, data) } connection.on_finish { |backend, name| frontend_disconnect(backend, name) } end
upstream_data(data)
click to toggle source
# File lib/invoker/power/balancer.rb, line 83 def upstream_data(data) if upgraded_to == "websocket" data else append_for_http_parsing(data) nil end end
Private Instance Methods
return_error_page(status)
click to toggle source
# File lib/invoker/power/balancer.rb, line 122 def return_error_page(status) http_response = Invoker::Power::HttpResponse.new() http_response.status = status http_response['Content-Type'] = "text/html; charset=utf-8" http_response.use_file_as_body(File.join(File.dirname(__FILE__), "templates/#{status}.html")) connection.send_data(http_response.http_string) end