Class: ActionDispatch::Cookies::CookieJar

Inherits:
Object
  • Object
show all
Includes:
ChainedCookieJars, Enumerable
Defined in:
actionpack/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

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

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#as_json, #exclude?, #index_by, #many?, #sum

Methods included from ChainedCookieJars

#encrypted, #permanent, #signed, #signed_or_encrypted

Constructor Details

#initialize(key_generator, host = nil, secure = false, options = {}) ⇒ CookieJar

Returns a new instance of CookieJar.



232
233
234
235
236
237
238
239
240
241
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 232

def initialize(key_generator, host = nil, secure = false, options = {})
  @key_generator = key_generator
  @set_cookies = {}
  @delete_cookies = {}
  @host = host
  @secure = secure
  @options = options
  @cookies = {}
  @committed = false
end

Class Method Details

.build(request) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 219

def self.build(request)
  env = request.env
  key_generator = env[GENERATOR_KEY]
  options = options_for_env env

  host = request.host
  secure = request.ssl?

  new(key_generator, host, secure, options).tap do |hash|
    hash.update(request.cookies)
  end
end

.options_for_env(env) ⇒ Object

:nodoc:



208
209
210
211
212
213
214
215
216
217
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 208

def self.options_for_env(env) #:nodoc:
  { signed_cookie_salt: env[SIGNED_COOKIE_SALT] || '',
    encrypted_cookie_salt: env[ENCRYPTED_COOKIE_SALT] || '',
    encrypted_signed_cookie_salt: env[ENCRYPTED_SIGNED_COOKIE_SALT] || '',
    secret_token: env[SECRET_TOKEN],
    secret_key_base: env[SECRET_KEY_BASE],
    upgrade_legacy_signed_cookies: env[SECRET_TOKEN].present? && env[SECRET_KEY_BASE].present?,
    serializer: env[COOKIES_SERIALIZER]
  }
end

Instance Method Details

#[](name) ⇒ Object

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



256
257
258
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 256

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

#[]=(name, options) ⇒ Object

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



294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 294

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 or 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



338
339
340
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 338

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

#commit!Object



245
246
247
248
249
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 245

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

#committed?Boolean

Returns:

  • (Boolean)


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

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.



317
318
319
320
321
322
323
324
325
326
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 317

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)


331
332
333
334
335
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 331

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

#each(&block) ⇒ Object



251
252
253
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 251

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

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



260
261
262
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 260

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

#handle_options(options) ⇒ Object

:nodoc:



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 274

def handle_options(options) #:nodoc:
  options[:path] ||= "/"

  if 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 (@host !~ /^[\d.]+$/) && (@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| @host.include? domain.sub(/^\./, '') }
  end
end

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

Returns:

  • (Boolean)


264
265
266
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 264

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

#recycle!Object

:nodoc:



347
348
349
350
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 347

def recycle! #:nodoc:
  @set_cookies = {}
  @delete_cookies = {}
end

#update(other_hash) ⇒ Object



269
270
271
272
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 269

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

#write(headers) ⇒ Object



342
343
344
345
# File 'actionpack/lib/action_dispatch/middleware/cookies.rb', line 342

def write(headers)
  @set_cookies.each { |k, v| ::Rack::Utils.set_cookie_header!(headers, k, v) if write_cookie?(v) }
  @delete_cookies.each { |k, v| ::Rack::Utils.delete_cookie_header!(headers, k, v) }
end