Module: JSONRPC2::HTTPUtils

Defined in:
lib/jsonrpc2/accept.rb

Overview

Utils for parsing HTTP fields

Class Method Summary collapse

Class Method Details

.parse_accept(field, regex = false) ⇒ Object

Parses the HTTP Accept field and returns a sorted list of prefered types

Parameters:

  • field


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/jsonrpc2/accept.rb', line 23

def parse_accept field, regex = false
  index = -1
  list = field.split(/,\s*/).map do |media|
   index += 1
   case media
   when /;/
     media, param_str = *media.split(/\s*;\s*(?=q\s*=)/,2)
     params = param_str.to_s.split(/\s*;\s*/).inject({}) { |hash, str|
       k,v = *str.strip.split(/=/).map(&:strip)
       hash.merge(k => v)
     }
     { :q => (params['q'] || 1.0).to_f, :media => media, :index => index }
   else
     { :q => 1.0, :media => media, :index => index }
   end
  end.sort_by { |option| [-1 * option[:q], option[:media].scan(/[*]/).size, option[:index]] }

  final = {}
  list.each do |item|
    q = item[:q]
    final[q] ||= []
    final[q].push(regex ? type_to_regex(item[:media]) : item[:media])
  end

  final.sort_by { |k,v| -1 * k }
end

.type_to_regex(type) ⇒ Regexp

Converts / -> /^.*?/.*?$/

text/* -> /^text\/.*?$/
text/html -> /^text\/html$/

Parameters:

  • type (String)

    Media type descriptor

Returns:

  • (Regexp)

    Regular expression that matches type



10
11
12
13
14
15
16
17
# File 'lib/jsonrpc2/accept.rb', line 10

def type_to_regex type
  case type
  when /[*]/
    Regexp.new("^#{type.split(/[*]/).map { |bit| Regexp.quote(bit) }.join('.*?')}$")
  else
    Regexp.new("^#{Regexp.quote(type)}$")
  end
end

.which(http_client_accepts, options) ⇒ Object

Selects the clients preferred media/mime type based on Accept header

Parameters:

  • http_client_accepts (String)

    HTTP Accepts header

  • options (Array<String>)

    Media types available



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/jsonrpc2/accept.rb', line 54

def which http_client_accepts, options
  return nil unless http_client_accepts

  parse_accept(http_client_accepts, true).each do |preference, types|
    types.each do |type|
      options.each do |option|
        return option if type.match(option)
      end
    end
  end

  nil
end