class Camo::Request

Constants

SUPPORTED_PROTOCOLS

Attributes

destination_url[R]
digest[R]
digest_type[R]
errors[R]
headers[R]
host[R]
key[R]
method[R]
params[R]
path[R]
protocol[R]
query_string[R]

Public Class Methods

new(env, key) click to toggle source
# File lib/camo/request.rb, line 13
def initialize(env, key)
  @method = env["REQUEST_METHOD"]
  @query_string = env["QUERY_STRING"]
  @params = parse_query(@query_string)
  @protocol = env["rack.url_scheme"] || "http"
  @host = env["HTTP_HOST"]
  @path = env["PATH_INFO"]
  @headers = build_headers(env)
  @key = key

  @digest, encoded_url = path[1..].split("/", 2).map { |part| String(part) }

  if encoded_url
    @digest_type = "path"
    @destination_url = Addressable::URI.parse(String(decode_hex(encoded_url)))
  else
    @digest_type = "query"
    @destination_url = Addressable::URI.parse(String(params["url"]))
  end

  @errors = []
end

Public Instance Methods

url() click to toggle source
# File lib/camo/request.rb, line 36
def url
  "#{protocol}://#{host}#{path}#{query_string.empty? ? nil : "?#{query_string}"}"
end
valid_digest?() click to toggle source
# File lib/camo/request.rb, line 45
def valid_digest?
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"), key, destination_url) == digest
end
valid_request?() click to toggle source
# File lib/camo/request.rb, line 40
def valid_request?
  validate_request
  Array(errors).empty?
end

Private Instance Methods

build_headers(env) click to toggle source
# File lib/camo/request.rb, line 51
def build_headers(env)
  hash = env.select { |k, _| k.start_with?("HTTP_") }
  hash = hash.each_with_object({}) do |header, headers|
    headers[header[0].sub("HTTP_", "")] = header[1]
  end

  HeaderHash[hash]
end
decode_hex(str) click to toggle source
# File lib/camo/request.rb, line 74
def decode_hex(str)
  [str].pack("H*")
end
validate_request() click to toggle source
# File lib/camo/request.rb, line 60
def validate_request
  @errors ||= []

  errors << "Empty URL" if destination_url.empty?
  errors << "Empty host" if !destination_url.empty? && String(destination_url.host).empty?

  if destination_url.scheme && !SUPPORTED_PROTOCOLS.include?(destination_url.scheme)
    errors << "Unsupported protocol: '#{destination_url.scheme}'"
  end

  errors << "Recursive request" if headers["VIA"] == user_agent
  errors
end