Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 136 lines (112 sloc) 3.889 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
require 'rack/utils'

module Rack
  # Rack::Request provides a convenient interface to a Rack
  # environment. It is stateless, the environment +env+ passed to the
  # constructor will be directly modified.
  #
  # req = Rack::Request.new(env)
  # req.post?
  # req.params["data"]
  
  class Request
    # The environment of the request.
    attr_reader :env
    
    def initialize(env)
      @env = env
    end

    def body; @env["rack.input"] end
    def scheme; @env["rack.url_scheme"] end
    def script_name; @env["SCRIPT_NAME"].to_s end
    def path_info; @env["PATH_INFO"].to_s end
    def port; @env["SERVER_PORT"].to_i end
    def request_method; @env["REQUEST_METHOD"] end
    def query_string; @env["QUERY_STRING"].to_s end

    def host
      # Remove port number.
      (@env["HTTP_HOST"] || @env["SERVER_NAME"]).gsub(/:\d+\z/, '')
    end

    def script_name=(s); @env["SCRIPT_NAME"] = s.to_s end
    def path_info=(s); @env["PATH_INFO"] = s.to_s end

    def get?; request_method == "GET" end
    def post?; request_method == "POST" end
    def put?; request_method == "PUT" end
    def delete?; request_method == "DELETE" end

    # Returns the data recieved in the query string.
    def GET
      if @env["rack.request.query_string"] == query_string
        @env["rack.request.query_hash"]
      else
        @env["rack.request.query_string"] = query_string
        @env["rack.request.query_hash"] =
          Utils.parse_query(query_string)
      end
    end

    # Returns the data recieved in the request body.
    #
    # This method support both application/x-www-form-urlencoded and
    # multipart/form-data.
    def POST
      if @env["rack.request.form_input"] == @env["rack.input"]
        @env["rack.request.form_hash"]
      else
        @env["rack.request.form_input"] = @env["rack.input"]
        unless @env["rack.request.form_hash"] =
            Utils::Multipart.parse_multipart(env)
          @env["rack.request.form_vars"] = @env["rack.input"].read
          @env["rack.request.form_hash"] = Utils.parse_query(@env["rack.request.form_vars"])
        end
        @env["rack.request.form_hash"]
      end
    end

    # The union of GET and POST data.
    def params
      self.GET.update(self.POST)
    end

    # shortcut for request.params[key]
    def [](key)
      params[key.to_s]
    end

    # shortcut for request.params[key] = value
    def []=(key, value)
      params[key.to_s] = value
    end

    # like Hash#values_at
    def values_at(*keys)
      keys.map{|key| params[key] }
    end

    # the referer of the client or '/'
    def referer
      @env['HTTP_REFERER'] || '/'
    end
    alias referrer referer


    def cookies
      return {} unless @env["HTTP_COOKIE"]

      if @env["rack.request.cookie_string"] == @env["HTTP_COOKIE"]
        @env["rack.request.cookie_hash"]
      else
        @env["rack.request.cookie_string"] = @env["HTTP_COOKIE"]
        # XXX sure?
        @env["rack.request.cookie_hash"] =
          Utils.parse_query(@env["rack.request.cookie_string"], ';,')
      end
    end

    def xhr?
      @env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"
    end

    # Tries to return a remake of the original request URL as a string.
    def url
      url = scheme + "://"
      url << host

      if scheme == "https" && port != 443 ||
          scheme == "http" && port != 80
        url << ":#{port}"
      end

      url << fullpath

      url
    end

    def fullpath
      path = script_name + path_info
      path << "?" << query_string unless query_string.empty?
      path
    end
  end
end
Something went wrong with that request. Please try again.