Module: ExpoTurbo::Rails::MediaType

Defined in:
lib/expo_turbo/rails/media_type.rb

Overview

Recognizes a verified native request from its Accept header.

A native client names the Expo Turbo media type exactly and prefers it: it sends the type alone, or beside the Turbo Stream type at equal quality. Three values therefore do not qualify, because getting this wrong denies service to a client that is not native:

  • a wildcard, which every browser sends
  • the type at a lower quality than another media range, which means the client prefers that other range
  • a malformed quality value, which the server cannot interpret at all

Constant Summary collapse

ACCEPT_ENTRY =
/[^,\s"](?:[^,"]|"[^"]*")*/
QUALITY =

RFC 9110 qvalue: 0[.0-3 digits] or 1[.up to three zeros].

/\A(?:0(?:\.\d{1,3})?|1(?:\.0{1,3})?)\z/
PARAMETER_NAME =

Parameter names of one media range. A quoted value is consumed whole, so a semicolon inside it does not read as another parameter.

/;\s*([^;=\s"]+)\s*=\s*(?:"(?:[^"\\]|\\.)*"|[^;]*)/

Class Method Summary collapse

Class Method Details

.explicitly_accepted?(accept) ⇒ Boolean

Returns:

  • (Boolean)


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/expo_turbo/rails/media_type.rb', line 28

def explicitly_accepted?(accept)
  return false unless accept.is_a?(String)

  accept = accept.dup.force_encoding(Encoding::UTF_8)
  return false unless accept.valid_encoding? && !accept.strip.empty?

  preferred = 0.0
  expo_turbo = nil
  accept.scan(ACCEPT_ENTRY).each do |entry|
    quality = entry_quality(entry)
    next unless quality

    preferred = quality if quality > preferred
    expo_turbo = quality if expo_turbo_entry?(entry) && (expo_turbo.nil? || quality > expo_turbo)
  end

  !expo_turbo.nil? && expo_turbo.positive? && expo_turbo >= preferred
end