Module: Rack::Request::Helpers

Included in:
Rack::Request
Defined in:
lib/rack/request.rb

Constant Summary collapse

FORM_DATA_MEDIA_TYPES =

The set of form-data media-types. Requests that do not indicate one of the media types present 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 present 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 }
HTTP_X_FORWARDED_FOR =

The address of the client which connected to the proxy.

'HTTP_X_FORWARDED_FOR'
HTTP_X_FORWARDED_HOST =

The contents of the host/:authority header sent to the proxy.

'HTTP_X_FORWARDED_HOST'
HTTP_FORWARDED =
'HTTP_FORWARDED'
HTTP_X_FORWARDED_SCHEME =

The value of the scheme sent to the proxy.

'HTTP_X_FORWARDED_SCHEME'
HTTP_X_FORWARDED_PROTO =

The protocol used to connect to the proxy.

'HTTP_X_FORWARDED_PROTO'
HTTP_X_FORWARDED_PORT =

The port used to connect to the proxy.

'HTTP_X_FORWARDED_PORT'
HTTP_X_FORWARDED_SSL =

Another way for specifying https scheme was used.

'HTTP_X_FORWARDED_SSL'

Instance Method Summary collapse

Instance Method Details

#accept_encodingObject



589
590
591
# File 'lib/rack/request.rb', line 589

def accept_encoding
  parse_http_accept_header(get_header("HTTP_ACCEPT_ENCODING"))
end

#accept_languageObject



593
594
595
# File 'lib/rack/request.rb', line 593

def accept_language
  parse_http_accept_header(get_header("HTTP_ACCEPT_LANGUAGE"))
end

#authorityObject

The authority of the incoming request as defined by RFC3976. tools.ietf.org/html/rfc3986#section-3.2

In HTTP/1, this is the ‘host` header. In HTTP/2, this is the `:authority` pseudo-header.



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

def authority
  forwarded_authority || host_authority || server_authority
end

#base_urlObject



572
573
574
# File 'lib/rack/request.rb', line 572

def base_url
  "#{scheme}://#{host_with_port}"
end

#bodyObject



195
# File 'lib/rack/request.rb', line 195

def body;            get_header(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.



465
466
467
# File 'lib/rack/request.rb', line 465

def content_charset
  media_type_params['charset']
end

#content_lengthObject



204
# File 'lib/rack/request.rb', line 204

def content_length;  get_header('CONTENT_LENGTH')                   end

#content_typeObject



313
314
315
316
# File 'lib/rack/request.rb', line 313

def content_type
  content_type = get_header('CONTENT_TYPE')
  content_type.nil? || content_type.empty? ? nil : content_type
end

#cookiesObject



298
299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/rack/request.rb', line 298

def cookies
  hash = fetch_header(RACK_REQUEST_COOKIE_HASH) do |key|
    set_header(key, {})
  end

  string = get_header(HTTP_COOKIE)

  unless string == get_header(RACK_REQUEST_COOKIE_STRING)
    hash.replace Utils.parse_cookies_header(string)
    set_header(RACK_REQUEST_COOKIE_STRING, string)
  end

  hash
end

#delete?Boolean

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

Returns:

  • (Boolean)


225
# File 'lib/rack/request.rb', line 225

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['rack.input'] is not touched.



567
568
569
570
# File 'lib/rack/request.rb', line 567

def delete_param(k)
  post_value, get_value = self.POST.delete(k), self.GET.delete(k)
  post_value || get_value
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)


477
478
479
480
481
482
# File 'lib/rack/request.rb', line 477

def form_data?
  type = media_type
  meth = get_header(RACK_METHODOVERRIDE_ORIGINAL_METHOD) || get_header(REQUEST_METHOD)

  (meth == POST && type.nil?) || FORM_DATA_MEDIA_TYPES.include?(type)
end

#forwarded_authorityObject



398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# File 'lib/rack/request.rb', line 398

def forwarded_authority
  forwarded_priority.each do |type|
    case type
    when :forwarded
      if forwarded = get_http_forwarded(:host)
        return forwarded.last
      end
    when :x_forwarded
      if (value = get_header(HTTP_X_FORWARDED_HOST)) && (x_forwarded_host = split_header(value).last)
        return wrap_ipv6(x_forwarded_host)
      end
    end
  end

  nil
end

#forwarded_forObject



358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/rack/request.rb', line 358

def forwarded_for
  forwarded_priority.each do |type|
    case type
    when :forwarded
      if forwarded_for = get_http_forwarded(:for)
        return(forwarded_for.map! do |authority|
          split_authority(authority)[1]
        end)
      end
    when :x_forwarded
      if value = get_header(HTTP_X_FORWARDED_FOR)
        return(split_header(value).map do |authority|
          split_authority(wrap_ipv6(authority))[1]
        end)
      end
    end
  end

  nil
end

#forwarded_portObject



379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/rack/request.rb', line 379

def forwarded_port
  forwarded_priority.each do |type|
    case type
    when :forwarded
      if forwarded = get_http_forwarded(:for)
        return(forwarded.map do |authority|
          split_authority(authority)[2]
        end.compact)
      end
    when :x_forwarded
      if value = get_header(HTTP_X_FORWARDED_PORT)
        return split_header(value).map(&:to_i)
      end
    end
  end

  nil
end

#fullpathObject



585
586
587
# File 'lib/rack/request.rb', line 585

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

#GETObject

Returns the data received in the query string.



491
492
493
# File 'lib/rack/request.rb', line 491

def GET
  get_header(RACK_REQUEST_QUERY_HASH) || set_header(RACK_REQUEST_QUERY_HASH, parse_query(query_string, '&'))
end

#get?Boolean

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

Returns:

  • (Boolean)


228
# File 'lib/rack/request.rb', line 228

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)


231
# File 'lib/rack/request.rb', line 231

def head?;    request_method == HEAD    end

#hostObject

Returns a formatted host, suitable for being used in a URI.



338
339
340
# File 'lib/rack/request.rb', line 338

def host
  split_authority(self.authority)[0]
end

#host_authorityObject

The ‘HTTP_HOST` header.



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

def host_authority
  get_header(HTTP_HOST)
end

#host_with_port(authority = self.authority) ⇒ Object



327
328
329
330
331
332
333
334
335
# File 'lib/rack/request.rb', line 327

def host_with_port(authority = self.authority)
  host, _, port = split_authority(authority)

  if port == DEFAULT_PORTS[self.scheme]
    host
  else
    authority
  end
end

#hostnameObject

Returns an address suitable for being to resolve to an address. In the case of a domain name or IPv4 address, the result is the same as host. In the case of IPv6 or future address formats, the square brackets are removed.



346
347
348
# File 'lib/rack/request.rb', line 346

def hostname
  split_authority(self.authority)[1]
end

#ipObject



419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
# File 'lib/rack/request.rb', line 419

def ip
  remote_addresses = split_header(get_header('REMOTE_ADDR'))

  remote_addresses.reverse_each do |ip|
    return ip unless trusted_proxy?(ip)
  end

  if (forwarded_for = self.forwarded_for) && !forwarded_for.empty?
    # The forwarded for addresses are ordered: client, proxy1, proxy2.
    # So we reject all the trusted addresses (proxy*) and return the
    # last client. Or if we trust everyone, we just return the first
    # address.
    forwarded_for.reverse_each do |ip|
      return ip unless trusted_proxy?(ip)
    end
    return forwarded_for.first
  end

  # If all the addresses are trusted, and we aren't forwarded, just return
  # the first remote address, which represents the source of the request.
  remote_addresses.first
end

#link?Boolean

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

Returns:

  • (Boolean)


237
# File 'lib/rack/request.rb', line 237

def link?;    request_method == LINK    end

#loggerObject



205
# File 'lib/rack/request.rb', line 205

def logger;          get_header(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



448
449
450
# File 'lib/rack/request.rb', line 448

def media_type
  MediaType.type(content_type)
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' }


457
458
459
# File 'lib/rack/request.rb', line 457

def media_type_params
  MediaType.params(content_type)
end

#options?Boolean

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

Returns:

  • (Boolean)


234
# File 'lib/rack/request.rb', line 234

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.



538
539
540
# File 'lib/rack/request.rb', line 538

def params
  self.GET.merge(self.POST)
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)


486
487
488
# File 'lib/rack/request.rb', line 486

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)


240
# File 'lib/rack/request.rb', line 240

def patch?;   request_method == PATCH   end

#pathObject



581
582
583
# File 'lib/rack/request.rb', line 581

def path
  script_name + path_info
end

#path_infoObject



199
# File 'lib/rack/request.rb', line 199

def path_info;       get_header(PATH_INFO).to_s                     end

#path_info=(s) ⇒ Object



200
# File 'lib/rack/request.rb', line 200

def path_info=(s);   set_header(PATH_INFO, s.to_s)                  end

#portObject



350
351
352
353
354
355
356
# File 'lib/rack/request.rb', line 350

def port
  if authority = self.authority
    _, _, port = split_authority(authority)
  end

  port || forwarded_port&.last || DEFAULT_PORTS[scheme] || server_port
end

#POSTObject

Returns the data received in the request body.

This method support both application/x-www-form-urlencoded and multipart/form-data.



499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
# File 'lib/rack/request.rb', line 499

def POST
  if form_hash = get_header(RACK_REQUEST_FORM_HASH)
    return form_hash
  elsif error = get_header(RACK_REQUEST_FORM_ERROR)
    raise error.class, error.message, cause: error.cause
  end

  begin
    rack_input = get_header(RACK_INPUT)

    # Otherwise, figure out how to parse the input:
    if rack_input.nil?
      set_header(RACK_REQUEST_FORM_HASH, {})
    elsif form_data? || parseable_data?
      if pairs = Rack::Multipart.parse_multipart(env, Rack::Multipart::ParamList)
        set_header RACK_REQUEST_FORM_PAIRS, pairs
        set_header RACK_REQUEST_FORM_HASH, expand_param_pairs(pairs)
      else
        form_vars = get_header(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.end_with?("\0")

        set_header RACK_REQUEST_FORM_VARS, form_vars
        set_header RACK_REQUEST_FORM_HASH, parse_query(form_vars, '&')
      end
    else
      set_header(RACK_REQUEST_FORM_HASH, {})
    end
  rescue => error
    set_header(RACK_REQUEST_FORM_ERROR, error)
    raise
  end
end

#post?Boolean

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

Returns:

  • (Boolean)


243
# File 'lib/rack/request.rb', line 243

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)


246
# File 'lib/rack/request.rb', line 246

def put?;     request_method == PUT     end

#query_stringObject



203
# File 'lib/rack/request.rb', line 203

def query_string;    get_header(QUERY_STRING).to_s                  end

#refererObject Also known as: referrer

the referer of the client



209
# File 'lib/rack/request.rb', line 209

def referer;         get_header('HTTP_REFERER')                     end

#request_methodObject



202
# File 'lib/rack/request.rb', line 202

def request_method;  get_header(REQUEST_METHOD)                     end

#schemeObject



254
255
256
257
258
259
260
261
262
263
264
# File 'lib/rack/request.rb', line 254

def scheme
  if get_header(HTTPS) == 'on'
    'https'
  elsif get_header(HTTP_X_FORWARDED_SSL) == 'on'
    'https'
  elsif forwarded_scheme
    forwarded_scheme
  else
    get_header(RACK_URL_SCHEME)
  end
end

#script_nameObject



196
# File 'lib/rack/request.rb', line 196

def script_name;     get_header(SCRIPT_NAME).to_s                   end

#script_name=(s) ⇒ Object



197
# File 'lib/rack/request.rb', line 197

def script_name=(s); set_header(SCRIPT_NAME, s.to_s)                end

#server_authorityObject

The authority as defined by the ‘SERVER_NAME` and `SERVER_PORT` variables.



277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/rack/request.rb', line 277

def server_authority
  host = self.server_name
  port = self.server_port

  if host
    if port
      "#{host}:#{port}"
    else
      host
    end
  end
end

#server_nameObject



290
291
292
# File 'lib/rack/request.rb', line 290

def server_name
  get_header(SERVER_NAME)
end

#server_portObject



294
295
296
# File 'lib/rack/request.rb', line 294

def server_port
  get_header(SERVER_PORT)
end

#sessionObject



212
213
214
215
216
# File 'lib/rack/request.rb', line 212

def session
  fetch_header(RACK_SESSION) do |k|
    set_header RACK_SESSION, default_session
  end
end

#session_optionsObject



218
219
220
221
222
# File 'lib/rack/request.rb', line 218

def session_options
  fetch_header(RACK_SESSION_OPTIONS) do |k|
    set_header RACK_SESSION_OPTIONS, {}
  end
end

#ssl?Boolean

Returns:

  • (Boolean)


415
416
417
# File 'lib/rack/request.rb', line 415

def ssl?
  scheme == 'https' || scheme == 'wss'
end

#trace?Boolean

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

Returns:

  • (Boolean)


249
# File 'lib/rack/request.rb', line 249

def trace?;   request_method == TRACE   end

#trusted_proxy?(ip) ⇒ Boolean

Returns:

  • (Boolean)


597
598
599
# File 'lib/rack/request.rb', line 597

def trusted_proxy?(ip)
  Rack::Request.ip_filter.call(ip)
end

#unlink?Boolean

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

Returns:

  • (Boolean)


252
# File 'lib/rack/request.rb', line 252

def unlink?;  request_method == UNLINK  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['rack.input'] is not touched.



547
548
549
550
551
552
553
554
555
556
557
558
559
560
# File 'lib/rack/request.rb', line 547

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
end

#urlObject

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



577
578
579
# File 'lib/rack/request.rb', line 577

def url
  base_url + fullpath
end

#user_agentObject



206
# File 'lib/rack/request.rb', line 206

def user_agent;      get_header('HTTP_USER_AGENT')                  end

#xhr?Boolean

Returns:

  • (Boolean)


318
319
320
# File 'lib/rack/request.rb', line 318

def xhr?
  get_header("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest"
end