sbsm 1.3.0 → 1.3.1

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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
- #
3
+ #--
4
4
  # State Based Session Management
5
5
  # Copyright (C) 2004 Hannes Wyss
6
6
  #
@@ -22,7 +22,7 @@
22
22
  # hwyss@ywesee.com
23
23
  #
24
24
  # Exception -- sbsm -- 22.10.2002 -- hwyss@ywesee.com
25
-
25
+ #++
26
26
  module SBSM
27
27
  class ProcessingError < RuntimeError
28
28
  end
data/lib/sbsm/index.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
- #
3
+ #--
4
4
  # State Based Session Management
5
5
  # Copyright (C) 2004 Hannes Wyss
6
6
  #
@@ -22,6 +22,7 @@
22
22
  # hwyss@ywesee.com
23
23
  #
24
24
  # Index -- sbsm -- 04.03.2003 -- hwyss@ywesee.com
25
+ #++
25
26
 
26
27
  module SBSM
27
28
  class Index
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ #--
4
+ # State Based Session Management
5
+ # Copyright (C) 2016 Niklaus Giger
6
+ #
7
+ # This library is free software; you can redistribute it and/or
8
+ # modify it under the terms of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation; either
10
+ # version 2.1 of the License, or (at your option) any later version.
11
+ #
12
+ # This library is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public
18
+ # License along with this library; if not, write to the Free Software
19
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+ #
21
+ # ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Zürich, Switzerland
22
+ # ngiger@ywesee.com
23
+ #++
24
+
25
+ require 'chrono_logger'
26
+ require 'sbsm/version'
27
+ module SBSM
28
+ @@logger = ChronoLogger.new("/tmp/sbsm_#{VERSION}.log.%Y%m%d")
29
+ @@logger.level= :warn
30
+ def self.logger=(logger)
31
+ @@logger = logger
32
+ end
33
+ def self.logger
34
+ @@logger
35
+ end
36
+ # a simple logger, which makes it easy to compare the timing of the entries
37
+ # by the different process. Should probably later be replaced by a Rack based logger
38
+ def self.info(msg)
39
+ info = "#{File.basename(caller[0])} #{msg}"
40
+ @@logger.info(info) if @@logger
41
+ end
42
+ def self.debug(msg)
43
+ info = "#{File.basename(caller[0])} #{msg}"
44
+ @@logger.debug(info) if @@logger
45
+ end
46
+ end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
- #
3
+ #--
4
4
  # State Based Session Management
5
5
  # Copyright (C) 2004 Hannes Wyss
6
6
  #
@@ -22,7 +22,7 @@
22
22
  # hwyss@ywesee.com
23
23
  #
24
24
  # Lookandfeel -- sbsm -- hwyss@ywesee.com
25
-
25
+ #++
26
26
  require 'sbsm/time'
27
27
  require 'cgi'
28
28
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
- #
3
+ #--
4
4
  # State Based Session Management
5
5
  # Copyright (C) 2004 Hannes Wyss
6
6
  #
@@ -22,7 +22,7 @@
22
22
  # hwyss@ywesee.com
23
23
  #
24
24
  # LookandfeelFactory -- sbsm -- hwyss@ywesee.com
25
-
25
+ #++
26
26
  require 'sbsm/lookandfeel'
27
27
 
28
28
  module SBSM
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
- #
3
+ #--
4
4
  # State Based Session Management
5
5
  # Copyright (C) 2004 Hannes Wyss
6
6
  #
@@ -22,6 +22,7 @@
22
22
  # hwyss@ywesee.com
23
23
  #
24
24
  # LookandfeelWrapper -- sbsm -- hwyss@ywesee.com
25
+ #++
25
26
 
26
27
  require "sbsm/lookandfeel"
27
28
 
@@ -1,17 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
+ #--
3
4
  # Redirector -- sbsm -- 02.11.2006 -- hwyss@ywesee.com
4
-
5
+ #++
5
6
  module SBSM
6
7
  module Redirector
7
8
  def http_headers
8
- if(redirect?)
9
+ if(redirect?)
9
10
  @redirected = @state.redirected = true
10
11
  event, *args = @state.direct_event
11
12
  if(args.first.is_a? Hash)
12
13
  args = args.first
13
14
  end
14
- {
15
+ {
15
16
  "Location" => lookandfeel._event_url(event, args || {}),
16
17
  }
17
18
  else
data/lib/sbsm/session.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
- #
3
+ #--
4
4
  # State Based Session Management
5
5
  # Copyright (C) 2004 Hannes Wyss
6
6
  #
@@ -24,19 +24,21 @@
24
24
  # SBSM::Session -- sbsm -- 27.09.2012 -- yasaka@ywesee.com
25
25
  # SBSM::Session -- sbsm -- 17.01.2012 -- mhatakeyama@ywesee.com
26
26
  # SBSM::Session -- sbsm -- 22.10.2002 -- hwyss@ywesee.com
27
+ #++
27
28
 
28
29
  require 'cgi'
29
-
30
30
  require 'sbsm/cgi'
31
31
  require 'sbsm/drb'
32
32
  require 'sbsm/state'
33
33
  require 'sbsm/lookandfeelfactory'
34
34
  require 'delegate'
35
+ require 'sbsm/trans_handler'
35
36
 
36
37
  module SBSM
37
38
  class Session < SimpleDelegator
38
- attr_reader :user, :active_thread, :app, :key, :cookie_input,
39
+ attr_reader :user, :active_thread, :key, :cookie_input,
39
40
  :unsafe_input, :valid_input, :request_path, :cgi
41
+ attr_writer :trans_handler, :app, :validator
40
42
  include DRbUndumped
41
43
  PERSISTENT_COOKIE_NAME = "sbsm-persistent-cookie"
42
44
  DEFAULT_FLAVOR = 'sbsm'
@@ -90,6 +92,7 @@ module SBSM
90
92
  touch()
91
93
  reset_input()
92
94
  reset_cookie()
95
+ raise "Must pass key and app and validator to session" unless key && app # && validator
93
96
  @app = app
94
97
  @key = key
95
98
  @validator = validator
@@ -100,6 +103,7 @@ module SBSM
100
103
  @variables = {}
101
104
  @mutex = Mutex.new
102
105
  @cgi = CGI.initialize_without_offline_prompt('html4')
106
+ SBSM.debug "session initialized #{self} key #{key} app #{app.class} #{validator.class} with @cgi #{@cgi}"
103
107
  super(app)
104
108
  end
105
109
  def age(now=Time.now)
@@ -107,8 +111,7 @@ module SBSM
107
111
  end
108
112
  def cap_max_states
109
113
  if(@attended_states.size > self::class::CAP_MAX_THRESHOLD)
110
- #puts "too many states in session! Keeping only #{self::class::MAX_STATES}"
111
- #$stdout.flush
114
+ SBSM.info "too many states in session! Keeping only #{self::class::MAX_STATES}"
112
115
  sorted = @attended_states.values.sort
113
116
  sorted[0...(-self::class::MAX_STATES)].each { |state|
114
117
  state.__checkout
@@ -152,22 +155,31 @@ module SBSM
152
155
  @cookie_input[key]
153
156
  end
154
157
  def cookie_name
155
- self::class::PERSISTENT_COOKIE_NAME
158
+ # self::class::PERSISTENT_COOKIE_NAME
159
+ nil
156
160
  end
157
161
  def default_language
158
162
  self::class::DEFAULT_LANGUAGE
159
163
  end
160
164
  def direct_event
165
+ # used when
161
166
  @state.direct_event
162
167
  end
163
- def drb_process(request)
168
+ def drb_process(app, rack_request)
164
169
  start = Time.now
170
+ @request_path ||= rack_request.path
171
+ SBSM.debug("rack_request #{rack_request.class} #{@request_path} #{rack_request.request_method} #{@cgi}")
172
+ rack_request.params.each { |key, val| @cgi.params.store(key, val) }
173
+ @trans_handler.translate_uri(rack_request)
165
174
  html = @mutex.synchronize do
166
- process(request)
175
+ process(rack_request)
167
176
  to_html
168
177
  end
169
178
  (@@stats[@request_path] ||= []).push(Time.now - start)
170
179
  html
180
+ rescue => err
181
+ SBSM.info "Error in drb_process #{err.backtrace[0..5].join("\n")}"
182
+ raise err
171
183
  end
172
184
  def error(key)
173
185
  @state.error(key) if @state.respond_to?(:error)
@@ -200,40 +212,40 @@ module SBSM
200
212
  def import_cookies(request)
201
213
  reset_cookie()
202
214
  return if request.cookies.is_a?(DRb::DRbUnknown)
203
- if(cuki = request.cookies[self::class::PERSISTENT_COOKIE_NAME])
204
- cuki.each { |cuki_str|
205
- CGI.parse(CGI.unescape(cuki_str)).each { |key, val|
206
- key = key.intern
207
- valid = @validator.validate(key, val.compact.last)
208
- @cookie_input.store(key, valid)
209
- }
215
+ if(cuki_str = request.cookies[self::class::PERSISTENT_COOKIE_NAME])
216
+ CGI.parse(CGI.unescape(cuki_str)).each { |key, val|
217
+ key = key.intern
218
+ valid = @validator.validate(key, val.compact.last)
219
+ @cookie_input.store(key, valid)
210
220
  }
211
221
  end
212
222
  end
213
223
  @@hash_ptrn = /([^\[]+)((\[[^\]]+\])+)/
214
224
  @@index_ptrn = /[^\[\]]+/
215
- def import_user_input(request)
225
+ def import_user_input(rack_req)
216
226
  # attempting to read the cgi-params more than once results in a
217
227
  # DRbConnectionRefused Exception. Therefore, do it only once...
218
228
  return if(@user_input_imported)
219
- request.params.each { |key, value|
220
- #puts "importing #{key} -> #{value}"
229
+ hash = rack_req.env.merge rack_req.params
230
+ hash.each do |key, value|
231
+ next if /^rack\./.match(key)
221
232
  index = nil
222
233
  @unsafe_input.push([key.to_s.dup, value.to_s.dup])
223
234
  unless(key.nil? || key.empty?)
224
235
  if match = @@hash_ptrn.match(key)
225
236
  key = match[1]
226
237
  index = match[2]
227
- #puts key, index
238
+ #puts key, index
228
239
  end
229
240
  key = key.intern
230
241
  if(key == :confirm_pass)
231
- pass = request.params["pass"]
232
- #puts "pass:#{pass} - confirm:#{value}"
242
+ pass = rack_req.params["pass"]
243
+ # puts "pass:#{pass} - confirm:#{value}"
233
244
  @valid_input[key] = @valid_input[:set_pass] \
234
245
  = @validator.set_pass(pass, value)
235
246
  else
236
247
  valid = @validator.validate(key, value)
248
+ # puts "Checking #{key} -> #{value} valid #{valid.inspect} index #{index.inspect}"
237
249
  if(index)
238
250
  target = (@valid_input[key] ||= {})
239
251
  indices = []
@@ -247,13 +259,15 @@ module SBSM
247
259
  target.store(last, valid)
248
260
  else
249
261
  @valid_input[key] = valid
262
+ # puts "@valid_input #{key} -> #{value} valid #{valid.inspect} index #{index.inspect}"
250
263
  "dummy" # Some statement is necessary here to avoid Date data loading error on Ruby 1.9.3
251
264
  end
252
265
  end
253
266
  end
254
267
  #puts "imported #{key} -> #{value} => #{@valid_input[key].inspect}"
255
- }
268
+ end
256
269
  @user_input_imported = true
270
+ @valid_input
257
271
  #puts @unsafe_input.inspect
258
272
  #puts @valid_input.inspect
259
273
  #$stdout.flush
@@ -277,10 +291,14 @@ module SBSM
277
291
  end
278
292
  def login
279
293
  if(user = @app.login(self))
294
+ SBSM.debug "user is #{user} #{request_path.inspect}"
280
295
  @user = user
296
+ else
297
+ SBSM.debug "login no user #{request_path.inspect}"
281
298
  end
282
299
  end
283
300
  def logout
301
+ SBSM.debug "logout #{request_path.inspect} setting @state #{self::class::DEFAULT_STATE.new(self, @user)}"
284
302
  __checkout
285
303
  @user = @app.unknown_user()
286
304
  @active_state = @state = self::class::DEFAULT_STATE.new(self, @user)
@@ -316,9 +334,7 @@ module SBSM
316
334
  rescue DRb::DRbConnError
317
335
  raise
318
336
  rescue NameError, StandardError => err
319
- puts "error in SBSM::Session#http_headers: #@request_path"
320
- puts err.class, err.message
321
- puts err.backtrace[0,5]
337
+ SBSM.info "NameError, StandardError: #@request_path"
322
338
  {'Content-Type' => 'text/plain'}
323
339
  end
324
340
  def http_protocol
@@ -345,15 +361,16 @@ module SBSM
345
361
  @persistent_user_input[key]
346
362
  end
347
363
  end
348
- def process(request)
349
- begin
350
- @request = request
351
- @request_method = request.request_method
352
- @request_path = @request.unparsed_uri
353
- @validator.reset_errors() if @validator
354
- import_user_input(request)
355
- import_cookies(request)
356
- @state = active_state.trigger(event())
364
+ def process(rack_request)
365
+ begin
366
+ @request_method =rack_request.request_method
367
+ @request = rack_request
368
+ @request_method ||= @request.request_method
369
+ @request_path = @request.path
370
+ @validator.reset_errors() if @validator && @validator.respond_to?(:reset_errors)
371
+ import_user_input(rack_request)
372
+ import_cookies(rack_request)
373
+ @state = active_state.trigger(event())
357
374
  #FIXME: is there a better way to distinguish returning states?
358
375
  # ... we could simply refuse to init if event == :sort, but that
359
376
  # would not solve the problem cleanly, I think.
@@ -361,38 +378,22 @@ module SBSM
361
378
  @state.request_path = @request_path
362
379
  @state.init
363
380
  end
364
- unless @state.volatile?
365
- @active_state = @state
366
- @attended_states.store(@state.object_id, @state)
367
- end
368
- @zone = @active_state.zone
369
- @active_state.touch
370
- cap_max_states
381
+ unless @state.volatile?
382
+ SBSM.debug "Changing to #{@state.class}"
383
+ @active_state = @state
384
+ @attended_states.store(@state.object_id, @state)
385
+ end
386
+ @zone = @active_state.zone
387
+ @active_state.touch
388
+ cap_max_states
371
389
  rescue DRb::DRbConnError
372
390
  raise
373
- rescue StandardError => err
374
- #@state = @state.previous
375
- puts "error in SBSM::Session#process: #@request_path"
376
- puts err.class, err.message
377
- puts err.backtrace[0,5]
378
- $stdout.flush
379
391
  ensure
380
392
  @user_input_imported = false
381
393
  end
382
394
  ''
383
395
  end
384
396
  def reset
385
- =begin
386
- if(@active_thread \
387
- && @active_thread.alive? \
388
- && @active_thread != Thread.current)
389
- begin
390
- #@active_thread.exit
391
- rescue StandardError
392
- end
393
- end
394
- @active_thread = Thread.current
395
- =end
396
397
  if @redirected
397
398
  @redirected = false
398
399
  else
@@ -443,10 +444,7 @@ module SBSM
443
444
  rescue DRb::DRbConnError
444
445
  raise
445
446
  rescue StandardError => err
446
- puts "error in SBSM::Session#to_html: #@request_path"
447
- puts err.class, err.message
448
- puts err.backtrace#[0,5]
449
- $stdout.flush
447
+ SBSM.info "StandardError: #@request_path"
450
448
  [ err.class, err.message ].join("\n")
451
449
  end
452
450
  def user_agent
@@ -487,13 +485,9 @@ module SBSM
487
485
  end
488
486
  # CGI::SessionHandler compatibility
489
487
  def restore
490
- #puts "restore was called"
491
- #@unix_socket = DRb.start_service('drbunix:', self)
492
488
  hash = {
493
- #:proxy => DRbObject.new(self, @unix_socket.uri)
494
- :proxy => self,
489
+ :proxy => self,
495
490
  }
496
- hash.extend(DRbUndumped) # added for Ruby1.8 compliance
497
491
  hash
498
492
  end
499
493
  def update
data/lib/sbsm/state.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
- #
3
+ #--
4
4
  # State Based Session Management
5
5
  # Copyright (C) 2004 Hannes Wyss
6
6
  #
@@ -23,6 +23,8 @@
23
23
  #
24
24
  # SBSM::State -- sbsm -- 15.05.2012 -- yasaka@ywesee.com
25
25
  # SBSM::State -- sbsm -- 22.10.2002 -- hwyss@ywesee.com
26
+ #++
27
+ require 'sbsm/logger'
26
28
 
27
29
  module SBSM
28
30
  class ProcessingError < RuntimeError
@@ -121,29 +123,19 @@ module SBSM
121
123
  @errors.store(key, error)
122
124
  end
123
125
  end
124
- if RUBY_VERSION >= '1.9'
125
- def extend(mod)
126
- if(mod.constants.include?(:VIRAL))
127
- @viral_modules.push(mod)
128
- end
129
- if(mod.constants.include?(:EVENT_MAP))
130
- @events.update(mod::EVENT_MAP)
131
- end
132
- super
126
+ def extend(mod)
127
+ if(mod.constants.include?(:VIRAL))
128
+ @viral_modules.push(mod)
133
129
  end
134
- else
135
- def extend(mod)
136
- if(mod.constants.include?('VIRAL'))
137
- @viral_modules.push(mod)
138
- end
139
- if(mod.constants.include?('EVENT_MAP'))
140
- @events.update(mod::EVENT_MAP)
141
- end
142
- super
130
+ if(mod.constants.include?(:EVENT_MAP))
131
+ @events.update(mod::EVENT_MAP)
143
132
  end
133
+ super
144
134
  end
145
135
  def http_headers
146
- @http_headers || view.http_headers
136
+ return @http_headers if @http_headers
137
+ name = view
138
+ name ? view.http_headers : {}
147
139
  end
148
140
  def info?
149
141
  !@infos.empty?
@@ -178,7 +170,8 @@ module SBSM
178
170
  @mtime = Time.now
179
171
  end
180
172
  def to_html(context)
181
- view.to_html(context)
173
+ name = view
174
+ name ? name.to_html(context) : ''
182
175
  end
183
176
  def trigger(event)
184
177
  if(@redirected)
@@ -197,6 +190,7 @@ module SBSM
197
190
  if(state.respond_to?(:previous=))
198
191
  state.previous = self
199
192
  end
193
+ # puts "state.rb #{__LINE__} state #{state.inspect}"
200
194
  state
201
195
  end
202
196
  def _trigger(event)
@@ -236,6 +230,7 @@ module SBSM
236
230
  end
237
231
  def view
238
232
  klass = @default_view
233
+ return nil unless @default_view
239
234
  if(klass.is_a?(Hash))
240
235
  klass = klass.fetch(@session.user.class) {
241
236
  klass[:default]