Class: ActionDispatch::Cookies::CookieJar

Inherits:
Object
  • Object
show all
Includes:
ChainedCookieJars, Enumerable
Defined in:
lib/action_dispatch/middleware/cookies.rb

Overview

:nodoc:

Constant Summary collapse

DOMAIN_REGEXP =

This regular expression is used to split the levels of a domain. The top level domain can be any string without a period or *.*, **.* style TLDs like co.uk or com.au

www.example.co.uk gives: $& => example.co.uk

example.com gives: $& => example.com

lots.of.subdomains.example.local gives: $& => example.local

/[^.]*\.([^.]*|..\...|...\...)$/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ChainedCookieJars

#encrypted, #permanent, #signed, #signed_or_encrypted

Constructor Details

#initialize(request) ⇒ CookieJar

Returns a new instance of CookieJar.



296
297
298
299
300
301
302
# File 'lib/action_dispatch/middleware/cookies.rb', line 296

def initialize(request)
  @set_cookies = {}
  @delete_cookies = {}
  @request = request
  @cookies = {}
  @committed = false
end

Instance Attribute Details

#requestObject (readonly)

Returns the value of attribute request.



294
295
296
# File 'lib/action_dispatch/middleware/cookies.rb', line 294

def request
  @request
end

Class Method Details

.build(req, cookies) ⇒ Object



288
289
290
291
292
# File 'lib/action_dispatch/middleware/cookies.rb', line 288

def self.build(req, cookies)
  new(req).tap do |hash|
    hash.update(cookies)
  end
end

Instance Method Details

#[](name) ⇒ Object

Returns the value of the cookie by name, or nil if no such cookie exists.



317
318
319
# File 'lib/action_dispatch/middleware/cookies.rb', line 317

def [](name)
  @cookies[name.to_s]
end

#[]=(name, options) ⇒ Object

Sets the cookie named name. The second argument may be the cookie's value or a hash of options as documented above.



373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/action_dispatch/middleware/cookies.rb', line 373

def []=(name, options)
  if options.is_a?(Hash)
    options.symbolize_keys!
    value = options[:value]
  else
    value = options
    options = { value: value }
  end

  handle_options(options)

  if @cookies[name.to_s] != value || options[:expires]
    @cookies[name.to_s] = value
    @set_cookies[name.to_s] = options
    @delete_cookies.delete(name.to_s)
  end

  value
end

#clear(options = {}) ⇒ Object

Removes all cookies on the client machine by calling delete for each cookie.



417
418
419
# File 'lib/action_dispatch/middleware/cookies.rb', line 417

def clear(options = {})
  @cookies.each_key { |k| delete(k, options) }
end

#commit!Object



306
307
308
309
310
# File 'lib/action_dispatch/middleware/cookies.rb', line 306

def commit!
  @committed = true
  @set_cookies.freeze
  @delete_cookies.freeze
end

#committed?Boolean

Returns:

  • (Boolean)


304
# File 'lib/action_dispatch/middleware/cookies.rb', line 304

def committed?; @committed; end

#delete(name, options = {}) ⇒ Object

Removes the cookie on the client machine by setting the value to an empty string and the expiration date in the past. Like []=, you can pass in an options hash to delete cookies with extra data such as a :path.



396
397
398
399
400
401
402
403
404
405
# File 'lib/action_dispatch/middleware/cookies.rb', line 396

def delete(name, options = {})
  return unless @cookies.has_key? name.to_s

  options.symbolize_keys!
  handle_options(options)

  value = @cookies.delete(name.to_s)
  @delete_cookies[name.to_s] = options
  value
end

#deleted?(name, options = {}) ⇒ Boolean

Whether the given cookie is to be deleted by this CookieJar. Like []=, you can pass in an options hash to test if a deletion applies to a specific :path, :domain etc.

Returns:

  • (Boolean)


410
411
412
413
414
# File 'lib/action_dispatch/middleware/cookies.rb', line 410

def deleted?(name, options = {})
  options.symbolize_keys!
  handle_options(options)
  @delete_cookies[name.to_s] == options
end

#each(&block) ⇒ Object



312
313
314
# File 'lib/action_dispatch/middleware/cookies.rb', line 312

def each(&block)
  @cookies.each(&block)
end

#fetch(name, *args, &block) ⇒ Object



321
322
323
# File 'lib/action_dispatch/middleware/cookies.rb', line 321

def fetch(name, *args, &block)
  @cookies.fetch(name.to_s, *args, &block)
end

#handle_options(options) ⇒ Object

:nodoc:



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
# File 'lib/action_dispatch/middleware/cookies.rb', line 349

def handle_options(options) # :nodoc:
  if options[:expires].respond_to?(:from_now)
    options[:expires] = options[:expires].from_now
  end

  options[:path] ||= "/"

  if options[:domain] == :all || options[:domain] == "all"
    # If there is a provided tld length then we use it otherwise default domain regexp.
    domain_regexp = options[:tld_length] ? /([^.]+\.?){#{options[:tld_length]}}$/ : DOMAIN_REGEXP

    # If host is not ip and matches domain regexp.
    # (ip confirms to domain regexp so we explicitly check for ip)
    options[:domain] = if (request.host !~ /^[\d.]+$/) && (request.host =~ domain_regexp)
      ".#{$&}"
    end
  elsif options[:domain].is_a? Array
    # If host matches one of the supplied domains without a dot in front of it.
    options[:domain] = options[:domain].find { |domain| request.host.include? domain.sub(/^\./, "") }
  end
end

#key?(name) ⇒ Boolean Also known as: has_key?

Returns:

  • (Boolean)


325
326
327
# File 'lib/action_dispatch/middleware/cookies.rb', line 325

def key?(name)
  @cookies.key?(name.to_s)
end

#to_headerObject



345
346
347
# File 'lib/action_dispatch/middleware/cookies.rb', line 345

def to_header
  @cookies.map { |k, v| "#{escape(k)}=#{escape(v)}" }.join "; "
end

#update(other_hash) ⇒ Object



333
334
335
336
# File 'lib/action_dispatch/middleware/cookies.rb', line 333

def update(other_hash)
  @cookies.update other_hash.stringify_keys
  self
end

#update_cookies_from_jarObject



338
339
340
341
342
343
# File 'lib/action_dispatch/middleware/cookies.rb', line 338

def update_cookies_from_jar
  request_jar = @request.cookie_jar.instance_variable_get(:@cookies)
  set_cookies = request_jar.reject { |k, _| @delete_cookies.key?(k) || @set_cookies.key?(k) }

  @cookies.update set_cookies if set_cookies
end

#write(headers) ⇒ Object



421
422
423
424
425
# File 'lib/action_dispatch/middleware/cookies.rb', line 421

def write(headers)
  if header = make_set_cookie_header(headers[HTTP_HEADER])
    headers[HTTP_HEADER] = header
  end
end