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 +45 -0
- data/Rakefile +21 -0
- data/VERSION.yml +4 -0
- data/lib/noie.rb +62 -0
- data/test/noie_test.rb +86 -0
- metadata +71 -0
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
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
|