robworley-rack-noie 1.0

Sign up to get free protection for your applications and to get access to all the features.
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