55# See the file LICENSE.txt for details.
66#++
77
8- require 'rack/session/abstract/id' unless defined? ( ::Rack ::Session ::Abstract ::ID )
8+ require 'rack/session/abstract/id' unless defined? ( ::Rack ::Session ::Abstract ::Persisted )
99
1010module JRuby ::Rack
1111 module Session
@@ -28,7 +28,7 @@ def method_missing(method, *args, &block)
2828 end
2929
3030 # Rack based SessionStore implementation but compatible with (older) AbstractStore.
31- class SessionStore < ::Rack ::Session ::Abstract ::ID
31+ class SessionStore < ::Rack ::Session ::Abstract ::Persisted
3232
3333 ENV_SERVLET_SESSION_KEY = 'java.servlet_session' . freeze
3434 RAILS_SESSION_KEY = "__current_rails_session" . freeze
@@ -37,13 +37,6 @@ def initialize(app, options={})
3737 super ( app , options . merge! ( :cookie_only => false , :defer => true ) )
3838 end
3939
40- def context ( env , app = @app )
41- req = make_request env
42- prepare_session ( req )
43- status , headers , body = app . call ( req . env )
44- commit_session ( req , status , headers , body )
45- end
46-
4740 # (public) servlet specific methods :
4841
4942 def get_servlet_session ( env , create = false )
@@ -69,7 +62,7 @@ def get_servlet_session(env, create = false)
6962 servlet_session
7063 end
7164
72- private # Rack::Session::Abstract::ID overrides :
65+ private # Rack::Session::Abstract::Persisted overrides :
7366
7467 def session_class
7568 ::JRuby ::Rack ::Session ::SessionHash
@@ -83,6 +76,7 @@ def generate_sid(secure = @sid_secure)
8376 nil # dummy method - no session id generation with servlet API
8477 end
8578
79+ # Alternative to overriding find_session(req)
8680 def load_session ( req ) # session_id arg for get_session alias
8781 session_id , session = false , { }
8882 if servlet_session = get_servlet_session ( req . env )
@@ -122,40 +116,48 @@ def loaded_session?(session)
122116 ! session . is_a? ( ::JRuby ::Rack ::Session ::SessionHash ) || session . loaded?
123117 end
124118
125- def commit_session ( req , status , headers , body )
126- session = req . env [ ::Rack ::RACK_SESSION ]
127- options = req . env [ :: Rack :: RACK_SESSION_OPTIONS ]
119+ def commit_session ( req , res )
120+ session = req . get_header ::Rack ::RACK_SESSION
121+ options = session . options
128122
129123 if options [ :drop ] || options [ :renew ]
130- destroy_session ( req . env , options [ :id ] , options )
124+ delete_session ( req , session . id , options )
131125 end
132126
133- return [ status , headers , body ] if options [ :drop ] || options [ :skip ]
127+ # Mirror behaviour of Rails ActionDispatch::Session::AbstractStore#commit_session for Rails 7.1+ compatibility
128+ commit_csrf_token ( req , session )
134129
135- if loaded_session? ( session )
136- session_id = session . respond_to? ( :id= ) ? session . id : options [ :id ]
137- session_data = session . to_hash . delete_if { |_ , v | v . nil? }
138- unless set_session ( req . env , session_id , session_data , options )
139- req . env [ "rack.errors" ] . puts ( "WARNING #{ self . class . name } failed to save session. Content dropped." )
140- end
130+ return if options [ :drop ] || options [ :skip ] || ! loaded_session? ( session )
131+
132+ session_id ||= session . id
133+ session_data = session . to_hash . delete_if { |k , v | v . nil? }
134+
135+ unless write_session ( req , session_id , session_data , options )
136+ req . get_header ( RACK_ERRORS ) . puts ( "Warning! #{ self . class . name } failed to save session. Content dropped." )
141137 end
138+ end
142139
143- [ status , headers , body ]
140+ def commit_csrf_token ( req , session_hash )
141+ csrf_token = req . env [ ::ActionController ::RequestForgeryProtection ::CSRF_TOKEN ] if defined? ( ::ActionController ::RequestForgeryProtection ::CSRF_TOKEN )
142+ if csrf_token
143+ session_hash [ :_csrf_token ] = csrf_token
144+ end
144145 end
145146
146- def set_session ( env , session_id , hash , options )
147- if session_id . nil? && hash . empty?
148- destroy_session ( env )
147+ def write_session ( req , session_id , session_hash , options )
148+ if session_id . nil? && session_hash . empty?
149+ delete_session ( req )
149150 return true
150151 end
151- if servlet_session = get_servlet_session ( env , true )
152+
153+ if servlet_session = get_servlet_session ( req . env , true )
152154 begin
153155 servlet_session . synchronized do
154156 keys = servlet_session . getAttributeNames
155- keys . select { |key | ! hash . has_key? ( key ) } . each do |key |
157+ keys . select { |key | ! session_hash . has_key? ( key ) } . each do |key |
156158 servlet_session . removeAttribute ( key )
157159 end
158- hash . delete_if do |key , value |
160+ session_hash . delete_if do |key , value |
159161 if String === key
160162 case value
161163 when String , Numeric , true , false , nil
@@ -171,8 +173,8 @@ def set_session(env, session_id, hash, options)
171173 end
172174 end
173175 end
174- if ! hash . empty?
175- marshalled_string = Marshal . dump ( hash )
176+ if ! session_hash . empty?
177+ marshalled_string = Marshal . dump ( session_hash )
176178 marshalled_bytes = marshalled_string . to_java_bytes
177179 servlet_session . setAttribute ( RAILS_SESSION_KEY , marshalled_bytes )
178180 elsif servlet_session . getAttribute ( RAILS_SESSION_KEY )
@@ -188,9 +190,9 @@ def set_session(env, session_id, hash, options)
188190 end
189191 end
190192
191- def destroy_session ( env , session_id = nil , options = nil )
192- # session_id and options arg defaults for destory alias
193- ( session = get_servlet_session ( env ) ) && session . synchronized { session . invalidate }
193+ def delete_session ( req , session_id = nil , options = nil )
194+ # session_id and options arg defaults for delete alias
195+ ( session = get_servlet_session ( req . env ) ) && session . synchronized { session . invalidate }
194196 rescue java . lang . IllegalStateException # if session already invalid
195197 nil
196198 end
0 commit comments