From d5fc6f66bc17f27770b38126b6c4211fd938c5b5 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 12 Oct 2011 14:00:23 -0700 Subject: avoid inadvertant object creation with invalid addresses Just in case somebody tries to scan all addresses, we won't run out of memory as easily. --- lib/raindrops/watcher.rb | 30 ++++++++++++++++++------------ test/test_watcher.rb | 14 ++++++++++++++ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/lib/raindrops/watcher.rb b/lib/raindrops/watcher.rb index 7683ed4..1f3aaf3 100644 --- a/lib/raindrops/watcher.rb +++ b/lib/raindrops/watcher.rb @@ -120,14 +120,14 @@ class Raindrops::Watcher end end - agg_class = opts[:agg_class] || Aggregate - start = Time.now.utc - @active = Hash.new { |h,k| h[k] = agg_class.new } - @queued = Hash.new { |h,k| h[k] = agg_class.new } - @resets = Hash.new { |h,k| h[k] = start } - @peak_active = Hash.new { |h,k| h[k] = Peak.new(start, start) } - @peak_queued = Hash.new { |h,k| h[k] = Peak.new(start, start) } - @snapshot = [ start, {} ] + @agg_class = opts[:agg_class] || Aggregate + @start_time = Time.now.utc + @active = Hash.new { |h,k| h[k] = @agg_class.new } + @queued = Hash.new { |h,k| h[k] = @agg_class.new } + @resets = Hash.new { |h,k| h[k] = @start_time } + @peak_active = Hash.new { |h,k| h[k] = Peak.new(@start_time, @start_time) } + @peak_queued = Hash.new { |h,k| h[k] = Peak.new(@start_time, @start_time) } + @snapshot = [ @start_time, {} ] @delay = opts[:delay] || 1 @lock = Mutex.new @start = Mutex.new @@ -186,19 +186,25 @@ class Raindrops::Watcher thr end + def non_existent_stats(time) + [ time, @start_time, @agg_class.new, 0, Peak.new(@start_time, @start_time) ] + end + def active_stats(addr) # :nodoc: @lock.synchronize do - tmp, peak = @active[addr], @peak_active[addr] time, combined = @snapshot - [ time, @resets[addr], tmp.dup, combined[addr].active, peak ] + stats = combined[addr] or return non_existent_stats(time) + tmp, peak = @active[addr], @peak_active[addr] + [ time, @resets[addr], tmp.dup, stats.active, peak ] end end def queued_stats(addr) # :nodoc: @lock.synchronize do - tmp, peak = @queued[addr], @peak_queued[addr] time, combined = @snapshot - [ time, @resets[addr], tmp.dup, combined[addr].queued, peak ] + stats = combined[addr] or return non_existent_stats(time) + tmp, peak = @queued[addr], @peak_queued[addr] + [ time, @resets[addr], tmp.dup, stats.queued, peak ] end end diff --git a/test/test_watcher.rb b/test/test_watcher.rb index f22a954..056a3bf 100644 --- a/test/test_watcher.rb +++ b/test/test_watcher.rb @@ -43,6 +43,20 @@ class TestWatcher < Test::Unit::TestCase check_headers(resp.headers) end + def test_invalid + assert_nothing_raised do + @req.get("/active/666.666.666.666%3A666.txt") + @req.get("/queued/666.666.666.666%3A666.txt") + @req.get("/active/666.666.666.666%3A666.html") + @req.get("/queued/666.666.666.666%3A666.html") + end + addr = @app.instance_eval do + @peak_active.keys + @peak_queued.keys + + @resets.keys + @active.keys + @queued.keys + end + assert addr.grep(/666\.666\.666\.666/).empty?, addr.inspect + end + def test_active_html resp = @req.get "/active/#@addr.html" assert_equal 200, resp.status.to_i -- cgit v1.2.3-24-ge0c7