rack-attack 4.3.1 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/rack/attack.rb +1 -0
- data/lib/rack/attack/store_proxy.rb +12 -6
- data/lib/rack/attack/store_proxy/mem_cache_proxy.rb +51 -0
- data/lib/rack/attack/version.rb +1 -1
- data/spec/integration/rack_attack_cache_spec.rb +3 -0
- metadata +18 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 7d06cf65c8cfce9d8611003c5da19f1384273d6d
         | 
| 4 | 
            +
              data.tar.gz: 4e8e0064ab9087fc7503e9e1cb850f6dd10c8838
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: d66f18bf9e4f6058c2f40339392e38a62f71afd6852eb0f3f30075fe1eb233b5a355b61bcac39dcf109644987c1ae41fb4831d6c0ed206827258f59a06c4883e
         | 
| 7 | 
            +
              data.tar.gz: b5f72dc5abf4c6b27d89b38dfea3ba85cdbed807bf9aced9388c69707f5e8115aa06a32204bd6fc7c49263ea73dff8fbf2914fcb3868b8965b36e0b63729d10c
         | 
    
        data/README.md
    CHANGED
    
    | @@ -83,7 +83,7 @@ def call(env) | |
| 83 83 | 
             
            end
         | 
| 84 84 | 
             
            ```
         | 
| 85 85 |  | 
| 86 | 
            -
            Note: `Rack::Attack::Request` is just a subclass of `Rack:: | 
| 86 | 
            +
            Note: `Rack::Attack::Request` is just a subclass of `Rack::Request` so that you
         | 
| 87 87 | 
             
            can cleanly monkey patch helper methods onto the
         | 
| 88 88 | 
             
            [request object](https://github.com/kickstarter/rack-attack/blob/master/lib/rack/attack/request.rb).
         | 
| 89 89 |  | 
    
        data/lib/rack/attack.rb
    CHANGED
    
    | @@ -11,6 +11,7 @@ class Rack::Attack | |
| 11 11 | 
             
              autoload :Track,           'rack/attack/track'
         | 
| 12 12 | 
             
              autoload :StoreProxy,      'rack/attack/store_proxy'
         | 
| 13 13 | 
             
              autoload :DalliProxy,      'rack/attack/store_proxy/dalli_proxy'
         | 
| 14 | 
            +
              autoload :MemCacheProxy,   'rack/attack/store_proxy/mem_cache_proxy'
         | 
| 14 15 | 
             
              autoload :RedisStoreProxy, 'rack/attack/store_proxy/redis_store_proxy'
         | 
| 15 16 | 
             
              autoload :Fail2Ban,        'rack/attack/fail2ban'
         | 
| 16 17 | 
             
              autoload :Allow2Ban,       'rack/attack/allow2ban'
         | 
| @@ -1,19 +1,25 @@ | |
| 1 1 | 
             
            module Rack
         | 
| 2 2 | 
             
              class Attack
         | 
| 3 3 | 
             
                module StoreProxy
         | 
| 4 | 
            -
                  PROXIES = [DalliProxy, RedisStoreProxy]
         | 
| 4 | 
            +
                  PROXIES = [DalliProxy, MemCacheProxy, RedisStoreProxy]
         | 
| 5 5 |  | 
| 6 6 | 
             
                  def self.build(store)
         | 
| 7 7 | 
             
                    # RedisStore#increment needs different behavior, so detect that
         | 
| 8 8 | 
             
                    # (method has an arity of 2; must call #expire separately
         | 
| 9 | 
            -
                    if defined?(::ActiveSupport::Cache::RedisStore) && store.is_a?(::ActiveSupport::Cache::RedisStore)
         | 
| 9 | 
            +
                    if (defined?(::ActiveSupport::Cache::RedisStore) && store.is_a?(::ActiveSupport::Cache::RedisStore)) ||
         | 
| 10 | 
            +
                      (defined?(::ActiveSupport::Cache::MemCacheStore) && store.is_a?(::ActiveSupport::Cache::MemCacheStore))
         | 
| 11 | 
            +
             | 
| 10 12 | 
             
                      # ActiveSupport::Cache::RedisStore doesn't expose any way to set an expiry,
         | 
| 11 | 
            -
                      # so use the raw Redis::Store instead
         | 
| 12 | 
            -
                       | 
| 13 | 
            +
                      # so use the raw Redis::Store instead.
         | 
| 14 | 
            +
                      # We also want to use the underlying Dalli client instead of ::ActiveSupport::Cache::MemCacheStore,
         | 
| 15 | 
            +
                      # and the MemCache client if using Rails 3.x
         | 
| 16 | 
            +
                      client = store.instance_variable_get(:@data)
         | 
| 17 | 
            +
                      if (defined?(::Redis::Store) && client.is_a?(Redis::Store)) ||
         | 
| 18 | 
            +
                        (defined?(Dalli::Client) && client.is_a?(Dalli::Client)) || (defined?(MemCache) && client.is_a?(MemCache))
         | 
| 19 | 
            +
                        store = store.instance_variable_get(:@data)
         | 
| 20 | 
            +
                      end
         | 
| 13 21 | 
             
                    end
         | 
| 14 | 
            -
             | 
| 15 22 | 
             
                    klass = PROXIES.find { |proxy| proxy.handle?(store) }
         | 
| 16 | 
            -
             | 
| 17 23 | 
             
                    klass ? klass.new(store) : store
         | 
| 18 24 | 
             
                  end
         | 
| 19 25 |  | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            module Rack
         | 
| 2 | 
            +
              class Attack
         | 
| 3 | 
            +
                module StoreProxy
         | 
| 4 | 
            +
                  class MemCacheProxy < SimpleDelegator
         | 
| 5 | 
            +
                    def self.handle?(store)
         | 
| 6 | 
            +
                      defined?(::MemCache) && store.is_a?(::MemCache)
         | 
| 7 | 
            +
                    end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def initialize(store)
         | 
| 10 | 
            +
                      super(store)
         | 
| 11 | 
            +
                      stub_with_if_missing
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    def read(key)
         | 
| 15 | 
            +
                      # Second argument: reading raw value
         | 
| 16 | 
            +
                      get(key, true)
         | 
| 17 | 
            +
                      rescue MemCache::MemCacheError
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    def write(key, value, options={})
         | 
| 21 | 
            +
                      # Third argument: writing raw value
         | 
| 22 | 
            +
                      set(key, value, options.fetch(:expires_in, 0), true)
         | 
| 23 | 
            +
                    rescue MemCache::MemCacheError
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    def increment(key, amount, options={})
         | 
| 27 | 
            +
                      incr(key, amount)
         | 
| 28 | 
            +
                    rescue MemCache::MemCacheError
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    def delete(key, options={})
         | 
| 32 | 
            +
                      with do |client|
         | 
| 33 | 
            +
                        client.delete(key)
         | 
| 34 | 
            +
                      end
         | 
| 35 | 
            +
                    rescue MemCache::MemCacheError
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                    private
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                    def stub_with_if_missing
         | 
| 41 | 
            +
                      unless __getobj__.respond_to?(:with)
         | 
| 42 | 
            +
                        class << self
         | 
| 43 | 
            +
                          def with; yield __getobj__; end
         | 
| 44 | 
            +
                        end
         | 
| 45 | 
            +
                      end
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         | 
    
        data/lib/rack/attack/version.rb
    CHANGED
    
    
| @@ -17,12 +17,14 @@ describe Rack::Attack::Cache do | |
| 17 17 | 
             
              end
         | 
| 18 18 |  | 
| 19 19 | 
             
              require 'active_support/cache/dalli_store'
         | 
| 20 | 
            +
              require 'active_support/cache/mem_cache_store'
         | 
| 20 21 | 
             
              require 'active_support/cache/redis_store'
         | 
| 21 22 | 
             
              require 'connection_pool'
         | 
| 22 23 | 
             
              cache_stores = [
         | 
| 23 24 | 
             
                ActiveSupport::Cache::MemoryStore.new,
         | 
| 24 25 | 
             
                ActiveSupport::Cache::DalliStore.new("127.0.0.1"),
         | 
| 25 26 | 
             
                ActiveSupport::Cache::RedisStore.new("127.0.0.1"),
         | 
| 27 | 
            +
                ActiveSupport::Cache::MemCacheStore.new("127.0.0.1"),
         | 
| 26 28 | 
             
                Dalli::Client.new,
         | 
| 27 29 | 
             
                ConnectionPool.new { Dalli::Client.new },
         | 
| 28 30 | 
             
                Redis::Store.new
         | 
| @@ -54,6 +56,7 @@ describe Rack::Attack::Cache do | |
| 54 56 | 
             
                      @cache.send(:do_count, @key, @expires_in).must_equal 2
         | 
| 55 57 | 
             
                    end
         | 
| 56 58 | 
             
                  end
         | 
| 59 | 
            +
             | 
| 57 60 | 
             
                  describe "do_count after expires_in" do
         | 
| 58 61 | 
             
                    it "must be 1" do
         | 
| 59 62 | 
             
                      @cache.send(:do_count, @key, @expires_in)
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rack-attack
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 4. | 
| 4 | 
            +
              version: 4.4.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Aaron Suggs
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2016-02-10 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rack
         | 
| @@ -150,6 +150,20 @@ dependencies: | |
| 150 150 | 
             
                - - ">="
         | 
| 151 151 | 
             
                  - !ruby/object:Gem::Version
         | 
| 152 152 | 
             
                    version: '0'
         | 
| 153 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 154 | 
            +
              name: memcache-client
         | 
| 155 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 156 | 
            +
                requirements:
         | 
| 157 | 
            +
                - - ">="
         | 
| 158 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 159 | 
            +
                    version: '0'
         | 
| 160 | 
            +
              type: :development
         | 
| 161 | 
            +
              prerelease: false
         | 
| 162 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 163 | 
            +
                requirements:
         | 
| 164 | 
            +
                - - ">="
         | 
| 165 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 166 | 
            +
                    version: '0'
         | 
| 153 167 | 
             
            description: A rack middleware for throttling and blocking abusive requests
         | 
| 154 168 | 
             
            email: aaron@ktheory.com
         | 
| 155 169 | 
             
            executables: []
         | 
| @@ -168,6 +182,7 @@ files: | |
| 168 182 | 
             
            - lib/rack/attack/request.rb
         | 
| 169 183 | 
             
            - lib/rack/attack/store_proxy.rb
         | 
| 170 184 | 
             
            - lib/rack/attack/store_proxy/dalli_proxy.rb
         | 
| 185 | 
            +
            - lib/rack/attack/store_proxy/mem_cache_proxy.rb
         | 
| 171 186 | 
             
            - lib/rack/attack/store_proxy/redis_store_proxy.rb
         | 
| 172 187 | 
             
            - lib/rack/attack/throttle.rb
         | 
| 173 188 | 
             
            - lib/rack/attack/track.rb
         | 
| @@ -205,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 205 220 | 
             
                  version: '0'
         | 
| 206 221 | 
             
            requirements: []
         | 
| 207 222 | 
             
            rubyforge_project: 
         | 
| 208 | 
            -
            rubygems_version: 2. | 
| 223 | 
            +
            rubygems_version: 2.5.1
         | 
| 209 224 | 
             
            signing_key: 
         | 
| 210 225 | 
             
            specification_version: 4
         | 
| 211 226 | 
             
            summary: Block & throttle abusive requests
         |