rsence 2.0.0.6.pre → 2.0.0.7.pre
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.
- data/INSTALL.rdoc +39 -25
- data/VERSION +1 -1
- data/conf/default_conf.yaml +0 -3
- data/lib/conf/default.rb +59 -60
- data/lib/daemon/daemon.rb +269 -280
- data/lib/http/broker.rb +47 -14
- data/lib/http/rackup.rb +4 -0
- data/lib/http/request.rb +47 -49
- data/lib/http/response.rb +47 -45
- data/lib/plugins/gui_plugin.rb +22 -21
- data/lib/plugins/guiparser.rb +95 -94
- data/lib/plugins/plugin.rb +300 -295
- data/lib/plugins/plugin_plugins.rb +64 -40
- data/lib/plugins/plugin_sqlite_db.rb +63 -63
- data/lib/plugins/plugin_util.rb +95 -104
- data/lib/plugins/pluginmanager.rb +373 -414
- data/lib/plugins/plugins.rb +11 -4
- data/lib/plugins/servlet.rb +10 -9
- data/lib/session/msg.rb +249 -248
- data/lib/session/sessionmanager.rb +364 -373
- data/lib/session/sessionstorage.rb +265 -272
- data/lib/transporter/transporter.rb +164 -169
- data/lib/util/gzstring.rb +2 -0
- data/lib/values/hvalue.rb +224 -224
- data/lib/values/valuemanager.rb +98 -98
- data/plugins/index_html/index_html.rb +1 -32
- metadata +4 -4
@@ -6,341 +6,334 @@
|
|
6
6
|
# with this software package. If not, contact licensing@riassence.com
|
7
7
|
##
|
8
8
|
|
9
|
-
require 'rubygems'
|
10
|
-
require 'sequel'
|
11
|
-
|
12
|
-
## HValue class for session restoration
|
13
|
-
require 'values/hvalue'
|
14
|
-
|
15
9
|
|
16
10
|
module RSence
|
17
11
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
12
|
+
require 'rubygems'
|
13
|
+
require 'sequel'
|
14
|
+
|
15
|
+
## HValue class for session restoration
|
16
|
+
require 'values/hvalue'
|
17
|
+
|
18
|
+
# SessionStorage doesn't do anything by itself, it's simply
|
19
|
+
# the superclass for SessionManager that does all the boring
|
20
|
+
# housekeeping duties.
|
21
|
+
#
|
22
|
+
# Splitted of as a separate file to reduce the complexity
|
23
|
+
# of SessionManager.
|
24
|
+
class SessionStorage
|
25
|
+
attr_accessor :db
|
26
|
+
def initialize
|
27
|
+
## Session data storage (by ses_id)
|
28
|
+
@sessions = {}
|
32
29
|
|
33
|
-
|
34
|
-
|
30
|
+
## Session id by key
|
31
|
+
@session_keys = {}
|
35
32
|
|
36
|
-
|
37
|
-
|
33
|
+
## Session id by cookie key
|
34
|
+
@session_cookie_keys = {}
|
38
35
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
36
|
+
@clone_origins = {
|
37
|
+
# id => [ id, id, id ... ]
|
38
|
+
}
|
39
|
+
@clone_sources = {
|
40
|
+
# id => id
|
41
|
+
}
|
42
|
+
@clone_targets = {
|
43
|
+
# id => [ id, id, id ... ]
|
44
|
+
}
|
48
45
|
|
49
|
-
|
50
|
-
|
46
|
+
## Disposable keys (new ses_key each request)
|
47
|
+
@config = ::RSence.config[:session_conf]
|
51
48
|
|
52
|
-
|
49
|
+
@db_uri = ::RSence.config[:database][:ses_db]
|
53
50
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
51
|
+
if db_test
|
52
|
+
@db_avail = true
|
53
|
+
db_init
|
54
|
+
else
|
55
|
+
@db_avail = false
|
56
|
+
puts "Warning: Session database is not available. Can't use persistent sessions."
|
57
|
+
@id_counter = 0
|
58
|
+
end
|
62
59
|
|
63
|
-
|
60
|
+
@accept_requests = true
|
64
61
|
|
65
|
-
|
62
|
+
end
|
66
63
|
|
67
|
-
|
64
|
+
attr_reader :accept_requests
|
68
65
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
def db_test
|
67
|
+
begin
|
68
|
+
db_open
|
69
|
+
if @db.table_exists?(:rsence_test)
|
70
|
+
@db.drop_table(:rsence_test)
|
71
|
+
end
|
72
|
+
@db.create_table(:rsence_test) { primary_key :id; String :test }
|
73
|
+
test_id = @db[:rsence_test].insert( :test => 'TestFoo' )
|
74
|
+
@db[:rsence_test].filter( :id => test_id ).update( :test => 'TestFoo2' )
|
75
|
+
@db[:rsence_test].filter( :id => test_id ).delete
|
76
|
+
@db[:rsence_test].delete
|
73
77
|
@db.drop_table(:rsence_test)
|
78
|
+
db_close
|
79
|
+
return true
|
80
|
+
rescue => e
|
81
|
+
if RSence.args[:debug]
|
82
|
+
err_msg = [
|
83
|
+
"ERROR: SessionStorage couldn't open database",
|
84
|
+
"#{e.class.to_s}, #{e.message}",
|
85
|
+
"Backtrace:",
|
86
|
+
"\t"+e.backtrace.join("\n\t")
|
87
|
+
].join("\n")+"\n"
|
88
|
+
$stderr.write( err_msg )
|
89
|
+
elsif RSence.args[:verbose]
|
90
|
+
puts "Failed to open database '#{@db_uri}'."
|
91
|
+
puts "Run RSence in debug mode for full error output."
|
92
|
+
end
|
93
|
+
return false
|
74
94
|
end
|
75
|
-
@db.create_table(:rsence_test) { primary_key :id; String :test }
|
76
|
-
test_id = @db[:rsence_test].insert( :test => 'TestFoo' )
|
77
|
-
@db[:rsence_test].filter( :id => test_id ).update( :test => 'TestFoo2' )
|
78
|
-
@db[:rsence_test].filter( :id => test_id ).delete
|
79
|
-
@db[:rsence_test].delete
|
80
|
-
@db.drop_table(:rsence_test)
|
81
|
-
db_close
|
82
|
-
return true
|
83
|
-
rescue => e
|
84
|
-
if RSence.args[:debug]
|
85
|
-
err_msg = [
|
86
|
-
"ERROR: SessionStorage couldn't open database",
|
87
|
-
"#{e.class.to_s}, #{e.message}",
|
88
|
-
"Backtrace:",
|
89
|
-
"\t"+e.backtrace.join("\n\t")
|
90
|
-
].join("\n")+"\n"
|
91
|
-
$stderr.write( err_msg )
|
92
|
-
elsif RSence.args[:verbose]
|
93
|
-
puts "Failed to open database '#{@db_uri}'."
|
94
|
-
puts "Run RSence in debug mode for full error output."
|
95
|
-
end
|
96
|
-
return false
|
97
95
|
end
|
98
|
-
end
|
99
96
|
|
100
|
-
|
101
|
-
|
102
|
-
|
97
|
+
def db_close
|
98
|
+
@db.disconnect
|
99
|
+
end
|
103
100
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
101
|
+
def db_open
|
102
|
+
# work-around for windows (drive letters causing confusion)
|
103
|
+
if @db_uri.start_with?('sqlite://')
|
104
|
+
@db = Sequel.sqlite( @db_uri.split('sqlite://')[1] )
|
105
|
+
else
|
106
|
+
@db = Sequel.connect(@db_uri)
|
107
|
+
end
|
110
108
|
end
|
111
|
-
end
|
112
109
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
110
|
+
## Creates the 'rsence_session' table, if necessary
|
111
|
+
## This table is used to store sessions
|
112
|
+
def create_session_table
|
113
|
+
db_open
|
114
|
+
unless @db.table_exists?(:rsence_session)
|
115
|
+
puts "Creating session table..." if RSence.args[:verbose]
|
116
|
+
@db.create_table :rsence_session do
|
117
|
+
primary_key( :id )
|
118
|
+
column( :cookie_key, String )
|
119
|
+
column( :ses_key, String )
|
120
|
+
column( :ses_timeout, Integer )
|
121
|
+
column( :user_id, Integer )
|
122
|
+
column( :ses_active, TrueClass )
|
123
|
+
column( :ses_stored, Integer )
|
124
|
+
column( :ses_data, File )
|
125
|
+
end
|
128
126
|
end
|
127
|
+
db_close
|
129
128
|
end
|
130
|
-
db_close
|
131
|
-
end
|
132
129
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
130
|
+
## Creates the 'rsence_version' table, if necessary
|
131
|
+
## This table is used to check for the need of future database upgrades
|
132
|
+
def create_version_table
|
133
|
+
db_open
|
134
|
+
unless @db.table_exists?(:rsence_version)
|
135
|
+
puts "Creating version info table..." if RSence.args[:verbose]
|
136
|
+
@db.create_table :rsence_version do
|
137
|
+
Integer :version
|
138
|
+
end
|
139
|
+
@db[:rsence_version].insert(:version => 586)
|
141
140
|
end
|
142
|
-
|
141
|
+
db_close
|
143
142
|
end
|
144
|
-
db_close
|
145
|
-
end
|
146
143
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
144
|
+
## Creates the 'rsence_uploads' table, if necessary
|
145
|
+
## This table is used for storing temporary uploads before processing
|
146
|
+
def create_uploads_table
|
147
|
+
db_open
|
148
|
+
unless @db.table_exists?(:rsence_uploads)
|
149
|
+
puts "Creating uploads table..." if RSence.args[:verbose]
|
150
|
+
@db.create_table :rsence_uploads do
|
151
|
+
primary_key( :id )
|
152
|
+
foreign_key( :ses_id, :rsence_session )
|
153
|
+
column( :upload_date, Integer )
|
154
|
+
column( :upload_done, Integer )
|
155
|
+
column( :ticket_id, String )
|
156
|
+
column( :file_size, Integer )
|
157
|
+
column( :file_name, String )
|
158
|
+
column( :file_mime, String )
|
159
|
+
column( :file_data, File )
|
160
|
+
end
|
163
161
|
end
|
162
|
+
db_close
|
164
163
|
end
|
165
|
-
db_close
|
166
|
-
end
|
167
164
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
165
|
+
# returns the version in the rsence_version table
|
166
|
+
def table_version
|
167
|
+
db_open
|
168
|
+
rsence_version = @db[:rsence_version].select(:version).all[0][:version]
|
169
|
+
db_close
|
170
|
+
return rsence_version
|
171
|
+
end
|
175
172
|
|
176
|
-
|
177
|
-
|
173
|
+
## Checks database connectivity and loads stored sessions from the database
|
174
|
+
def db_init
|
178
175
|
|
179
|
-
|
180
|
-
|
181
|
-
|
176
|
+
create_session_table
|
177
|
+
create_version_table
|
178
|
+
create_uploads_table
|
182
179
|
|
183
|
-
|
184
|
-
|
180
|
+
## Used for future upgrades:
|
181
|
+
# version = table_version
|
185
182
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
183
|
+
if @config[:reset_sessions]
|
184
|
+
puts "Resetting all sessions..."
|
185
|
+
reset_sessions()
|
186
|
+
else
|
187
|
+
restore_sessions()
|
188
|
+
end
|
192
189
|
|
193
|
-
|
194
|
-
end
|
195
|
-
|
196
|
-
## Deletes all rows from rsence_session as well as rsence_uploads
|
197
|
-
def reset_sessions
|
198
|
-
unless @db_avail
|
199
|
-
puts "Warning: Can't reset sessions: No database!" if RSence.args[:verbose]
|
200
|
-
return
|
190
|
+
return true
|
201
191
|
end
|
202
|
-
db_open
|
203
|
-
@db[:rsence_session].delete if @db.table_exists?(:rsence_session)
|
204
|
-
@db[:rsence_uploads].delete if @db.table_exists?(:rsence_uploads)
|
205
|
-
db_close
|
206
|
-
end
|
207
192
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
193
|
+
## Deletes all rows from rsence_session as well as rsence_uploads
|
194
|
+
def reset_sessions
|
195
|
+
unless @db_avail
|
196
|
+
puts "Warning: Can't reset sessions: No database!" if RSence.args[:verbose]
|
197
|
+
return
|
198
|
+
end
|
199
|
+
db_open
|
200
|
+
@db[:rsence_session].delete if @db.table_exists?(:rsence_session)
|
201
|
+
@db[:rsence_uploads].delete if @db.table_exists?(:rsence_uploads)
|
202
|
+
db_close
|
213
203
|
end
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
204
|
+
|
205
|
+
## Restores all saved sessions from db to ram
|
206
|
+
def restore_sessions
|
207
|
+
unless @db_avail
|
208
|
+
puts "Warning: Can't restore sessions: No database!" if RSence.args[:verbose]
|
209
|
+
return
|
210
|
+
end
|
211
|
+
puts "Restoring sessions..." if RSence.args[:verbose]
|
212
|
+
db_open
|
213
|
+
@db[:rsence_session].all do |ses_row|
|
214
|
+
ses_id = ses_row[:id]
|
215
|
+
ses_data_dump = ses_row[:ses_data]
|
219
216
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
217
|
+
if ses_data_dump == nil
|
218
|
+
@db[:rsence_session].filter(:id => ses_id).delete
|
219
|
+
@db[:rsence_uploads].filter(:ses_id => ses_id).delete
|
220
|
+
else
|
221
|
+
ses_data = Marshal.restore( ses_data_dump )
|
222
|
+
ses_key = ses_data[:ses_key]
|
223
|
+
@sessions[ses_id] = ses_data
|
224
|
+
@session_keys[ ses_key ] = ses_id
|
225
|
+
@session_cookie_keys[ ses_data[:cookie_key] ] = ses_id
|
226
|
+
end
|
229
227
|
end
|
228
|
+
db_close
|
230
229
|
end
|
231
|
-
db_close
|
232
|
-
end
|
233
230
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
231
|
+
## Stores all sessions to db from ram
|
232
|
+
def store_sessions
|
233
|
+
unless @db_avail
|
234
|
+
puts "Warning: Can't store sessions: No database!" if RSence.args[:verbose]
|
235
|
+
return
|
236
|
+
end
|
237
|
+
puts "Storing sessions..." if RSence.args[:verbose]
|
238
|
+
db_open
|
239
|
+
@sessions.each_key do |ses_id|
|
240
|
+
ses_data = @sessions[ ses_id ]
|
241
|
+
ses_data_dump = Marshal.dump( ses_data )
|
242
|
+
@db[:rsence_session].filter(
|
243
|
+
:id => ses_id
|
244
|
+
).update(
|
245
|
+
:cookie_key => ses_data[:cookie_key],
|
246
|
+
:ses_key => ses_data[:ses_key],
|
247
|
+
:user_id => ses_data[:user_id],
|
248
|
+
:ses_data => ses_data_dump.to_sequel_blob,
|
249
|
+
:ses_timeout => ses_data[:timeout],
|
250
|
+
:ses_stored => Time.now.to_i
|
251
|
+
)
|
252
|
+
end
|
253
|
+
db_close
|
255
254
|
end
|
256
|
-
db_close
|
257
|
-
end
|
258
255
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
256
|
+
## Shut-down signal, triggers store_sessions for now
|
257
|
+
def shutdown
|
258
|
+
@accept_requests = false
|
259
|
+
puts "Session shutdown in progress..." if RSence.args[:verbose]
|
260
|
+
store_sessions
|
261
|
+
puts "Session shutdown complete." if RSence.args[:verbose]
|
262
|
+
end
|
266
263
|
|
267
264
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
265
|
+
## Returns a new, unique session identifier by storing the params to the database
|
266
|
+
def new_ses_id( cookie_key, ses_key, timeout_secs, user_id=0 )
|
267
|
+
unless @db_avail
|
268
|
+
@id_counter += 1
|
269
|
+
return @id_counter
|
270
|
+
end
|
271
|
+
db_open
|
272
|
+
new_id = @db[:rsence_session].insert(
|
273
|
+
:cookie_key => cookie_key,
|
274
|
+
:ses_key => ses_key,
|
275
|
+
:ses_timeout => timeout_secs,
|
276
|
+
:user_id => user_id
|
277
|
+
)
|
278
|
+
db_close
|
279
|
+
return new_id
|
273
280
|
end
|
274
|
-
db_open
|
275
|
-
new_id = @db[:rsence_session].insert(
|
276
|
-
:cookie_key => cookie_key,
|
277
|
-
:ses_key => ses_key,
|
278
|
-
:ses_timeout => timeout_secs,
|
279
|
-
:user_id => user_id
|
280
|
-
)
|
281
|
-
db_close
|
282
|
-
return new_id
|
283
|
-
end
|
284
281
|
|
285
|
-
|
286
|
-
|
282
|
+
## Expires a session by its identifier
|
283
|
+
def expire_session( ses_id )
|
287
284
|
|
288
|
-
|
285
|
+
return unless @sessions.has_key? ses_id
|
289
286
|
|
290
|
-
|
287
|
+
ses_data = @sessions[ ses_id ]
|
291
288
|
|
292
|
-
|
293
|
-
|
289
|
+
# Makes the session invalid for xhr's by deleting its key
|
290
|
+
@session_keys.delete( ses_data[:ses_key] )
|
294
291
|
|
295
|
-
|
296
|
-
|
292
|
+
# Makes the session invalid for all requests by deleting its cookie key
|
293
|
+
@session_cookie_keys.delete( ses_data[:cookie_key] )
|
297
294
|
|
298
|
-
|
299
|
-
|
295
|
+
# Deletes the session data itself
|
296
|
+
@sessions.delete( ses_id )
|
300
297
|
|
301
|
-
|
302
|
-
|
298
|
+
# Removes all ticket-based storage bound to the session
|
299
|
+
@plugins[:ticketservices].expire_ses( ses_id ) if @plugins
|
303
300
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
301
|
+
# target -> source cleanup
|
302
|
+
if @clone_sources.has_key?( ses_id )
|
303
|
+
source_id = @clone_sources[ ses_id ]
|
304
|
+
@clone_sources.delete( ses_id ) if @clone_sources.has_key?( ses_id )
|
305
|
+
@clone_targets[ source_id ].delete( ses_id ) if @clone_targets.has_key?( source_id )
|
306
|
+
end
|
310
307
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
308
|
+
# source -> targets cleanup
|
309
|
+
if @clone_targets.has_key?( ses_id )
|
310
|
+
@clone_targets[ ses_id ].each do |target_id|
|
311
|
+
@clone_sources.delete( target_id ) if @clone_sources.has_key?( target_id )
|
312
|
+
end
|
313
|
+
@clone_targets.delete( ses_id ) if @clone_targets.has_key?( ses_id )
|
315
314
|
end
|
316
|
-
@clone_targets.delete( ses_id ) if @clone_targets.has_key?( ses_id )
|
317
|
-
end
|
318
315
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
316
|
+
if @db_avail
|
317
|
+
db_open
|
318
|
+
# Deletes the session's row from the database
|
319
|
+
@db[:rsence_session].filter(:id => ses_id).delete
|
320
|
+
db_close
|
321
|
+
end
|
325
322
|
|
326
|
-
|
323
|
+
end
|
327
324
|
|
328
|
-
|
329
|
-
|
325
|
+
## Expires all sessions that meet the timeout criteria
|
326
|
+
def expire_sessions
|
330
327
|
|
331
|
-
|
332
|
-
|
328
|
+
# Loop through all sessions in memory:
|
329
|
+
@sessions.each_key do |ses_id|
|
333
330
|
|
334
|
-
|
331
|
+
timed_out = @sessions[ ses_id ][:timeout] < Time.now.to_i
|
335
332
|
|
336
|
-
|
337
|
-
|
333
|
+
## Deletes the session, if the session is too old
|
334
|
+
expire_session( ses_id ) if timed_out
|
338
335
|
|
336
|
+
end
|
339
337
|
end
|
340
338
|
end
|
341
|
-
|
342
|
-
end
|
343
|
-
|
344
339
|
end
|
345
|
-
|
346
|
-
|