Class: Rack::Request
- Inherits:
-
Object
- Object
- Rack::Request
- Defined in:
- rack/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
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.
Direct Known Subclasses
Constant Summary
- 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)
-
- (void) env
readonly
The environment of the request.
Instance Method Summary (collapse)
-
- (void) [](key)
shortcut for request.params.
-
- (void) []=(key, value)
shortcut for request.params = value.
- - (void) accept_encoding
- - (void) base_url
- - (void) body
-
- (void) content_charset
The character set of the request body if a "charset" media type parameter was given, or nil if no "charset" was specified.
- - (void) content_length
- - (void) content_type
- - (void) cookies
-
- (Boolean) delete?
Checks the HTTP request method (or verb) to see if it was of type DELETE.
-
- (void) delete_param(k)
Destructively delete a parameter, whether it's in GET or POST.
-
- (Boolean) form_data?
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".
- - (void) fullpath
-
- (void) GET
Returns the data received in the query string.
-
- (Boolean) get?
Checks the HTTP request method (or verb) to see if it was of type GET.
-
- (Boolean) head?
Checks the HTTP request method (or verb) to see if it was of type HEAD.
- - (void) host
- - (void) host_with_port
-
- (Request) initialize(env)
constructor
A new instance of Request.
- - (void) ip
- - (void) logger
-
- (void) media_type
The media type (type/subtype) portion of the CONTENT_TYPE header without any media type parameters.
-
- (void) media_type_params
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.
-
- (Boolean) options?
Checks the HTTP request method (or verb) to see if it was of type OPTIONS.
-
- (void) params
The union of GET and POST data.
- - (void) parse_multipart(env) protected
- - (void) parse_query(qs) protected
-
- (Boolean) parseable_data?
Determine whether the request body contains data by checking the request media_type against registered parse-data media-types.
-
- (Boolean) patch?
Checks the HTTP request method (or verb) to see if it was of type PATCH.
- - (void) path
- - (void) path_info
- - (void) path_info=(s)
- - (void) port
-
- (void) POST
Returns the data received in the request body.
-
- (Boolean) post?
Checks the HTTP request method (or verb) to see if it was of type POST.
-
- (Boolean) put?
Checks the HTTP request method (or verb) to see if it was of type PUT.
- - (void) query_string
-
- (void) referer
(also: #referrer)
the referer of the client.
- - (void) reject_trusted_ip_addresses(ip_addresses) protected
- - (void) request_method
- - (void) scheme
- - (void) script_name
- - (void) script_name=(s)
- - (void) session
- - (void) session_options
- - (void) split_ip_addresses(ip_addresses) protected
- - (Boolean) ssl?
-
- (Boolean) trace?
Checks the HTTP request method (or verb) to see if it was of type TRACE.
- - (Boolean) trusted_proxy?(ip)
-
- (void) update_param(k, v)
Destructively update a parameter, whether it's in GET and/or POST.
-
- (void) url
Tries to return a remake of the original request URL as a string.
- - (void) user_agent
-
- (void) values_at(*keys)
like Hash#values_at.
- - (Boolean) xhr?
Constructor Details
- (Request) initialize(env)
Returns a new instance of Request
20 21 22 |
# File 'rack/rack/request.rb', line 20 def initialize(env) @env = env end |
Instance Attribute Details
- (void) env (readonly)
The environment of the request.
18 19 20 |
# File 'rack/rack/request.rb', line 18 def env @env end |
Instance Method Details
- (void) [](key)
shortcut for request.params
264 265 266 |
# File 'rack/rack/request.rb', line 264 def [](key) params[key.to_s] end |
- (void) []=(key, value)
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.
271 272 273 |
# File 'rack/rack/request.rb', line 271 def []=(key, value) params[key.to_s] = value end |
- (void) accept_encoding
331 332 333 334 335 336 337 338 339 340 |
# File 'rack/rack/request.rb', line 331 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 |
- (void) base_url
312 313 314 315 316 |
# File 'rack/rack/request.rb', line 312 def base_url url = "#{scheme}://#{host}" url << ":#{port}" if port != DEFAULT_PORTS[scheme] url end |
- (void) body
24 |
# File 'rack/rack/request.rb', line 24 def body; @env["rack.input"] end |
- (void) content_charset
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 'rack/rack/request.rb', line 66 def content_charset media_type_params['charset'] end |
- (void) content_length
29 |
# File 'rack/rack/request.rb', line 29 def content_length; @env['CONTENT_LENGTH'] end |
- (void) content_type
31 32 33 34 |
# File 'rack/rack/request.rb', line 31 def content_type content_type = @env['CONTENT_TYPE'] content_type.nil? || content_type.empty? ? nil : content_type end |
- (void) cookies
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
# File 'rack/rack/request.rb', line 290 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 |
- (Boolean) delete?
Checks the HTTP request method (or verb) to see if it was of type DELETE
118 |
# File 'rack/rack/request.rb', line 118 def delete?; request_method == "DELETE" end |
- (void) delete_param(k)
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.
257 258 259 260 261 |
# File 'rack/rack/request.rb', line 257 def delete_param(k) v = [ self.POST.delete(k), self.GET.delete(k) ].compact.first @params = nil v end |
- (Boolean) form_data?
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.
170 171 172 173 174 |
# File 'rack/rack/request.rb', line 170 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 |
- (void) fullpath
327 328 329 |
# File 'rack/rack/request.rb', line 327 def fullpath query_string.empty? ? path : "#{path}?#{query_string}" end |
- (void) GET
Returns the data received in the query string.
183 184 185 186 187 188 189 190 |
# File 'rack/rack/request.rb', line 183 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 |
- (Boolean) get?
Checks the HTTP request method (or verb) to see if it was of type GET
121 |
# File 'rack/rack/request.rb', line 121 def get?; request_method == "GET" end |
- (Boolean) head?
Checks the HTTP request method (or verb) to see if it was of type HEAD
124 |
# File 'rack/rack/request.rb', line 124 def head?; request_method == "HEAD" end |
- (void) host
108 109 110 111 |
# File 'rack/rack/request.rb', line 108 def host # Remove port number. host_with_port.to_s.gsub(/:\d+\z/, '') end |
- (void) host_with_port
88 89 90 91 92 93 94 |
# File 'rack/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 |
- (void) ip
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
# File 'rack/rack/request.rb', line 346 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 |
- (void) logger
38 |
# File 'rack/rack/request.rb', line 38 def logger; @env['rack.logger'] end |
- (void) media_type
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 'rack/rack/request.rb', line 46 def media_type content_type && content_type.split(/\s*[;,]\s*/, 2).first.downcase end |
- (void) media_type_params
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 'rack/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 |
- (Boolean) options?
Checks the HTTP request method (or verb) to see if it was of type OPTIONS
127 |
# File 'rack/rack/request.rb', line 127 def ; request_method == "OPTIONS" end |
- (void) params
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.
224 225 226 227 228 |
# File 'rack/rack/request.rb', line 224 def params @params ||= self.GET.merge(self.POST) rescue EOFError self.GET.dup end |
- (void) parse_multipart(env) (protected)
376 377 378 |
# File 'rack/rack/request.rb', line 376 def parse_multipart(env) Rack::Multipart.parse_multipart(env) end |
- (void) parse_query(qs) (protected)
372 373 374 |
# File 'rack/rack/request.rb', line 372 def parse_query(qs) Utils.parse_nested_query(qs) end |
- (Boolean) parseable_data?
Determine whether the request body contains data by checking the request media_type against registered parse-data media-types
178 179 180 |
# File 'rack/rack/request.rb', line 178 def parseable_data? PARSEABLE_DATA_MEDIA_TYPES.include?(media_type) end |
- (Boolean) patch?
Checks the HTTP request method (or verb) to see if it was of type PATCH
130 |
# File 'rack/rack/request.rb', line 130 def patch?; request_method == "PATCH" end |
- (void) path
323 324 325 |
# File 'rack/rack/request.rb', line 323 def path script_name + path_info end |
- (void) path_info
26 |
# File 'rack/rack/request.rb', line 26 def path_info; @env["PATH_INFO"].to_s end |
- (void) path_info=(s)
114 |
# File 'rack/rack/request.rb', line 114 def path_info=(s); @env["PATH_INFO"] = s.to_s end |
- (void) port
96 97 98 99 100 101 102 103 104 105 106 |
# File 'rack/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] else @env["SERVER_PORT"].to_i end end |
- (void) POST
Returns the data received in the request body.
This method support both application/x-www-form-urlencoded and multipart/form-data.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'rack/rack/request.rb', line 196 def POST if @env["rack.input"].nil? raise "Missing rack.input" elsif @env["rack.request.form_input"].eql? @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 |
- (Boolean) post?
Checks the HTTP request method (or verb) to see if it was of type POST
133 |
# File 'rack/rack/request.rb', line 133 def post?; request_method == "POST" end |
- (Boolean) put?
Checks the HTTP request method (or verb) to see if it was of type PUT
136 |
# File 'rack/rack/request.rb', line 136 def put?; request_method == "PUT" end |
- (void) query_string
28 |
# File 'rack/rack/request.rb', line 28 def query_string; @env["QUERY_STRING"].to_s end |
- (void) referer Also known as: referrer
the referer of the client
281 282 283 |
# File 'rack/rack/request.rb', line 281 def referer @env['HTTP_REFERER'] end |
- (void) reject_trusted_ip_addresses(ip_addresses) (protected)
368 369 370 |
# File 'rack/rack/request.rb', line 368 def reject_trusted_ip_addresses(ip_addresses) ip_addresses.reject { |ip| trusted_proxy?(ip) } end |
- (void) request_method
27 |
# File 'rack/rack/request.rb', line 27 def request_method; @env["REQUEST_METHOD"] end |
- (void) scheme
70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'rack/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 |
- (void) script_name
25 |
# File 'rack/rack/request.rb', line 25 def script_name; @env["SCRIPT_NAME"].to_s end |
- (void) script_name=(s)
113 |
# File 'rack/rack/request.rb', line 113 def script_name=(s); @env["SCRIPT_NAME"] = s.to_s end |
- (void) session
36 |
# File 'rack/rack/request.rb', line 36 def session; @env['rack.session'] ||= {} end |
- (void) session_options
37 |
# File 'rack/rack/request.rb', line 37 def ; @env['rack.session.options'] ||= {} end |
- (void) split_ip_addresses(ip_addresses) (protected)
364 365 366 |
# File 'rack/rack/request.rb', line 364 def split_ip_addresses(ip_addresses) ip_addresses ? ip_addresses.strip.split(/[,\s]+/) : [] end |
- (Boolean) ssl?
84 85 86 |
# File 'rack/rack/request.rb', line 84 def ssl? scheme == 'https' end |
- (Boolean) trace?
Checks the HTTP request method (or verb) to see if it was of type TRACE
139 |
# File 'rack/rack/request.rb', line 139 def trace?; request_method == "TRACE" end |
- (Boolean) trusted_proxy?(ip)
342 343 344 |
# File 'rack/rack/request.rb', line 342 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 |
- (void) update_param(k, v)
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.
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'rack/rack/request.rb', line 235 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 |
- (void) url
Tries to return a remake of the original request URL as a string.
319 320 321 |
# File 'rack/rack/request.rb', line 319 def url base_url + fullpath end |
- (void) user_agent
286 287 288 |
# File 'rack/rack/request.rb', line 286 def user_agent @env['HTTP_USER_AGENT'] end |
- (void) values_at(*keys)
like Hash#values_at
276 277 278 |
# File 'rack/rack/request.rb', line 276 def values_at(*keys) keys.map{|key| params[key] } end |
- (Boolean) xhr?
308 309 310 |
# File 'rack/rack/request.rb', line 308 def xhr? @env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest" end |