Sha256: 6582f3536c45d742171f165c3568aedf5c547fc7dcb55149c5121a8cdba1e12f

Contents?: true

Size: 1.56 KB

Versions: 1

Compression:

Stored size: 1.56 KB

Contents

module Rack
  class AcceptOnly
    def initialize(app, permitted_type = nil)
      raise "Keep the permitted content-type simple please" if permitted_type && permitted_type.match(%r{[*; ]})
      @app = app
      @permitted_type = permitted_type
    end
    
    def call(env)
      acceptable_types = get_acceptable_types(env)
      return @app.call(env) unless !acceptable_types.empty? || @permitted_type

      if !match_against_types?(acceptable_types, @permitted_type)
        return unacceptable(@permitted_type)
      end

      reply = @app.call(env)
      reply_type = reply[1]['Content-Type']
      
      return server_error unless reply_type
      
      if @permitted_type && reply_type != @permitted_type
        reply = server_error
      end
      
      if !match_against_types?(acceptable_types, reply_type)
        reply = unacceptable(reply_type)
      end

      reply
    end
    
    def get_acceptable_types(env)
      return [] unless env['HTTP_ACCEPT']

      acceptable_types = env['HTTP_ACCEPT'].split(",")
      acceptable_types.collect do |type|
        temp = type.strip.split(";")[0].gsub("*", "(.+)")
        Regexp.new("^#{temp}$")
      end
    end

    def match_against_types?(types, string)
      return true unless !types.empty? && string

      types.each do |type|
        return true if string.match(type)
      end
      false
    end
    
    def unacceptable(supplyable_type)
      [406, {'Content-Type' => supplyable_type, "Content-Length" => "0"}, [""]]
    end

    def server_error
      [500, {"Content-Length" => "0"}, [""]]
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
kissifer-rack-accept-only-0.1.0 lib/rack/accept-only.rb