From 8ee9728595a4ad8f77837033dd5de17fdedce00a Mon Sep 17 00:00:00 2001 From: Isaac Seymour Date: Tue, 8 Nov 2016 10:55:52 +0000 Subject: [PATCH] Limit the size of usage of the session store to ~1KB Very approximate, but bounds the cookie usage to leave about 75% for other things. --- lib/analytical/session_command_store.rb | 15 +++++++++---- spec/analytical/session_command_store_spec.rb | 22 +++++++++++++++---- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/analytical/session_command_store.rb b/lib/analytical/session_command_store.rb index fa6d1f7..9a96d93 100644 --- a/lib/analytical/session_command_store.rb +++ b/lib/analytical/session_command_store.rb @@ -6,18 +6,21 @@ def initialize(session, module_key, initial_list=nil) @session = session @module_key = module_key @session_key = ('analytical_'+module_key.to_s).to_sym - ensure_session_setup!(initial_list) + assign(initial_list || []) end def assign(v) self.commands = v + trim_commands! end def commands + trim_commands! @session[@session_key] end def commands=(v) @session[@session_key] = v + trim_commands! end def flush @@ -30,13 +33,17 @@ def remove(processed_commands) # Pass any array methods on to the internal array def method_missing(method, *args, &block) - commands.send(method, *args, &block) + commands.send(method, *args, &block).tap { trim_commands! } end private - def ensure_session_setup!(initial_list=nil) - self.commands ||= (initial_list || []) + # Make sure to not exceed ~1KB of session storage use (max cookie is 4KB) + def trim_commands! + serialized_length = @session[@session_key].inspect.length + return unless serialized_length > 1000 + @session[@session_key] = @session[@session_key][0..-2] + trim_commands! end end diff --git a/spec/analytical/session_command_store_spec.rb b/spec/analytical/session_command_store_spec.rb index aa43bc2..bb5a837 100644 --- a/spec/analytical/session_command_store_spec.rb +++ b/spec/analytical/session_command_store_spec.rb @@ -1,12 +1,12 @@ require 'spec_helper' describe Analytical::SessionCommandStore do - + describe 'with a session hash' do before(:each) do @session = {} end - + it 'should add elements' do @store = Analytical::SessionCommandStore.new @session, :some_module, ['a'] @store << 'b' @@ -30,7 +30,21 @@ it 'should set up the :analytical session hash' do @store = Analytical::SessionCommandStore.new @session, :some_module, ['a', 'b'] - @session[:analytical_some_module].should_not be_nil + @session[:analytical_some_module].should_not be_nil + end + + it 'should discard older items when the store is full' do + large_item = [ + "set", + { + "I have some key" => "and a long param", + "and more key" => "and some more value", + "so much key" => "such such value", + }, + ] + @store = Analytical::SessionCommandStore.new @session, :some_module, [large_item] * 100 + @session[:analytical_some_module].should_not be_nil + @session[:analytical_some_module].inspect.length.should be < 1000 end describe 'when flushing' do @@ -55,5 +69,5 @@ end end end - + end