sbsm 1.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.
Files changed (50) hide show
  1. data/COPYING +515 -0
  2. data/History.txt +5 -0
  3. data/Manifest.txt +49 -0
  4. data/README.txt +41 -0
  5. data/Rakefile +28 -0
  6. data/data/_flavored_uri.grammar +24 -0
  7. data/data/_uri.grammar +22 -0
  8. data/data/_zone_uri.grammar +24 -0
  9. data/data/flavored_uri.grammar +24 -0
  10. data/data/uri.grammar +22 -0
  11. data/data/zone_uri.grammar +24 -0
  12. data/install.rb +1098 -0
  13. data/lib/cgi/drbsession.rb +37 -0
  14. data/lib/sbsm/cgi.rb +79 -0
  15. data/lib/sbsm/drb.rb +19 -0
  16. data/lib/sbsm/drbserver.rb +162 -0
  17. data/lib/sbsm/exception.rb +28 -0
  18. data/lib/sbsm/flavored_uri_parser.rb +47 -0
  19. data/lib/sbsm/index.rb +66 -0
  20. data/lib/sbsm/lookandfeel.rb +176 -0
  21. data/lib/sbsm/lookandfeelfactory.rb +50 -0
  22. data/lib/sbsm/lookandfeelwrapper.rb +109 -0
  23. data/lib/sbsm/redefine_19_cookie.rb +4 -0
  24. data/lib/sbsm/redirector.rb +37 -0
  25. data/lib/sbsm/request.rb +162 -0
  26. data/lib/sbsm/session.rb +542 -0
  27. data/lib/sbsm/state.rb +301 -0
  28. data/lib/sbsm/time.rb +29 -0
  29. data/lib/sbsm/trans_handler.rb +119 -0
  30. data/lib/sbsm/turing.rb +25 -0
  31. data/lib/sbsm/uri_parser.rb +45 -0
  32. data/lib/sbsm/user.rb +47 -0
  33. data/lib/sbsm/validator.rb +256 -0
  34. data/lib/sbsm/viralstate.rb +47 -0
  35. data/lib/sbsm/zone_uri_parser.rb +48 -0
  36. data/test/data/dos_file.txt +2 -0
  37. data/test/data/lnf_file.txt +2 -0
  38. data/test/data/mac_file.txt +1 -0
  39. data/test/stub/cgi.rb +35 -0
  40. data/test/suite.rb +29 -0
  41. data/test/test_drbserver.rb +83 -0
  42. data/test/test_index.rb +90 -0
  43. data/test/test_lookandfeel.rb +230 -0
  44. data/test/test_session.rb +372 -0
  45. data/test/test_state.rb +176 -0
  46. data/test/test_trans_handler.rb +447 -0
  47. data/test/test_user.rb +44 -0
  48. data/test/test_validator.rb +126 -0
  49. data/usage-en.txt +112 -0
  50. metadata +142 -0
@@ -0,0 +1,37 @@
1
+ #
2
+ # DRbSession - CGI::Session session database manager using DRb.
3
+ # Copyright (C) 2001 by Tietew. All Rights Reserved.
4
+ #
5
+ require 'drb/drb'
6
+
7
+ class CGI
8
+ class Session
9
+ class DRbSession
10
+ def initialize(session, option={})
11
+ unless uri = option['drbsession_uri']
12
+ raise ArgumentError, "drbsession_uri not specified"
13
+ end
14
+
15
+ unless DRb.thread
16
+ DRb.start_service
17
+ end
18
+
19
+ holder = DRbObject.new(nil, uri)
20
+ @obj = holder[session.session_id]
21
+ end
22
+
23
+ def restore
24
+ @obj.restore
25
+ end
26
+ def update
27
+ @obj.update
28
+ end
29
+ def close
30
+ @obj.close
31
+ end
32
+ def delete
33
+ @obj.delete
34
+ end
35
+ end
36
+ end
37
+ end
data/lib/sbsm/cgi.rb ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # State Based Session Management
4
+ # Copyright (C) 2004 Hannes Wyss
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ # ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Z�rich, Switzerland
21
+ # hwyss@ywesee.com
22
+ #
23
+ # CGI redefinitions
24
+
25
+ require 'cgi'
26
+ require 'drb/drb'
27
+
28
+ class CGI
29
+ module TagMaker
30
+ def nOE_element_def(element, append = nil)
31
+ s = <<-END
32
+ "<#{element.upcase}" + attributes.collect{|name, value|
33
+ next unless value
34
+ " " + name.to_s +
35
+ if true == value
36
+ ""
37
+ else
38
+ '="' + CGI::escapeHTML(value) + '"'
39
+ end
40
+ }.to_s + ">"
41
+ END
42
+ s.sub!(/\Z/, " +") << append if append
43
+ s
44
+ end
45
+ end
46
+ class Session
47
+ attr_reader :output_cookies
48
+ end
49
+ def CGI::pretty(string, shift = " ")
50
+ lines = string.gsub(/(?!\A)<(?!\/(pre|textarea))(?:.)*?>/ni, "\n\\0").gsub(/<(?!(pre|textarea))(?:.)*?>(?!\n)/i, "\\0\n")
51
+ end_pos = 0
52
+ preformatted = []
53
+ while (end_pos = lines.index(/<\/pre\s*>/i, end_pos)) \
54
+ && (start_pos = lines.rindex(/<pre(\s+[^>]+)?>/i, end_pos))
55
+ start_pos += $~[0].length
56
+ preformatted.push(lines[ start_pos ... end_pos ])
57
+ lines[ start_pos ... end_pos ] = ''
58
+ end_pos = start_pos + 6
59
+ end
60
+ end_pos = 0
61
+ while end_pos = lines.index(/^<\/(\w+)/, end_pos)
62
+ element = $1.dup
63
+ start_pos = lines.rindex(/^\s*<#{element}/i, end_pos)
64
+ lines[start_pos ... end_pos] = "__" + lines[start_pos ... end_pos].gsub(/\n(?!\z)/, "\n" + shift) + "__"
65
+ end
66
+ pretty = lines.gsub(/^((?:#{Regexp::quote(shift)})*)__(?=<\/?\w)/, '\1')
67
+ pos = 0
68
+ preformatted.each { |pre|
69
+ if(pos = pretty.index(/<\/pre\s*>/i, pos))
70
+ pretty[pos,0] = pre
71
+ pos += pre.length + 6
72
+ end
73
+ }
74
+ pretty
75
+ end
76
+ def CGI::escapeHTML(string)
77
+ string.to_s.gsub(/&(?![^;]{2,6};)/, '&amp;').gsub(/\"/, '&quot;').gsub(/>/, '&gt;').gsub(/</, '&lt;')
78
+ end
79
+ end
data/lib/sbsm/drb.rb ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ # DRb::DRbObject -- fix bug in ruby -- 23.09.2005 -- hwyss@ywesee.com
3
+
4
+ require 'drb'
5
+
6
+ module DRb
7
+ class DRbObject
8
+ def respond_to?(msg_id)
9
+ case msg_id
10
+ when :_dump
11
+ true
12
+ when :marshal_dump
13
+ false
14
+ else
15
+ method_missing(:respond_to?, msg_id)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # State Based Session Management
4
+ # Copyright (C) 2004 Hannes Wyss
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ # ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Z�rich, Switzerland
21
+ # hwyss@ywesee.com
22
+ #
23
+ # DrbServer -- sbsm -- hwyss@ywesee.com
24
+
25
+ require 'delegate'
26
+ require 'sbsm/drb'
27
+ require 'sbsm/session'
28
+ require 'sbsm/user'
29
+ require 'thread'
30
+ require 'digest/md5'
31
+
32
+ module SBSM
33
+ class DRbServer < SimpleDelegator
34
+ include DRbUndumped
35
+ CLEANING_INTERVAL = 30
36
+ CAP_MAX_THRESHOLD = 120
37
+ ENABLE_ADMIN = false
38
+ MAX_SESSIONS = 100
39
+ RUN_CLEANER = true
40
+ SESSION = Session
41
+ UNKNOWN_USER = UnknownUser
42
+ VALIDATOR = nil
43
+ attr_reader :cleaner, :updater
44
+ def initialize(persistence_layer=nil)
45
+ @sessions = {}
46
+ @mutex = Mutex.new
47
+ @cleaner = run_cleaner if(self.class.const_get(:RUN_CLEANER))
48
+ @admin_threads = ThreadGroup.new
49
+ @async = ThreadGroup.new
50
+ @system = persistence_layer
51
+ super(persistence_layer)
52
+ end
53
+ def _admin(src, result, priority=0)
54
+ raise "admin interface disabled" unless(self::class::ENABLE_ADMIN)
55
+ t = Thread.new {
56
+ Thread.current.abort_on_exception = false
57
+ result << begin
58
+ response = begin
59
+ instance_eval(src)
60
+ rescue NameError => e
61
+ e
62
+ end
63
+ str = response.to_s
64
+ if(str.length > 200)
65
+ response.class
66
+ else
67
+ str
68
+ end
69
+ rescue StandardError => e
70
+ e.message
71
+ end.to_s
72
+ }
73
+ t[:source] = src
74
+ t.priority = priority
75
+ @admin_threads.add(t)
76
+ t
77
+ end
78
+ def async(&block)
79
+ @async.add(Thread.new(&block))
80
+ end
81
+ def cap_max_sessions(now = Time.now)
82
+ if(@sessions.size > self::class::CAP_MAX_THRESHOLD)
83
+ puts "too many sessions! Keeping only #{self::class::MAX_SESSIONS}"
84
+ sess = nil
85
+ sorted = @sessions.values.sort
86
+ sorted[0...(-self::class::MAX_SESSIONS)].each { |sess|
87
+ sess.__checkout
88
+ @sessions.delete(sess.key)
89
+ }
90
+ if(sess)
91
+ age = sess.age(now)
92
+ puts sprintf("deleted all sessions that had not been accessed for more than %im %is", age / 60, age % 60)
93
+ end
94
+ end
95
+ end
96
+ def clean
97
+ now = Time.now
98
+ @sessions.delete_if { |key, s|
99
+ begin
100
+ if s.respond_to?(:expired?)
101
+ if s.expired?(now)
102
+ s.__checkout
103
+ true
104
+ else
105
+ s.cap_max_states
106
+ false
107
+ end
108
+ else
109
+ true
110
+ end
111
+ rescue
112
+ true
113
+ end
114
+ }
115
+ #cap_max_sessions(now)
116
+ end
117
+ def clear
118
+ @sessions.each_value { |sess| sess.__checkout }
119
+ @sessions.clear
120
+ end
121
+ def delete_session(key)
122
+ if(sess = @sessions.delete(key))
123
+ sess.__checkout
124
+ end
125
+ end
126
+ def reset
127
+ @mutex.synchronize {
128
+ @sessions.clear
129
+ }
130
+ end
131
+ def run_cleaner
132
+ # puts "running cleaner thread"
133
+ Thread.new {
134
+ Thread.current.abort_on_exception = true
135
+ #Thread.current.priority = 1
136
+ loop {
137
+ sleep self::class::CLEANING_INTERVAL
138
+ @mutex.synchronize {
139
+ clean()
140
+ }
141
+ }
142
+ }
143
+ end
144
+ def unknown_user
145
+ self::class::UNKNOWN_USER.new
146
+ end
147
+ def [](key)
148
+ @mutex.synchronize {
149
+ unless((s = @sessions[key]) && !s.expired?)
150
+ args = [key, self]
151
+ if(klass = self::class::VALIDATOR)
152
+ args.push(klass.new)
153
+ end
154
+ s = @sessions[key] = self::class::SESSION.new(*args.compact)
155
+ end
156
+ s.reset()
157
+ s.touch()
158
+ s
159
+ }
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # State Based Session Management
4
+ # Copyright (C) 2004 Hannes Wyss
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ # ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Z�rich, Switzerland
21
+ # hwyss@ywesee.com
22
+ #
23
+ # Exception -- sbsm -- 22.10.2002 -- hwyss@ywesee.com
24
+
25
+ module SBSM
26
+ class ProcessingError < RuntimeError
27
+ end
28
+ end
@@ -0,0 +1,47 @@
1
+ require 'rockit/rockit'
2
+ module SBSM
3
+ # Parser for Uri
4
+ # created by Rockit version 0.3.8 on Wed Jul 19 18:22:18 CEST 2006
5
+ # Rockit is copyright (c) 2001 Robert Feldt, feldt@ce.chalmers.se
6
+ # and licensed under GPL
7
+ # but this parser is under LGPL
8
+ tokens = [
9
+ t1 = EofToken.new("EOF",/^(�~~��~^^~2220240369)/),
10
+ t2 = Token.new("SLASH",/^(\/)/),
11
+ t3 = Token.new("OTHER",/^([^\/]+)/),
12
+ t4 = Token.new("LANG",/^([a-z]{2})/)
13
+ ]
14
+ productions = [
15
+ p1 = Production.new("Uri'".intern,[:Uri],SyntaxTreeBuilder.new("Uri'",["uri"],[])),
16
+ p2 = Production.new(:Uri,[t2, t4, t2, t3, t2, t3, t2, :Variables],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "flavor", "_", "event", "_", "variables"],[])),
17
+ p3 = Production.new(:Uri,[t2, t4, t2, t3, t2, t3, t2],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "flavor", "_", "event"],[])),
18
+ p4 = Production.new(:Uri,[t2, t4, t2, t3, t2, t3],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "flavor", "_", "event"],[nil])),
19
+ p5 = Production.new(:Uri,[t2, t4, t2, t3, t2],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "flavor"],[])),
20
+ p6 = Production.new(:Uri,[t2, t4, t2, t3],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "flavor"],[nil])),
21
+ p7 = Production.new(:Uri,[t2, t4, t2],SyntaxTreeBuilder.new("Uri",["_", "language"],[])),
22
+ p8 = Production.new(:Uri,[t2, t4],SyntaxTreeBuilder.new("Uri",["_", "language"],[nil])),
23
+ p9 = Production.new(:Uri,[t2],SyntaxTreeBuilder.new("Uri",["_"],[])),
24
+ p10 = Production.new(:Variables,[:Plus404231304, t2],LiftingSyntaxTreeBuilder.new(["pair"],[])),
25
+ p11 = Production.new(:Variables,[:Plus404231304],LiftingSyntaxTreeBuilder.new(["pair"],[nil])),
26
+ p12 = Production.new(:Plus404231304,[:Plus404231304, :Pair],ArrayNodeBuilder.new([1],0,nil,nil,[],true)),
27
+ p13 = Production.new(:Plus404231304,[:Pair],ArrayNodeBuilder.new([0],nil,nil,nil,[],true)),
28
+ p14 = Production.new(:Pair,[t3, t2, t3, t2],SyntaxTreeBuilder.new("Pair",["key", "_", "value"],[])),
29
+ p15 = Production.new(:Pair,[t3, t2, t3],SyntaxTreeBuilder.new("Pair",["key", "_", "value"],[nil])),
30
+ p16 = Production.new(:Pair,[t3, t2, t2],SyntaxTreeBuilder.new("Pair",["key"],[])),
31
+ p17 = Production.new(:Pair,[t3],SyntaxTreeBuilder.new("Pair",["key"],[]))
32
+ ]
33
+ relations = [
34
+
35
+ ]
36
+ priorities = ProductionPriorities.new(relations)
37
+ action_table = [[9, 2], [2, 1], [13, 8, 32, 1], [17, 2, 28, 1], [21, 4, 24, 1], [25, 2, 20, 1], [29, 4, 16, 1], [33, 2, 12, 1], [45, 4, 8, 1], [4, 1], [48, 7], [53, 2, 64, 7], [61, 2, 45, 4, 40, 1], [65, 2, 69, 4], [44, 7], [36, 1], [60, 7], [73, 2, 56, 7], [52, 7]]
38
+ goto_hash = {0 => {1 => 1}, 12 => {4 => 14}, 8 => {2 => 9, 3 => 12, 4 => 10}}
39
+ @@parse_table404014956 = ParseTable.new(productions,tokens,priorities,action_table,goto_hash,2,[
40
+ :REDUCE,
41
+ :SHIFT,
42
+ :ACCEPT
43
+ ])
44
+ def SBSM._flavored_uri_parser
45
+ GeneralizedLrParser.new(@@parse_table404014956)
46
+ end
47
+ end
data/lib/sbsm/index.rb ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # State Based Session Management
4
+ # Copyright (C) 2004 Hannes Wyss
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ # ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Z�rich, Switzerland
21
+ # hwyss@ywesee.com
22
+ #
23
+ # Index -- sbsm -- 04.03.2003 -- hwyss@ywesee.com
24
+
25
+ module SBSM
26
+ VERSION = '1.0.0'
27
+ class Index
28
+ def initialize
29
+ @values = []
30
+ @children = []
31
+ end
32
+ def delete(key, value)
33
+ if (key.size == 0)
34
+ @values.delete(value)
35
+ elsif (child = @children.at(key[0]))
36
+ child.delete(key[1..-1], value)
37
+ end
38
+ end
39
+ def fetch(key)
40
+ if(key.size == 1)
41
+ @values + @children[key[0]].to_a
42
+ elsif(key.size > 1 && @children.at(key[0]))
43
+ @children.at(key[0])[key[1..-1]]
44
+ else
45
+ []
46
+ end
47
+ end
48
+ def replace(oldkey, newkey, value)
49
+ delete(oldkey, value)
50
+ store(newkey, value)
51
+ end
52
+ def store(key, *values)
53
+ if(key.size == 0)
54
+ @values += values
55
+ else
56
+ @children[key[0]] ||= self.class.new
57
+ @children.at(key[0]).store(key[1..-1], *values)
58
+ end
59
+ end
60
+ def to_a
61
+ @values + @children.inject([]) { |inj, child| inj += child.to_a.compact }
62
+ end
63
+ alias :[] :fetch
64
+ alias :[]= :store
65
+ end
66
+ end