rsence 2.0.0.6.pre → 2.0.0.7.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|