<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -33,6 +33,11 @@ require 'openssl'       # to generate the HMAC message digest
 #   integrity defaults to 'SHA1' but may be any digest provided by OpenSSL,
 #   such as 'MD5', 'RIPEMD160', 'SHA256', etc.
 #
+# * &lt;tt&gt;:stable_session_id&lt;/tt&gt;: The Cookie Session Store doesn't maintain any server side 
+#   state by default.A unique session identifier is spawned per request, which may not be 
+#   desireable for some applications.Set :stable_session_id to true to maintain a stable     
+#   session identifier within the cookie.  
+#
 # To generate a secret key for an existing application, run
 # &quot;rake secret&quot; and set the key in config/environment.rb.
 #
@@ -50,6 +55,7 @@ class CGI::Session::CookieStore
 
   # Called from CGI::Session only.
   def initialize(session, options = {})
+    options.reverse_merge!( 'stable_session_id' =&gt; false )
     # The session_key option is required.
     if options['session_key'].blank?
       raise ArgumentError, 'A session_key is required to write a cookie containing the session data. Use config.action_controller.session = { :session_key =&gt; &quot;_myapp_session&quot;, :secret =&gt; &quot;some secret phrase&quot; } in config/environment.rb'
@@ -59,7 +65,7 @@ class CGI::Session::CookieStore
     ensure_secret_secure(options['secret'])
 
     # Keep the session and its secret on hand so we can read and write cookies.
-    @session, @secret = session, options['secret']
+    @session, @secret, @stable_session_id = session, options['secret'], options['stable_session_id']
 
     # Message digest defaults to SHA1.
     @digest = options['digest'] || 'SHA1'
@@ -129,6 +135,7 @@ class CGI::Session::CookieStore
   private
     # Marshal a session hash into safe cookie data. Include an integrity hash.
     def marshal(session)
+      session = stable_session_id!( session )
       data = ActiveSupport::Base64.encode64(Marshal.dump(session)).chop
       &quot;#{data}--#{generate_digest(data)}&quot;
     end
@@ -144,10 +151,25 @@ class CGI::Session::CookieStore
           raise TamperedWithCookie
         end
 
-        Marshal.load(ActiveSupport::Base64.decode64(data))
+        returning( stable_session_id!( Marshal.load(ActiveSupport::Base64.decode64(data)) ) ) do |data|
+          @session.instance_variable_set(:@session_id, data[:session_id]) if @stable_session_id 
+        end
       end
     end
 
+    def stable_session_id!( data  )
+      return data unless @stable_session_id
+      ( data ||= {} ).merge( inject_stable_session_id!( data ) )
+    end
+
+    def inject_stable_session_id!( data )
+      if data.respond_to?(:key?) &amp;&amp; !data.key?( :session_id )
+        { :session_id =&gt; CGI::Session.generate_unique_id }
+      else
+        {}
+      end  
+    end
+
     # Read the session data cookie.
     def read_cookie
       @session.cgi.cookies[@cookie_options['name']].first</diff>
      <filename>actionpack/lib/action_controller/session/cookie_store.rb</filename>
    </modified>
    <modified>
      <diff>@@ -178,6 +178,15 @@ class CookieStoreTest &lt; Test::Unit::TestCase
     end
   end
 
+  def test_should_inject_a_radom_session_id_within_the_cookie
+    set_cookie! cookie_value(:typical)
+    new_session( 'stable_session_id' =&gt; true ) do |session|
+      assert_not_nil session['user_id']
+      assert_not_nil session[:session_id]      
+      assert_not_equal session.session_id, cookie_value(:typical)
+    end
+  end
+
   private
     def assert_no_cookies(session)
       assert_nil session.cgi.output_cookies, session.cgi.output_cookies.inspect
@@ -209,16 +218,17 @@ class CookieStoreTest &lt; Test::Unit::TestCase
     end
 
     def new_session(options = {})
+      #options.reverse_merge!( 'stable_session_id' =&gt; true )
       with_cgi do |cgi|
         assert_nil cgi.output_hidden, &quot;Output hidden params should be empty: #{cgi.output_hidden.inspect}&quot;
         assert_nil cgi.output_cookies, &quot;Output cookies should be empty: #{cgi.output_cookies.inspect}&quot;
 
         @options = self.class.default_session_options.merge(options)
-        session = CGI::Session.new(cgi, @options)
 
+        session = CGI::Session.new(cgi, @options)
         assert_nil cgi.output_hidden, &quot;Output hidden params should be empty: #{cgi.output_hidden.inspect}&quot;
         assert_nil cgi.output_cookies, &quot;Output cookies should be empty: #{cgi.output_cookies.inspect}&quot;
-
+        
         yield session if block_given?
         session
       end</diff>
      <filename>actionpack/test/controller/session/cookie_store_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>183cc2f23234f5dba8615f26cf67b66b31633b21</id>
    </parent>
  </parents>
  <author>
    <name>Lourens Naude</name>
    <email>lourens@methodmissing.com</email>
  </author>
  <url>http://github.com/methodmissing/rails/commit/7f83b1365bcc27939d9b3c308d41f1075eb2670e</url>
  <id>7f83b1365bcc27939d9b3c308d41f1075eb2670e</id>
  <committed-date>2008-07-22T20:45:24-07:00</committed-date>
  <authored-date>2008-07-22T20:45:24-07:00</authored-date>
  <message>Stable session identifier support for CGI::Session::CookieStore</message>
  <tree>8fedafacd2d73c9791112c55f621079da20e7a55</tree>
  <committer>
    <name>Lourens Naude</name>
    <email>lourens@methodmissing.com</email>
  </committer>
</commit>
