module Nitro # Encapsulates a request. This is an abstract request # typically extended by sub-classes. This module # is included in Context module Request # The request input stream. attr_accessor :in # The request headers collection. Also called # the request environment (env). attr_accessor :headers alias_method :env, :headers alias_method :env=, :headers= # for compatibility with cgi.rb alias_method :env_table, :headers # The parsed query parameters collection. attr_accessor :params alias_method :query, :params # The request cookies. attr_accessor :cookies # The request protocol. def protocol 443 == port ? 'https://' : 'http://' end # Is this an ssl request? def ssl? 443 == port end # The request uri. def uri @headers['REQUEST_URI'] end # The path is the uri without the query string. def path path = uri ? uri.split('?').first : '' end def path_info @headers['PATH_INFO'] end # The request query string. def query_string @headers['QUERY_STRING'] end # The request method. def method @headers['REQUEST_METHOD'].downcase.intern end # Is this a post method? def post? method == :post end # Return the referer. For the initial page in the # clickstream there is no referer, set "/" by default. def referer return @headers['HTTP_REFERER'] || '/' end # The content_length def content_length return @headers['CONTENT_LENGTH'].to_i end # The remote IP address. REMOTE_ADDR is the standard # but will fail if the user is behind a proxy. # HTTP_CLIENT_IP and/or HTTP_X_FORWARDED_FOR are set by # proxies so check for these before falling back to # REMOTE_ADDR. HTTP_X_FORWARDED_FOR may be a comma-delimited # list in the case of multiple chained proxies; the first # is the originating IP. def remote_ip return @headers['HTTP_CLIENT_IP'] if @headers.include?('HTTP_CLIENT_IP') if @headers.include?('HTTP_X_FORWARDED_FOR') then remote_ips = @headers['HTTP_X_FORWARDED_FOR'].split(',').reject do |ip| ip =~ /^unknown$|^(10|172\.16|192\.168)\./i end return remote_ips.first.strip unless remote_ips.empty? end return @headers['REMOTE_ADDR'] end # The server port. def port @headers['SERVER_PORT'].to_i end # The server host name. def host @headers['HTTP_HOST'] end def host_url "http://#{host}" end # The raw data of the request. # Useful to implement Webservices. #-- # FIXME: better name and implementation. #++ def raw_body unless @raw_body @in.rewind @raw_body = @in.read(content_length) end @raw_body end # Lookup a query parameter. def [](param) @params[param] end # Set a query parameter. def []=(param, value) @params[param] = value end end end