Sha256: aec2eb8f87f89fe88765c9c05a235144f87bf6463665498d56b76dec7a16b72c

Contents?: true

Size: 1.78 KB

Versions: 1

Compression:

Stored size: 1.78 KB

Contents

require 'logger'

module Rack
  module Contrib
    #
    # Validate a request's age isn't too old or too young, indicating a
    # replayed request.
    #
    class StaleCall
      VERSION = '0.0.1'

      attr_reader :opts


      def initialize app, opts = {}
        @app = app
        @opts = opts
        @opts[:header] ||= 'Date'
        @opts[:grace] ||= 5
        @opts[:logger] ||= Logger.new('/dev/null')
      end

      # Translate a header name to a variable which Rack might provide
      def header_variable
        'HTTP_' + opts[:header].upcase.gsub(/-/, '_')
      end

      # Return the standard date error contents
      def date_error
        [401, {}, []]
      end

      # Convert an RFC2822 compatible date string to a diff against now
      def date_to_diff_seconds date
        date = DateTime.rfc2822(date)
        datediff = date - DateTime.now # Number of days apart as a float
        datediff *= 24 # hours apart
        datediff *= 60 # minutes apart
        datediff *= 60 # seconds apart
        seconds = datediff.to_i.abs
      end

      # Determine if the date is recent enough
      def date_is_recent seconds
        seconds <= opts[:grace]
      end

      # Verify the age of the request
      def call env
        unless env.has_key? header_variable
          @opts[:logger].info "Denied: #{opts[:header]} header missing."
          return date_error
        end

        diff_seconds = date_to_diff_seconds(env[header_variable])
        unless date_is_recent diff_seconds
          @opts[:logger].info sprintf(
            "Denied: %s header is %ss over the %ss grace period.",
            @opts[:header],
            diff_seconds - @opts[:grace],
            @opts[:grace]
          )
          return date_error
        end

        @app.call env
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rack-stale-call-0.0.1 lib/rack/contrib/stale_call.rb