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.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/.travis.yml +2 -3
- data/Gemfile +1 -10
- data/History.txt +14 -0
- data/README.md +7 -2
- data/Rakefile +29 -2
- data/lib/cgi/drbsession.rb +4 -2
- data/lib/sbsm.rb +31 -0
- data/lib/sbsm/app.rb +112 -0
- data/lib/sbsm/cgi.rb +2 -52
- data/lib/sbsm/drb.rb +2 -1
- data/lib/sbsm/drbserver.rb +20 -16
- data/lib/sbsm/exception.rb +2 -2
- data/lib/sbsm/index.rb +2 -1
- data/lib/sbsm/logger.rb +46 -0
- data/lib/sbsm/lookandfeel.rb +2 -2
- data/lib/sbsm/lookandfeelfactory.rb +2 -2
- data/lib/sbsm/lookandfeelwrapper.rb +2 -1
- data/lib/sbsm/redirector.rb +4 -3
- data/lib/sbsm/session.rb +61 -67
- data/lib/sbsm/state.rb +16 -21
- data/lib/sbsm/time.rb +2 -0
- data/lib/sbsm/trans_handler.rb +82 -49
- data/lib/sbsm/turing.rb +2 -1
- data/lib/sbsm/user.rb +2 -0
- data/lib/sbsm/validator.rb +2 -0
- data/lib/sbsm/version.rb +1 -1
- data/lib/sbsm/viralstate.rb +2 -0
- data/sbsm.gemspec +4 -2
- data/test/simple_sbsm.rb +207 -0
- data/test/suite.rb +5 -2
- data/test/test_application.rb +122 -0
- data/test/test_logger.rb +121 -0
- data/test/test_session.rb +26 -17
- data/test/test_trans_handler.rb +167 -386
- metadata +67 -3
- data/lib/sbsm/request.rb +0 -234
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9709fd562058b81d1408b0bc88142076bddad4f5
|
4
|
+
data.tar.gz: 2976e9b526e9112093bd5aab2993abd5e385eec1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddcbee6256f6fe7d1c19512b7c03c4291988968c0730e8cf53717f2b59f5a2b004cc9abfe21ea124030d7f36c1522f4f399d9936b265db2e7fb50566cda7d29c
|
7
|
+
data.tar.gz: 1d5e713387d3a460bd6beccf6003836f438d7c65dbd2ea84ea4213e2c6b593ee3a1ea14b3825912e57c1ed4e97f03139f43e630562ecf7031ba3d51328d709d7
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -12,15 +12,14 @@ sudo: false
|
|
12
12
|
before_install:
|
13
13
|
- gem --version
|
14
14
|
|
15
|
-
script: bundle exec test/suite.rb
|
16
|
-
|
17
15
|
bundler_args: --without debugger
|
18
16
|
|
19
17
|
rvm:
|
20
18
|
- ruby-head
|
21
|
-
- 2.1.7
|
22
19
|
- 2.2.3
|
23
20
|
- 2.3.0
|
24
21
|
matrix:
|
25
22
|
allow_failures:
|
23
|
+
# On november 1 had failure compiling the child_processes
|
26
24
|
- rvm: ruby-head
|
25
|
+
- rvm: 2.2.3
|
data/Gemfile
CHANGED
data/History.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== 1.3.1 / 9.11.2016
|
2
|
+
* Moved from mod_ruby to using webrick/rack interface
|
3
|
+
* Incompatible changes to 1.3.0 are that all trans_handlers must be fixed, as the parameters are
|
4
|
+
* changed now in the params field (to be compatible with Rack::Request). The SBSM::Request field notes has gone!
|
5
|
+
* See changes in steinwies.ch which were minimal
|
6
|
+
** Removed an unused require 'sbsm/request' in src/view/navbar.rb
|
7
|
+
** added a config.ru
|
8
|
+
** Changed Steinwies::App to derive from SBSM::App instead of SBSM::DRbServer and its initialize method
|
9
|
+
** The Session.initialize method had to pass a validator when calling super
|
10
|
+
|
11
|
+
* Open problems
|
12
|
+
** Handling redirects is not tested (and probably will not work)
|
13
|
+
** Handling passthru is not tested (and probably will not work)
|
14
|
+
|
1
15
|
=== 1.3.0 / 08.08.2016
|
2
16
|
* Add a support to avoid offline mode by CGI.new in test purpose
|
3
17
|
|
data/README.md
CHANGED
@@ -4,11 +4,16 @@
|
|
4
4
|
|
5
5
|
## DESCRIPTION:
|
6
6
|
|
7
|
-
Application framework for state based session management
|
7
|
+
Application framework for state based session management. See lib/sbsm.rb
|
8
8
|
|
9
9
|
## FEATURES/PROBLEMS:
|
10
10
|
|
11
|
-
*
|
11
|
+
* Open problems
|
12
|
+
** There is no real integration test using rack-test to prove that a minimal app is working
|
13
|
+
** Handling a POST request for handling a form does not work yet
|
14
|
+
** Handling redirects is not tested (and probably will not work)
|
15
|
+
** Handling passthru is not tested (and probably will not work)
|
16
|
+
** I get often the error `Errno::EACCES at / Permission denied @ rb_sysopen - /tmp/sbsm_lock`. Reloading the page once or twices fixes the problem.
|
12
17
|
|
13
18
|
## REQUIREMENTS:
|
14
19
|
|
data/Rakefile
CHANGED
@@ -4,9 +4,13 @@ lib = File.expand_path('../lib', __FILE__)
|
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
require 'sbsm/version'
|
6
6
|
require "bundler/gem_tasks"
|
7
|
-
require '
|
7
|
+
require 'rake/testtask'
|
8
8
|
|
9
|
-
|
9
|
+
config = File.expand_path('../etc/config.yml', __FILE__)
|
10
|
+
if !File.exist?(config)
|
11
|
+
FileUtils.makedirs(File.dirname(config))
|
12
|
+
File.open(config, 'w+') {|file| file.puts("---") }
|
13
|
+
end
|
10
14
|
|
11
15
|
# dependencies are now declared in sbsm.gemspec
|
12
16
|
|
@@ -19,3 +23,26 @@ task :spec => :clean
|
|
19
23
|
|
20
24
|
require 'rake/clean'
|
21
25
|
CLEAN.include FileList['pkg/*.gem']
|
26
|
+
|
27
|
+
desc "create RDoc documentation"
|
28
|
+
|
29
|
+
task :rdoc do
|
30
|
+
cmd = "bundle exec rdoc --exclude='/coverage|vendor|test|data|etc|Manifest|.*.lock|.*.css|.*.js|.*.gemspec|.*.patch/' --include=lib" +
|
31
|
+
" --main=lib/sbsm.rb --title='SBSM: a framework for state based session management'"
|
32
|
+
puts cmd
|
33
|
+
res = system(cmd)
|
34
|
+
puts "Running test/suite.rb returned #{res.inspect}. Output is found in the doc sub-directory"
|
35
|
+
exit 1 unless res
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
desc "Run tests"
|
40
|
+
task :default => :test
|
41
|
+
|
42
|
+
task :test do
|
43
|
+
log_file = 'suite.log'
|
44
|
+
res = system("bash -c 'set -o pipefail && bundle exec ruby test/suite.rb 2>&1 | tee #{log_file}'")
|
45
|
+
puts "Running test/suite.rb returned #{res.inspect}. Output was redirected to #{log_file}"
|
46
|
+
exit 1 unless res
|
47
|
+
end
|
48
|
+
|
data/lib/cgi/drbsession.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
#--
|
2
3
|
# DRbSession - CGI::Session session database manager using DRb.
|
3
4
|
# Copyright (C) 2001 by Tietew. All Rights Reserved.
|
4
|
-
|
5
|
+
#++
|
5
6
|
require 'drb/drb'
|
6
|
-
|
7
|
+
require 'sbsm/logger'
|
7
8
|
class CGI
|
8
9
|
class Session
|
9
10
|
class DRbSession
|
11
|
+
attr_reader :obj
|
10
12
|
def initialize(session, option={})
|
11
13
|
unless uri = option['drbsession_uri']
|
12
14
|
raise ArgumentError, "drbsession_uri not specified"
|
data/lib/sbsm.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2016 Niklaus Giger <ngiger@ywesee.com>
|
3
|
+
#++
|
4
|
+
#
|
5
|
+
# *SBSM:* Application framework for state based session management.
|
6
|
+
#
|
7
|
+
# We document here a few aspects of SBSM. As it is written over 10 years
|
8
|
+
# after the creation of one of the few users, who never had the chance to
|
9
|
+
# discuss with the creator of this piece of software, errors/obmission
|
10
|
+
# are found quite often.
|
11
|
+
#
|
12
|
+
# The behaviour of SBSM can be extended or overriden in many ways.
|
13
|
+
# Often in derived classes you simply define a few constants, these
|
14
|
+
# extension points can be spotted by searching for occurrences of
|
15
|
+
# -self::class::- in the implementation of SBSM.
|
16
|
+
#
|
17
|
+
# * *lookandfeel*: offers a simple way to customize views, constants
|
18
|
+
# for different languages
|
19
|
+
#
|
20
|
+
# * *viralstate*: Used in bbmb and sandoz.com
|
21
|
+
#
|
22
|
+
# * *session*: Used in bbmb and sandoz.com
|
23
|
+
#
|
24
|
+
# * *request*: Used in bbmb and sandoz.com
|
25
|
+
#
|
26
|
+
# * *transhandler*: Responsible for converting an URI into a hash of
|
27
|
+
# option values, e.g. /de/gcc/fachinfo/reg/58980
|
28
|
+
#
|
29
|
+
module SBSM
|
30
|
+
|
31
|
+
end
|
data/lib/sbsm/app.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
#--
|
4
|
+
# State Based Session Management
|
5
|
+
# Copyright (C) 2004 Hannes Wyss
|
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
|
+
# App -- sbsm -- ngiger@ywesee.com
|
25
|
+
#++
|
26
|
+
require 'cgi'
|
27
|
+
require 'cgi/session'
|
28
|
+
require 'sbsm/cgi'
|
29
|
+
require 'cgi/drbsession'
|
30
|
+
require 'sbsm/drbserver'
|
31
|
+
module SBSM
|
32
|
+
###
|
33
|
+
# App a base class for Webrick server
|
34
|
+
class App < SBSM::DRbServer
|
35
|
+
include DRbUndumped
|
36
|
+
PERSISTENT_COOKIE_NAME = "cookie-persistent-sbsm-1.3.1"
|
37
|
+
SBSM.info "PERSISTENT_COOKIE_NAME #{PERSISTENT_COOKIE_NAME}"
|
38
|
+
|
39
|
+
attr_reader :sbsm, :my_self, :validator
|
40
|
+
|
41
|
+
OPTIONS = [ :app, :config_file, :trans_handler, :validator, :persistence_layer, :server_uri, :session, :unknown_user ]
|
42
|
+
COOKIE_ID = 'sbsm-persistent-cookie-id'
|
43
|
+
|
44
|
+
OPTIONS.each{ |opt| eval "attr_reader :#{opt}" }
|
45
|
+
|
46
|
+
# Base class for a SBSM based WebRick HTTP server
|
47
|
+
# * offers a start_server() method to launch a DRB server for handling the DRB-requests
|
48
|
+
# * offer a call(env) method form handling the WebRick requests
|
49
|
+
# This is all what is needed to be compatible with WebRick
|
50
|
+
#
|
51
|
+
# === arguments
|
52
|
+
#
|
53
|
+
# * +validator+ - A Ruby class overriding the SBSM::Validator class
|
54
|
+
# * +trans_handler+ - A Ruby class overriding the SBSM::TransHandler class
|
55
|
+
# * +persistence_layer+ - Persistence Layer to use
|
56
|
+
#
|
57
|
+
# === Examples
|
58
|
+
# Look at steinwies.ch
|
59
|
+
# * https://github.com/zdavatz/steinwies.ch (simple, mostly static files, one form, no persistence layer)
|
60
|
+
#
|
61
|
+
def initialize(app:, validator:, trans_handler:, persistence_layer: nil)
|
62
|
+
@app = app
|
63
|
+
@trans_handler = trans_handler
|
64
|
+
@validator = validator
|
65
|
+
SBSM.info "initialize @app is now #{@app.class} validator #{validator} th #{trans_handler} "
|
66
|
+
super(persistence_layer)
|
67
|
+
end
|
68
|
+
|
69
|
+
def call(env) ## mimick sbsm/lib/app.rb
|
70
|
+
request = Rack::Request.new(env)
|
71
|
+
response = Rack::Response.new
|
72
|
+
if request.cookies[PERSISTENT_COOKIE_NAME] && request.cookies[PERSISTENT_COOKIE_NAME].length > 1
|
73
|
+
session_id = request.cookies[PERSISTENT_COOKIE_NAME]
|
74
|
+
else
|
75
|
+
session_id = rand((2**(0.size * 8 -2) -1)*10240000000000).to_s(16)
|
76
|
+
end
|
77
|
+
file_name = File.expand_path(File.join('doc', request.path))
|
78
|
+
if File.file?(file_name)
|
79
|
+
if /css/i.match(File.basename(file_name))
|
80
|
+
response.set_header('Content-Type', 'text/css')
|
81
|
+
else
|
82
|
+
response.set_header('Content-Type', 'text/plain')
|
83
|
+
end
|
84
|
+
response.write(File.open(file_name, File::RDONLY){|file| file.read})
|
85
|
+
return response
|
86
|
+
end
|
87
|
+
|
88
|
+
return [400, {}, []] if /favicon.ico/i.match(request.path)
|
89
|
+
SBSM.debug "#{request.path}: cookies are #{request.cookies} for session_id #{session_id}"
|
90
|
+
@drb_uri ||= @app.drb_uri
|
91
|
+
args = {
|
92
|
+
'database_manager' => CGI::Session::DRbSession,
|
93
|
+
'drbsession_uri' => @drb_uri,
|
94
|
+
'session_path' => '/',
|
95
|
+
PERSISTENT_COOKIE_NAME => session_id,
|
96
|
+
}
|
97
|
+
@cgi = CGI.initialize_without_offline_prompt('html4')
|
98
|
+
@session = CGI::Session.new(@cgi, args)
|
99
|
+
saved = self[session_id]
|
100
|
+
@proxy = DRbObject.new(saved, server_uri)
|
101
|
+
@proxy.trans_handler = @trans_handler
|
102
|
+
@proxy.app = @app
|
103
|
+
res = @proxy.drb_process(self, request)
|
104
|
+
response.write res
|
105
|
+
response.headers['Content-Type'] ||= 'text/html; charset=utf-8'
|
106
|
+
response.set_cookie(PERSISTENT_COOKIE_NAME, session_id)
|
107
|
+
@proxy.cookie_input.each{|key, value| response.set_cookie(key, value) }
|
108
|
+
SBSM.debug "finish session_id #{session_id}: header #{response.headers}"
|
109
|
+
response.finish
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/lib/sbsm/cgi.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
|
#
|
@@ -21,6 +21,7 @@
|
|
21
21
|
# ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Zürich, Switzerland
|
22
22
|
# hwyss@ywesee.com
|
23
23
|
#
|
24
|
+
#++
|
24
25
|
# CGI redefinitions
|
25
26
|
|
26
27
|
require 'cgi'
|
@@ -42,55 +43,4 @@ class CGI
|
|
42
43
|
end
|
43
44
|
cgi
|
44
45
|
end
|
45
|
-
module TagMaker
|
46
|
-
def nOE_element_def(element, append = nil)
|
47
|
-
s = <<-END
|
48
|
-
"<#{element.upcase}" + attributes.collect{|name, value|
|
49
|
-
next unless value
|
50
|
-
" " + name.to_s +
|
51
|
-
if true == value
|
52
|
-
""
|
53
|
-
else
|
54
|
-
'="' + CGI::escapeHTML(value) + '"'
|
55
|
-
end
|
56
|
-
}.to_s + ">"
|
57
|
-
END
|
58
|
-
s.sub!(/\Z/, " +") << append if append
|
59
|
-
s
|
60
|
-
end
|
61
|
-
end
|
62
|
-
class Session
|
63
|
-
attr_reader :output_cookies
|
64
|
-
end
|
65
|
-
def CGI::pretty(string, shift = " ")
|
66
|
-
lines = string.gsub(/(?!\A)<(?!\/(pre|textarea))(?:.)*?>/ni, "\n\\0").gsub(/<(?!(pre|textarea))(?:.)*?>(?!\n)/i, "\\0\n")
|
67
|
-
end_pos = 0
|
68
|
-
preformatted = []
|
69
|
-
while (end_pos = lines.index(/<\/pre\s*>/i, end_pos)) \
|
70
|
-
&& (start_pos = lines.rindex(/<pre(\s+[^>]+)?>/i, end_pos))
|
71
|
-
start_pos += $~[0].length
|
72
|
-
preformatted.push(lines[ start_pos ... end_pos ])
|
73
|
-
lines[ start_pos ... end_pos ] = ''
|
74
|
-
end_pos = start_pos + 6
|
75
|
-
end
|
76
|
-
end_pos = 0
|
77
|
-
while end_pos = lines.index(/^<\/(\w+)/, end_pos)
|
78
|
-
element = $1.dup
|
79
|
-
start_pos = lines.rindex(/^\s*<#{element}/i, end_pos)
|
80
|
-
lines[start_pos ... end_pos] = "__" + lines[start_pos ... end_pos].gsub(/\n(?!\z)/, "\n" + shift) + "__"
|
81
|
-
end
|
82
|
-
pretty = lines.gsub(/^((?:#{Regexp::quote(shift)})*)__(?=<\/?\w)/, '\1')
|
83
|
-
pos = 0
|
84
|
-
preformatted.each { |pre|
|
85
|
-
if(pos = pretty.index(/<\/pre\s*>/i, pos))
|
86
|
-
pretty[pos,0] = pre
|
87
|
-
pos += pre.length + 6
|
88
|
-
end
|
89
|
-
}
|
90
|
-
pretty
|
91
|
-
end
|
92
|
-
def CGI::escapeHTML(string)
|
93
|
-
s = string.to_s.frozen? ? string.to_s : string.to_s.force_encoding('UTF-8')
|
94
|
-
s.gsub(/&(?![^;]{2,6};)/, '&').gsub(/\"/, '"').gsub(/>/, '>').gsub(/</, '<')
|
95
|
-
end
|
96
46
|
end
|
data/lib/sbsm/drb.rb
CHANGED
data/lib/sbsm/drbserver.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: utf-8
|
3
|
+
#--
|
3
4
|
#
|
4
5
|
# State Based Session Management
|
5
6
|
# Copyright (C) 2004 Hannes Wyss
|
@@ -22,6 +23,7 @@
|
|
22
23
|
# hwyss@ywesee.com
|
23
24
|
#
|
24
25
|
# DrbServer -- sbsm -- hwyss@ywesee.com
|
26
|
+
#++
|
25
27
|
|
26
28
|
require 'delegate'
|
27
29
|
require 'sbsm/drb'
|
@@ -29,6 +31,8 @@ require 'sbsm/session'
|
|
29
31
|
require 'sbsm/user'
|
30
32
|
require 'thread'
|
31
33
|
require 'digest/md5'
|
34
|
+
require 'sbsm/logger'
|
35
|
+
require 'sbsm/validator'
|
32
36
|
|
33
37
|
module SBSM
|
34
38
|
class DRbServer < SimpleDelegator
|
@@ -81,7 +85,7 @@ module SBSM
|
|
81
85
|
end
|
82
86
|
def cap_max_sessions(now = Time.now)
|
83
87
|
if(@sessions.size > self::class::CAP_MAX_THRESHOLD)
|
84
|
-
|
88
|
+
SBSM.info "too many sessions! Keeping only #{self::class::MAX_SESSIONS}"
|
85
89
|
sess = nil
|
86
90
|
sorted = @sessions.values.sort
|
87
91
|
sorted[0...(-self::class::MAX_SESSIONS)].each { |sess|
|
@@ -90,7 +94,7 @@ module SBSM
|
|
90
94
|
}
|
91
95
|
if(sess)
|
92
96
|
age = sess.age(now)
|
93
|
-
|
97
|
+
SBSM.info sprintf("deleted all sessions that had not been accessed for more than %im %is", age / 60, age % 60)
|
94
98
|
end
|
95
99
|
end
|
96
100
|
end
|
@@ -145,19 +149,19 @@ module SBSM
|
|
145
149
|
def unknown_user
|
146
150
|
self::class::UNKNOWN_USER.new
|
147
151
|
end
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
152
|
+
def [](key)
|
153
|
+
@mutex.synchronize {
|
154
|
+
unless((s = @sessions[key]) && !s.expired?)
|
155
|
+
args = [key, self]
|
156
|
+
if(klass = self::class::VALIDATOR)
|
157
|
+
args.push(klass.new)
|
158
|
+
end
|
159
|
+
s = @sessions[key] = self::class::SESSION.new(*args.compact)
|
160
|
+
end
|
161
|
+
s.reset()
|
162
|
+
s.touch()
|
163
|
+
s
|
164
|
+
}
|
165
|
+
end
|
162
166
|
end
|
163
167
|
end
|