class Rack::Fernet

Public Class Methods

new(app, secret, content_type="application/json") click to toggle source
# File lib/rack/fernet.rb, line 26
def initialize(app, secret, content_type="application/json")
  @app = app
  @secret = secret
  @content_type = content_type
end

Public Instance Methods

call(env) click to toggle source
# File lib/rack/fernet.rb, line 32
def call(env)
  payload = env["rack.input"].read
  env["CONTENT_TYPE"] = @content_type

  unless payload.empty?
    payload = decrypt_request(env, payload)
    env["rack.input"] = StringIO.new(payload)
  end

  status, headers, body = @app.call(env)
  str_body = read_body(body)
  unless str_body.empty?
    encoded = encrypt_response(env, str_body)
    headers['Content-Type'] = 'application/octet-stream'
    headers['Content-Length'] = encoded.length
    body = [ encoded ]
  end
  [status, headers, body]
rescue ::Fernet::Error
  bad_request
end

Private Instance Methods

bad_request() click to toggle source
# File lib/rack/fernet.rb, line 88
def bad_request
  return [ 400,
    { 'Content-Type' => 'text/plain',
      'Content-Length' => '0' },
    []
  ]
end
decrypt_request(env, payload) click to toggle source
# File lib/rack/fernet.rb, line 78
def decrypt_request(env, payload)
  # read the payload
  verifier = ::Fernet.verifier(secret(env), payload)
  if verifier.valid?
    verifier.message
  else
    raise ::Fernet::Error
  end
end
encrypt_response(env, payload) click to toggle source
# File lib/rack/fernet.rb, line 74
def encrypt_response(env, payload)
  ::Fernet.generate(secret(env), payload)
end
read_body(body) click to toggle source
# File lib/rack/fernet.rb, line 56
def read_body(body)
  if body.respond_to? :join
    body.join('')
  else
    result = []
    body.each { |line| result << line }
    result.join('')
  end
end
secret(env) click to toggle source
# File lib/rack/fernet.rb, line 66
def secret(env)
  if @secret.respond_to?(:call)
    @secret.call(env)
  else
    @secret
  end
end