robworley-rack-noie 1.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/README.markdown ADDED
@@ -0,0 +1,45 @@
1
+ # rack-noie
2
+
3
+ rack-noie is the coolest rack middleware ever created. And it is so because it does _everyone_
4
+ a favor: it shows the way out of your website to poor souls out there using Internet Explorer 6.
5
+
6
+ # installation
7
+
8
+ sudo gem install robworley-rack-noie
9
+
10
+ # usage
11
+
12
+ just
13
+
14
+ require 'noie'
15
+
16
+ and
17
+
18
+ use Rack::NoIE, :redirect => '/noieplease.html'
19
+
20
+ the above will redirect to a page noieplease.html in your website. You can redirect to
21
+ a URL as well, like so
22
+
23
+ use Rack::NoIE, :redirect => 'http://slashdot.org'
24
+
25
+ you can also define specific regex patterns or paths to redirect
26
+
27
+ use Rack::NoIE, :only => /^\/admin\//
28
+
29
+ or define specific regex patterns or paths as exceptions
30
+
31
+ use Rack::NoIE, :except => /^\/admin\//
32
+ use Rack::NoIE, :except => "/login"
33
+ use Rack::NoIE, :except => ["/home", "/login"]
34
+
35
+ or let the default kick in
36
+
37
+ use Rack::NoIE
38
+
39
+ # disclaimer
40
+
41
+ I'm a nice guy. I'm so nice that the default URL points to Microsoft's IE8 upgrade page.
42
+
43
+ # license
44
+
45
+ MIT, as usual.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'rake/testtask'
2
+
3
+ task :default => [:test]
4
+
5
+ Rake::TestTask.new do |task|
6
+ task.pattern = 'test/noie_test.rb'
7
+ task.warning, task.verbose = true, true
8
+ end
9
+
10
+ begin
11
+ require 'jeweler'
12
+ Jeweler::Tasks.new do |gemspec|
13
+ gemspec.name = "rack-noie"
14
+ gemspec.summary = "A Rack middleware to redirect IE users out of your website"
15
+ gemspec.email = "julioody@gmail.com"
16
+ gemspec.homepage = "http://github.com/juliocesar/rack-noie"
17
+ gemspec.authors = ["Julio Cesar Ody"]
18
+ end
19
+ rescue LoadError
20
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
21
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 0
3
+ :major: 1
4
+ :minor: 0
data/lib/noie.rb ADDED
@@ -0,0 +1,62 @@
1
+ module Rack
2
+ class NoIE
3
+ def initialize(app, options = {})
4
+ @app = app
5
+ @options = options
6
+ @options[:redirect] ||= 'http://www.microsoft.com/windows/internet-explorer/default.aspx'
7
+ @options[:minimum] ||= 7.0
8
+ end
9
+
10
+ def call(env)
11
+ if enforce_noie?(env) && ie_found_in?(env)
12
+ kick_it
13
+ else
14
+ @app.call(env)
15
+ end
16
+ end
17
+
18
+ private
19
+ def ie_found_in?(env)
20
+ if env['HTTP_USER_AGENT']
21
+ is_ie?(env['HTTP_USER_AGENT']) and ie_version(env['HTTP_USER_AGENT']) < @options[:minimum] and @options[:redirect] != env['PATH_INFO']
22
+ end
23
+ end
24
+
25
+ def is_ie?(ua_string)
26
+ # We need at least one digit to be able to get the version, hence the \d
27
+ ua_string.match(/MSIE \d/) ? true : false
28
+ end
29
+
30
+ def ie_version(ua_string)
31
+ ua_string.match(/MSIE (\S+)/)[1].to_f
32
+ end
33
+
34
+ def kick_it
35
+ [301, {'Location' => @options[:redirect]}, ['Fail browser is fail']]
36
+ end
37
+
38
+ def enforce_noie?(env)
39
+ request = Rack::Request.new(env)
40
+ if @options[:only]
41
+ match_rule?(request.path, @options[:only])
42
+ elsif @options[:except]
43
+ !match_rule?(request.path, @options[:except])
44
+ else
45
+ true
46
+ end
47
+ end
48
+
49
+ # matches a path against a rule
50
+ # Accepts a string path, a regex matcher or an array of these
51
+ def match_rule?(path, options)
52
+ rules = [options].flatten
53
+ rules.any? do |pattern|
54
+ if pattern.is_a?(Regexp)
55
+ path =~ pattern
56
+ else
57
+ path[0, pattern.length] == pattern
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
data/test/noie_test.rb ADDED
@@ -0,0 +1,86 @@
1
+ require 'test/unit'
2
+
3
+ require 'rubygems'
4
+ require 'rack/mock'
5
+
6
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'noie')
7
+
8
+ class TestApp
9
+ def call(env)
10
+ [200, {}, ['Hi Internets!']]
11
+ end
12
+ end
13
+
14
+ class NoieTest < Test::Unit::TestCase
15
+
16
+ def test_redirects_to_where_it_should_if_ie
17
+ request = Rack::MockRequest.new(Rack::NoIE.new(TestApp.new, {:redirect => 'http://slashdot.org'}))
18
+ response = request.get('/', {'HTTP_USER_AGENT' => 'MSIE 6.0' })
19
+ assert_equal 301, response.status
20
+ assert_equal response.location, 'http://slashdot.org'
21
+ end
22
+
23
+ def test_redirects_to_where_it_should_if_user_specified_minimum_not_met
24
+ request = Rack::MockRequest.new(Rack::NoIE.new(TestApp.new, {:redirect => 'http://slashdot.org', :minimum => 6.0}))
25
+ response = request.get('/', {'HTTP_USER_AGENT' => 'Mozilla/4.0 (compatible; MSIE 5.5b1; Mac_PowerPC)' })
26
+ assert_equal 301, response.status
27
+ assert_equal response.location, 'http://slashdot.org'
28
+ end
29
+
30
+ def test_redirects_to_local_urls
31
+ request = Rack::MockRequest.new(Rack::NoIE.new(TestApp.new, {:redirect => '/foo'}))
32
+ response = request.get('/foo', {'HTTP_USER_AGENT' => 'MSIE 6.0' })
33
+ assert_equal "Hi Internets!", response.body
34
+ end
35
+
36
+ def test_allows_if_not_ie
37
+ request = Rack::MockRequest.new(Rack::NoIE.new(TestApp.new, {:redirect => 'http://slashdot.org'}))
38
+ response = request.get('/', {'HTTP_USER_AGENT' => 'Mozilla/5.0'})
39
+ assert_equal "Hi Internets!", response.body
40
+ end
41
+
42
+ def test_allows_if_UA_version_greater_than_minimum
43
+ request = Rack::MockRequest.new(Rack::NoIE.new(TestApp.new, {:redirect => 'http://slashdot.org'}))
44
+ response = request.get('/', {'HTTP_USER_AGENT' => 'Mozilla/4.0 (compatible; MSIE 8.0; Windows XP)'})
45
+ assert_equal "Hi Internets!", response.body
46
+ end
47
+
48
+ def test_allows_if_no_UA_version_no_available
49
+ request = Rack::MockRequest.new(Rack::NoIE.new(TestApp.new, {:redirect => 'http://slashdot.org'}))
50
+ response = request.get('/', {'HTTP_USER_AGENT' => 'Mozilla/4.0 (compatible; MSIE l4me; Windows XP)'})
51
+ assert_equal "Hi Internets!", response.body
52
+ end
53
+
54
+ def test_allows_if_no_user_agent_specified
55
+ request = Rack::MockRequest.new(Rack::NoIE.new(TestApp.new, {:redirect => 'http://slashdot.org'}))
56
+ response = request.get('/')
57
+ assert_equal "Hi Internets!", response.body
58
+ end
59
+
60
+ def test_except_option_allows_request_if_path_is_in_list
61
+ request = Rack::MockRequest.new(Rack::NoIE.new(TestApp.new, {:redirect => 'http://slashdot.org', :except => '/ie6permitted'}))
62
+ response = request.get('/ie6permitted', {'HTTP_USER_AGENT' => 'MSIE 6.0' })
63
+ assert_equal "Hi Internets!", response.body
64
+ end
65
+
66
+ def test_except_option_redirects_if_path_is_not_in_list
67
+ request = Rack::MockRequest.new(Rack::NoIE.new(TestApp.new, {:redirect => 'http://slashdot.org', :except => '/ie6permitted'}))
68
+ response = request.get('/', {'HTTP_USER_AGENT' => 'MSIE 6.0' })
69
+ assert_equal 301, response.status
70
+ assert_equal response.location, 'http://slashdot.org'
71
+ end
72
+
73
+ def test_only_option_allows_request_if_path_is_not_in_list
74
+ request = Rack::MockRequest.new(Rack::NoIE.new(TestApp.new, {:redirect => 'http://slashdot.org', :only => '/ie6notpermitted'}))
75
+ response = request.get('/', {'HTTP_USER_AGENT' => 'MSIE 6.0' })
76
+ assert_equal "Hi Internets!", response.body
77
+ end
78
+
79
+ def test_only_option_redirects_if_path_is_in_list
80
+ request = Rack::MockRequest.new(Rack::NoIE.new(TestApp.new, {:redirect => 'http://slashdot.org', :only => '/ie6notpermitted'}))
81
+ response = request.get('/ie6notpermitted', {'HTTP_USER_AGENT' => 'MSIE 6.0' })
82
+ assert_equal 301, response.status
83
+ assert_equal response.location, 'http://slashdot.org'
84
+ end
85
+
86
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: robworley-rack-noie
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ version: "1.0"
10
+ platform: ruby
11
+ authors:
12
+ - Julio Cesar Ody
13
+ - Rob Worley
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2009-05-11 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description:
23
+ email: robert.worley@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - README.markdown
30
+ files:
31
+ - README.markdown
32
+ - Rakefile
33
+ - VERSION.yml
34
+ - lib/noie.rb
35
+ - test/noie_test.rb
36
+ has_rdoc: true
37
+ homepage: http://github.com/robworley/rack-noie
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options:
42
+ - --charset=UTF-8
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ hash: 3
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.4.2
67
+ signing_key:
68
+ specification_version: 2
69
+ summary: A Rack middleware to redirect IE6 users out of your website
70
+ test_files:
71
+ - test/noie_test.rb