sbsm 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|