rack-denyie 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/html/default.erb +7 -4
- data/lib/rack-denyie.rb +78 -56
- data/rack-denyie.gemspec +2 -2
- data/test/test_rack-denyie.rb +70 -104
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.1.0
|
data/lib/html/default.erb
CHANGED
@@ -45,19 +45,19 @@
|
|
45
45
|
font-family: Arial, Helvetica, Tahoma, sans-serif;
|
46
46
|
background-image: url("http://digitalstarstudios.com/images/denyie/default_bg.jpg");
|
47
47
|
background-repeat: repeat;
|
48
|
+
text-align: center;
|
48
49
|
}
|
49
50
|
|
50
|
-
|
51
|
+
#container {
|
51
52
|
overflow: auto;
|
52
53
|
margin: 0 auto;
|
53
54
|
margin-top: 100px;
|
54
55
|
padding: 20px 20px 15px 20px;
|
55
56
|
width: 500px;
|
56
|
-
text-align:
|
57
|
+
text-align: left;
|
57
58
|
background-color: #FFFFFF;
|
58
59
|
border: 2px solid #2B445F;
|
59
60
|
}
|
60
|
-
div#container * { text-align: left }
|
61
61
|
|
62
62
|
p, li { font-size: 18px }
|
63
63
|
h1, p { margin-bottom: 10px }
|
@@ -68,7 +68,7 @@
|
|
68
68
|
span { font-weight: bold }
|
69
69
|
|
70
70
|
ul { margin-top: 20px }
|
71
|
-
ul li { float: left;
|
71
|
+
ul li { float: left; margin-bottom: 20px; width: 250px }
|
72
72
|
ul li img { float: left; margin-right: 10px; border: none }
|
73
73
|
|
74
74
|
a, a:visited, a:active {
|
@@ -82,6 +82,9 @@
|
|
82
82
|
|
83
83
|
|
84
84
|
</style>
|
85
|
+
<!--[if lte IE 5]>
|
86
|
+
<style type="text/css">#container { width: 540px } ul li { width: 230px }</style>
|
87
|
+
<![endif]-->
|
85
88
|
</head>
|
86
89
|
<body>
|
87
90
|
<div id="container">
|
data/lib/rack-denyie.rb
CHANGED
@@ -2,76 +2,98 @@ require 'rack'
|
|
2
2
|
require 'erb'
|
3
3
|
|
4
4
|
module Rack
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
5
|
+
|
6
|
+
class DenyIE
|
7
|
+
|
8
|
+
URL_REGEX = %r{\b(([\w-]+://?|[\w\d]+[.])[^\s()<>]+(?:(?:\([\w\d)]+\)[^\s()<>]*)+|([^[:punct:]\s]|/)))} # http://alanstorm.com/url_regex_explained
|
9
|
+
|
10
|
+
# Default Options
|
11
|
+
DEFAULT_MIN_VERSION = 7
|
12
|
+
DEFAULT_HEADLINE = "This version of Internet Explorer is not supported."
|
13
|
+
DEFAULT_SITE = "this site"
|
14
|
+
DEFAULT_TEMPLATE_PATH = ::File.join(::File.dirname(__FILE__), 'html', 'default.erb')
|
15
|
+
|
16
|
+
DEFAULT_REDIRECT_MESSAGE = "Your browser is unsupported."
|
17
|
+
|
18
|
+
def initialize(app, options = {})
|
19
|
+
@app = app
|
20
|
+
@options = {
|
21
|
+
:min_version => DEFAULT_MIN_VERSION, # The minimum version of IE you want allowed through
|
22
|
+
:headline => DEFAULT_HEADLINE, # The headline message displayed to filtered IE users
|
23
|
+
:site_name => DEFAULT_SITE, # Your site name.
|
24
|
+
:template => DEFAULT_TEMPLATE_PATH, # A custom template, either ERB or HTML
|
25
|
+
:redirect_url => nil }.merge options # Redirects users to a new location rather than displaying a template
|
26
|
+
end
|
19
27
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
28
|
+
def call(env)
|
29
|
+
status, @headers, content = @app.call(env)
|
30
|
+
is_unsupported?(env) && is_content_html? ? act_on_ie : @app.call(env)
|
31
|
+
end
|
24
32
|
|
25
|
-
|
33
|
+
private
|
26
34
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
35
|
+
# Uses a regex to filter IE versions
|
36
|
+
def is_unsupported?(env)
|
37
|
+
minimum_version = (@options[:min_version].to_i - 1)
|
38
|
+
env["HTTP_USER_AGENT"].match(/MSIE [0-#{minimum_version}]/) # \.[0-9][0-9]?
|
39
|
+
end
|
31
40
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
def act_on_ie
|
37
|
-
should_redirect? ? redirect_browser : display_template
|
38
|
-
end
|
41
|
+
# Checks if the content is html, this middleware ONLY filters content that is HTML
|
42
|
+
def is_content_html?
|
43
|
+
@headers["Content-Type"] && @headers["Content-Type"].include?("text/html")
|
44
|
+
end
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
# Decides which action to take, either redirect or display template
|
47
|
+
def act_on_ie
|
48
|
+
should_redirect? ? redirect_browser : display_template
|
49
|
+
end
|
43
50
|
|
44
|
-
|
45
|
-
|
46
|
-
|
51
|
+
# Checks if redirection is set
|
52
|
+
def should_redirect?
|
53
|
+
!@options[:redirect_url].nil? && @options[:redirect_url].match(URL_REGEX)
|
54
|
+
end
|
47
55
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
56
|
+
# Redirects the browser to a new location
|
57
|
+
def redirect_browser
|
58
|
+
[302, { 'Location' => @options[:redirect_url] }, DEFAULT_REDIRECT_MESSAGE ]
|
59
|
+
end
|
53
60
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
template.gsub(/\n$/,'')
|
60
|
-
end
|
61
|
+
# Displays the template
|
62
|
+
def display_template
|
63
|
+
response = (::File.extname(@options[:template]) == ".erb") ? ProcessERB.new(@options).bound : ::File.read(@options[:template])
|
64
|
+
[200, @headers, response]
|
65
|
+
end
|
61
66
|
|
62
|
-
|
67
|
+
end
|
63
68
|
|
64
|
-
|
69
|
+
class ProcessERB
|
65
70
|
|
66
|
-
|
67
|
-
|
68
|
-
|
71
|
+
def initialize(options = {})
|
72
|
+
@options = options
|
73
|
+
@erb = ERB.new(::File.read(@options[:template]), nil, "%<>")
|
69
74
|
end
|
75
|
+
|
76
|
+
def bound
|
77
|
+
binding = TemplateVars.new(@options).get_binding # Variables passed to ERB template
|
78
|
+
@template = @erb.result(binding)
|
79
|
+
@template.gsub(/\n$/,'')
|
80
|
+
end
|
81
|
+
|
70
82
|
end
|
83
|
+
|
84
|
+
# Binds the options as template variables (NOTE: This is probably a better way of doing this, I just don't know it.)
|
85
|
+
class TemplateVars
|
86
|
+
|
87
|
+
def initialize(options = {})
|
88
|
+
options.each_pair do |key, value|
|
89
|
+
self.instance_variable_set("@#{key}", value)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def get_binding
|
94
|
+
binding
|
95
|
+
end
|
71
96
|
|
72
|
-
def get_binding
|
73
|
-
binding
|
74
97
|
end
|
75
98
|
|
76
|
-
end
|
77
99
|
end
|
data/rack-denyie.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rack-denyie}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brad Whitcomb"]
|
12
|
-
s.date = %q{2009-
|
12
|
+
s.date = %q{2009-12-03}
|
13
13
|
s.description = %q{Rack middleware that denies specified versions of IE.}
|
14
14
|
s.email = %q{brad@digitalstarstudios.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/test/test_rack-denyie.rb
CHANGED
@@ -6,42 +6,30 @@ class TestRackDenyIE < Test::Unit::TestCase
|
|
6
6
|
BODY = "OK"
|
7
7
|
CUSTOM_TEMPLATE_PATH = File.expand_path(File.join(File.dirname(__FILE__), 'html', 'custom_template.html'))
|
8
8
|
|
9
|
-
def
|
9
|
+
def request(user_agent, options = {}, content_type = 'text/html')
|
10
10
|
app = Rack::Builder.new do
|
11
11
|
use Rack::DenyIE, options
|
12
|
-
run lambda { |env| env["HTTP_USER_AGENT"] = user_agent; [200, {'Content-Type' => content_type},
|
12
|
+
run lambda { |env| env["HTTP_USER_AGENT"] = user_agent; [200, {'Content-Type' => content_type}, BODY ] }
|
13
13
|
end
|
14
14
|
Rack::MockRequest.new(app).get('/')
|
15
15
|
end
|
16
|
-
|
17
|
-
def read_erb(ver)
|
18
|
-
@defaults = {
|
19
|
-
:min_version => ver || 7,
|
20
|
-
:headline => "Your version of Internet Explorer is not supported.",
|
21
|
-
:site_name => "this site",
|
22
|
-
:template => Rack::DenyIE::DEFAULT_TEMPLATE_PATH,
|
23
|
-
:redirect_url => nil
|
24
|
-
}
|
25
|
-
raw = File.read(@defaults[:template])
|
26
|
-
erb = ERB.new(raw, nil, "%<>")
|
27
|
-
binding = Rack::TemplateVars.new(@defaults).get_binding
|
28
|
-
template = erb.result(binding)
|
29
|
-
template.gsub(/\n$/,'')
|
30
|
-
end
|
31
16
|
|
32
|
-
context "When
|
17
|
+
context "When the App" do
|
33
18
|
|
34
|
-
|
19
|
+
# Non-IE Tests
|
20
|
+
|
21
|
+
other_user_agents = [
|
35
22
|
"Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.5) Gecko/Firefox/3.5.5",
|
36
23
|
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; fi-fi) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9",
|
37
24
|
"Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/417.9 (KHTML, like Gecko) Safari/417.8",
|
38
25
|
"Opera/9.64 (X11; Linux i686; U; tr) Presto/2.1.1"
|
39
26
|
]
|
40
27
|
|
41
|
-
|
28
|
+
# Non-IE User Agents
|
29
|
+
other_user_agents.each do |agent|
|
42
30
|
context "encounters a user agent like #{agent}" do
|
43
31
|
setup do
|
44
|
-
@response =
|
32
|
+
@response = request(agent)
|
45
33
|
end
|
46
34
|
should "return original response" do
|
47
35
|
assert_equal BODY, @response.body
|
@@ -49,91 +37,69 @@ class TestRackDenyIE < Test::Unit::TestCase
|
|
49
37
|
end
|
50
38
|
end
|
51
39
|
|
52
|
-
|
53
|
-
setup do
|
54
|
-
user_agent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729)"
|
55
|
-
@response = get_response(user_agent, BODY, "text/html", { :min_version => 8 })
|
56
|
-
end
|
57
|
-
should "return original response" do
|
58
|
-
assert_equal BODY, @response.body
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# IE 6 Tests
|
63
|
-
|
64
|
-
context "encounters supported IE 6" do
|
65
|
-
setup do
|
66
|
-
user_agent = "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
|
67
|
-
@response = get_response(user_agent, BODY, "text/html", { :min_version => 6 })
|
68
|
-
end
|
69
|
-
should "return original response" do
|
70
|
-
assert_equal BODY, @response.body
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
context "encounters unsupported IE 6" do
|
75
|
-
setup do
|
76
|
-
user_agent = "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
|
77
|
-
@response = get_response(user_agent, BODY, "text/html", { :min_version => 7 })
|
78
|
-
end
|
79
|
-
should "return default IE template" do
|
80
|
-
default_template = read_erb(7)
|
81
|
-
|
82
|
-
assert_equal default_template, @response.body
|
83
|
-
end
|
84
|
-
end
|
40
|
+
# Internet Explorer Tests
|
85
41
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
custom_template = File.read(CUSTOM_TEMPLATE_PATH)
|
94
|
-
|
95
|
-
assert_not_equal default_template, @response.body
|
96
|
-
assert_equal custom_template, @response.body
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
# IE 7 Tests
|
101
|
-
|
102
|
-
context "encounters supported IE 7" do
|
103
|
-
setup do
|
104
|
-
user_agent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; Media Center PC 5.0; .NET CLR 1.1.4322; .NET CLR 3.5.21022)"
|
105
|
-
@response = get_response(user_agent, BODY, "text/html", { :min_version => 7 })
|
106
|
-
end
|
107
|
-
should "return original response" do
|
108
|
-
assert_equal BODY, @response.body
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context "encounters unsupported IE 7" do
|
113
|
-
setup do
|
114
|
-
user_agent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; Media Center PC 5.0; .NET CLR 1.1.4322; .NET CLR 3.5.21022)"
|
115
|
-
@response = get_response(user_agent, BODY, "text/html", { :min_version => 8 })
|
116
|
-
end
|
117
|
-
should "return default IE template" do
|
118
|
-
default_template = read_erb(8)
|
119
|
-
|
120
|
-
assert_equal default_template, @response.body
|
121
|
-
end
|
122
|
-
end
|
42
|
+
ie_user_agents = [
|
43
|
+
[8, "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729)"],
|
44
|
+
[7, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; Media Center PC 5.0; .NET CLR 1.1.4322; .NET CLR 3.5.21022)"],
|
45
|
+
[6, "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"],
|
46
|
+
[5, "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"],
|
47
|
+
[4, "Mozilla/4.0 PPC (compatible; MSIE 4.01; Windows CE; PPC; 240x320; Sprint:PPC-6700; PPC; 240x320)"],
|
48
|
+
]
|
123
49
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
50
|
+
# All IE versions with Default Template
|
51
|
+
(4..8).each do |min_ver|
|
52
|
+
ie_user_agents.each do |ie_agent|
|
53
|
+
context "encounters Internet Explorer #{ie_agent[0]}," do
|
54
|
+
setup do
|
55
|
+
@options = { :min_version => min_ver, :headline => "Why are you using IE?", :site_name => "DenyIE Test" }
|
56
|
+
end
|
57
|
+
if ie_agent[0] >= min_ver
|
58
|
+
context "and the browser version (#{ie_agent[0]}) is greater than the minimum version (#{min_ver}), then it" do
|
59
|
+
setup do
|
60
|
+
@response = request(ie_agent[1], @options)
|
61
|
+
end
|
62
|
+
should "return the original body" do
|
63
|
+
assert_equal BODY, @response.body
|
64
|
+
end
|
65
|
+
end
|
66
|
+
else
|
67
|
+
context "if the browser version is less than or equal to #{min_ver}" do
|
68
|
+
context "and there is no custom template specified, then it" do
|
69
|
+
setup do
|
70
|
+
@response = request(ie_agent[1], @options)
|
71
|
+
@options[:template] = Rack::DenyIE::DEFAULT_TEMPLATE_PATH
|
72
|
+
@default_template = Rack::ProcessERB.new(@options).bound
|
73
|
+
end
|
74
|
+
should "return the default template" do
|
75
|
+
assert_equal @default_template, @response.body
|
76
|
+
end
|
77
|
+
end
|
78
|
+
context "and there is a custom template specified, then it" do
|
79
|
+
setup do
|
80
|
+
@options[:template] = CUSTOM_TEMPLATE_PATH
|
81
|
+
@response = request(ie_agent[1], @options)
|
82
|
+
@custom_template = File.read(CUSTOM_TEMPLATE_PATH)
|
83
|
+
end
|
84
|
+
should "return the custom template" do
|
85
|
+
assert_equal @custom_template, @response.body
|
86
|
+
end
|
87
|
+
end
|
88
|
+
context "and a redirection url is specified, then it" do
|
89
|
+
setup do
|
90
|
+
@options[:redirect_url] = "http://browsehappy.org"
|
91
|
+
@response = request(ie_agent[1], @options)
|
92
|
+
end
|
93
|
+
should "redirect the user to the new location" do
|
94
|
+
assert_equal @response.status, 302
|
95
|
+
assert_equal @response.headers["Location"], "http://browsehappy.org"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end # Context
|
99
|
+
end # Conditional
|
100
|
+
end # Context
|
101
|
+
end # Array
|
102
|
+
end # Loop
|
137
103
|
|
138
104
|
end
|
139
105
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-denyie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brad Whitcomb
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-12-03 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|