Class: Rack::Request

Inherits:
Object show all
Defined in:
lib/vendor/rack-1.5.2/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.

Direct Known Subclasses

Sinatra::Request

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

Instance Method Summary collapse

Constructor Details

#initialize(env) ⇒ Request

Returns a new instance of Request.



20
21
22
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 20

def initialize(env)
  @env = env
end

Instance Attribute Details

#envObject (readonly)

The environment of the request.



18
19
20
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 18

def env
  @env
end

Instance Method Details

#[](key) ⇒ Object

shortcut for request.params



264
265
266
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 264

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.



271
272
273
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 271

def []=(key, value)
  params[key.to_s] = value
end

#accept_encodingObject



331
332
333
334
335
336
337
338
339
340
# File 'lib/vendor/rack-1.5.2/lib/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

#base_urlObject



312
313
314
315
316
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 312

def base_url
  url = "#{scheme}://#{host}"
  url << ":#{port}" if port != DEFAULT_PORTS[scheme]
  url
end

#bodyObject



24
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 24

def body;            @env["rack.input"]                       end

#content_charsetObject

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/vendor/rack-1.5.2/lib/rack/request.rb', line 66

def content_charset
  media_type_params['charset']
end

#content_lengthObject



29
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 29

def content_length;  @env['CONTENT_LENGTH']                   end

#content_typeObject



31
32
33
34
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 31

def content_type
  content_type = @env['CONTENT_TYPE']
  content_type.nil? || content_type.empty? ? nil : content_type
end

#cookiesObject



290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 290

def cookies
  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.
  cookies = Utils.parse_query(string, ';,') { |s| Rack::Utils.unescape(s) rescue s }
  cookies.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

Returns:

  • (Boolean)


118
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 118

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.



257
258
259
260
261
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 257

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.

Returns:

  • (Boolean)


170
171
172
173
174
# File 'lib/vendor/rack-1.5.2/lib/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

#fullpathObject



327
328
329
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 327

def fullpath
  query_string.empty? ? path : "#{path}?#{query_string}"
end

#GETObject

Returns the data received in the query string.



183
184
185
186
187
188
189
190
# File 'lib/vendor/rack-1.5.2/lib/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

#get?Boolean

Checks the HTTP request method (or verb) to see if it was of type GET

Returns:

  • (Boolean)


121
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 121

def get?;     request_method == "GET"     end

#head?Boolean

Checks the HTTP request method (or verb) to see if it was of type HEAD

Returns:

  • (Boolean)


124
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 124

def head?;    request_method == "HEAD"    end

#hostObject



108
109
110
111
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 108

def host
  # Remove port number.
  host_with_port.to_s.gsub(/:\d+\z/, '')
end

#host_with_portObject



88
89
90
91
92
93
94
# File 'lib/vendor/rack-1.5.2/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

#ipObject



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
# File 'lib/vendor/rack-1.5.2/lib/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

#loggerObject



38
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 38

def logger;          @env['rack.logger']                      end

#media_typeObject

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/vendor/rack-1.5.2/lib/rack/request.rb', line 46

def media_type
  content_type && content_type.split(/\s*[;,]\s*/, 2).first.downcase
end

#media_type_paramsObject

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/vendor/rack-1.5.2/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

Returns:

  • (Boolean)


127
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 127

def options?; request_method == "OPTIONS" end

#paramsObject

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 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 224

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

Returns:

  • (Boolean)


178
179
180
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 178

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

Returns:

  • (Boolean)


130
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 130

def patch?;   request_method == "PATCH"   end

#pathObject



323
324
325
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 323

def path
  script_name + path_info
end

#path_infoObject



26
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 26

def path_info;       @env["PATH_INFO"].to_s                   end

#path_info=(s) ⇒ Object



114
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 114

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

#portObject



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/vendor/rack-1.5.2/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]
  else
    @env["SERVER_PORT"].to_i
  end
end

#POSTObject

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 'lib/vendor/rack-1.5.2/lib/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

#post?Boolean

Checks the HTTP request method (or verb) to see if it was of type POST

Returns:

  • (Boolean)


133
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 133

def post?;    request_method == "POST"    end

#put?Boolean

Checks the HTTP request method (or verb) to see if it was of type PUT

Returns:

  • (Boolean)


136
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 136

def put?;     request_method == "PUT"     end

#query_stringObject



28
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 28

def query_string;    @env["QUERY_STRING"].to_s                end

#refererObject Also known as: referrer

the referer of the client



281
282
283
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 281

def referer
  @env['HTTP_REFERER']
end

#request_methodObject



27
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 27

def request_method;  @env["REQUEST_METHOD"]                   end

#schemeObject



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/vendor/rack-1.5.2/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_nameObject



25
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 25

def script_name;     @env["SCRIPT_NAME"].to_s                 end

#script_name=(s) ⇒ Object



113
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 113

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

#sessionObject



36
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 36

def session;         @env['rack.session'] ||= {}              end

#session_optionsObject



37
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 37

def session_options; @env['rack.session.options'] ||= {}      end

#ssl?Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/vendor/rack-1.5.2/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

Returns:

  • (Boolean)


139
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 139

def trace?;   request_method == "TRACE"   end

#trusted_proxy?(ip) ⇒ Boolean

Returns:

  • (Boolean)


342
343
344
# File 'lib/vendor/rack-1.5.2/lib/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

#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.



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/vendor/rack-1.5.2/lib/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

#urlObject

Tries to return a remake of the original request URL as a string.



319
320
321
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 319

def url
  base_url + fullpath
end

#user_agentObject



286
287
288
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 286

def user_agent
  @env['HTTP_USER_AGENT']
end

#values_at(*keys) ⇒ Object

like Hash#values_at



276
277
278
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 276

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

#xhr?Boolean

Returns:

  • (Boolean)


308
309
310
# File 'lib/vendor/rack-1.5.2/lib/rack/request.rb', line 308

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