/lib/innate/request.rb
Ruby | 141 lines | 33 code | 10 blank | 98 comment | 4 complexity | 0a5d3e518cb01b56eb8d3c3f440858a8 MD5 | raw file
- module Innate
- # Subclass Rack::Request and add some convenient methods.
- #
- # An instance is available via the #request method in your Node.
- #
- # NOTE:
- # Please make sure to read the documentation of Rack::Request together with
- # this, as there are a lot of features available.
- #
- # A list of methods from Rack::Request so you get a gist of it:
- #
- # ## Generally
- #
- # * body
- # * cookies
- # * env
- # * fullpath
- # * host
- # * port
- # * scheme
- # * url
- #
- # ## ENV shortcuts
- #
- # * accept_encoding
- # * content_charset
- # * content_length
- # * content_type
- # * ip
- # * media_type
- # * media_type_params
- # * path_info
- # * path_info=
- # * query_string
- # * referrer
- # * script_name
- # * script_name=
- # * xhr?
- #
- # ## Query request method
- #
- # * delete?
- # * get?
- # * head?
- # * post?
- # * put?
- # * request_method
- #
- # ## parameter handling
- #
- # * []
- # * []=
- # * form_data?
- # * params
- # * values_at
- class Request < Rack::Request
- # Currently handled request from Thread.current[:request]
- # Call it from anywhere via Innate::Request.current
- def self.current
- Current.request
- end
- # Let's allow #[] to act like #values_at.
- #
- # Usage given a GET request like /hey?foo=duh&bar=doh
- #
- # request[:foo, :bar] # => ['duh', 'doh']
- #
- # Both +value+ and the elements of +keys+ will be turned into String by #to_s.
- def [](value, *keys)
- return super(value) if keys.empty?
- [value, *keys].map{|key| super(key) }
- end
- # the full request URI provided by Rack::Request
- # e.g. "http://localhost:7000/controller/action?foo=bar.xhtml"
- def request_uri
- env['REQUEST_URI'] || env['PATH_INFO']
- end
- # Answers with a subset of request.params with only the key/value pairs for
- # which you pass the keys.
- # Valid keys are objects that respond to :to_s
- #
- # @example usage
- #
- # request.params
- # # => {'name' => 'jason', 'age' => '45', 'job' => 'lumberjack'}
- # request.subset('name')
- # # => {'name' => 'jason'}
- # request.subset(:name, :job)
- # # => {'name' => 'jason', 'job' => 'lumberjack'}
- def subset(*keys)
- keys = keys.map{|key| key.to_s }
- params.reject{|key, value| not keys.include?(key) }
- end
- # Try to figure out the domain we are running on, this might work for some
- # deployments but fail for others, given the combination of servers in
- # front.
- #
- # @example usage
- #
- # domain
- # # => #<URI::HTTPS:0xb769ecb0 URL:https://localhost:7000/>
- # domain('/foo')
- # # => #<URI::HTTPS:0xb769ecb0 URL:https://localhost:7000/foo>
- #
- # @param [#to_s] path
- #
- # @return [URI]
- #
- # @api external
- # @author manveru
- def domain(path = nil, options = {})
- uri = URI(self.url)
- uri.path = path.to_s if path
- uri.query = nil unless options[:keep_query]
- uri
- end
- ipv4 = %w[ 127.0.0.1/32 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 169.254.0.0/16 ]
- ipv6 = %w[ fc00::/7 fe80::/10 fec0::/10 ::1 ]
- LOCAL = (ipv4 + ipv6).map{|range| IPAddr.new(range)} unless defined?(LOCAL)
- # Request is from a local network?
- # Checks both IPv4 and IPv6
- # Answer is true if the IP address making the request is from local network.
- # Optional argument address can be used to check any IP address.
- def local_net?(address = ip)
- addr = IPAddr.new(address)
- LOCAL.find{|range| range.include?(addr) }
- rescue ArgumentError => ex
- raise ArgumentError, ex unless ex.message == 'invalid address'
- end
- end
- end