rack-mobile-detect 0.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/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +21 -0
- data/README.md +75 -0
- data/Rakefile +55 -0
- data/TODO +2 -0
- data/VERSION.yml +5 -0
- data/lib/rack-mobile-detect.rb +150 -0
- data/test/helper.rb +10 -0
- data/test/test_rack-mobile-detect.rb +191 -0
- data/util/echo_env.rb +20 -0
- metadata +79 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2009 Tom Alison
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
Overview
|
2
|
+
========
|
3
|
+
|
4
|
+
`Rack::MobileDetect` detects mobile devices and adds an
|
5
|
+
`X_MOBILE_DEVICE` header to the request if a mobile device is
|
6
|
+
detected. The strategy for detecting a mobile device is as
|
7
|
+
follows:
|
8
|
+
|
9
|
+
### Targeted Detection ###
|
10
|
+
|
11
|
+
Search for a 'targeted' mobile device. A targeted mobile device is a
|
12
|
+
device you may want to provide special content to because it has
|
13
|
+
advanced capabilities - for example and iPhone or Android phone.
|
14
|
+
Targeted mobile devices are detected via a `Regexp` applied against
|
15
|
+
the HTTP User-Agent header.
|
16
|
+
|
17
|
+
By default, the targeted devices are iPhone, Android and iPod. If a
|
18
|
+
targeted device is detected, the token match from the regular
|
19
|
+
expression will be the value passed in the `X_MOBILE_DEVICE` header,
|
20
|
+
i.e.: `X_MOBILE_DEVICE: iPhone`
|
21
|
+
|
22
|
+
|
23
|
+
### UAProf Detection ###
|
24
|
+
|
25
|
+
Search for a UAProf device. More about UAProf detection can be found
|
26
|
+
[here](http://www.developershome.com/wap/detection/detection.asp?page=profileHeader).
|
27
|
+
|
28
|
+
If a UAProf device is detected, it will have `X_MOBILE_DEVICE: true`
|
29
|
+
|
30
|
+
### Accept Header Detection ###
|
31
|
+
|
32
|
+
Look at the HTTP Accept header to see if the device accepts WAP
|
33
|
+
content. More information about this form of detection is found
|
34
|
+
[here](http://www.developershome.com/wap/detection/detection.asp?page=httpHeaders).
|
35
|
+
|
36
|
+
Any device detected using this method will have `X_MOBILE_DEVICE: true`
|
37
|
+
|
38
|
+
### Catchall Detection ###
|
39
|
+
|
40
|
+
Use a 'catch-all' regex. The current catch-all regex was taken from
|
41
|
+
the [mobile-fu project](http://github.com/brendanlim/mobile-fu)
|
42
|
+
|
43
|
+
Any device detected using this method will have `X_MOBILE_DEVICE: true`
|
44
|
+
|
45
|
+
Notes
|
46
|
+
=====
|
47
|
+
|
48
|
+
If none of the detection methods detect a mobile device, the
|
49
|
+
`X_MOBILE_DEVICE` header will be _absent_.
|
50
|
+
|
51
|
+
Note that `Rack::MobileDetect::X_HEADER` holds the string
|
52
|
+
'X\_MOBILE\_DEVICE' that is inserted into the request headers.
|
53
|
+
|
54
|
+
Usage
|
55
|
+
=====
|
56
|
+
|
57
|
+
use Rack::MobileDetect
|
58
|
+
|
59
|
+
This allows you to do mobile device detection with the defaults.
|
60
|
+
|
61
|
+
use Rack::MobileDetect, :targeted => /SCH-\w*$|[Bb]lack[Bb]erry\w*/
|
62
|
+
|
63
|
+
In this usage you can set the value of the regular expression used to
|
64
|
+
target particular devices. This regular expression captures Blackberry
|
65
|
+
and Samsung SCH-* model phones. For example, if a phone with the
|
66
|
+
user-agent: 'BlackBerry9000/4.6.0.167 Profile/MIDP-2.0
|
67
|
+
Configuration/CLDC-1.1 VendorID/102' connects, the value of
|
68
|
+
`X_MOBILE_DEVICE` will be set to 'BlackBerry9000'
|
69
|
+
|
70
|
+
use Rack::MobileDetect, :catchall => /mydevice/i
|
71
|
+
|
72
|
+
This allows you to limit the catchall expression to only the device
|
73
|
+
list you choose.
|
74
|
+
|
75
|
+
See the unit test source code for more info.
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "rack-mobile-detect"
|
8
|
+
gem.summary = %Q{Rack middleware for ruby webapps to detect mobile devices.}
|
9
|
+
gem.description = %Q{Rack::MobileDetect detects mobile devices and adds an
|
10
|
+
X_MOBILE_DEVICE header to the request if a mobile device is detected. Specific
|
11
|
+
devices can be targeted with custom Regexps.}
|
12
|
+
gem.email = "accounts@majortom.fastmail.us"
|
13
|
+
gem.homepage = "http://github.com/talison/rack-mobile-detect"
|
14
|
+
gem.authors = ["Tom Alison"]
|
15
|
+
gem.add_development_dependency "shoulda", ">= 0"
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
Jeweler::GemcutterTasks.new
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rake/testtask'
|
24
|
+
Rake::TestTask.new(:test) do |test|
|
25
|
+
test.libs << 'lib' << 'test'
|
26
|
+
test.pattern = 'test/**/test_*.rb'
|
27
|
+
test.verbose = true
|
28
|
+
end
|
29
|
+
|
30
|
+
begin
|
31
|
+
require 'rcov/rcovtask'
|
32
|
+
Rcov::RcovTask.new do |test|
|
33
|
+
test.libs << 'test'
|
34
|
+
test.pattern = 'test/**/test_*.rb'
|
35
|
+
test.verbose = true
|
36
|
+
end
|
37
|
+
rescue LoadError
|
38
|
+
task :rcov do
|
39
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
task :test => :check_dependencies
|
44
|
+
|
45
|
+
task :default => :test
|
46
|
+
|
47
|
+
require 'rake/rdoctask'
|
48
|
+
Rake::RDocTask.new do |rdoc|
|
49
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
50
|
+
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "rack-mobile-detect #{version}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
data/TODO
ADDED
data/VERSION.yml
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
# The MIT License
|
2
|
+
#
|
3
|
+
# Copyright (c) 2009 Tom Alison
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
module Rack
|
24
|
+
#
|
25
|
+
# Full project at http://github.com/talison/rack-mobile-detect
|
26
|
+
#
|
27
|
+
# Rack::MobileDetect detects mobile devices and adds an
|
28
|
+
# X_MOBILE_DEVICE header to the request if a mobile device is
|
29
|
+
# detected. The strategy for detecting a mobile device is as
|
30
|
+
# follows:
|
31
|
+
#
|
32
|
+
# 1. Search for a 'targeted' mobile device. A targeted mobile device
|
33
|
+
# is a mobile device you may want to provide special content to
|
34
|
+
# because it has advanced capabilities - for example and iPhone or
|
35
|
+
# Android device. Targeted mobile devices are detected via a Regexp
|
36
|
+
# applied against the HTTP User-Agent header.
|
37
|
+
#
|
38
|
+
# By default, the targeted devices are iPhone, Android and iPod. If
|
39
|
+
# a targeted device is detected, the token match from the regular
|
40
|
+
# expression will be the value passed in the X_MOBILE_DEVICE header,
|
41
|
+
# i.e.: X_MOBILE_DEVICE: iPhone
|
42
|
+
#
|
43
|
+
# 2. Search for a UAProf device. More about UAProf detection can be
|
44
|
+
# found here:
|
45
|
+
# http://www.developershome.com/wap/detection/detection.asp?page=profileHeader
|
46
|
+
#
|
47
|
+
# If a UAProf device is detected, the value of X_MOBILE_DEVICE is
|
48
|
+
# simply set to 'true'.
|
49
|
+
#
|
50
|
+
# 3. Look at the HTTP Accept header to see if the device accepts WAP
|
51
|
+
# content. More information about this form of detection is found
|
52
|
+
# here:
|
53
|
+
# http://www.developershome.com/wap/detection/detection.asp?page=httpHeaders
|
54
|
+
#
|
55
|
+
# Any device detected using this method will have X_MOBILE_DEVICE
|
56
|
+
# set to 'true'.
|
57
|
+
#
|
58
|
+
# 4. Use a 'catch-all' regex. The current catch-all regex was taken
|
59
|
+
# from the mobile-fu project. See:
|
60
|
+
# http://github.com/brendanlim/mobile-fu
|
61
|
+
#
|
62
|
+
# Any device detected using this method will have X_MOBILE_DEVICE
|
63
|
+
# set to 'true'.
|
64
|
+
#
|
65
|
+
# If none of the detection methods detected a mobile device, the
|
66
|
+
# X_MOBILE_DEVICE header will be absent.
|
67
|
+
#
|
68
|
+
# Note that Rack::MobileDetect::X_HEADER holds the string
|
69
|
+
# 'X_MOBILE_DEVICE' that is inserted into the request headers.
|
70
|
+
#
|
71
|
+
# Usage:
|
72
|
+
# use Rack::MobileDetect
|
73
|
+
#
|
74
|
+
# This allows you to do mobile device detection with the defaults.
|
75
|
+
#
|
76
|
+
# use Rack::MobileDetect, :targeted => /SCH-\w*$|[Bb]lack[Bb]erry\w*/
|
77
|
+
#
|
78
|
+
# In this usage you can set the value of the regular expression used
|
79
|
+
# to target particular devices. This regular expression captures
|
80
|
+
# Blackberry and Samsung SCH-* model phones. For example, if a phone
|
81
|
+
# with the user-agent: 'BlackBerry9000/4.6.0.167 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/102'
|
82
|
+
# connects, the value of X_MOBILE_DEVICE will be set to 'BlackBerry9000'
|
83
|
+
#
|
84
|
+
# use Rack::MobileDetect, :catchall => /mydevice/i
|
85
|
+
#
|
86
|
+
# This allows you to limit the catchall expression to only the
|
87
|
+
# device list you choose.
|
88
|
+
#
|
89
|
+
# See the unit test source code for more info.
|
90
|
+
#
|
91
|
+
# Author: Tom Alison (tom.alison at gmail.com)
|
92
|
+
# License: MIT
|
93
|
+
#
|
94
|
+
class MobileDetect
|
95
|
+
X_HEADER = 'X_MOBILE_DEVICE'
|
96
|
+
|
97
|
+
# Users can pass in a :targeted option, which should be a Regexp
|
98
|
+
# specifying which user-agent agent tokens should be specifically
|
99
|
+
# captured and passed along in the X_MOBILE_DEVICE variable.
|
100
|
+
#
|
101
|
+
# The :catchall option allows specifying a Regexp to catch mobile
|
102
|
+
# devices that fall through the other tests.
|
103
|
+
def initialize(app, options = {})
|
104
|
+
@app = app
|
105
|
+
|
106
|
+
# @ua_targeted holds a list of user-agent tokens that are
|
107
|
+
# captured. Captured tokens are passed through in the
|
108
|
+
# environment variable. These are special mobile devices that
|
109
|
+
# may have special rendering capabilities for you to target.
|
110
|
+
@regex_ua_targeted = options[:targeted] || /iphone|android|ipod/i
|
111
|
+
|
112
|
+
# Match mobile content in Accept header:
|
113
|
+
# http://www.developershome.com/wap/detection/detection.asp?page=httpHeaders
|
114
|
+
@regex_accept = /vnd\.wap/i
|
115
|
+
|
116
|
+
# From mobile-fu: http://github.com/brendanlim/mobile-fu
|
117
|
+
@regex_ua_catchall = options[:catchall] ||
|
118
|
+
Regexp.new('palm|palmos|palmsource|iphone|blackberry|nokia|phone|midp|mobi|pda|' +
|
119
|
+
'wap|java|nokia|hand|symbian|chtml|wml|ericsson|lg|audiovox|motorola|' +
|
120
|
+
'samsung|sanyo|sharp|telit|tsm|mobile|mini|windows ce|smartphone|' +
|
121
|
+
'240x320|320x320|mobileexplorer|j2me|sgh|portable|sprint|vodafone|' +
|
122
|
+
'docomo|kddi|softbank|pdxgw|j-phone|astel|minimo|plucker|netfront|' +
|
123
|
+
'xiino|mot-v|mot-e|portalmmm|sagem|sie-s|sie-m|android|ipod', true)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Because the web app may be multithreaded, this method must
|
127
|
+
# create new Regexp instances to ensure thread safety.
|
128
|
+
def call(env)
|
129
|
+
device = nil
|
130
|
+
user_agent = env.fetch('HTTP_USER_AGENT', '')
|
131
|
+
|
132
|
+
# First check for targeted devices and store the device token
|
133
|
+
device = Regexp.new(@regex_ua_targeted).match(user_agent)
|
134
|
+
|
135
|
+
# Fall-back on UAProf detection
|
136
|
+
# http://www.developershome.com/wap/detection/detection.asp?page=profileHeader
|
137
|
+
device ||= env.keys.detect { |k| k.start_with?('HTTP_') && k.end_with?('_PROFILE') } != nil
|
138
|
+
|
139
|
+
# Fall back to Accept header detection
|
140
|
+
device ||= Regexp.new(@regex_accept).match(env.fetch('HTTP_ACCEPT','')) != nil
|
141
|
+
|
142
|
+
# Fall back on catch-all User-Agent regex
|
143
|
+
device ||= Regexp.new(@regex_ua_catchall).match(user_agent) != nil
|
144
|
+
|
145
|
+
env[X_HEADER] = device.to_s if device
|
146
|
+
|
147
|
+
@app.call(env)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestRackMobileDetect < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "An app with mobile-device defaults" do
|
6
|
+
setup do
|
7
|
+
@app = test_app
|
8
|
+
@rack = Rack::MobileDetect.new(@app)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "not detect a non-mobile device" do
|
12
|
+
env = test_env
|
13
|
+
@rack.call(env)
|
14
|
+
assert !env.key?(x_mobile)
|
15
|
+
end
|
16
|
+
|
17
|
+
should "detect all default targeted devices" do
|
18
|
+
env = test_env({ 'HTTP_USER_AGENT' => ipod })
|
19
|
+
@rack.call(env)
|
20
|
+
assert_equal 'iPod', env[x_mobile]
|
21
|
+
|
22
|
+
env = test_env({ 'HTTP_USER_AGENT' => iphone })
|
23
|
+
@rack.call(env)
|
24
|
+
assert_equal 'iPhone', env[x_mobile]
|
25
|
+
|
26
|
+
env = test_env({ 'HTTP_USER_AGENT' => android })
|
27
|
+
@rack.call(env)
|
28
|
+
assert_equal 'Android', env[x_mobile]
|
29
|
+
end
|
30
|
+
|
31
|
+
should "detect UAProf device" do
|
32
|
+
env = test_env({ 'HTTP_X_WAP_PROFILE' =>
|
33
|
+
'"http://www.blackberry.net/go/mobile/profiles/uaprof/9000_80211g/4.6.0.rdf"' })
|
34
|
+
@rack.call(env)
|
35
|
+
assert_equal "true", env[x_mobile]
|
36
|
+
|
37
|
+
env = test_env({ 'HTTP_PROFILE' =>
|
38
|
+
'http://www.blackberry.net/go/mobile/profiles/uaprof/9000_80211g/4.6.0.rdf' })
|
39
|
+
@rack.call(env)
|
40
|
+
assert_equal "true", env[x_mobile]
|
41
|
+
|
42
|
+
# See http://www.developershome.com/wap/detection/detection.asp?page=uaprof
|
43
|
+
env = test_env({ 'HTTP_80_PROFILE' =>
|
44
|
+
'http://wap.sonyericsson.com/UAprof/T68R502.xml' })
|
45
|
+
@rack.call(env)
|
46
|
+
assert_equal "true", env[x_mobile]
|
47
|
+
end
|
48
|
+
|
49
|
+
should "not detect spurious profile header match" do
|
50
|
+
env = test_env({ 'HTTP_X_PROFILE_FOO' => 'bar' })
|
51
|
+
@rack.call(env)
|
52
|
+
assert !env.key?(x_mobile)
|
53
|
+
end
|
54
|
+
|
55
|
+
should "detect wap in Accept header" do
|
56
|
+
env = test_env({ 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/vnd.wap.xhtml+xml,*/*;q=0.5' })
|
57
|
+
@rack.call(env)
|
58
|
+
assert_equal "true", env[x_mobile]
|
59
|
+
|
60
|
+
env = test_env({ 'HTTP_ACCEPT' => 'application/vnd.wap.wmlscriptc;q=0.7,text/vnd.wap.wml;q=0.7,*/*;q=0.5' })
|
61
|
+
@rack.call(env)
|
62
|
+
assert_equal "true", env[x_mobile]
|
63
|
+
end
|
64
|
+
|
65
|
+
should "detect additional devices in catchall" do
|
66
|
+
env = test_env({ 'HTTP_USER_AGENT' => blackberry })
|
67
|
+
@rack.call(env)
|
68
|
+
assert_equal "true", env[x_mobile]
|
69
|
+
|
70
|
+
env = test_env({ 'HTTP_USER_AGENT' => samsung })
|
71
|
+
@rack.call(env)
|
72
|
+
assert_equal "true", env[x_mobile]
|
73
|
+
|
74
|
+
env = test_env({ 'HTTP_USER_AGENT' => 'opera' })
|
75
|
+
@rack.call(env)
|
76
|
+
assert !env.key?(x_mobile)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "An app with a custom targeted option" do
|
81
|
+
setup do
|
82
|
+
@app = test_app
|
83
|
+
# Target Samsung SCH and Blackberries. Note case-sensitivity.
|
84
|
+
@rack = Rack::MobileDetect.new(@app, :targeted => /SCH-\w*$|[Bb]lack[Bb]erry\w*/)
|
85
|
+
end
|
86
|
+
|
87
|
+
should "capture the targeted token" do
|
88
|
+
env = test_env({ 'HTTP_USER_AGENT' => samsung })
|
89
|
+
@rack.call(env)
|
90
|
+
assert_equal 'SCH-U960', env[x_mobile]
|
91
|
+
|
92
|
+
env = test_env({ 'HTTP_USER_AGENT' => "Samsung SCH-I760" })
|
93
|
+
@rack.call(env)
|
94
|
+
assert_equal 'SCH-I760', env[x_mobile]
|
95
|
+
|
96
|
+
env = test_env({ 'HTTP_USER_AGENT' => blackberry })
|
97
|
+
@rack.call(env)
|
98
|
+
assert_equal 'BlackBerry9000', env[x_mobile]
|
99
|
+
|
100
|
+
# An iPhone will be detected, but the token won't be captured
|
101
|
+
env = test_env({ 'HTTP_USER_AGENT' => iphone })
|
102
|
+
@rack.call(env)
|
103
|
+
assert_equal "true", env[x_mobile]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "An app with a custom catchall option" do
|
108
|
+
setup do
|
109
|
+
@app = test_app
|
110
|
+
# Custom catchall regex
|
111
|
+
@rack = Rack::MobileDetect.new(@app, :catchall => /mysupermobiledevice/i)
|
112
|
+
end
|
113
|
+
|
114
|
+
should "catch only the specified devices" do
|
115
|
+
env = test_env({ 'HTTP_USER_AGENT' => "MySuperMobileDevice v1.0" })
|
116
|
+
@rack.call(env)
|
117
|
+
assert_equal "true", env[x_mobile]
|
118
|
+
|
119
|
+
env = test_env({ 'HTTP_USER_AGENT' => samsung })
|
120
|
+
@rack.call(env)
|
121
|
+
assert !env.key?(x_mobile)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Expected x_header
|
126
|
+
def x_mobile
|
127
|
+
Rack::MobileDetect::X_HEADER
|
128
|
+
end
|
129
|
+
|
130
|
+
# User agents for testing
|
131
|
+
def ipod
|
132
|
+
'Mozilla/5.0 (iPod; U; CPU iPhone OS 2_2 like Mac OS X; en-us) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5G77 Safari/525.20'
|
133
|
+
end
|
134
|
+
|
135
|
+
def iphone
|
136
|
+
'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7C144 Safari/528.16'
|
137
|
+
end
|
138
|
+
|
139
|
+
def android
|
140
|
+
'Mozilla/5.0 (Linux; U; Android 2.0; ld-us; sdk Build/ECLAIR) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17'
|
141
|
+
end
|
142
|
+
|
143
|
+
def blackberry
|
144
|
+
'BlackBerry9000/4.6.0.167 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/102'
|
145
|
+
end
|
146
|
+
|
147
|
+
def samsung
|
148
|
+
'Mozilla/4.0 (compatible; MSIE 6.0; BREW 3.1.5; en )/800x480 Samsung SCH-U960'
|
149
|
+
end
|
150
|
+
|
151
|
+
# Our test web app. Doesn't do anything.
|
152
|
+
def test_app()
|
153
|
+
Class.new { def call(app); true; end }.new
|
154
|
+
end
|
155
|
+
|
156
|
+
# Test environment variables
|
157
|
+
def test_env(overwrite = {})
|
158
|
+
{
|
159
|
+
'GATEWAY_INTERFACE'=> 'CGI/1.2',
|
160
|
+
'HTTP_ACCEPT'=> 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
161
|
+
'HTTP_ACCEPT_CHARSET'=> 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
|
162
|
+
'HTTP_ACCEPT_ENCODING'=> 'gzip,deflate',
|
163
|
+
'HTTP_ACCEPT_LANGUAGE'=> 'en-us,en;q=0.5',
|
164
|
+
'HTTP_CONNECTION'=> 'keep-alive',
|
165
|
+
'HTTP_HOST'=> 'localhost:4567',
|
166
|
+
'HTTP_KEEP_ALIVE'=> 300,
|
167
|
+
'HTTP_USER_AGENT'=> 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.3) Gecko/20090920 Firefox/3.5.3 (Swiftfox)',
|
168
|
+
'HTTP_VERSION'=> 'HTTP/1.1',
|
169
|
+
'PATH_INFO'=> '/',
|
170
|
+
'QUERY_STRING'=> '',
|
171
|
+
'REMOTE_ADDR'=> '127.0.0.1',
|
172
|
+
'REQUEST_METHOD'=> 'GET',
|
173
|
+
'REQUEST_PATH'=> '/',
|
174
|
+
'REQUEST_URI'=> '/',
|
175
|
+
'SCRIPT_NAME'=> '',
|
176
|
+
'SERVER_NAME'=> 'localhost',
|
177
|
+
'SERVER_PORT'=> '4567',
|
178
|
+
'SERVER_PROTOCOL'=> 'HTTP/1.1',
|
179
|
+
'SERVER_SOFTWARE'=> 'Mongrel 1.1.5',
|
180
|
+
'rack.multiprocess'=> false,
|
181
|
+
'rack.multithread'=> true,
|
182
|
+
'rack.request.form_hash'=> '',
|
183
|
+
'rack.request.form_vars'=> '',
|
184
|
+
'rack.request.query_hash'=> '',
|
185
|
+
'rack.request.query_string'=> '',
|
186
|
+
'rack.run_once'=> false,
|
187
|
+
'rack.url_scheme'=> 'http',
|
188
|
+
'rack.version'=> '1: 0'
|
189
|
+
}.merge(overwrite)
|
190
|
+
end
|
191
|
+
end
|
data/util/echo_env.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
+
|
6
|
+
require 'rack-mobile-detect'
|
7
|
+
|
8
|
+
use Rack::MobileDetect
|
9
|
+
|
10
|
+
# Very simple sinatra app that allows debugging of the headers with
|
11
|
+
# Rack::MobileDetect. Also useful for looking at various mobile phone
|
12
|
+
# headers.
|
13
|
+
get '/' do
|
14
|
+
content_type 'text/plain'
|
15
|
+
env_string = env.sort.map{ |v| v.join(': ') }.join("\n") + "\n"
|
16
|
+
# Print to log if debug is passed, i.e.:
|
17
|
+
# http://localhost:4567/?debug
|
18
|
+
puts env_string if params.key?('debug')
|
19
|
+
env_string
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-mobile-detect
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tom Alison
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-29 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: shoulda
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: |-
|
26
|
+
Rack::MobileDetect detects mobile devices and adds an
|
27
|
+
X_MOBILE_DEVICE header to the request if a mobile device is detected. Specific
|
28
|
+
devices can be targeted with custom Regexps.
|
29
|
+
email: accounts@majortom.fastmail.us
|
30
|
+
executables: []
|
31
|
+
|
32
|
+
extensions: []
|
33
|
+
|
34
|
+
extra_rdoc_files:
|
35
|
+
- LICENSE
|
36
|
+
- README.md
|
37
|
+
files:
|
38
|
+
- .document
|
39
|
+
- .gitignore
|
40
|
+
- LICENSE
|
41
|
+
- README.md
|
42
|
+
- Rakefile
|
43
|
+
- TODO
|
44
|
+
- VERSION.yml
|
45
|
+
- lib/rack-mobile-detect.rb
|
46
|
+
- test/helper.rb
|
47
|
+
- test/test_rack-mobile-detect.rb
|
48
|
+
- util/echo_env.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/talison/rack-mobile-detect
|
51
|
+
licenses: []
|
52
|
+
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options:
|
55
|
+
- --charset=UTF-8
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.3.5
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Rack middleware for ruby webapps to detect mobile devices.
|
77
|
+
test_files:
|
78
|
+
- test/test_rack-mobile-detect.rb
|
79
|
+
- test/helper.rb
|