dalli 3.2.13 → 4.0.0

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.
@@ -9,6 +9,10 @@ module Rack
9
9
  module Session
10
10
  # Rack::Session::Dalli provides memcached based session management.
11
11
  class Dalli < Abstract::PersistedSecure
12
+ class MissingSessionError < StandardError; end
13
+
14
+ RACK_SESSION_PERSISTED = 'rack.session.persisted'
15
+
12
16
  attr_reader :data
13
17
 
14
18
  # Don't freeze this until we fix the specs/implementation
@@ -70,23 +74,37 @@ module Rack
70
74
  @data = build_data_source(options)
71
75
  end
72
76
 
73
- def find_session(_req, sid)
77
+ def call(*_args)
78
+ super
79
+ rescue MissingSessionError
80
+ [401, {}, ['Wrong session ID']]
81
+ end
82
+
83
+ def find_session(req, sid)
74
84
  with_dalli_client([nil, {}]) do |dc|
75
85
  existing_session = existing_session_for_sid(dc, sid)
76
- return [sid, existing_session] unless existing_session.nil?
86
+ if existing_session.nil?
87
+ sid = create_sid_with_empty_session(dc)
88
+ existing_session = {}
89
+ end
77
90
 
78
- [create_sid_with_empty_session(dc), {}]
91
+ update_session_persisted_data(req, { id: sid })
92
+ return [sid, existing_session]
79
93
  end
80
94
  end
81
95
 
82
- def write_session(_req, sid, session, options)
96
+ def write_session(req, sid, session, options)
83
97
  return false unless sid
84
98
 
85
99
  key = memcached_key_from_sid(sid)
86
100
  return false unless key
87
101
 
88
102
  with_dalli_client(false) do |dc|
89
- dc.set(memcached_key_from_sid(sid), session, ttl(options[:expire_after]))
103
+ write_session_safely!(
104
+ dc, sid, session_persisted_data(req),
105
+ write_args: [memcached_key_from_sid(sid), session, ttl(options[:expire_after])]
106
+ )
107
+
90
108
  sid
91
109
  end
92
110
  end
@@ -145,6 +163,15 @@ module Rack
145
163
  end
146
164
  end
147
165
 
166
+ def write_session_safely!(dalli_client, sid, persisted_data, write_args:)
167
+ if persisted_data && persisted_data[:id] == sid # That means that we update the existing session
168
+ # Override the session only if it still exists in the store!
169
+ raise MissingSessionError unless dalli_client.replace(*write_args)
170
+ else
171
+ dalli_client.set(*write_args)
172
+ end
173
+ end
174
+
148
175
  def extract_dalli_options(options)
149
176
  raise 'Rack::Session::Dalli no longer supports the :cache option.' if options[:cache]
150
177
 
@@ -175,8 +202,8 @@ module Rack
175
202
  raise e
176
203
  end
177
204
 
178
- def with_dalli_client(result_on_error = nil, &block)
179
- @data.with(&block)
205
+ def with_dalli_client(result_on_error = nil, &)
206
+ @data.with(&)
180
207
  rescue ::Dalli::DalliError, Errno::ECONNREFUSED
181
208
  raise if $ERROR_INFO.message.include?('undefined class')
182
209
 
@@ -190,6 +217,14 @@ module Rack
190
217
  def ttl(expire_after)
191
218
  expire_after.nil? ? 0 : expire_after + 1
192
219
  end
220
+
221
+ def session_persisted_data(req)
222
+ req.get_header RACK_SESSION_PERSISTED
223
+ end
224
+
225
+ def update_session_persisted_data(req, data)
226
+ req.set_header RACK_SESSION_PERSISTED, data
227
+ end
193
228
  end
194
229
  end
195
230
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dalli
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.13
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter M. Goldstein
@@ -40,7 +40,6 @@ files:
40
40
  - lib/dalli/cas/client.rb
41
41
  - lib/dalli/client.rb
42
42
  - lib/dalli/compressor.rb
43
- - lib/dalli/json_serializer.rb
44
43
  - lib/dalli/key_manager.rb
45
44
  - lib/dalli/options.rb
46
45
  - lib/dalli/pid_cache.rb
@@ -64,7 +63,6 @@ files:
64
63
  - lib/dalli/protocol/value_marshaller.rb
65
64
  - lib/dalli/protocol/value_serializer.rb
66
65
  - lib/dalli/ring.rb
67
- - lib/dalli/server.rb
68
66
  - lib/dalli/servers_arg_normalizer.rb
69
67
  - lib/dalli/socket.rb
70
68
  - lib/dalli/version.rb
@@ -83,14 +81,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
83
81
  requirements:
84
82
  - - ">="
85
83
  - !ruby/object:Gem::Version
86
- version: '2.6'
84
+ version: '3.1'
87
85
  required_rubygems_version: !ruby/object:Gem::Requirement
88
86
  requirements:
89
87
  - - ">="
90
88
  - !ruby/object:Gem::Version
91
89
  version: '0'
92
90
  requirements: []
93
- rubygems_version: 4.0.21
91
+ rubygems_version: 4.0.3
94
92
  specification_version: 4
95
93
  summary: High performance memcached client for Ruby
96
94
  test_files: []
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'json'
4
-
5
- module Dalli
6
- ##
7
- # A serializer that stores values as JSON and never creates Ruby objects
8
- # from what it reads.
9
- #
10
- # Passing the JSON module itself as the serializer (serializer: JSON) reads
11
- # values back with JSON.load, which on json gem versions before 3.0 honors
12
- # "json_class" and instantiates other classes when the json gem's additions
13
- # are loaded. This serializer reads with JSON.parse, so a value written to
14
- # memcached by someone else can only come back as plain hashes, arrays,
15
- # strings, numbers, booleans and nil.
16
- #
17
- # Dalli::Client.new(servers, serializer: Dalli::JSONSerializer)
18
- ##
19
- module JSONSerializer
20
- def self.dump(value)
21
- JSON.generate(value)
22
- end
23
-
24
- def self.load(data)
25
- JSON.parse(data)
26
- end
27
- end
28
- end
data/lib/dalli/server.rb DELETED
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dalli # rubocop:disable Style/Documentation
4
- warn 'Dalli::Server is deprecated, use Dalli::Protocol::Binary instead'
5
- Server = Protocol::Binary
6
- end