merb-core 0.9.6 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. data/CHANGELOG +67 -0
  2. data/CONTRIBUTORS +1 -0
  3. data/PUBLIC_CHANGELOG +34 -0
  4. data/Rakefile +7 -4
  5. data/bin/merb +1 -31
  6. data/lib/merb-core.rb +17 -6
  7. data/lib/merb-core/config.rb +0 -7
  8. data/lib/merb-core/controller/abstract_controller.rb +6 -3
  9. data/lib/merb-core/dispatch/cookies.rb +11 -10
  10. data/lib/merb-core/dispatch/dispatcher.rb +11 -5
  11. data/lib/merb-core/dispatch/request.rb +7 -2
  12. data/lib/merb-core/dispatch/session.rb +33 -17
  13. data/lib/merb-core/dispatch/session/container.rb +19 -9
  14. data/lib/merb-core/dispatch/session/cookie.rb +27 -12
  15. data/lib/merb-core/dispatch/session/memcached.rb +47 -27
  16. data/lib/merb-core/dispatch/session/memory.rb +10 -6
  17. data/lib/merb-core/dispatch/session/store_container.rb +25 -20
  18. data/lib/merb-core/test/helpers/request_helper.rb +6 -3
  19. data/lib/merb-core/test/helpers/route_helper.rb +1 -1
  20. data/lib/merb-core/test/matchers/view_matchers.rb +5 -1
  21. data/lib/merb-core/version.rb +1 -1
  22. data/spec/private/dispatch/fixture/log/merb_test.log +144 -0
  23. data/spec/private/router/fixture/log/merb_test.log +16 -0
  24. data/spec/public/controller/controllers/cookies.rb +14 -3
  25. data/spec/public/controller/cookies_spec.rb +53 -10
  26. data/spec/public/controller/url_spec.rb +6 -0
  27. data/spec/public/directory_structure/directory/log/merb_test.log +112 -0
  28. data/spec/public/reloading/directory/log/merb_test.log +16 -0
  29. data/spec/public/request/request_spec.rb +19 -10
  30. data/spec/public/router/fixture/log/merb_test.log +224 -0
  31. data/spec/public/session/controllers/sessions.rb +4 -0
  32. data/spec/public/session/memcached_session_spec.rb +2 -2
  33. data/spec/public/session/multiple_sessions_spec.rb +2 -2
  34. data/spec/public/session/session_spec.rb +15 -0
  35. data/spec/public/test/request_helper_spec.rb +21 -0
  36. data/spec/public/test/route_helper_spec.rb +7 -0
  37. metadata +6 -17
  38. data/lib/merb-core/script.rb +0 -112
data/CHANGELOG CHANGED
@@ -1,3 +1,70 @@
1
+ == 0.9.7 "Universe In A Bundle" 2008-09-13
2
+
3
+ * Made the post body available to the routing when testing a request.
4
+ * Better local gems dir detection and end-user feedback
5
+ * Updated PUBLIC_CHANGELOG regarding gem management and merb.thor
6
+ * Fixed compatibility with the *new* bundle logic
7
+ * Made request('/path', {}, {:post_body => 'some XML'}) not setting the post body to nil.
8
+ * Added two specs for setting request.raw_post. Passes for #dispatch_to, fails for #request.
9
+ * You can now use request_to with a post body:
10
+ * It's official: Thor is now a dependency
11
+ * Removed MerbScriptHelper - simplified loading bundled gems - see merb.thor
12
+ * Bug Fix: Cookie headers not being formatted correctly
13
+ * Added request.session.clear! method to clear and destroy the session (including the _session_id cookie itself)
14
+ * Both memcache-client and memcached gems are supported by the session store
15
+ * Added better query param parsing (naive but adequate) for nested params
16
+ * Added specs to make sure blank cookie options aren't used for Set-Cookie
17
+ * Fixed cookie issues in WebKit/Safari browsers
18
+ * Log ControllerExceptions with error level and only ServerErrors with info.
19
+ * Modified absolute_url to handle an object as well as a Hash
20
+ * Touches to new sessions: doc and minor code improvements.
21
+ * More meaningful exception message when no session container is configured.
22
+ * Make it clear how session mixin makes it's way into controller.
23
+ * Leave a note where new sessions doc needs to be improved.
24
+ * Fix smart formatting.
25
+ * Give smart people proper credit when you use their work.
26
+ * Loosen extlib dependency a bit.
27
+ * Meaningful message when Memcached session store can't be loaded because of load error.
28
+ * Remove libxml-ruby and memcache-client dev dependencies.
29
+ * Require memcached gem where memcached session store is defined (it's lazy loaded).
30
+ * Meaninful message when have_xpath matcher is used but libxml-ruby fails to load.
31
+ * Don't blow up when there are no system paths.
32
+
33
+ == 0.9.6 "Therapy session" 2008-09-08
34
+
35
+ * Merge in simple conditional get support at controller level.
36
+ * Merged in new bundling (aka freezer) branch
37
+ * Merged in new-sessions branch
38
+ * Simplify one more clever line.
39
+ * Trenary operator is always hard to read.
40
+ * Added PUBLIC_CHANGELOG note on Language::English::Inflector => English::Inflect
41
+ * Filters with procs created via class methods have identical signatures regardless if they handle content differently or not. So modified add_filter to just append procs to the filter list.
42
+ * Consolidating raw Rakefile commands to merb-core/tasks/merb_rake_helper.rb
43
+ * Update contributors list.
44
+ * Ticket #461 - This simply adds output for what host and port the adapter has started on.
45
+ * More Language::English::Inflect to English::Inflect changes - getting ready for Extlib move soon
46
+ * Language::English::Inflect => English::Inflect name changes
47
+ * Use frozen strings where possible.
48
+ * First pass at adding in CSRF protection in to Rack middleware.
49
+ * Query string of the format "foo=bar&foo=baz" should return params {"foo" => "baz"}
50
+ * Fixed multiple select not honored in params bug
51
+ * Public specs for 'fragment' changes in url.
52
+ * AbstractController now uniformly uses instance_eval for Procs where previously
53
+ * Renamed anchor to fragment along with some minor tweeks to follow rfc2396 better.
54
+ * Add support for :anchor when generating url's. Ex. url(:root, :anchor => :lower_half).
55
+ * Revert "Make Merb::Request#protocol return valid protocol names (http, not http://)."
56
+ * Adds specs for previous commit
57
+ * Fixes display @object, :template => "path/to/foo"
58
+ * Clean up Rakefile.
59
+ * Remove a line of extra code
60
+ * Set cookie expires to nil when session_expiry is set to 0.
61
+ * ConditionalGet refactoring.
62
+ * Fix: ConditionalGet should not return the message body when the status code is 304.
63
+ * Rescue Exception subclasses, not only StandardError subclasses.
64
+ * Make Merb::Request#protocol return valid protocol names (http, not http://).
65
+ * Add :protocol and :host options to absolute_url
66
+ * extends basic authentication a bit to allow usage outside of before filters
67
+
1
68
  == 0.9.5 "Knife and Spoons" 2008-26-08
2
69
  * Add Hpricot to dependencies: provided RSpec matchers depend on it.
3
70
  * Documentation fixes
@@ -63,6 +63,7 @@ Michael Sheakoski
63
63
  Mirko Froehlich
64
64
  Nathan Weizenbaum
65
65
  Oliver Jakubiec
66
+ Paul Barry
66
67
  Paul Boone
67
68
  Paul Carey
68
69
  Ray Morgan
@@ -1,3 +1,37 @@
1
+ 9/13/2008:
2
+ * Merb apps will always give priority to gems that are available locally in
3
+ Merb.root / gems. Because of the specific load order, you will need to use
4
+ bin/merb to load merb-core from local gems, as detailed below. This is also
5
+ the case for bin/merb-gen, bin/rake and bin/spec for example. The added
6
+ advantage is that your app will be completely independent from system gems.
7
+
8
+ * Thor tasks 'merb.thor' have been added for newly generated apps; regenerate
9
+ your app to get them; alternatively these are available on merbivore.com:
10
+
11
+ http://merbivore.com/merb.thor
12
+
13
+ * Release 0.9.6 introduced 'merb-gen scripts' which added script/merb and
14
+ script/merb-gen. However, now that merb.thor provides tasks to manage
15
+ bundled gems, we can directly extract the correct executables. To follow the
16
+ standard convention, these will be installed in ./bin instead of ./script.
17
+
18
+ With merb.thor installed, run the following to get started:
19
+
20
+ $ thor merb:tasks:setup # adds bin/thor, bin/rake etc.
21
+
22
+ As soon as you install other gems using merb.thor you'll have the required
23
+ bin executables available; these are setup so that running them will load
24
+ merb-core from the local gems dir, not from the system-wide rubygems.
25
+
26
+ To get bin/merb and bin/merb-gen for a fresh application, you can use:
27
+
28
+ $ thor merb:stable -a mongrel # install a full merb stack from stable rubygems
29
+
30
+ Alternatively, you can install from the bleeding edge:
31
+
32
+ $ thor merb:edge --install # install a full merb stack from github
33
+ $ thor merb:gems:install mongrel # or ebb, thin...
34
+
1
35
  9/5/2008:
2
36
  * Language::English::Inflector is now English::Inflect - be sure to change your
3
37
  custom inflections in config/init.rb. Additionally, the merb-gen template
data/Rakefile CHANGED
@@ -58,16 +58,19 @@ spec = Gem::Specification.new do |s|
58
58
  s.extra_rdoc_files = %w( README LICENSE TODO )
59
59
 
60
60
  # Dependencies
61
- s.add_dependency "extlib", ">= 0.9.5"
61
+ s.add_dependency "extlib", ">= 0.9.6"
62
62
  s.add_dependency "erubis"
63
63
  s.add_dependency "rake"
64
64
  s.add_dependency "json_pure"
65
65
  s.add_dependency "rspec"
66
66
  s.add_dependency "rack"
67
67
  s.add_dependency "mime-types"
68
- s.add_dependency "hpricot"
69
- s.add_development_dependency "libxml-ruby"
70
- s.add_development_dependency "memcache-client"
68
+ s.add_dependency "hpricot"
69
+ s.add_dependency "thor", ">= 0.9.6"
70
+ # this escalates to "regular" dependencies, comment it out
71
+ # for now. RubyGems need some love.
72
+ #s.add_development_dependency "libxml-ruby"
73
+ #s.add_development_dependency "memcache-client"
71
74
  # Requirements
72
75
  s.requirements << "install the json gem to get faster json parsing"
73
76
  s.required_ruby_version = ">= 1.8.6"
data/bin/merb CHANGED
@@ -1,36 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # See also: merb-gen scripts and script/merb
4
-
5
- # Try to use minigems instead of the fully rubygems library
6
- begin
7
- require 'minigems'
8
- rescue LoadError
9
- require 'rubygems'
10
- end
11
-
12
- # Load script helpers if available - either local or system-wide.
13
- begin
14
- # Figure out the merb root - defaults to the current directory.
15
- root_key = %w[-m --merb-root].detect { |o| ARGV.index(o) }
16
- root = ARGV[ARGV.index(root_key) + 1] if root_key
17
- __DIR__ = root.to_a.empty? ? Dir.getwd : root
18
-
19
- # Piggyback on the merb-core rubygem for initial setup scripts.
20
- # Requiring it doesn't affect the local gem version of merb-core
21
- # we might effectively want to load here after.
22
- if merb_core_dir = Dir[File.join(__DIR__, 'gems', 'gems', 'merb-core-*')].last
23
- require File.join(merb_core_dir, 'lib', 'merb-core', 'script')
24
- else
25
- require 'merb-core/script'
26
- end
27
- # Now setup local gems to be incorporated into the normal loaded gems.
28
- # Unless the option --no-bundle is given, bundled gems are enabled.
29
- include Merb::ScriptHelpers
30
- setup_local_gems!(__DIR__)
31
- rescue LoadError
32
- end
33
-
3
+ require 'rubygems'
34
4
  require 'merb-core'
35
5
 
36
6
  ARGV.push '-H' if ARGV[0] && ARGV[0] =~ /^[^-]/
@@ -1,6 +1,21 @@
1
1
  #---
2
2
  # require 'merb' must happen after Merb::Config is instantiated
3
3
  require 'rubygems'
4
+
5
+ # Add the local gems dir if found within the app root; any dependencies loaded
6
+ # hereafter will try to load from the local gems before loading system gems.
7
+ root_key = %w[-m --merb-root].detect { |o| ARGV.index(o) }
8
+ root = ARGV[ARGV.index(root_key) + 1] if root_key
9
+ root = root.to_a.empty? ? Dir.getwd : root
10
+ if File.directory?(gems_dir = File.join(root, 'gems'))
11
+ $BUNDLE = true; Gem.clear_paths; Gem.path.unshift(gems_dir)
12
+ # Warn if local merb-core is available but not loaded.
13
+ if !($0 =~ /^(\.\/)?bin\/merb$/) &&
14
+ (local_mc = Dir[File.join(gems_dir, 'specifications', 'merb-core-*.gemspec')].last)
15
+ puts "Warning: please use bin/merb to load #{File.basename(local_mc, '.gemspec')} from ./gems"
16
+ end
17
+ end
18
+
4
19
  require 'set'
5
20
  require 'fileutils'
6
21
  require 'socket'
@@ -356,12 +371,8 @@ module Merb
356
371
 
357
372
  Merb.klass_hashes = []
358
373
 
359
- attr_accessor :frozen
360
-
361
374
  # ==== Returns
362
375
  # Boolean:: True if Merb is running as an application with bundled gems.
363
- # Can only be disabled by --no-bundle option on startup (or for Rakefile
364
- # use NO_BUNDLE=true to disable local gems).
365
376
  #
366
377
  # ==== Notes
367
378
  # Bundling required gems makes your application independent from the
@@ -369,7 +380,7 @@ module Merb
369
380
  # framework and gems it uses and very useful when application is run in
370
381
  # some sort of sandbox, for instance, shared hosting with preconfigured gems.
371
382
  def bundled?
372
- ENV.key?("BUNDLE") || Merb::Config[:bundle] || ENV.key?("NO_BUNDLE")
383
+ $BUNDLE || ENV.key?("BUNDLE")
373
384
  end
374
385
 
375
386
  # Load configuration and assign logger.
@@ -577,4 +588,4 @@ require 'merb-core/version'
577
588
  require 'merb-core/controller/mime'
578
589
 
579
590
  # Set the environment if it hasn't already been set.
580
- Merb.environment ||= ENV['MERB_ENV'] || Merb::Config[:environment] || (Merb.testing? ? 'test' : 'development')
591
+ Merb.environment ||= ENV['MERB_ENV'] || Merb::Config[:environment] || (Merb.testing? ? 'test' : 'development')
@@ -116,9 +116,6 @@ module Merb
116
116
  # Environment variables always win
117
117
  options[:environment] = ENV["MERB_ENV"] if ENV["MERB_ENV"]
118
118
 
119
- # Enable bundled gems by default; used by bundled?
120
- options[:bundle] = true
121
-
122
119
  # Build a parser for the command line arguments
123
120
  opts = OptionParser.new do |opts|
124
121
  opts.version = Merb::VERSION
@@ -242,10 +239,6 @@ module Merb
242
239
  options[:verbose] = true
243
240
  end
244
241
 
245
- opts.on("-B", "--[no-]bundle", "Run application using bundled gems. Enabled by default.") do |b|
246
- options[:bundle] = b
247
- end
248
-
249
242
  opts.on("-?", "-H", "--help", "Show this help message") do
250
243
  puts opts
251
244
  exit
@@ -461,11 +461,14 @@ class Merb::AbstractController
461
461
  def absolute_url(name, rparams={})
462
462
  # FIXME: arrgh, why request.protocol returns http://?
463
463
  # :// is not part of protocol name
464
- protocol = rparams.delete(:protocol)
465
- protocol << "://" if protocol
464
+ if rparams.is_a?(Hash)
465
+ protocol = rparams.delete(:protocol)
466
+ protocol << "://" if protocol
467
+ host = rparams.delete(:host)
468
+ end
466
469
 
467
470
  (protocol || request.protocol) +
468
- (rparams.delete(:host) || request.host) +
471
+ (host || request.host) +
469
472
  url(name, rparams)
470
473
  end
471
474
 
@@ -2,9 +2,9 @@ module Merb
2
2
 
3
3
  class Cookies < Mash
4
4
 
5
- def initialize(constructor = {}, cookie_defaults = {})
6
- @_options_lookup = Mash.new
7
- @_cookie_defaults = cookie_defaults
5
+ def initialize(constructor = {})
6
+ @_options_lookup = Mash.new
7
+ @_cookie_defaults = { "domain" => Merb::Controller._default_cookie_domain, "path" => '/' }
8
8
  super constructor
9
9
  end
10
10
 
@@ -50,7 +50,7 @@ module Merb
50
50
  # name<~to_s>:: Name of the cookie to delete.
51
51
  # options<Hash>:: Additional options to pass to +set_cookie+.
52
52
  def delete(name, options = {})
53
- set_cookie(name, "", options.merge(:expires => Time.at(0)))
53
+ set_cookie(name, "", options.merge("expires" => Time.at(0)))
54
54
  end
55
55
 
56
56
  # Generate any necessary headers.
@@ -64,12 +64,13 @@ module Merb
64
64
  # Only set cookies that marked for inclusion in the response header.
65
65
  next unless @_options_lookup[name]
66
66
  options = defaults.merge(@_options_lookup[name])
67
- if (expiry = options[:expires]).respond_to?(:gmtime)
68
- options[:expires] = expiry.gmtime.strftime(Merb::Const::COOKIE_EXPIRATION_FORMAT)
67
+ if (expiry = options["expires"]).respond_to?(:gmtime)
68
+ options["expires"] = expiry.gmtime.strftime(Merb::Const::COOKIE_EXPIRATION_FORMAT)
69
69
  end
70
- secure = options.delete(:secure)
70
+ secure = options.delete("secure")
71
71
  kookie = "#{name}=#{Merb::Request.escape(value)}; "
72
- options.each { |k, v| kookie << "#{k}=#{v}; " }
72
+ # WebKit in particular doens't like empty cookie options - skip them.
73
+ options.each { |k, v| kookie << "#{k}=#{v}; " unless v.blank? }
73
74
  kookie << 'secure' if secure
74
75
  cookies << kookie.rstrip
75
76
  end
@@ -87,7 +88,7 @@ module Merb
87
88
 
88
89
  # Add a callback to enable Set-Cookie headers
89
90
  base._after_dispatch_callbacks << lambda do |c|
90
- headers = c.request.cookies.extract_headers(:domain => c._default_cookie_domain)
91
+ headers = c.request.cookies.extract_headers("domain" => c._default_cookie_domain)
91
92
  c.headers.update(headers)
92
93
  end
93
94
  end
@@ -116,7 +117,7 @@ module Merb
116
117
  def cookies
117
118
  @cookies ||= begin
118
119
  values = self.class.query_parse(@env[Merb::Const::HTTP_COOKIE], ';,')
119
- cookies = Merb::Cookies.new(values, :domain => Merb::Controller._default_cookie_domain, :path => '/')
120
+ cookies = Merb::Cookies.new(values)
120
121
  cookies.update(default_cookies) if respond_to?(:default_cookies)
121
122
  cookies
122
123
  end
@@ -139,12 +139,18 @@ module Merb
139
139
  # Exceptions::
140
140
  # The Merb::Controller that was dispatched to.
141
141
  def dispatch_exception(exception)
142
- Merb.logger.error(Merb.exception(exception))
142
+ if(exception.is_a?(Merb::ControllerExceptions::Base) &&
143
+ !exception.is_a?(Merb::ControllerExceptions::ServerError))
144
+ Merb.logger.info(Merb.exception(exception))
145
+ else
146
+ Merb.logger.error(Merb.exception(exception))
147
+ end
148
+
143
149
  self.exceptions = [exception]
144
-
150
+
145
151
  begin
146
152
  e = exceptions.first
147
-
153
+
148
154
  if action_name = e.action_name
149
155
  dispatch_action(Exceptions, action_name, e.class.status)
150
156
  else
@@ -156,11 +162,11 @@ module Merb
156
162
  else
157
163
  Merb.logger.error("Dispatching #{e.class} raised another error.")
158
164
  Merb.logger.error(Merb.exception(dispatch_issue))
159
-
165
+
160
166
  exceptions.unshift dispatch_issue
161
167
  retry
162
168
  end
163
169
  end
164
170
  end
165
171
  end
166
- end
172
+ end
@@ -652,9 +652,14 @@ module Merb
652
652
  parms[key] = val
653
653
  elsif after == "[]"
654
654
  (parms[key] ||= []) << val
655
- elsif after =~ %r(^\[\])
655
+ elsif after =~ %r(^\[\]\[([^\[\]]+)\]$)
656
+ child_key = $1
656
657
  parms[key] ||= []
657
- parms[key] << normalize_params({}, after, val)
658
+ if parms[key].last.is_a?(Hash) && !parms[key].last.key?(child_key)
659
+ parms[key].last.update(child_key => val)
660
+ else
661
+ parms[key] << { child_key => val }
662
+ end
658
663
  else
659
664
  parms[key] ||= {}
660
665
  parms[key] = normalize_params(parms[key], after, val)
@@ -2,10 +2,10 @@ require 'merb-core/dispatch/session/container'
2
2
  require 'merb-core/dispatch/session/store_container'
3
3
 
4
4
  module Merb
5
-
6
5
  class Config
7
-
8
- # List of all session_stores taken from :session_stores or :session_store
6
+ # Returns stores list constructed from
7
+ # configured session stores (:session_stores config option)
8
+ # or default one (:session_store config option).
9
9
  def self.session_stores
10
10
  @session_stores ||= begin
11
11
  config_stores = Array(
@@ -14,16 +14,20 @@ module Merb
14
14
  config_stores.map { |name| name.to_sym }
15
15
  end
16
16
  end
17
-
18
- end
17
+ end # Config
19
18
 
20
19
  # The Merb::Session module gets mixed into Merb::SessionContainer to allow
21
- # app-level functionality (usually found in app/models/merb/session.rb)
20
+ # app-level functionality (usually found in app/models/merb/session.rb) for
21
+ # session.
22
+ #
23
+ # You can use this module to implement additional methods to simplify
24
+ # building wizard-like application components,
25
+ # authentication frameworks, etc.
22
26
  module Session
23
27
  end
24
28
 
29
+ # This is mixed into Merb::Controller on framework boot.
25
30
  module SessionMixin
26
-
27
31
  # Raised when no suitable session store has been setup.
28
32
  class NoSessionContainer < StandardError; end
29
33
 
@@ -42,7 +46,6 @@ module Merb
42
46
  # session data; min. 16 chars
43
47
  #
44
48
  # :default_cookie_domain The default domain to write cookies for.
45
-
46
49
  def self.included(base)
47
50
  # Register a callback to finalize sessions - needs to run before the cookie
48
51
  # callback extracts Set-Cookie headers from request.cookies.
@@ -54,7 +57,9 @@ module Merb
54
57
  #
55
58
  # ==== Returns
56
59
  # SessionContainer:: The session that was extracted from the request object.
57
- def session(session_store = nil) request.session(session_store) end
60
+ def session(session_store = nil)
61
+ request.session(session_store)
62
+ end
58
63
 
59
64
  # Module methods
60
65
 
@@ -125,6 +130,9 @@ module Merb
125
130
  @session_stores ||= {}
126
131
  end
127
132
 
133
+ # Returns session container. Merb is able to handle multiple session
134
+ # stores, hence a parameter to pick it.
135
+ #
128
136
  # ==== Parameters
129
137
  # session_store<String>:: The type of session store to access,
130
138
  # defaults to default_session_store.
@@ -137,12 +145,13 @@ module Merb
137
145
  if class_name = self.class.registered_session_types[session_store]
138
146
  session_stores[session_store] ||= Object.full_const_get(class_name).setup(self)
139
147
  elsif fallback = self.class.registered_session_types.keys.first
140
- Merb.logger.warn "Session store not found, '#{session_store}'."
141
- Merb.logger.warn "Defaulting to #{fallback} sessions."
148
+ Merb.logger.warn "Session store '#{session_store}' not found. Check your configuration in init file."
149
+ Merb.logger.warn "Falling back to #{fallback} session store."
142
150
  session(fallback)
143
151
  else
144
- Merb.logger.error "Can't use sessions because no session store is available."
145
- raise NoSessionContainer, "No session store configured."
152
+ msg = "No session store set. Set it in init file like this: c[:session_store] = 'activerecord'"
153
+ Merb.logger.error!(msg)
154
+ raise NoSessionContainer, msg
146
155
  end
147
156
  end
148
157
 
@@ -184,12 +193,13 @@ module Merb
184
193
  defaults
185
194
  end
186
195
 
196
+ # Sets session cookie value.
197
+ #
187
198
  # ==== Parameters
188
199
  # value<String>:: The value of the session cookie; either the session id or the actual encoded data.
189
- def set_session_cookie_value(value)
190
- options = {}
191
- options[:expires] = Time.now + _session_expiry
192
- cookies.set_cookie(_session_id_key, value, options)
200
+ # options<Hash>:: Cookie options like domain, path and expired.
201
+ def set_session_cookie_value(value, options = {})
202
+ cookies.set_cookie(_session_id_key, value, { :expires => Time.now + _session_expiry }.merge(options))
193
203
  end
194
204
  alias :set_session_id_cookie :set_session_cookie_value
195
205
 
@@ -199,6 +209,12 @@ module Merb
199
209
  cookies[_session_id_key]
200
210
  end
201
211
  alias :session_id :session_cookie_value
212
+
213
+ # Destroy the session cookie.
214
+ def destroy_session_cookie
215
+ cookies.delete(_session_id_key)
216
+ end
217
+
202
218
  end
203
219
  end
204
220
  end