Permalink
Browse files

Use session generated by DEA as sticky session

Instead of routers encrypt/decrypt the sticky session.

Change-Id: I8ef4891e336003aadca2cb84ee9390feb8239113
  • Loading branch information...
anfernee committed Oct 29, 2012
1 parent 346867c commit f1a5d3fd992a3593fac2b0ecd8398b0976fbd037
View
@@ -4,7 +4,7 @@ class Router
VERSION = 0.98
class << self
- attr_reader :log, :notfound_redirect, :session_key
+ attr_reader :log, :notfound_redirect
attr_accessor :server, :local_server, :timestamp, :pid_file
attr_accessor :inet, :port
@@ -32,7 +32,6 @@ def config(config)
log.info "Registered 404 redirect at #{config['404_redirect']}"
end
- @session_key = config['session_key'] || '14fbc303b76bacd1e0a3ab641c11d11400341c5d'
@expose_all_apps = config['status']['expose_all_apps'] if config['status']
@enable_nonprod_apps = config['enable_nonprod_apps'] || false
@@ -49,7 +48,7 @@ def setup_listeners
msg_hash = Yajl::Parser.parse(msg, :symbolize_keys => true)
return unless uris = msg_hash[:uris]
uris.each { |uri| register_droplet(uri, msg_hash[:host], msg_hash[:port],
- msg_hash[:tags], msg_hash[:app]) }
+ msg_hash[:tags], msg_hash[:app], msg_hash[:private_instance_id]) }
}
NATS.subscribe('router.unregister') { |msg|
msg_hash = Yajl::Parser.parse(msg, :symbolize_keys => true)
@@ -136,39 +135,15 @@ def check_registered_urls
to_drop.each { |droplet| unregister_droplet(droplet[:url], droplet[:host], droplet[:port]) }
end
- def generate_session_cookie(droplet)
- token = [ droplet[:url], droplet[:host], droplet[:port] ]
- c = OpenSSL::Cipher::Cipher.new('blowfish')
- c.encrypt
- c.key = @session_key
- e = c.update(Marshal.dump(token))
- e << c.final
- session = [e].pack('m0').gsub("\n",'')
- droplet[:session] = session
- session
- end
-
- def decrypt_session_cookie(key)
- e = key.unpack('m*')[0]
- d = OpenSSL::Cipher::Cipher.new('blowfish')
- d.decrypt
- d.key = @session_key
- p = d.update(e)
- p << d.final
- Marshal.load(p)
- rescue
- nil
- end
-
def get_session_cookie(droplet)
- droplet[:session] || generate_session_cookie(droplet)
+ droplet[:session] || ""
end
def lookup_droplet(url)
@droplets[url.downcase]
end
- def register_droplet(url, host, port, tags, app_id)
+ def register_droplet(url, host, port, tags, app_id, session=nil)
return unless host && port
url.downcase!
tags ||= {}
@@ -185,6 +160,7 @@ def register_droplet(url, host, port, tags, app_id)
tags.delete_if { |key, value| key.nil? || value.nil? }
droplet = {
:app => app_id,
+ :session => session,
:host => host,
:port => port,
:clients => Hash.new(0),
@@ -35,8 +35,8 @@ class ParserError < StandardError; end
# Pick a droplet based on original backend addr or pick a droplet randomly
if sticky
- _, host, port = Router.decrypt_session_cookie(sticky)
- droplet = check_original_droplet(droplets, host, port)
+ droplet = droplets.find { |d| d[:session] == sticky }
+ Router.log.debug "request's __VCAP_ID__ is stale" unless droplet
end
droplet ||= droplets[rand*droplets.size]
Router.log.debug "Routing #{droplet[:url]} to #{droplet[:host]}:#{droplet[:port]}"
@@ -86,21 +86,6 @@ class ParserError < StandardError; end
protected
- def check_original_droplet(droplets, host, port)
- droplet = nil
- if host and port
- Router.log.debug "request has __VCAP_ID__ cookie for #{host}:#{port}"
- # Check host?
- droplets.each do |d|
- if(d[:host] == host && d[:port] == port.to_i)
- droplet = d; break
- end
- end
- Router.log.debug "request's __VCAP_ID__ is stale" unless droplet
- end
- droplet
- end
-
def update_uls_stats(stats)
stats.each do |stat|
if stat[ULS_REQUEST_TAGS].length > 0
@@ -103,20 +103,6 @@
original_apps_set.should == received_apps_set
end
- it 'should generate the same token as router v1 did' do
- Router.config({})
- token = Router.generate_session_cookie(ROUTER_V1_DROPLET)
- token.should == ROUTER_V1_SESSION
- end
-
- it 'should decrypt router v1 session' do
- Router.config({})
- url, host, port = Router.decrypt_session_cookie(ROUTER_V1_SESSION)
- url.should == ROUTER_V1_DROPLET[:url]
- host.should == ROUTER_V1_DROPLET[:host]
- port.should == ROUTER_V1_DROPLET[:port]
- end
-
it 'should properly exit when NATS fails to reconnect' do
@nats_server.stop
@nats_server.ready?.should be_false
@@ -213,8 +213,6 @@
# Verify cookie to backend that never exists
Router.config({})
- droplet = { :url => 'sticky.vcap.me', :host => '10.10.10.10', :port => 10 }
- down_dea_cookie = "__VCAP_ID__=#{Router.generate_session_cookie(droplet)}"
sticky_request = simple_sticky_request('sticky.vcap.me', '/sticky', bad_cookie)
results = send_requests_to_apps(RouterServer.host, RouterServer.port,
@@ -314,16 +314,19 @@ def initialize(nats_uri, dea_id, host='127.0.0.1')
@host = host
end
- def reg_hash_for_app(app, tags = {})
+ def reg_hash_for_app(app, tags={})
+ session = VCAP.secure_uuid + VCAP.secure_uuid
+
{ :dea => @dea_id,
+ :session => session,
:host => @host,
:port => app.port,
:uris => app.uris,
:tags => tags
}
end
- def register_app(app, tags = {})
+ def register_app(app, tags={})
NATS.start(:uri => @nats_uri) do
NATS.publish('router.register', reg_hash_for_app(app, tags).to_json) { NATS.stop }
end

0 comments on commit f1a5d3f

Please sign in to comment.