user_agent_sanitizer 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.md +45 -0
- data/Rakefile +45 -0
- data/lib/user_agent_sanitizer.rb +62 -0
- data/spec/spec_helper.rb +0 -0
- data/spec/user_agent_sanitizer_spec.rb +52 -0
- data/user_agent_sanitizer.gemspec +25 -0
- metadata +59 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Wes Oldenbeuving
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
User agent sanitizer
|
2
|
+
====================
|
3
|
+
|
4
|
+
Parse a HTTP user agent and attempt to return something that means something to a human.
|
5
|
+
|
6
|
+
Example:
|
7
|
+
|
8
|
+
require 'user_agent_sanitizer'
|
9
|
+
|
10
|
+
UserAgentSanitizer.sanitize_user_agent('Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A405 Safari/7534.48.3')
|
11
|
+
# => 'iPhone'
|
12
|
+
|
13
|
+
UserAgentSanitizer.sanitize_user_agent('Mozilla/5.0 (Linux; U; Android 2.3.3; nl-nl; SAMSUNG GT-I9100/I9100BUKE5 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1')
|
14
|
+
# => 'Samsung GT-I9100'
|
15
|
+
|
16
|
+
Installation
|
17
|
+
------------
|
18
|
+
|
19
|
+
Via rubygems
|
20
|
+
|
21
|
+
gem install user_agent_sanitizer
|
22
|
+
|
23
|
+
Bundler:
|
24
|
+
|
25
|
+
# Gemfile
|
26
|
+
gem 'user_agent_sanitizer'
|
27
|
+
|
28
|
+
From source:
|
29
|
+
|
30
|
+
rake install
|
31
|
+
|
32
|
+
New devices
|
33
|
+
-----------
|
34
|
+
|
35
|
+
Every time I encounter a new user agent that does not resolve to something useful, I add it as a test case and tweak the parser until all tested headers are correctly parsed. See [the spec](http://github.com/Narnach/user_agent_sanitizer/blob/master/spec/user_agent_sanitizer_spec.rb)
|
36
|
+
|
37
|
+
Contributing
|
38
|
+
------------
|
39
|
+
|
40
|
+
Create a Github issue and/or send a pull request.
|
41
|
+
|
42
|
+
Contributors
|
43
|
+
------------
|
44
|
+
|
45
|
+
* [Wes 'Narnach' Oldenbeuving](http://narnach.com/)
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rdoc/task'
|
3
|
+
require "rake/gempackagetask"
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Generate documentation for the file_wrapper plugin.'
|
9
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'FileWrapper'
|
12
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
13
|
+
rdoc.rdoc_files.include('README')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
begin
|
18
|
+
# Parse gemspec using the github safety level.
|
19
|
+
data = File.read('user_agent_sanitizer.gemspec')
|
20
|
+
spec = nil
|
21
|
+
Thread.new { spec = eval("$SAFE = 3\n%s" % data)}.join
|
22
|
+
|
23
|
+
# Create the gem tasks
|
24
|
+
Rake::GemPackageTask.new(spec) do |package|
|
25
|
+
package.gem_spec = spec
|
26
|
+
end
|
27
|
+
rescue Exception => e
|
28
|
+
printf "WARNING: Error caught (%s): %s\n", e.class.name, e.message
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Package and install the gem for the current version'
|
32
|
+
task :install => :gem do
|
33
|
+
system "sudo gem install -l pkg/file_wrapper-%s.gem" % spec.version
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'rspec/core/rake_task'
|
37
|
+
|
38
|
+
desc 'Default: run specs.'
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
desc "Run specs"
|
42
|
+
RSpec::Core::RakeTask.new do |t|
|
43
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
44
|
+
# Put spec opts in a file named .rspec in root
|
45
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module UserAgentSanitizer
|
2
|
+
extend self
|
3
|
+
|
4
|
+
BRANDS=["nokia", "samsung", "SonyEricsson", "BlackBerry", "htc", "sec", 'gt', 'iphone']
|
5
|
+
|
6
|
+
def sanitize_user_agent(string)
|
7
|
+
string = string.to_s
|
8
|
+
return nil if string.empty?
|
9
|
+
result = basic_user_agent_recognizer(string)
|
10
|
+
result.gsub!(/^SAMSUNG/i, 'Samsung')
|
11
|
+
result.gsub!(/^GT/i, 'Samsung GT')
|
12
|
+
result.gsub!(/^Samsung GT\s+/i, 'Samsung GT-')
|
13
|
+
result.gsub!(/^Desire(_\w+)/i, 'HTC Desire')
|
14
|
+
result = "SonyEricsson #{$1}" if result =~ /^SonyEricsson(\w+)/i
|
15
|
+
result.strip!
|
16
|
+
result.squeeze!(" ")
|
17
|
+
result
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def basic_user_agent_recognizer(string)
|
23
|
+
case string
|
24
|
+
when /(Mac OS X) (\d+_\d+_\d+)/
|
25
|
+
return "#{$1} #{$2.gsub("_", ".")}"
|
26
|
+
when /(LG|sagem)[\-\/](\w+)/i
|
27
|
+
return "#{$1} #{$2}"
|
28
|
+
when /(MSIE) (\d+(\.\d+)*)/
|
29
|
+
return "#{$1} #{$2}"
|
30
|
+
when /(Blackberry) ?(\d+)/i
|
31
|
+
return "#{$1} #{$2}"
|
32
|
+
when /(HTC)[_\/]([a-z0-9]+)?/i
|
33
|
+
return [$1, $2].compact.join(" ")
|
34
|
+
when /(Samsung)[\/\-]([a-z0-9]+)([\/\-]([a-z0-9]+))?/i
|
35
|
+
return [$1, $2, $4].compact.join(" ")
|
36
|
+
when /\((Linux; U; Android.*)\)/
|
37
|
+
return $1.split(";").last.split("/").first.gsub(/build/i, "").strip
|
38
|
+
when /(iPod)/
|
39
|
+
return $1
|
40
|
+
when /((#{BRANDS.join("|")}).*?)\//i
|
41
|
+
result=$1
|
42
|
+
|
43
|
+
result.gsub!(/build/i, "")
|
44
|
+
result.gsub!(/-1/, "")
|
45
|
+
result.gsub!(/-/, " ")
|
46
|
+
|
47
|
+
if result=~/(.+?);/
|
48
|
+
result = $1
|
49
|
+
end
|
50
|
+
|
51
|
+
if result=~/(\D+)([A-Z]+\d+)/
|
52
|
+
result="#{$1} #{$2}"
|
53
|
+
elsif result=~/(\D+)(\d+)/
|
54
|
+
result="#{$1} #{$2}"
|
55
|
+
end
|
56
|
+
|
57
|
+
return result
|
58
|
+
else
|
59
|
+
return string
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/spec_helper.rb
ADDED
File without changes
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'user_agent_sanitizer'
|
4
|
+
|
5
|
+
describe UserAgentSanitizer do
|
6
|
+
describe "sanitize_user_agent" do
|
7
|
+
{
|
8
|
+
'BlackBerry8520/4.6.1.296 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/150' => 'BlackBerry 8520',
|
9
|
+
'BlackBerry8900/4.6.1.199 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/302' => 'BlackBerry 8900',
|
10
|
+
'LG-GD510/V100 Teleca/WAP2.0 Profile/MIDP-2.1 Configuration/CLDC-1.1' => 'LG GD510',
|
11
|
+
'LG/KU990/v10a Browser/Obigo-Q05A/3.6 MMS/LG-MMS-V1.0/1.2 Java/ASVM/1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1' => 'LG KU990',
|
12
|
+
'Mozilla/5.0 (Linux; U; Android 2.1-update1; nl-nl; Desire_A8181 Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17' => 'HTC Desire',
|
13
|
+
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; GTB0.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30618)' => 'MSIE 7.0',
|
14
|
+
'Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; nl) AppleWebKit/534.1+ (KHTML, like Gecko) Version/6.0.0.246 Mobile Safari/534.1+' => 'BlackBerry 9800',
|
15
|
+
'Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A405 Safari/7534.48.3' => 'iPhone',
|
16
|
+
'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8L1 Safari/6533.18.5' => 'iPhone',
|
17
|
+
'Mozilla/5.0 (iPhone; U; CPU like Mac OS X; nl-nl) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A102 Safari/419.3' => 'iPhone',
|
18
|
+
'Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F190 Safari/6533.18.5' => 'iPod',
|
19
|
+
'Mozilla/5.0 (SAMSUNG; SAMSUNG-GT-S8500/S8500XXJEC; U; Bada/1.0; nl-nl) AppleWebKit/533.1 (KHTML, like Gecko) Dolfin/2.0 Mobile WVGA SMM-MMS/1.2.0 OPN-B' => 'Samsung GT-S8500',
|
20
|
+
'HTC_Touch2_T3333 Opera/9.50 (Windows NT 5.1; U; nl)' => 'HTC Touch2',
|
21
|
+
'Mozilla/5.0 (Linux; U; Android 1.5; en-gb; HTC Magic Build/CRB17) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1' => 'HTC Magic',
|
22
|
+
'Mozilla/5.0 (Linux; U; Android 1.5; nl-nl; GT-I5700 Build/CUPCAKE) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1' => 'Samsung GT-I5700',
|
23
|
+
'Mozilla/5.0 (Linux; U; Android 2.1; nl-nl; HTC Legend Build/ERD79) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17' => 'HTC Legend',
|
24
|
+
'Mozilla/5.0 (Linux; U; Android 2.2.1; es-es; Vodafone 858 Build/Vodafone858C02B617) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1' => 'Vodafone 858',
|
25
|
+
'Mozilla/5.0 (Linux; U; Android 2.2; es-es; Light Pro Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1' => 'Light Pro',
|
26
|
+
'Mozilla/5.0 (Linux; U; Android 2.2; nl-nl; HTC_DesireZ_A7272 Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1' => 'HTC DesireZ',
|
27
|
+
'Mozilla/5.0 (Linux; U; Android 2.3.3; nl-nl; GT-I9100 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1' => 'Samsung GT-I9100',
|
28
|
+
'Mozilla/5.0 (Linux; U; Android 2.3.3; nl-nl; HTC/DesireS/1.32.161.2 Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1' => 'HTC DesireS',
|
29
|
+
'Mozilla/5.0 (Linux; U; Android 2.3.3; nl-nl; SAMSUNG GT-I9100/I9100BUKE5 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1' => 'Samsung GT-I9100',
|
30
|
+
'Mozilla/5.0 (Linux; U; Android 2.3.5; es-es; ZTE Skate Build/V1.0.0B03) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1' => 'ZTE Skate',
|
31
|
+
'Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus One Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1' => 'Nexus One',
|
32
|
+
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; nl-nl) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.2 Safari/525.20.1' => 'Mac OS X 10.5.5',
|
33
|
+
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10' => 'Mac OS X 10.6.2',
|
34
|
+
'Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaE90-1/07.24.0.3; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413' => 'Nokia E90',
|
35
|
+
'Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaE75-1/110.48.125 Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413' => 'Nokia E75',
|
36
|
+
'Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0 Samsung/I8910; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Version/3.0 Safari/525' => 'Samsung I8910',
|
37
|
+
'Opera/9.80 (BlackBerry; Opera Mini/5.1.22303/24.871; U; pt) Presto/2.5.25 Version/10.54' => 'BlackBerry',
|
38
|
+
'SAGEM-my411C/1.0/ MIDP-2.0 Configuration/CLDC-1.1 Browser/UP.Browser/7.2.6.c.1.386 (GUI)' => 'SAGEM my411C',
|
39
|
+
'SAMSUNG-GT-C3510/C3510XXIL4 NetFront/3.5 Profile/MIDP-2.0 Configuration/CLDC-1.1' => 'Samsung GT-C3510',
|
40
|
+
'SAMSUNG-SGH-L600/L600ASGI3 Profile/MIDP-2.0 Configuration/CLDC-1.1 UP.Browser/6.2.3.3.c.1.101 (GUI) MMP/2.0' => 'Samsung SGH L600',
|
41
|
+
'SEC-SGHM620/1.0 Openwave/6.2.3 Profile/MIDP-2.0 Configuration/CLDC-1.1 UP.Browser/6.2.3.3.c.1.101 (GUI) MMP/2.0' => 'SEC SGH M620',
|
42
|
+
'SonyEricssonW995/R1FA Browser/NetFront/3.4 Profile/MIDP-2.1 Configuration/CLDC-1.1 JavaPlatform/JP-8.4.3' => 'SonyEricsson W995',
|
43
|
+
'Mozilla/5.0 (Linux; U; Android 1.6; nl-nl; SonyEricssonX10i Build/R1FA016) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1' => 'SonyEricsson X10i',
|
44
|
+
'' => nil,
|
45
|
+
nil => nil,
|
46
|
+
}.each do |user_agent, device_name|
|
47
|
+
it "should return #{device_name.inspect} for #{user_agent.inspect}" do
|
48
|
+
UserAgentSanitizer.sanitize_user_agent(user_agent).should == device_name
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
# Project
|
3
|
+
s.name = 'user_agent_sanitizer'
|
4
|
+
s.summary = "Browser user agent sanitizer"
|
5
|
+
s.description = "Browser user agent sanitizer, with a focus on sanitizing mobile phone user agents to brand + model number"
|
6
|
+
s.version = '1.0.0'
|
7
|
+
s.date = '2002-06-15'
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Wes Oldenbeuving"]
|
10
|
+
s.email = "narnach@gmail.com"
|
11
|
+
s.homepage = "http://www.github.com/Narnach/user_agent_sanitizer"
|
12
|
+
|
13
|
+
# Files
|
14
|
+
s.require_path = "lib"
|
15
|
+
s.files = ['user_agent_sanitizer.gemspec', 'LICENSE', 'README.md', 'Rakefile', 'lib/user_agent_sanitizer.rb', 'spec/user_agent_sanitizer_spec.rb', 'spec/spec_helper.rb']
|
16
|
+
s.test_files = ['spec/user_agent_sanitizer_spec.rb']
|
17
|
+
|
18
|
+
# rdoc
|
19
|
+
s.has_rdoc = true
|
20
|
+
s.extra_rdoc_files = %w[ README.md LICENSE]
|
21
|
+
s.rdoc_options << '--inline-source' << '--line-numbers' << '--main' << 'README.md'
|
22
|
+
|
23
|
+
# Requirements
|
24
|
+
s.required_ruby_version = ">= 1.9.3"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: user_agent_sanitizer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Wes Oldenbeuving
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2002-06-15 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Browser user agent sanitizer, with a focus on sanitizing mobile phone
|
15
|
+
user agents to brand + model number
|
16
|
+
email: narnach@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files:
|
20
|
+
- README.md
|
21
|
+
- LICENSE
|
22
|
+
files:
|
23
|
+
- user_agent_sanitizer.gemspec
|
24
|
+
- LICENSE
|
25
|
+
- README.md
|
26
|
+
- Rakefile
|
27
|
+
- lib/user_agent_sanitizer.rb
|
28
|
+
- spec/user_agent_sanitizer_spec.rb
|
29
|
+
- spec/spec_helper.rb
|
30
|
+
homepage: http://www.github.com/Narnach/user_agent_sanitizer
|
31
|
+
licenses: []
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options:
|
34
|
+
- --inline-source
|
35
|
+
- --line-numbers
|
36
|
+
- --main
|
37
|
+
- README.md
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.9.3
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.8.11
|
55
|
+
signing_key:
|
56
|
+
specification_version: 3
|
57
|
+
summary: Browser user agent sanitizer
|
58
|
+
test_files:
|
59
|
+
- spec/user_agent_sanitizer_spec.rb
|