class DeviceDetector::ClientHint

Constants

REGEX_CACHE
ROOT

Attributes

app_name[R]
browser_list[R]
full_version[R]
headers[R]
mobile[R]
model[R]
platform[R]
platform_version[R]

Public Class Methods

new(headers) click to toggle source
# File lib/device_detector/client_hint.rb, line 13
def initialize(headers)
  return if headers.nil?

  @headers = headers
  @full_version = extract_full_version
  @browser_list = extract_browser_list
  @app_name = extract_app_name
  @platform = extract_platform
  @platform_version = extract_platform_version
  @mobile = extract_mobile
  @model = extract_model
end

Public Instance Methods

browser_name() click to toggle source
# File lib/device_detector/client_hint.rb, line 29
def browser_name
  return 'Iridium' if iridium?
  return '360 Secure Browser' if secure_browser?

  browser_name_from_list || app_name
end
os_family() click to toggle source
# File lib/device_detector/client_hint.rb, line 59
def os_family
  return if os_short_name.nil?

  DeviceDetector::OS::FAMILY_TO_OS[os_short_name]
end
os_name() click to toggle source
# File lib/device_detector/client_hint.rb, line 44
def os_name
  return 'Android' if android_app?
  return 'Lineage OS' if lineage_os_app?
  return 'Fire OS' if fire_os_app?
  return unless ['Windows', 'Chromium OS'].include?(platform)

  platform
end
os_short_name() click to toggle source
# File lib/device_detector/client_hint.rb, line 53
def os_short_name
  return if os_name.nil?

  DeviceDetector::OS::DOWNCASED_OPERATING_SYSTEMS[os_name.downcase]
end
os_version() click to toggle source
# File lib/device_detector/client_hint.rb, line 36
def os_version
  return windows_version if platform == 'Windows'
  return lineage_version if lineage_os_app?
  return fire_os_version if fire_os_app?

  platform_version
end

Private Instance Methods

android_app?() click to toggle source

github.com/matomo-org/device-detector/blob/28211c6f411528abf41304e07b886fdf322a49b7/Parser/OperatingSystem.php#L330

# File lib/device_detector/client_hint.rb, line 68
def android_app?
  %w[com.hisense.odinbrowser com.seraphic.openinet.pre
     com.appssppa.idesktoppcbrowser every.browser.inc].include?(app_name_from_headers)
end
app_name_from_headers() click to toggle source
# File lib/device_detector/client_hint.rb, line 140
def app_name_from_headers
  return if headers.nil?

  headers['http-x-requested-with'] ||
    headers['X-Requested-With'] ||
    headers['x-requested-with']
end
available_browsers() click to toggle source
# File lib/device_detector/client_hint.rb, line 90
def available_browsers
  DeviceDetector::Browser::AVAILABLE_BROWSERS.values
end
available_osses() click to toggle source
# File lib/device_detector/client_hint.rb, line 94
def available_osses
  DeviceDetector::OS::OPERATING_SYSTEMS.values
end
browser_name_from_list() click to toggle source

github.com/matomo-org/device-detector/blob/75d88bbefb0182f9207c9f48dc39b1bc8c7cc43f/Parser/Client/Browser.php#L1076-L1079

# File lib/device_detector/client_hint.rb, line 84
def browser_name_from_list
  @browser_name_from_list ||= browser_list&.reject do |b|
    ['Chromium', 'Microsoft Edge'].include?(b.name)
  end&.last&.name
end
extract_app_name() click to toggle source
# File lib/device_detector/client_hint.rb, line 148
def extract_app_name
  requested_with = app_name_from_headers
  return if requested_with.nil?

  hint_app_names[requested_with]
end
extract_browser_list() click to toggle source
# File lib/device_detector/client_hint.rb, line 175
def extract_browser_list
  extract_browser_list_from_full_version_list ||
    extract_browser_list_from_header('Sec-CH-UA') ||
    extract_browser_list_from_header('Sec-CH-UA-Full-Version-List')
end
extract_browser_list_from_full_version_list() click to toggle source
# File lib/device_detector/client_hint.rb, line 199
def extract_browser_list_from_full_version_list
  return if headers['fullVersionList'].nil? && headers['brands'].nil?

  (headers['brands'] || headers['fullVersionList']).map do |item|
    name = name_from_known_browsers(item['brand'])
    next if name.nil?

    HintBrowser.new(name, full_version || item['version'])
  end.compact
end
extract_browser_list_from_header(header) click to toggle source
# File lib/device_detector/client_hint.rb, line 181
def extract_browser_list_from_header(header)
  return if headers[header].nil?

  headers[header].split(', ').map do |component|
    name_and_version = extract_browser_name_and_version(component)
    next if name_and_version[:name].nil?

    HintBrowser.new(name_and_version[:name], name_and_version[:version])
  end.compact
end
extract_browser_name_and_version(component) click to toggle source
# File lib/device_detector/client_hint.rb, line 192
def extract_browser_name_and_version(component)
  component_and_version = component.gsub('"', '').split("\;v=")
  name = name_from_known_browsers(component_and_version.first)
  browser_version = full_version&.gsub('"', '') || component_and_version.last
  { name: name, version: browser_version }
end
extract_from_header(header) click to toggle source
# File lib/device_detector/client_hint.rb, line 223
def extract_from_header(header)
  return if headers[header].nil? || headers[header] == ''

  headers[header]
end
extract_full_version() click to toggle source
# File lib/device_detector/client_hint.rb, line 229
def extract_full_version
  extract_from_header('Sec-CH-UA-Full-Version') || extract_from_header('uaFullVersion')
end
extract_mobile() click to toggle source
# File lib/device_detector/client_hint.rb, line 241
def extract_mobile
  extract_from_header('Sec-CH-UA-Mobile') || extract_from_header('mobile')
end
extract_model() click to toggle source
# File lib/device_detector/client_hint.rb, line 245
def extract_model
  extract_from_header('Sec-CH-UA-Model') || extract_from_header('model')
end
extract_platform() click to toggle source
# File lib/device_detector/client_hint.rb, line 233
def extract_platform
  extract_from_header('Sec-CH-UA-Platform') || extract_from_header('platform')
end
extract_platform_version() click to toggle source
# File lib/device_detector/client_hint.rb, line 237
def extract_platform_version
  extract_from_header('Sec-CH-UA-Platform-Version') || extract_from_header('platformVersion')
end
fire_os_app?() click to toggle source

github.com/matomo-org/device-detector/blob/67ae11199a5129b42fa8b985d372ea834104fe3a/Parser/OperatingSystem.php#L449-L456

# File lib/device_detector/client_hint.rb, line 74
def fire_os_app?
  app_name_from_headers == 'org.mozilla.tv.firefox'
end
fire_os_version() click to toggle source
# File lib/device_detector/client_hint.rb, line 113
def fire_os_version
  DeviceDetector::OS
    .mapped_os_version(platform_version, DeviceDetector::OS::FIRE_OS_VERSION_MAPPING)
end
hint_app_names() click to toggle source
# File lib/device_detector/client_hint.rb, line 155
def hint_app_names
  DeviceDetector.cache.get_or_set('hint_app_names') do
    load_hint_app_names.flatten.reduce({}, :merge)
  end
end
hint_filenames() click to toggle source
# File lib/device_detector/client_hint.rb, line 161
def hint_filenames
  %w[client/hints/browsers.yml client/hints/apps.yml]
end
hint_filepaths() click to toggle source
# File lib/device_detector/client_hint.rb, line 165
def hint_filepaths
  hint_filenames.map do |filename|
    [filename.to_sym, File.join(ROOT, 'regexes', filename)]
  end
end
iridium?() click to toggle source

github.com/matomo-org/device-detector/blob/67ae11199a5129b42fa8b985d372ea834104fe3a/Parser/Client/Browser.php#L923-L929 If the version reported from the client hints is YYYY or YYYY.MM (e.g., 2022 or 2022.04), then it is the Iridium browser iridiumbrowser.de/news/

# File lib/device_detector/client_hint.rb, line 122
def iridium?
  return if browser_list.nil?

  !browser_list.find do |browser|
    browser.name == 'Chromium' && browser.version =~ /^202[0-4]/
  end.nil?
end
lineage_os_app?() click to toggle source

github.com/matomo-org/device-detector/blob/67ae11199a5129b42fa8b985d372ea834104fe3a/Parser/OperatingSystem.php#L439-L447

# File lib/device_detector/client_hint.rb, line 79
def lineage_os_app?
  app_name_from_headers == 'org.lineageos.jelly'
end
lineage_version() click to toggle source
# File lib/device_detector/client_hint.rb, line 108
def lineage_version
  DeviceDetector::OS
    .mapped_os_version(platform_version, DeviceDetector::OS::LINEAGE_OS_VERSION_MAPPING)
end
load_hint_app_names() click to toggle source
# File lib/device_detector/client_hint.rb, line 171
def load_hint_app_names
  hint_filepaths.map { |_, full_path| YAML.load_file(full_path) }
end
name_from_known_browsers(name) click to toggle source

github.com/matomo-org/device-detector/blob/be1c9ef486c247dc4886668da5ed0b1c49d90ba8/Parser/Client/Browser.php#L865

# File lib/device_detector/client_hint.rb, line 211
def name_from_known_browsers(name)
  DeviceDetector::Browser::KNOWN_BROWSER_TO_NAME.fetch(name) do
    available_browsers.find do |i|
      i == name ||
        i.gsub(' ', '') == name.gsub(' ', '') ||
        i == name.gsub('Browser', '') ||
        i == name.gsub(' Browser', '') ||
        i == "#{name} Browser"
    end
  end
end
secure_browser?() click to toggle source

github.com/matomo-org/device-detector/blob/67ae11199a5129b42fa8b985d372ea834104fe3a/Parser/Client/Browser.php#L931-L937 bbs.360.cn/thread-16096544-1-1.html

# File lib/device_detector/client_hint.rb, line 132
def secure_browser?
  return if browser_list.nil?

  !browser_list.find do |browser|
    browser.name == 'Chromium' && browser.version =~ /^15/
  end.nil?
end
windows_version() click to toggle source

github.com/matomo-org/device-detector/blob/28211c6f411528abf41304e07b886fdf322a49b7/Parser/OperatingSystem.php#L434

# File lib/device_detector/client_hint.rb, line 99
def windows_version
  return if platform_version.nil?

  major_version = platform_version.split('.').first.to_i
  return if major_version < 1

  major_version < 11 ? '10' : '11'
end