Class/Module Index [+]

Quicksearch

Rack::Utils

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

Constants

DEFAULT_SEP
ESCAPE_HTML
ESCAPE_HTML_PATTERN
HTTP_STATUS_CODES

Every standard HTTP code mapped to the appropriate message. Generated with:

curl -s http://www.iana.org/assignments/http-status-codes | \
  ruby -ane 'm = /^(\d{3}) +(\S[^\[(]+)/.match($_) and
             puts "      #{m[1]}  => \x27#{m[2].strip}x27,"'
STATUS_WITH_NO_ENTITY_BODY

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

SYMBOL_TO_STATUS_CODE

Public Class Methods

build_nested_query(value, prefix = nil) click to toggle source
# File lib/rack/utils.rb, line 111
def build_nested_query(value, prefix = nil)
  case value
  when Array
    value.map { |v|
      build_nested_query(v, "#{prefix}[]")
    }.join("&")
  when Hash
    value.map { |k, v|
      build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
    }.join("&")
  when String
    raise ArgumentError, "value must be a Hash" if prefix.nil?
    "#{prefix}=#{escape(value)}"
  else
    prefix
  end
end
build_query(params) click to toggle source
# File lib/rack/utils.rb, line 100
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) click to toggle source
# File lib/rack/utils.rb, line 237
def bytesize(string)
  string.bytesize
end
escape(s) click to toggle source

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).

# File lib/rack/utils.rb, line 14
def escape(s)
  s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/) {
    '%'+$1.unpack('H2'*bytesize($1)).join('%').upcase
  }.tr(' ', '+')
end
escape_html(string) click to toggle source

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

# File lib/rack/utils.rb, line 140
def escape_html(string)
  string.to_s.gsub(ESCAPE_HTML_PATTERN){|c| ESCAPE_HTML[c] }
end
normalize_params(params, name, v = nil) click to toggle source
# File lib/rack/utils.rb, line 68
def normalize_params(params, name, v = nil)
  name =~ %(\A[\[\]]*([^\[\]]+)\]*)
  k = $1 || ''
  after = $' || ''

  return if k.empty?

  if after == ""
    params[k] = v
  elsif after == "[]"
    params[k] ||= []
    raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
    params[k] << v
  elsif after =~ %(^\[\]\[([^\[\]]+)\]$) || after =~ %(^\[\](.+)$)
    child_key = $1
    params[k] ||= []
    raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" 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] ||= {}
    raise TypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Hash)
    params[k] = normalize_params(params[k], after, v)
  end

  return params
end
parse_nested_query(qs, d = nil) click to toggle source
# File lib/rack/utils.rb, line 56
def parse_nested_query(qs, d = nil)
  params = {}

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

  return params
end
parse_query(qs, d = nil) click to toggle source

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 ‘&;’).

# File lib/rack/utils.rb, line 36
def parse_query(qs, d = nil)
  params = {}

  (qs || '').split(d ? /[#{d}] */ : DEFAULT_SEP).each do |p|
    k, v = p.split('=', 2).map { |x| unescape(x) }
    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
rfc2822(time) click to toggle source

Modified version of stdlib time.rb Time#rfc2822 to use ‘%d-%b-%Y’ instead of ‘% %b %Y’. It assumes that the time is in GMT to comply to the RFC 2109.

NOTE: I’m not sure the RFC says it requires GMT, but is ambigous enough that I’m certain someone implemented only that option. Do not use %a and %b from Time.strptime, it would use localized names for weekday and month.

# File lib/rack/utils.rb, line 256
def rfc2822(time)
  wday = Time::RFC2822_DAY_NAME[time.wday]
  mon = Time::RFC2822_MONTH_NAME[time.mon - 1]
  time.strftime("#{wday}, %d-#{mon}-%Y %T GMT")
end
select_best_encoding(available_encodings, accept_encoding) click to toggle source
# File lib/rack/utils.rb, line 145
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
status_code(status) click to toggle source
# File lib/rack/utils.rb, line 429
def status_code(status)
  if status.is_a?(Symbol)
    SYMBOL_TO_STATUS_CODE[status] || 500
  else
    status.to_i
  end
end
unescape(s) click to toggle source

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

# File lib/rack/utils.rb, line 22
def unescape(s)
  s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/){
    [$1.delete('%')].pack('H*')
  }
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.