rack-block 0.0.1.pre1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ pkg/*
4
+ *~
5
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ -fs --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rack-block.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rack-block (0.0.1)
5
+ rack (>= 1.3)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.1.3)
11
+ guard (0.8.8)
12
+ thor (~> 0.14.6)
13
+ guard-rspec (0.5.9)
14
+ guard (>= 0.8.4)
15
+ rack (1.3.5)
16
+ rack-test (0.6.1)
17
+ rack (>= 1.0)
18
+ rspec (2.7.0)
19
+ rspec-core (~> 2.7.0)
20
+ rspec-expectations (~> 2.7.0)
21
+ rspec-mocks (~> 2.7.0)
22
+ rspec-core (2.7.1)
23
+ rspec-expectations (2.7.0)
24
+ diff-lcs (~> 1.1.2)
25
+ rspec-mocks (2.7.0)
26
+ thor (0.14.6)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ guard-rspec
33
+ rack-block!
34
+ rack-test (> 0)
35
+ rspec (>= 2)
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { "spec" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ begin
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ spec.rspec_opts = "-fs --color"
9
+ end
10
+
11
+ RSpec::Core::RakeTask.new(:"spec:integrations") do |spec|
12
+ spec.pattern = FileList['spec/integrations/**/*_spec.rb']
13
+ spec.rspec_opts = "-fs --color"
14
+ end
15
+ task :default => :spec
16
+ rescue LoadError
17
+ end
18
+
19
+
data/lib/rack-block.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "rack/block"
2
+
data/lib/rack/block.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'rack'
2
+ module Rack
3
+ class Block
4
+ autoload :DSL, 'rack/block/dsl'
5
+
6
+ include DSL::Matchers
7
+ include DSL::Responses
8
+
9
+ def initialize(app, &b)
10
+ @_current_matching_type = nil
11
+ @_current_matching_ua_pattern = nil
12
+ @_current_matching_ip_pattern = nil
13
+ @_current_matching_path = nil
14
+ @ua_matchers = {}
15
+ @ip_matchers = {}
16
+ instance_eval(&b)
17
+ @app = app
18
+ end
19
+
20
+ attr_accessor :ua_matchers, :ip_matchers
21
+
22
+ def call(env)
23
+ req = Rack::Request.new(env)
24
+ self.ua_matchers.each_pair do |pattern, path_matchers|
25
+ if pattern =~ req.user_agent
26
+ path_matchers.each_pair do |path, action_with_args|
27
+ if path =~ req.path_info
28
+ action, *args = action_with_args
29
+ return send action, *args
30
+ end
31
+ end
32
+ end
33
+ end
34
+ app.call(env)
35
+ end
36
+ # Your code goes here...
37
+ end
38
+ end
39
+
40
+ require "rack/block/version"
@@ -0,0 +1,9 @@
1
+ module Rack
2
+ class Block
3
+ module DSL
4
+ autoload :Matchers, 'rack/block/dsl/matchers'
5
+ autoload :Responses, 'rack/block/dsl/responses'
6
+ end
7
+ end
8
+ end
9
+
@@ -0,0 +1,25 @@
1
+ module Rack::Block::DSL
2
+ module Matchers
3
+ BUILTIN_BOT_PATTERN = /googlebot/i
4
+
5
+ def bot_access(&block)
6
+ ua_pattern BUILTIN_BOT_PATTERN, &block
7
+ end
8
+
9
+ def ua_pattern(pattern, &block)
10
+ @_current_matching_type, orig = :by_UA, @_current_matching_type
11
+ @_current_matching_ua_pattern, orig_ptn = pattern, @_current_matching_ua_pattern
12
+ yield
13
+ ensure
14
+ @_current_matching_ua_pattern = orig_ptn
15
+ @_current_matching_type = orig
16
+ end
17
+
18
+ def path(pattern, &block)
19
+ @_current_matching_path, orig = pattern, @_current_matching_path
20
+ yield
21
+ ensure
22
+ @_current_matching_path = orig
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ module Rack::Block::DSL
2
+ module Responses
3
+ def halt(code, opts={})
4
+ if @_current_matching_path
5
+ path = Regexp.compile("^" + @_current_matching_path.sub(/\*/, '.*'))
6
+ current_matchers = (self.ua_matchers[@_current_matching_ua_pattern] ||= {})
7
+ current_matchers[path] = [:do_halt, code, opts]
8
+ else
9
+ path '*' do
10
+ halt code, opts
11
+ end
12
+ end
13
+ end
14
+
15
+ def do_halt(code, opts={})
16
+ headers = {"Content-Type" => "text/plain"}.merge(opts[:headers] || {})
17
+ body = opts[:body] || "Halt!"
18
+ return [code, headers, [body]]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class Block
3
+ VERSION = "0.0.1.pre1"
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rack/block/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rack-block"
7
+ s.version = Rack::Block::VERSION
8
+ s.authors = ["Uchio Kondo"]
9
+ s.email = ["udzura@udzura.jp"]
10
+ s.homepage = ""
11
+ s.summary = %q{A rack middleware for handling search bot access, ip block, etc.}
12
+ s.description = %q{A rack middleware for handling search bot access, ip block, etc.}
13
+
14
+ s.rubyforge_project = "rack-block"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency "rack", '>= 1.3'
22
+
23
+ s.add_development_dependency "rspec", '>= 2'
24
+ s.add_development_dependency "rack-test", '> 0'
25
+ s.add_development_dependency "guard-rspec"
26
+ end
@@ -0,0 +1,14 @@
1
+ RSpec.configure do |config|
2
+ config.include Rack::Test::Methods
3
+ end
4
+
5
+ DEFAULT_APP = lambda {|env| [200, {"Content-Type" => "text/plain"}, ["It is summer"]] }
6
+ @app = nil
7
+ def app
8
+ @app || DEFAULT_APP
9
+ end
10
+
11
+ require 'rack/builder'
12
+ def mock_app(&block)
13
+ @app = Rack::Builder.new(&block)
14
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/mock_app_helper')
3
+
4
+ describe "There is no problem that the #mock_app helper works" do
5
+ before do
6
+ mock_app do
7
+ map '/nil' do
8
+ run lambda {|env| [404, {"Content-Type" => "text/plain"}, ["It is no summer"]] }
9
+ end
10
+
11
+ map '/auth' do
12
+ use Rack::Auth::Basic, "fobbiden" do |u, p| false end
13
+ run lambda {|env| [200, {"Content-Type" => "text/plain"}, ["Not reachable"]] }
14
+ end
15
+
16
+ map '/' do
17
+ run lambda {|env| [200, {"Content-Type" => "text/plain"}, ["It is summer"]] }
18
+ end
19
+ end
20
+ end
21
+
22
+ it "works on a normal access" do
23
+ lambda { get '/' }.should_not raise_error
24
+ last_response.should be_ok
25
+ end
26
+
27
+ it "works when not found" do
28
+ get '/nil'
29
+ last_response.should be_not_found
30
+ end
31
+
32
+ it "works using rack middleware" do
33
+ get '/auth'
34
+ last_response.status.should eq 401
35
+ end
36
+ end
@@ -0,0 +1,63 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/mock_app_helper')
3
+
4
+ describe "Blocking by UA" do
5
+ before do
6
+ mock_app {
7
+ use Rack::Block do
8
+ bot_access do
9
+ path '/foo' do
10
+ halt 404
11
+ end
12
+
13
+ path '/bar' do
14
+ redirect '/'
15
+ end
16
+ end
17
+ end
18
+ run DEFAULT_APP
19
+ }
20
+ end
21
+
22
+ describe "Blocking built-in bot UA pattern" do
23
+
24
+ it "blocks all bot access if no nesting block" do
25
+ mock_app {
26
+ use Rack::Block do
27
+ bot_access do
28
+ halt 404
29
+ end
30
+ end
31
+ run DEFAULT_APP
32
+ }
33
+
34
+ header "User-Agent", "Googlebot"
35
+ ['/', '/any', '/path/blocked'].each do |path|
36
+ get path
37
+ last_response.should be_not_found
38
+ end
39
+ end
40
+
41
+ it "blocks specific paths" do
42
+ mock_app {
43
+ use Rack::Block do
44
+ bot_access do
45
+ path '/foo' do
46
+ halt 404
47
+ end
48
+ end
49
+ end
50
+ run DEFAULT_APP
51
+ }
52
+
53
+ header "User-Agent", "Googlebot"
54
+ get '/'
55
+ last_response.should be_ok
56
+
57
+ get '/foo'
58
+ last_response.should be_not_found
59
+ end
60
+
61
+ it "does not block excepting specified paths"
62
+ end
63
+ end
@@ -0,0 +1,14 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'rack/test'
5
+ require 'rack-block'
6
+
7
+ # Requires supporting files with custom matchers and macros, etc,
8
+ # in ./support/ and its subdirectories.
9
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
10
+
11
+ RSpec.configure do |config|
12
+ #...
13
+ end
14
+
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-block
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.pre1
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Uchio Kondo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-10 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: &76848810 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *76848810
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &76848430 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *76848430
36
+ - !ruby/object:Gem::Dependency
37
+ name: rack-test
38
+ requirement: &76847930 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>'
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *76847930
47
+ - !ruby/object:Gem::Dependency
48
+ name: guard-rspec
49
+ requirement: &76847490 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *76847490
58
+ description: A rack middleware for handling search bot access, ip block, etc.
59
+ email:
60
+ - udzura@udzura.jp
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - .gitignore
66
+ - .rspec
67
+ - Gemfile
68
+ - Gemfile.lock
69
+ - Guardfile
70
+ - Rakefile
71
+ - lib/rack-block.rb
72
+ - lib/rack/block.rb
73
+ - lib/rack/block/dsl.rb
74
+ - lib/rack/block/dsl/matchers.rb
75
+ - lib/rack/block/dsl/responses.rb
76
+ - lib/rack/block/version.rb
77
+ - rack-block.gemspec
78
+ - spec/integrations/mock_app_helper.rb
79
+ - spec/integrations/mock_app_works_spec.rb
80
+ - spec/integrations/ua_blocking_spec.rb
81
+ - spec/spec_helper.rb
82
+ homepage: ''
83
+ licenses: []
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>'
98
+ - !ruby/object:Gem::Version
99
+ version: 1.3.1
100
+ requirements: []
101
+ rubyforge_project: rack-block
102
+ rubygems_version: 1.8.10
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: A rack middleware for handling search bot access, ip block, etc.
106
+ test_files: []