Class: Waves::Accept

Inherits:
Array show all
Defined in:
lib/waves/request/accept.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.convert_params_to_hash(p) ⇒ Object



39
40
41
42
43
44
45
46
47
# File 'lib/waves/request/accept.rb', line 39

def Accept.convert_params_to_hash( p )
  rval = p.inject({}) { |h,p|
    k,v = p.split('=').map(&:strip)
    ( v = v.to_f ) if k == 'q'
    h[k] = v ; h
  }
  rval['q'] ||= 1.0
  rval
end

.parse(str) ⇒ Object

RFC 2616 section 14.1.

Returns an array of elements of the form:

term, params

where is term is an array of MIME type components, with the true value as the wildcard (*)

and where params is a hash of parameters (q, level, etc.), where the q param is auto-converted to a float and defaulted to 1.0.

sorted by q value and then specificity, with ties going to HTML-related media-types

TODO parsing must be optimized. This parses Accept,

lang and charset


25
26
27
28
# File 'lib/waves/request/accept.rb', line 25

def Accept.parse(str)
  return self.new if str.nil?
  self.new( Accept.sort( str.split(',').map { |term| Accept.parse_media_type( term ) } ).uniq )
end

.parse_media_range(t) ⇒ Object



35
36
37
# File 'lib/waves/request/accept.rb', line 35

def Accept.parse_media_range( t )
  t.split('/').map(&:strip).map { |x| x=='*' ? true : x }
end

.parse_media_type(term) ⇒ Object



30
31
32
33
# File 'lib/waves/request/accept.rb', line 30

def Accept.parse_media_type( term )
  t, *p = term.to_s.split(';').map(&:strip) 
  [ Accept.parse_media_range( t ), Accept.convert_params_to_hash( p ) ]
end

.sort(terms) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/waves/request/accept.rb', line 49

def Accept.sort( terms )
  terms.sort { |t1,t2| 
    # first compare on quality
    c = t2[1]['q'] <=> t1[1]['q']
    # next compare on specificity of the media type
    c = t2[0].size <=> t1[0].size if ( c == 0 )
    # finally, compare on specificity of parameters
    c = t2[1].size <=> t1[1].size if ( c == 0 )
    c
  }
end

.to_media_type(term) ⇒ Object



61
62
63
# File 'lib/waves/request/accept.rb', line 61

def Accept.to_media_type( term )
  term.first.map { |x| x==true ? '*' : x }.join("/")
end

Instance Method Details

#===(arg) ⇒ Object



66
# File 'lib/waves/request/accept.rb', line 66

def ===(arg) ; self.include? arg ; end

#=~(arg) ⇒ Object



65
# File 'lib/waves/request/accept.rb', line 65

def =~(arg) ; self.include? arg ; end

#include?(arg) ⇒ Boolean

Check these Accepts against constraints.

Returns:

  • (Boolean)


70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/waves/request/accept.rb', line 70

def include?(arg)
  # recursively test for any possibility if we get an array
  # thus you can match against, say, %w( png jpg gif )
  return arg.any? {|pat| self.include? pat } if arg.kind_of? Array
  term = Accept.parse_media_type( arg ).first
  self.map(&:first).any? { | type, subtype |
    case term
    when [ type ], [ subtype ], [ true ],
        [ type, subtype ], [ type, true ], 
        [ true, true ] then true
    else false
    end
  }
end

#preferred_media_typeObject

Again, we play favorites here: in the absence of any accept header we go with ‘text/html’ as our favorite



87
88
89
# File 'lib/waves/request/accept.rb', line 87

def preferred_media_type
  Accept.to_media_type( first ) || 'text/html'
end