rack-bouncer 1.2.1 → 1.3.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.
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  pkg/*
2
2
  .DS_Store
3
3
  *.gem
4
+ *.tmproj
data/README.md CHANGED
@@ -4,13 +4,14 @@ A Rack middleware that expels undesirable browsers out of your website. This pro
4
4
 
5
5
  | _Browser_ | _Undesirable Versions_ |
6
6
  |-------------------|------------------------|
7
- | Internet Explorer | < 8 |
7
+ | Internet Explorer | < 8.0 |
8
+ | Firefox | < 4.0 |
8
9
  | AOL | All |
9
10
 
10
11
  ## usage
11
12
 
12
13
  gem install rack-bouncer
13
- require "rack/bouncer"
14
+ require "rack-bouncer"
14
15
 
15
16
  The default redirects users to [Browse Happy](http://browsehappy.com/):
16
17
 
@@ -24,11 +25,15 @@ You can redirect users to a URL as well:
24
25
 
25
26
  use Rack::Bouncer, :redirect => "http://slashdot.org"
26
27
 
27
- You can even specify a minimum version of IE like so:
28
+ You can specify a minimum version of IE like so:
28
29
 
29
30
  use Rack::Bouncer, :redirect => "http://slashdot.org", :minimum_ie => 6.0
30
31
 
31
- You can even specify a set of safe paths:
32
+ You can specify a minimum version of Firefox like so:
33
+
34
+ use Rack::Bouncer, :redirect => "http://slashdot.org", :minimum_firefox => 3.6
35
+
36
+ You can specify a set of safe paths:
32
37
 
33
38
  use Rack::Bouncer, :safe_paths => ["/asset", "/images", "/stylesheets", "/javascripts", "/feedback"]
34
39
 
@@ -0,0 +1,2 @@
1
+ # encoding: UTF-8
2
+ require "rack/bouncer"
data/lib/rack/bouncer.rb CHANGED
@@ -2,12 +2,13 @@
2
2
 
3
3
  module Rack
4
4
  class Bouncer
5
- VERSION = "1.2.1"
5
+ VERSION = "1.3.0"
6
6
 
7
7
  DEFAULT_OPTIONS = {
8
- :safe_paths => ["/asset", "/images", "/stylesheets", "/javascripts", "/feedback"],
9
- :redirect => "http://browsehappy.com/",
10
- :minimum_ie => 8.0
8
+ :safe_paths => ["/asset", "/images", "/stylesheets", "/javascripts", "/feedback"],
9
+ :redirect => "http://browsehappy.com/",
10
+ :minimum_ie => 8.0,
11
+ :minimum_firefox => 4.0
11
12
  }
12
13
 
13
14
  def initialize(app, options = {})
@@ -16,49 +17,76 @@ module Rack
16
17
  end
17
18
 
18
19
  def call(env)
19
- if !safe_path(env) && (ie6_found_in?(env) || aol_found_in?(env))
20
- kick_it
21
- else
22
- @app.call(env)
20
+ return @app.call(env) if safe_path?(env)
21
+ return @app.call(env) if user_agent_blank?(env)
22
+
23
+ user_agent = env["HTTP_USER_AGENT"]
24
+
25
+ if undesirable_ie_present?(user_agent) ||
26
+ undesirable_aol_present?(user_agent) ||
27
+ undesirable_firefox_present?(user_agent)
28
+ return kick_it
23
29
  end
30
+
31
+ @app.call(env)
24
32
  end
25
33
 
26
34
  private
27
35
 
28
- def safe_path(env)
29
- path = env["PATH_INFO"]
30
- safe_paths = @options[:safe_paths].join("|")
36
+ def safe_path?(env)
37
+ return true if @options[:redirect] == env["PATH_INFO"]
38
+ return env["PATH_INFO"] =~ Regexp.new("^(#{@options[:safe_paths].join("|")})")
39
+ end
31
40
 
32
- path == @options[:redirect] || path =~ Regexp.new("^(#{safe_paths})")
41
+ def user_agent_blank?(env)
42
+ env["HTTP_USER_AGENT"].nil? || env["HTTP_USER_AGENT"].empty?
33
43
  end
34
44
 
35
- def ie6_found_in?(env)
36
- if env["HTTP_USER_AGENT"]
37
- is_ie?(env["HTTP_USER_AGENT"]) and ie_version(env["HTTP_USER_AGENT"]) < @options[:minimum_ie] and @options[:redirect] != env["PATH_INFO"]
38
- end
45
+ def kick_it
46
+ [302, {"Location" => @options[:redirect], "Content-Type" => "text/html"}, "Browser not supported"]
47
+ end
48
+
49
+ # Internet Explorer
50
+ ###############################################################################################
51
+
52
+ def undesirable_ie_present?(user_agent)
53
+ is_ie?(user_agent) && ie_version(user_agent) < @options[:minimum_ie]
39
54
  end
40
55
 
41
- def is_ie?(ua_string)
56
+ def is_ie?(user_agent)
42
57
  # We need at least one digit to be able to get the version, hence the \d
43
- ua_string.match(/MSIE \d/) ? true : false
58
+ user_agent.match(/MSIE \d/) ? true : false
44
59
  end
45
60
 
46
- def aol_found_in?(env)
47
- if env["HTTP_USER_AGENT"]
48
- is_aol?(env["HTTP_USER_AGENT"])
49
- end
61
+ def ie_version(user_agent)
62
+ user_agent.match(/MSIE (\S+)/)[1].to_f
50
63
  end
51
64
 
52
- def is_aol?(ua_string)
53
- ua_string.match(/AOL \d/) ? true : false
65
+ # AOL
66
+ ###############################################################################################
67
+
68
+ def undesirable_aol_present?(user_agent)
69
+ is_aol?(user_agent)
54
70
  end
55
71
 
56
- def ie_version(ua_string)
57
- ua_string.match(/MSIE (\S+)/)[1].to_f
72
+ def is_aol?(user_agent)
73
+ user_agent.match(/AOL \d/) ? true : false
58
74
  end
59
75
 
60
- def kick_it
61
- [302, {"Location" => @options[:redirect], "Content-Type" => "text/html"}, "Browser not supported"]
76
+ # Firefox
77
+ ###############################################################################################
78
+
79
+ def undesirable_firefox_present?(user_agent)
80
+ is_firefox?(user_agent) && firefox_version(user_agent) < @options[:minimum_firefox]
81
+ end
82
+
83
+ def is_firefox?(user_agent)
84
+ # We need at least one digit to be able to get the version, hence the \d
85
+ user_agent.match(/Firefox\/\d/) ? true : false
86
+ end
87
+
88
+ def firefox_version(user_agent)
89
+ user_agent.match(/Firefox\/(\S+)/)[1].to_f
62
90
  end
63
91
  end
64
92
  end
data/rack-bouncer.gemspec CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
5
5
  s.name = "rack-bouncer"
6
6
  s.version = Rack::Bouncer::VERSION
7
7
  s.platform = Gem::Platform::RUBY
8
- s.authors = ["Jerod Santo", "Julio Cesar Ody", "Will Jessop", "Ryan Sobol"]
8
+ s.authors = ["Julio Cesar Ody", "Jerod Santo", "Will Jessop", "Ryan Sobol"]
9
9
  s.email = "contact@ryansobol.com"
10
10
  s.homepage = "https://github.com/ryansobol/rack-bouncer"
11
11
  s.summary = "A Rack middleware that expels undesirable browsers out of your website."
@@ -3,7 +3,7 @@ require "rubygems"
3
3
  require "minitest/autorun"
4
4
  require "rack/mock"
5
5
 
6
- require "rack/bouncer"
6
+ require "rack-bouncer"
7
7
 
8
8
  class TestApp
9
9
  def call(env)
@@ -18,7 +18,7 @@ end
18
18
  class Rack::Bouncer::Test < MiniTest::Unit::TestCase
19
19
 
20
20
  def test_version
21
- assert_equal "1.2.1", Rack::Bouncer::VERSION
21
+ assert_equal "1.3.0", Rack::Bouncer::VERSION
22
22
  end
23
23
 
24
24
  def test_default_safe_paths
@@ -34,6 +34,10 @@ class Rack::Bouncer::Test < MiniTest::Unit::TestCase
34
34
  assert_equal 8.0, Rack::Bouncer::DEFAULT_OPTIONS[:minimum_ie]
35
35
  end
36
36
 
37
+ def test_default_minimum_firefox
38
+ assert_equal 4.0, Rack::Bouncer::DEFAULT_OPTIONS[:minimum_firefox]
39
+ end
40
+
37
41
  def test_allows_if_no_user_agent_specified
38
42
  request = create_request
39
43
  response = request.get("/")
@@ -175,6 +179,48 @@ class Rack::Bouncer::Test < MiniTest::Unit::TestCase
175
179
  # Firefox
176
180
  #################################################################################################
177
181
 
182
+ def test_expels_firefox_3_6
183
+ request = create_request
184
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0(Windows; U; Windows NT 5.2; rv:1.9.2) Gecko/20100101 Firefox/3.6" })
185
+ assert_equal 302, response.status
186
+ assert_equal response.location, "http://browsehappy.com/"
187
+ end
188
+
189
+ def test_allows_firefox_3_6_when_minimum
190
+ request = create_request(:minimum_firefox => 3.6)
191
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0(Windows; U; Windows NT 5.2; rv:1.9.2) Gecko/20100101 Firefox/3.6" })
192
+ assert_equal 200, response.status
193
+ assert_equal "Hi Internets!", response.body
194
+ end
195
+
196
+ def test_expels_firefox_3_6_2
197
+ request = create_request
198
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2" })
199
+ assert_equal 302, response.status
200
+ assert_equal response.location, "http://browsehappy.com/"
201
+ end
202
+
203
+ def test_expels_firefox_3_6_b5
204
+ request = create_request
205
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b5) Gecko/20091204 Firefox/3.6b5" })
206
+ assert_equal 302, response.status
207
+ assert_equal response.location, "http://browsehappy.com/"
208
+ end
209
+
210
+ def test_expels_firefox_3_6_22
211
+ request = create_request
212
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.4; en-US; rv:1.9.2.22) Gecko/20110902 Firefox/3.6.22" })
213
+ assert_equal 302, response.status
214
+ assert_equal response.location, "http://browsehappy.com/"
215
+ end
216
+
217
+ def test_expels_firefox_3_8
218
+ request = create_request
219
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/20121223 Ubuntu/9.25 (jaunty) Firefox/3.8" })
220
+ assert_equal 302, response.status
221
+ assert_equal response.location, "http://browsehappy.com/"
222
+ end
223
+
178
224
  def test_allows_firefox_4
179
225
  request = create_request
180
226
  response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0" })
@@ -182,6 +228,48 @@ class Rack::Bouncer::Test < MiniTest::Unit::TestCase
182
228
  assert_equal "Hi Internets!", response.body
183
229
  end
184
230
 
231
+ def test_allows_firefox_4_0_1
232
+ request = create_request
233
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20110518 Firefox/4.0.1" })
234
+ assert_equal 200, response.status
235
+ assert_equal "Hi Internets!", response.body
236
+ end
237
+
238
+ def test_allows_firefox_5
239
+ request = create_request
240
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0 (Windows NT 5.1; U; rv:5.0) Gecko/20100101 Firefox/5.0" })
241
+ assert_equal 200, response.status
242
+ assert_equal "Hi Internets!", response.body
243
+ end
244
+
245
+ def test_allows_firefox_6
246
+ request = create_request
247
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0 (Windows NT 6.1; rv:6.0) Gecko/20110814 Firefox/6.0" })
248
+ assert_equal 200, response.status
249
+ assert_equal "Hi Internets!", response.body
250
+ end
251
+
252
+ def test_allows_firefox_9
253
+ request = create_request
254
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0" })
255
+ assert_equal 200, response.status
256
+ assert_equal "Hi Internets!", response.body
257
+ end
258
+
259
+ def test_allows_firefox_9_0_a2
260
+ request = create_request
261
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0a2) Gecko/20111101 Firefox/9.0a2" })
262
+ assert_equal 200, response.status
263
+ assert_equal "Hi Internets!", response.body
264
+ end
265
+
266
+ def test_allows_firefox_10_0_a4
267
+ request = create_request
268
+ response = request.get("/", {"HTTP_USER_AGENT" => "Mozilla/6.0 (Macintosh; I; Intel Mac OS X 11_7_9; de-LI; rv:1.9b4) Gecko/2012010317 Firefox/10.0a4" })
269
+ assert_equal 200, response.status
270
+ assert_equal "Hi Internets!", response.body
271
+ end
272
+
185
273
  # Safari
186
274
  #################################################################################################
187
275
 
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-bouncer
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 2
9
- - 1
10
- version: 1.2.1
8
+ - 3
9
+ - 0
10
+ version: 1.3.0
11
11
  platform: ruby
12
12
  authors:
13
- - Jerod Santo
14
13
  - Julio Cesar Ody
14
+ - Jerod Santo
15
15
  - Will Jessop
16
16
  - Ryan Sobol
17
17
  autorequire:
@@ -68,6 +68,7 @@ files:
68
68
  - Gemfile.lock
69
69
  - README.md
70
70
  - Rakefile
71
+ - lib/rack-bouncer.rb
71
72
  - lib/rack/bouncer.rb
72
73
  - rack-bouncer.gemspec
73
74
  - test/lib/rack/bouncer_test.rb