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,49 @@ 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+ # Overridden from Rack, removing support for deferral and unnecessary cookie support when using Java Servlet sessions.
120+ def commit_session ( req , _res )
121+ session = req . get_header ::Rack ::RACK_SESSION
122+ options = session . options
128123
129124 if options [ :drop ] || options [ :renew ]
130- destroy_session ( req . env , options [ :id ] , options )
125+ delete_session ( req , session . id , options )
131126 end
132127
133- return [ status , headers , body ] if options [ :drop ] || options [ :skip ]
128+ return if options [ :drop ] || options [ :skip ]
134129
135130 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." )
131+ # Mirror behaviour of Rails ActionDispatch::Session::AbstractStore#commit_session for Rails 7.1+ compatibility
132+ commit_csrf_token ( req , session )
133+
134+ session_id ||= session . id
135+ session_data = session . to_hash . delete_if { |k , v | v . nil? }
136+
137+ unless write_session ( req , session_id , session_data , options )
138+ req . get_header ( ::Rack ::RACK_ERRORS ) . puts ( "Warning! #{ self . class . name } failed to save session. Content dropped." )
140139 end
141140 end
141+ end
142142
143- [ status , headers , body ]
143+ def commit_csrf_token ( req , session_hash )
144+ csrf_token = req . env [ ::ActionController ::RequestForgeryProtection ::CSRF_TOKEN ] if defined? ( ::ActionController ::RequestForgeryProtection ::CSRF_TOKEN )
145+ session_hash [ :_csrf_token ] = csrf_token if csrf_token
144146 end
145147
146- def set_session ( env , session_id , hash , options )
147- if session_id . nil? && hash . empty?
148- destroy_session ( env )
148+ def write_session ( req , session_id , session_hash , _options )
149+ if session_id . nil? && session_hash . empty?
150+ delete_session ( req )
149151 return true
150152 end
151- if servlet_session = get_servlet_session ( env , true )
153+
154+ if servlet_session = get_servlet_session ( req . env , true )
152155 begin
153156 servlet_session . synchronized do
154157 keys = servlet_session . getAttributeNames
155- keys . select { |key | ! hash . has_key? ( key ) } . each do |key |
158+ keys . select { |key | ! session_hash . has_key? ( key ) } . each do |key |
156159 servlet_session . removeAttribute ( key )
157160 end
158- hash . delete_if do |key , value |
161+ session_hash . delete_if do |key , value |
159162 if String === key
160163 case value
161164 when String , Numeric , true , false , nil
@@ -171,8 +174,8 @@ def set_session(env, session_id, hash, options)
171174 end
172175 end
173176 end
174- if ! hash . empty?
175- marshalled_string = Marshal . dump ( hash )
177+ if ! session_hash . empty?
178+ marshalled_string = Marshal . dump ( session_hash )
176179 marshalled_bytes = marshalled_string . to_java_bytes
177180 servlet_session . setAttribute ( RAILS_SESSION_KEY , marshalled_bytes )
178181 elsif servlet_session . getAttribute ( RAILS_SESSION_KEY )
@@ -188,9 +191,9 @@ def set_session(env, session_id, hash, options)
188191 end
189192 end
190193
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 }
194+ def delete_session ( req , _session_id = nil , _options = nil )
195+ # session_id and options arg defaults for delete alias
196+ ( session = get_servlet_session ( req . env ) ) && session . synchronized { session . invalidate }
194197 rescue java . lang . IllegalStateException # if session already invalid
195198 nil
196199 end
0 commit comments