Module: Rack::Utils

Included in:
Chunked, ContentLength
Defined in:
lib/action_controller/vendor/rack-1.0/rack/utils.rb

Overview

Rack::Utils contains a grab-bag of useful methods for writing web applications adopted from all kinds of Ruby libraries.

Defined Under Namespace

Modules: Multipart Classes: Context, HeaderHash

Constant Summary collapse

HTTP_STATUS_CODES =

Every standard HTTP code mapped to the appropriate message. Stolen from Mongrel.

{
  100  => 'Continue',
  101  => 'Switching Protocols',
  200  => 'OK',
  201  => 'Created',
  202  => 'Accepted',
  203  => 'Non-Authoritative Information',
  204  => 'No Content',
  205  => 'Reset Content',
  206  => 'Partial Content',
  300  => 'Multiple Choices',
  301  => 'Moved Permanently',
  302  => 'Found',
  303  => 'See Other',
  304  => 'Not Modified',
  305  => 'Use Proxy',
  307  => 'Temporary Redirect',
  400  => 'Bad Request',
  401  => 'Unauthorized',
  402  => 'Payment Required',
  403  => 'Forbidden',
  404  => 'Not Found',
  405  => 'Method Not Allowed',
  406  => 'Not Acceptable',
  407  => 'Proxy Authentication Required',
  408  => 'Request Timeout',
  409  => 'Conflict',
  410  => 'Gone',
  411  => 'Length Required',
  412  => 'Precondition Failed',
  413  => 'Request Entity Too Large',
  414  => 'Request-URI Too Large',
  415  => 'Unsupported Media Type',
  416  => 'Requested Range Not Satisfiable',
  417  => 'Expectation Failed',
  500  => 'Internal Server Error',
  501  => 'Not Implemented',
  502  => 'Bad Gateway',
  503  => 'Service Unavailable',
  504  => 'Gateway Timeout',
  505  => 'HTTP Version Not Supported'
}
STATUS_WITH_NO_ENTITY_BODY =

Responses with HTTP status codes that should not have an entity body

Set.new((100..199).to_a << 204 << 304)

Class Method Summary collapse

Class Method Details

.build_query(params) ⇒ Object



96
97
98
99
100
101
102
103
104
# File 'lib/action_controller/vendor/rack-1.0/rack/utils.rb', line 96

def build_query(params)
  params.map { |k, v|
    if v.class == Array
      build_query(v.map { |x| [k, x] })
    else
      escape(k) + "=" + escape(v)
    end
  }.join("&")
end

.bytesize(string) ⇒ Object



150
151
152
# File 'lib/action_controller/vendor/rack-1.0/rack/utils.rb', line 150

def bytesize(string)
  string.bytesize
end

.escape(s) ⇒ Object

Performs URI escaping so that you can construct proper query strings faster. Use this rather than the cgi.rb version since it’s faster. (Stolen from Camping).



12
13
14
15
16
# File 'lib/action_controller/vendor/rack-1.0/rack/utils.rb', line 12

def escape(s)
  s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
    '%'+$1.unpack('H2'*$1.size).join('%').upcase
  }.tr(' ', '+')
end

.escape_html(string) ⇒ Object

Escape ampersands, brackets and quotes to their HTML/XML entities.



108
109
110
111
112
113
114
# File 'lib/action_controller/vendor/rack-1.0/rack/utils.rb', line 108

def escape_html(string)
  string.to_s.gsub("&", "&amp;").
    gsub("<", "&lt;").
    gsub(">", "&gt;").
    gsub("'", "&#39;").
    gsub('"', "&quot;")
end

.normalize_params(params, name, v = nil) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/action_controller/vendor/rack-1.0/rack/utils.rb', line 65

def normalize_params(params, name, v = nil)
  name =~ %r([\[\]]*([^\[\]]+)\]*)
  k = $1 || ''
  after = $' || ''

  return if k.empty?

  if after == ""
    params[k] = v
  elsif after == "[]"
    params[k] ||= []
    raise TypeError unless params[k].is_a?(Array)
    params[k] << v
  elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
    child_key = $1
    params[k] ||= []
    raise TypeError unless params[k].is_a?(Array)
    if params[k].last.is_a?(Hash) && !params[k].last.key?(child_key)
      normalize_params(params[k].last, child_key, v)
    else
      params[k] << normalize_params({}, child_key, v)
    end
  else
    params[k] ||= {}
    params[k] = normalize_params(params[k], after, v)
  end

  return params
end

.parse_nested_query(qs, d = '&;') ⇒ Object



53
54
55
56
57
58
59
60
61
62
# File 'lib/action_controller/vendor/rack-1.0/rack/utils.rb', line 53

def parse_nested_query(qs, d = '&;')
  params = {}

  (qs || '').split(/[#{d}] */n).each do |p|
    k, v = unescape(p).split('=', 2)
    normalize_params(params, k, v)
  end

  return params
end

.parse_query(qs, d = '&;') ⇒ Object

Stolen from Mongrel, with some small modifications: Parses a query string by breaking it up at the ‘&’ and ‘;’ characters. You can also use this to parse cookies by changing the characters used in the second parameter (which defaults to ‘&;’).



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/action_controller/vendor/rack-1.0/rack/utils.rb', line 32

def parse_query(qs, d = '&;')
  params = {}

  (qs || '').split(/[#{d}] */n).each do |p|
    k, v = unescape(p).split('=', 2)

    if cur = params[k]
      if cur.class == Array
        params[k] << v
      else
        params[k] = [cur, v]
      end
    else
      params[k] = v
    end
  end

  return params
end

.select_best_encoding(available_encodings, accept_encoding) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/action_controller/vendor/rack-1.0/rack/utils.rb', line 117

def select_best_encoding(available_encodings, accept_encoding)
  # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

  expanded_accept_encoding =
    accept_encoding.map { |m, q|
      if m == "*"
        (available_encodings - accept_encoding.map { |m2, _| m2 }).map { |m2| [m2, q] }
      else
        [[m, q]]
      end
    }.inject([]) { |mem, list|
      mem + list
    }

  encoding_candidates = expanded_accept_encoding.sort_by { |_, q| -q }.map { |m, _| m }

  unless encoding_candidates.include?("identity")
    encoding_candidates.push("identity")
  end

  expanded_accept_encoding.find_all { |m, q|
    q == 0.0
  }.each { |m, _|
    encoding_candidates.delete(m)
  }

  return (encoding_candidates & available_encodings)[0]
end

.unescape(s) ⇒ Object

Unescapes a URI escaped string. (Stolen from Camping).



20
21
22
23
24
# File 'lib/action_controller/vendor/rack-1.0/rack/utils.rb', line 20

def unescape(s)
  s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
    [$1.delete('%')].pack('H*')
  }
end