Class: Rack::Request
- Inherits:
-
Object
- Object
- Rack::Request
- Defined in:
- lib/rack/request.rb
Overview
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"]
The environment hash passed will store a reference to the Request object instantiated so that it will only instantiate if an instance of the Request object doesn’t already exist.
Constant Summary collapse
- FORM_DATA_MEDIA_TYPES =
The set of form-data media-types. Requests that do not indicate one of the media types presents in this list will not be eligible for form-data / param parsing.
[ 'application/x-www-form-urlencoded', 'multipart/form-data' ]
- PARSEABLE_DATA_MEDIA_TYPES =
The set of media-types. Requests that do not indicate one of the media types presents in this list will not be eligible for param parsing like soap attachments or generic multiparts
[ 'multipart/related', 'multipart/mixed' ]
- DEFAULT_PORTS =
Default ports depending on scheme. Used to decide whether or not to include the port in a generated URI.
{ 'http' => 80, 'https' => 443, 'coffee' => 80 }
Instance Attribute Summary collapse
-
#env ⇒ Object
readonly
The environment of the request.
Instance Method Summary collapse
-
#[](key) ⇒ Object
shortcut for request.params.
-
#[]=(key, value) ⇒ Object
shortcut for request.params = value.
- #accept_encoding ⇒ Object
- #base_url ⇒ Object
- #body ⇒ Object
-
#content_charset ⇒ Object
The character set of the request body if a “charset” media type parameter was given, or nil if no “charset” was specified.
- #content_length ⇒ Object
- #content_type ⇒ Object
- #cookies ⇒ Object
-
#delete? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type DELETE.
-
#delete_param(k) ⇒ Object
Destructively delete a parameter, whether it’s in GET or POST.
-
#form_data? ⇒ Boolean
Determine whether the request body contains form-data by checking the request Content-Type for one of the media-types: “application/x-www-form-urlencoded” or “multipart/form-data”.
- #fullpath ⇒ Object
-
#GET ⇒ Object
Returns the data received in the query string.
-
#get? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type GET.
-
#head? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type HEAD.
- #host ⇒ Object
- #host_with_port ⇒ Object
-
#initialize(env) ⇒ Request
constructor
A new instance of Request.
- #ip ⇒ Object
- #logger ⇒ Object
-
#media_type ⇒ Object
The media type (type/subtype) portion of the CONTENT_TYPE header without any media type parameters.
-
#media_type_params ⇒ Object
The media type parameters provided in CONTENT_TYPE as a Hash, or an empty Hash if no CONTENT_TYPE or media-type parameters were provided.
-
#options? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type OPTIONS.
-
#params ⇒ Object
The union of GET and POST data.
-
#parseable_data? ⇒ Boolean
Determine whether the request body contains data by checking the request media_type against registered parse-data media-types.
-
#patch? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type PATCH.
- #path ⇒ Object
- #path_info ⇒ Object
- #path_info=(s) ⇒ Object
- #port ⇒ Object
-
#POST ⇒ Object
Returns the data received in the request body.
-
#post? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type POST.
-
#put? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type PUT.
- #query_string ⇒ Object
-
#referer ⇒ Object
(also: #referrer)
the referer of the client.
- #request_method ⇒ Object
- #scheme ⇒ Object
- #script_name ⇒ Object
- #script_name=(s) ⇒ Object
- #session ⇒ Object
- #session_options ⇒ Object
- #ssl? ⇒ Boolean
-
#trace? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type TRACE.
- #trusted_proxy?(ip) ⇒ Boolean
-
#update_param(k, v) ⇒ Object
Destructively update a parameter, whether it’s in GET and/or POST.
-
#url ⇒ Object
Tries to return a remake of the original request URL as a string.
- #user_agent ⇒ Object
-
#values_at(*keys) ⇒ Object
like Hash#values_at.
- #xhr? ⇒ Boolean
Constructor Details
#initialize(env) ⇒ Request
Returns a new instance of Request.
20 21 22 |
# File 'lib/rack/request.rb', line 20 def initialize(env) @env = env end |
Instance Attribute Details
#env ⇒ Object (readonly)
The environment of the request.
18 19 20 |
# File 'lib/rack/request.rb', line 18 def env @env end |
Instance Method Details
#[](key) ⇒ Object
shortcut for request.params
266 267 268 |
# File 'lib/rack/request.rb', line 266 def [](key) params[key.to_s] end |
#[]=(key, value) ⇒ Object
shortcut for request.params = value
Note that modifications will not be persisted in the env. Use update_param or delete_param if you want to destructively modify params.
273 274 275 |
# File 'lib/rack/request.rb', line 273 def []=(key, value) params[key.to_s] = value end |
#accept_encoding ⇒ Object
333 334 335 336 337 338 339 340 341 342 |
# File 'lib/rack/request.rb', line 333 def accept_encoding @env["HTTP_ACCEPT_ENCODING"].to_s.split(/\s*,\s*/).map do |part| encoding, parameters = part.split(/\s*;\s*/, 2) quality = 1.0 if parameters and /\Aq=([\d.]+)/ =~ parameters quality = $1.to_f end [encoding, quality] end end |
#base_url ⇒ Object
314 315 316 317 318 |
# File 'lib/rack/request.rb', line 314 def base_url url = "#{scheme}://#{host}" url << ":#{port}" if port != DEFAULT_PORTS[scheme] url end |
#body ⇒ Object
24 |
# File 'lib/rack/request.rb', line 24 def body; @env["rack.input"] end |
#content_charset ⇒ Object
The character set of the request body if a “charset” media type parameter was given, or nil if no “charset” was specified. Note that, per RFC2616, text/* media types that specify no explicit charset are to be considered ISO-8859-1.
66 67 68 |
# File 'lib/rack/request.rb', line 66 def content_charset media_type_params['charset'] end |
#content_length ⇒ Object
29 |
# File 'lib/rack/request.rb', line 29 def content_length; @env['CONTENT_LENGTH'] end |
#content_type ⇒ Object
31 32 33 34 |
# File 'lib/rack/request.rb', line 31 def content_type content_type = @env['CONTENT_TYPE'] content_type.nil? || content_type.empty? ? nil : content_type end |
#cookies ⇒ Object
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/rack/request.rb', line 292 def hash = @env["rack.request.cookie_hash"] ||= {} string = @env["HTTP_COOKIE"] return hash if string == @env["rack.request.cookie_string"] hash.clear # According to RFC 2109: # If multiple cookies satisfy the criteria above, they are ordered in # the Cookie header such that those with more specific Path attributes # precede those with less specific. Ordering with respect to other # attributes (e.g., Domain) is unspecified. = Utils.parse_query(string, ';,') { |s| Rack::Utils.unescape(s) rescue s } .each { |k,v| hash[k] = Array === v ? v.first : v } @env["rack.request.cookie_string"] = string hash end |
#delete? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type DELETE
120 |
# File 'lib/rack/request.rb', line 120 def delete?; request_method == "DELETE" end |
#delete_param(k) ⇒ Object
Destructively delete a parameter, whether it’s in GET or POST. Returns the value of the deleted parameter.
If the parameter is in both GET and POST, the POST value takes precedence since that’s how #params works.
env is not touched.
259 260 261 262 263 |
# File 'lib/rack/request.rb', line 259 def delete_param(k) v = [ self.POST.delete(k), self.GET.delete(k) ].compact.first @params = nil v end |
#form_data? ⇒ Boolean
Determine whether the request body contains form-data by checking the request Content-Type for one of the media-types: “application/x-www-form-urlencoded” or “multipart/form-data”. The list of form-data media types can be modified through the FORM_DATA_MEDIA_TYPES
array.
A request body is also assumed to contain form-data when no Content-Type header is provided and the request_method is POST.
172 173 174 175 176 |
# File 'lib/rack/request.rb', line 172 def form_data? type = media_type meth = env["rack.methodoverride.original_method"] || env['REQUEST_METHOD'] (meth == 'POST' && type.nil?) || FORM_DATA_MEDIA_TYPES.include?(type) end |
#fullpath ⇒ Object
329 330 331 |
# File 'lib/rack/request.rb', line 329 def fullpath query_string.empty? ? path : "#{path}?#{query_string}" end |
#GET ⇒ Object
Returns the data received in the query string.
185 186 187 188 189 190 191 192 |
# File 'lib/rack/request.rb', line 185 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"] = parse_query(query_string) end end |
#get? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type GET
123 |
# File 'lib/rack/request.rb', line 123 def get?; request_method == "GET" end |
#head? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type HEAD
126 |
# File 'lib/rack/request.rb', line 126 def head?; request_method == "HEAD" end |
#host ⇒ Object
110 111 112 113 |
# File 'lib/rack/request.rb', line 110 def host # Remove port number. host_with_port.to_s.gsub(/:\d+\z/, '') end |
#host_with_port ⇒ Object
88 89 90 91 92 93 94 |
# File 'lib/rack/request.rb', line 88 def host_with_port if forwarded = @env["HTTP_X_FORWARDED_HOST"] forwarded.split(/,\s?/).last else @env['HTTP_HOST'] || "#{@env['SERVER_NAME'] || @env['SERVER_ADDR']}:#{@env['SERVER_PORT']}" end end |
#ip ⇒ Object
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
# File 'lib/rack/request.rb', line 348 def ip remote_addrs = split_ip_addresses(@env['REMOTE_ADDR']) remote_addrs = reject_trusted_ip_addresses(remote_addrs) return remote_addrs.first if remote_addrs.any? forwarded_ips = split_ip_addresses(@env['HTTP_X_FORWARDED_FOR']) if client_ip = @env['HTTP_CLIENT_IP'] # If forwarded_ips doesn't include the client_ip, it might be an # ip spoofing attempt, so we ignore HTTP_CLIENT_IP return client_ip if forwarded_ips.include?(client_ip) end return reject_trusted_ip_addresses(forwarded_ips).last || @env["REMOTE_ADDR"] end |
#logger ⇒ Object
38 |
# File 'lib/rack/request.rb', line 38 def logger; @env['rack.logger'] end |
#media_type ⇒ Object
The media type (type/subtype) portion of the CONTENT_TYPE header without any media type parameters. e.g., when CONTENT_TYPE is “text/plain;charset=utf-8”, the media-type is “text/plain”.
For more information on the use of media types in HTTP, see: www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
46 47 48 |
# File 'lib/rack/request.rb', line 46 def media_type content_type && content_type.split(/\s*[;,]\s*/, 2).first.downcase end |
#media_type_params ⇒ Object
The media type parameters provided in CONTENT_TYPE as a Hash, or an empty Hash if no CONTENT_TYPE or media-type parameters were provided. e.g., when the CONTENT_TYPE is “text/plain;charset=utf-8”, this method responds with the following Hash:
{ 'charset' => 'utf-8' }
55 56 57 58 59 60 |
# File 'lib/rack/request.rb', line 55 def media_type_params return {} if content_type.nil? Hash[*content_type.split(/\s*[;,]\s*/)[1..-1]. collect { |s| s.split('=', 2) }. map { |k,v| [k.downcase, v] }.flatten] end |
#options? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type OPTIONS
129 |
# File 'lib/rack/request.rb', line 129 def ; request_method == "OPTIONS" end |
#params ⇒ Object
The union of GET and POST data.
Note that modifications will not be persisted in the env. Use update_param or delete_param if you want to destructively modify params.
226 227 228 229 230 |
# File 'lib/rack/request.rb', line 226 def params @params ||= self.GET.merge(self.POST) rescue EOFError self.GET.dup end |
#parseable_data? ⇒ Boolean
Determine whether the request body contains data by checking the request media_type against registered parse-data media-types
180 181 182 |
# File 'lib/rack/request.rb', line 180 def parseable_data? PARSEABLE_DATA_MEDIA_TYPES.include?(media_type) end |
#patch? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type PATCH
132 |
# File 'lib/rack/request.rb', line 132 def patch?; request_method == "PATCH" end |
#path ⇒ Object
325 326 327 |
# File 'lib/rack/request.rb', line 325 def path script_name + path_info end |
#path_info ⇒ Object
26 |
# File 'lib/rack/request.rb', line 26 def path_info; @env["PATH_INFO"].to_s end |
#path_info=(s) ⇒ Object
116 |
# File 'lib/rack/request.rb', line 116 def path_info=(s); @env["PATH_INFO"] = s.to_s end |
#port ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/rack/request.rb', line 96 def port if port = host_with_port.split(/:/)[1] port.to_i elsif port = @env['HTTP_X_FORWARDED_PORT'] port.to_i elsif @env.has_key?("HTTP_X_FORWARDED_HOST") DEFAULT_PORTS[scheme] elsif @env.has_key?("HTTP_X_FORWARDED_PROTO") DEFAULT_PORTS[@env['HTTP_X_FORWARDED_PROTO']] else @env["SERVER_PORT"].to_i end end |
#POST ⇒ Object
Returns the data received in the request body.
This method support both application/x-www-form-urlencoded and multipart/form-data.
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/rack/request.rb', line 198 def POST if @env["rack.input"].nil? raise "Missing rack.input" elsif @env["rack.request.form_input"].equal? @env["rack.input"] @env["rack.request.form_hash"] elsif form_data? || parseable_data? @env["rack.request.form_input"] = @env["rack.input"] unless @env["rack.request.form_hash"] = parse_multipart(env) form_vars = @env["rack.input"].read # Fix for Safari Ajax postings that always append \0 # form_vars.sub!(/\0\z/, '') # performance replacement: form_vars.slice!(-1) if form_vars[-1] == ?\0 @env["rack.request.form_vars"] = form_vars @env["rack.request.form_hash"] = parse_query(form_vars) @env["rack.input"].rewind end @env["rack.request.form_hash"] else {} end end |
#post? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type POST
135 |
# File 'lib/rack/request.rb', line 135 def post?; request_method == "POST" end |
#put? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type PUT
138 |
# File 'lib/rack/request.rb', line 138 def put?; request_method == "PUT" end |
#query_string ⇒ Object
28 |
# File 'lib/rack/request.rb', line 28 def query_string; @env["QUERY_STRING"].to_s end |
#referer ⇒ Object Also known as: referrer
the referer of the client
283 284 285 |
# File 'lib/rack/request.rb', line 283 def referer @env['HTTP_REFERER'] end |
#request_method ⇒ Object
27 |
# File 'lib/rack/request.rb', line 27 def request_method; @env["REQUEST_METHOD"] end |
#scheme ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/rack/request.rb', line 70 def scheme if @env['HTTPS'] == 'on' 'https' elsif @env['HTTP_X_FORWARDED_SSL'] == 'on' 'https' elsif @env['HTTP_X_FORWARDED_SCHEME'] @env['HTTP_X_FORWARDED_SCHEME'] elsif @env['HTTP_X_FORWARDED_PROTO'] @env['HTTP_X_FORWARDED_PROTO'].split(',')[0] else @env["rack.url_scheme"] end end |
#script_name ⇒ Object
25 |
# File 'lib/rack/request.rb', line 25 def script_name; @env["SCRIPT_NAME"].to_s end |
#script_name=(s) ⇒ Object
115 |
# File 'lib/rack/request.rb', line 115 def script_name=(s); @env["SCRIPT_NAME"] = s.to_s end |
#session ⇒ Object
36 |
# File 'lib/rack/request.rb', line 36 def session; @env['rack.session'] ||= {} end |
#session_options ⇒ Object
37 |
# File 'lib/rack/request.rb', line 37 def ; @env['rack.session.options'] ||= {} end |
#ssl? ⇒ Boolean
84 85 86 |
# File 'lib/rack/request.rb', line 84 def ssl? scheme == 'https' end |
#trace? ⇒ Boolean
Checks the HTTP request method (or verb) to see if it was of type TRACE
141 |
# File 'lib/rack/request.rb', line 141 def trace?; request_method == "TRACE" end |
#trusted_proxy?(ip) ⇒ Boolean
344 345 346 |
# File 'lib/rack/request.rb', line 344 def trusted_proxy?(ip) ip =~ /\A127\.0\.0\.1\Z|\A(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.|\A::1\Z|\Afd[0-9a-f]{2}:.+|\Alocalhost\Z|\Aunix\Z|\Aunix:/i end |
#update_param(k, v) ⇒ Object
Destructively update a parameter, whether it’s in GET and/or POST. Returns nil.
The parameter is updated wherever it was previous defined, so GET, POST, or both. If it wasn’t previously defined, it’s inserted into GET.
env is not touched.
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/rack/request.rb', line 237 def update_param(k, v) found = false if self.GET.has_key?(k) found = true self.GET[k] = v end if self.POST.has_key?(k) found = true self.POST[k] = v end unless found self.GET[k] = v end @params = nil nil end |
#url ⇒ Object
Tries to return a remake of the original request URL as a string.
321 322 323 |
# File 'lib/rack/request.rb', line 321 def url base_url + fullpath end |
#user_agent ⇒ Object
288 289 290 |
# File 'lib/rack/request.rb', line 288 def user_agent @env['HTTP_USER_AGENT'] end |
#values_at(*keys) ⇒ Object
like Hash#values_at
278 279 280 |
# File 'lib/rack/request.rb', line 278 def values_at(*keys) keys.map{|key| params[key] } end |
#xhr? ⇒ Boolean
310 311 312 |
# File 'lib/rack/request.rb', line 310 def xhr? @env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest" end |