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 +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
|