iodine 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of iodine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +41 -1
- data/lib/iodine/core.rb +25 -3
- data/lib/iodine/http.rb +20 -8
- data/lib/iodine/http/http1.rb +1 -6
- data/lib/iodine/http/http2.rb +5 -3
- data/lib/iodine/http/rack_support.rb +2 -2
- data/lib/iodine/http/request.rb +1 -1
- data/lib/iodine/http/response.rb +11 -9
- data/lib/iodine/http/session.rb +69 -69
- data/lib/iodine/http/websocket_client.rb +190 -191
- data/lib/iodine/http/websocket_handler.rb +48 -14
- data/lib/iodine/http/websockets.rb +23 -4
- data/lib/iodine/io.rb +12 -27
- data/lib/iodine/logging.rb +7 -1
- data/lib/iodine/protocol.rb +4 -1
- data/lib/iodine/timers.rb +4 -3
- data/lib/iodine/version.rb +1 -1
- data/lib/rack/handler/iodine.rb +1 -1
- data/manual tests/hello_world +17 -20
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75cc90d10afaecdc798bdf39ec5d4a1063431faf
|
4
|
+
data.tar.gz: da27288f1c90ac8604c07c8f3d2ffb796c09e453
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce19f80d81def9ad8784648625007cca05a9513d6498dbff030b10a28a43e96ab7c3a54553c275393c2803b9bc5e47b47307ac03b2c1a7fc127646d396eeb017
|
7
|
+
data.tar.gz: 145b4f0cb2aeec486af8a09d3cf0d91819a7e97449a3bbb8a5a56e7324a2e9c4977a1a8119c52ac780a7b34b338ee8d3e934dd5a48bc0d0da757588b80e1a99a
|
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# Iodine
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/iodine.svg)](https://badge.fury.io/rb/iodine)
|
3
|
+
[![Inline docs](http://inch-ci.org/github/boazsegev/iodine.svg?branch=master)](http://www.rubydoc.info/github/boazsegev/iodine/master/frames)
|
2
4
|
|
3
5
|
Iodine makes writing Object Oriented evented server applications easy to write.
|
4
6
|
|
@@ -30,6 +32,7 @@ Iodine starts to work once you app is finished setting all the tasks up (upon ex
|
|
30
32
|
|
31
33
|
To see how that works, open your `irb` terminal an try this:
|
32
34
|
|
35
|
+
|
33
36
|
```ruby
|
34
37
|
require 'iodine'
|
35
38
|
|
@@ -62,6 +65,7 @@ To initiate this mode, simply set: `Iodine.protocol = :timers`
|
|
62
65
|
|
63
66
|
In example:
|
64
67
|
|
68
|
+
|
65
69
|
```ruby
|
66
70
|
require 'iodine'
|
67
71
|
|
@@ -83,9 +87,45 @@ exit
|
|
83
87
|
|
84
88
|
In this mode, Iodine will continue running until it receives a kill signal (i.e. `^C`). Once the kill signal had been received, Iodine will start shutting down, allowing up to ~20-25 seconds to complete any pending tasks (timeout).
|
85
89
|
|
86
|
-
## Server Usage: an Http and Websocket
|
90
|
+
## Server Usage: an Http and Websocket server
|
91
|
+
|
92
|
+
Using Iodine and leveraging Ruby's Object Oriented approach, is super fun to write our own network protocols and servers... This is Ioding itself includes an _optional_ Http and websocket server. Say "Hello World":
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
# require the 'iodine/http' module if you want to use Iodine's Http server.
|
96
|
+
require 'iodine/http'
|
97
|
+
# returning a string will automatically append it to the response.
|
98
|
+
Iodine::Http.on_http = { |request, response| "Hello World!" }
|
99
|
+
```
|
87
100
|
|
101
|
+
Iodine's Http server includes experimental support for Http/2 right out of the box as well as a Websocket server.
|
88
102
|
|
103
|
+
Here's a quick chatroom server (use [www.websocket.org](http://www.websocket.org/echo.html) to check it out):
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
# require the 'iodine/http' module if you want to use Iodine's Websocket server.
|
107
|
+
require 'iodine/http'
|
108
|
+
# create an object that will follow the Iodine Websocket API.
|
109
|
+
class WSChatServer < Iodine::Http::WebsocketHandler
|
110
|
+
def on_open
|
111
|
+
@nickname = request.params[:nickname] || "unknown"
|
112
|
+
broadcast "#{@nickname} has joined the chat!"
|
113
|
+
write "Welcome #{@nickname}, you have joined the chat!"
|
114
|
+
end
|
115
|
+
def on_message data
|
116
|
+
broadcast "#{@nickname} >> #{data}"
|
117
|
+
write ">> #{data}"
|
118
|
+
end
|
119
|
+
def on_broadcast data
|
120
|
+
write data
|
121
|
+
end
|
122
|
+
def on_close
|
123
|
+
broadcast "#{@nickname} has left the chat!"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
Iodine::Http.on_websocket WSChatServer
|
128
|
+
```
|
89
129
|
|
90
130
|
## Server Usage: Plug in your network protocol
|
91
131
|
|
data/lib/iodine/core.rb
CHANGED
@@ -25,6 +25,18 @@ module Iodine
|
|
25
25
|
self
|
26
26
|
end
|
27
27
|
|
28
|
+
# @return [nil] Signals Iodine to exit if it was running on Server or Timer mode. Tasks will rundown pending timeout.
|
29
|
+
def signal_exit
|
30
|
+
Process.kill("INT", 0) unless @stop
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
# forces Iodine to start prematurely and asyncronously. This might case Iodine to exit abruptly, depending how the hosting application behaves.
|
35
|
+
def force_start!
|
36
|
+
thread = Thread.new { startup true }
|
37
|
+
Kernel.at_exit {thread.raise("stop"); thread.join}
|
38
|
+
end
|
39
|
+
|
28
40
|
protected
|
29
41
|
|
30
42
|
@queue = Queue.new
|
@@ -58,12 +70,18 @@ module Iodine
|
|
58
70
|
end
|
59
71
|
end
|
60
72
|
|
61
|
-
|
73
|
+
def startup use_rescue = false, hide_message = false
|
62
74
|
threads = []
|
63
75
|
@thread_count.times { threads << Thread.new { cycle } }
|
64
76
|
unless @stop
|
65
|
-
|
66
|
-
|
77
|
+
if use_rescue
|
78
|
+
sleep rescue true
|
79
|
+
else
|
80
|
+
old_int_trap = trap('INT') { throw :stop; trap('INT', old_int_trap) if old_int_trap }
|
81
|
+
old_term_trap = trap('TERM') { throw :stop; trap('TERM', old_term_trap) if old_term_trap }
|
82
|
+
catch(:stop) { sleep }
|
83
|
+
end
|
84
|
+
log "\nShutting down Iodine. Setting shutdown timeout to 25 seconds.\n" unless hide_message
|
67
85
|
@stop = true
|
68
86
|
# setup exit timeout.
|
69
87
|
threads.each {|t| Thread.new {sleep 25; t.kill; t.kill } }
|
@@ -71,6 +89,10 @@ module Iodine
|
|
71
89
|
threads.each {|t| t.join rescue true }
|
72
90
|
end
|
73
91
|
|
92
|
+
Kernel.at_exit do
|
93
|
+
startup
|
94
|
+
end
|
95
|
+
|
74
96
|
# performed once - the shutdown sequence.
|
75
97
|
def shutdown
|
76
98
|
return if @done
|
data/lib/iodine/http.rb
CHANGED
@@ -18,7 +18,7 @@ require 'iodine/http/hpack'
|
|
18
18
|
require 'iodine/http/http2'
|
19
19
|
|
20
20
|
require 'iodine/http/websockets'
|
21
|
-
|
21
|
+
require 'iodine/http/websocket_handler'
|
22
22
|
require 'iodine/http/websocket_client'
|
23
23
|
|
24
24
|
require 'iodine/http/rack_support'
|
@@ -39,11 +39,14 @@ module Iodine
|
|
39
39
|
#
|
40
40
|
# require 'iodine/http'
|
41
41
|
# class WSChatServer
|
42
|
-
# def initialize nickname
|
42
|
+
# def initialize nickname, response
|
43
43
|
# @nickname = nickname || "unknown"
|
44
|
+
# @response = response
|
45
|
+
# # @response.io # => Http Protocol
|
44
46
|
# end
|
45
|
-
# def on_open
|
46
|
-
#
|
47
|
+
# def on_open
|
48
|
+
# # only now is the response.io pointing at the Websocket Protocol
|
49
|
+
# @io = @response.io
|
47
50
|
# @io.broadcast "#{@nickname} has joined the chat!"
|
48
51
|
# @io << "Welcome #{@nickname}, you have joined the chat!"
|
49
52
|
# end
|
@@ -52,14 +55,17 @@ module Iodine
|
|
52
55
|
# @io << ">> #{data}"
|
53
56
|
# end
|
54
57
|
# def on_broadcast data
|
55
|
-
#
|
58
|
+
# # the http response can also be used to send websocket data.
|
59
|
+
# @response << data
|
56
60
|
# end
|
57
61
|
# def on_close
|
58
62
|
# @io.broadcast "#{@nickname} has left the chat!"
|
59
63
|
# end
|
60
64
|
# end
|
61
65
|
#
|
62
|
-
# Iodine::Http.on_websocket { |request, response| WSChatServer.new request.params[:name]}
|
66
|
+
# Iodine::Http.on_websocket { |request, response| WSChatServer.new request.params[:name], response}
|
67
|
+
#
|
68
|
+
# See {Iodine::Http::WebsocketHandler} for a good starting point or inherit {Iodine::Http::WebsocketHandler} in your handler.
|
63
69
|
#
|
64
70
|
class Http < Iodine::Protocol
|
65
71
|
# Sets or gets the Http callback.
|
@@ -98,17 +104,23 @@ module Iodine
|
|
98
104
|
# i.e.:
|
99
105
|
#
|
100
106
|
# require 'iodine/http'
|
107
|
+
# # don't start the server
|
108
|
+
# Iodine.protocol = :timer
|
101
109
|
# options = {}
|
102
110
|
# options[:on_open] = Proc.new { write "Hello there!"}
|
103
111
|
# options[:on_message] = Proc.new do |data|
|
104
112
|
# puts ">> #{data}";
|
105
113
|
# write "Bye!";
|
106
114
|
# # It's possible to update the callback midstream.
|
107
|
-
# on_message {|data| puts "-- Goodbye message: #{data}"; close}
|
115
|
+
# on_message {|data| puts "-- Goodbye message: #{data}"; close;}
|
108
116
|
# end
|
109
|
-
#
|
117
|
+
# # After closing we will call `Iodine.signal_exit` to signal Iodine to finish up.
|
118
|
+
# options[:on_close] = Proc.new { puts "disconnected"; Iodine.signal_exit }
|
110
119
|
#
|
111
120
|
# Iodine::Http.ws_connect "ws://echo.websocket.org", options
|
121
|
+
#
|
122
|
+
# #if running from irb:
|
123
|
+
# exit
|
112
124
|
#
|
113
125
|
def self.ws_connect url, options={}, &block
|
114
126
|
::Iodine.run { ::Iodine::Http::WebsocketClient.connect url, options, &block }
|
data/lib/iodine/http/http1.rb
CHANGED
@@ -121,11 +121,6 @@ module Iodine
|
|
121
121
|
HTTP_METHODS = %w{GET HEAD POST PUT DELETE TRACE OPTIONS CONNECT PATCH}
|
122
122
|
HTTP_METHODS_REGEXP = /\A#{HTTP_METHODS.join('|')}/i
|
123
123
|
|
124
|
-
def parse data
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
|
129
124
|
def dispatch request, data
|
130
125
|
return data.string.clear if @io.closed? || @refuse_requests
|
131
126
|
::Iodine::Http::Request.parse request
|
@@ -209,7 +204,7 @@ module Iodine
|
|
209
204
|
request = response.request
|
210
205
|
return if Iodine.logger.nil? || request[:no_log]
|
211
206
|
t_n = Time.now
|
212
|
-
Iodine.
|
207
|
+
Iodine.log("#{request[:client_ip]} [#{t_n.utc}] \"#{request[:method]} #{request[:original_path]} #{request[:scheme]}\/#{request[:version]}\" #{response.status} #{response.bytes_written.to_s} #{((t_n - request[:time_recieved])*1000).round(2)}ms\n").clear
|
213
208
|
end
|
214
209
|
end
|
215
210
|
end
|
data/lib/iodine/http/http2.rb
CHANGED
@@ -122,6 +122,8 @@ module Iodine
|
|
122
122
|
self.new(io).on_message data
|
123
123
|
true
|
124
124
|
end
|
125
|
+
|
126
|
+
|
125
127
|
protected
|
126
128
|
|
127
129
|
# logs the sent response.
|
@@ -129,7 +131,7 @@ module Iodine
|
|
129
131
|
request = response.request
|
130
132
|
return if Iodine.logger.nil? || request[:no_log]
|
131
133
|
t_n = Time.now
|
132
|
-
Iodine.
|
134
|
+
Iodine.log("#{request[:client_ip]} [#{t_n.utc}] #{request[:method]} #{request[:original_path]} #{request[:scheme]}\/2 #{response.status} #{response.bytes_written.to_s} #{((t_n - request[:time_recieved])*1000).round(2)}ms\n").clear
|
133
135
|
end
|
134
136
|
|
135
137
|
# Sends an HTTP frame with the requested payload
|
@@ -368,7 +370,7 @@ module Iodine
|
|
368
370
|
# Iodine.info "Should Process request #{request.select { |k,v| k != :io } }"
|
369
371
|
@last_stream = request[:sid] if request[:sid] > @last_stream
|
370
372
|
# emit_frame [HTTP_1_1_REQUIRED].pack('N'), request[:sid], 0x3, 0
|
371
|
-
Iodine.run request, &(::Iodine::Http::Http2.dispatch)
|
373
|
+
::Iodine.run request, &(::Iodine::Http::Http2.dispatch)
|
372
374
|
|
373
375
|
end
|
374
376
|
|
@@ -407,7 +409,7 @@ module Iodine
|
|
407
409
|
#
|
408
410
|
# @return [true, false, nil] returns true if connection handling can continue of false (or nil) for a fatal error.
|
409
411
|
def connection_error type
|
410
|
-
Iodine.warn "HTTP/2 error #{type}."
|
412
|
+
::Iodine.warn "HTTP/2 error #{type}."
|
411
413
|
go_away type
|
412
414
|
# case type
|
413
415
|
# when NO_ERROR
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Iodine
|
2
2
|
|
3
|
-
|
3
|
+
class Http < ::Iodine::Protocol
|
4
4
|
# This (will be) a Rack handler for the Iodine HTTP server.
|
5
5
|
module Rack
|
6
6
|
module_function
|
@@ -90,7 +90,7 @@ begin
|
|
90
90
|
rescue Exception => e
|
91
91
|
|
92
92
|
end
|
93
|
-
::Rack::Handler.register( 'iodine', 'Iodine::
|
93
|
+
::Rack::Handler.register( 'iodine', 'Iodine::Http::Rack') if defined?(::Rack)
|
94
94
|
|
95
95
|
######
|
96
96
|
## example requests
|
data/lib/iodine/http/request.rb
CHANGED
@@ -332,7 +332,7 @@ module Iodine
|
|
332
332
|
# read the body's data and parse any incoming data.
|
333
333
|
def self.read_body request
|
334
334
|
# save body for Rack, if applicable
|
335
|
-
request[:rack_input] = StringIO.new(request[:body].dup.force_encoding(::Encoding::ASCII_8BIT)) if
|
335
|
+
request[:rack_input] = StringIO.new(request[:body].dup.force_encoding(::Encoding::ASCII_8BIT)) if ::Iodine::Http.on_http == ::Iodine::Http::Rack
|
336
336
|
# parse content
|
337
337
|
case request['content-type'.freeze].to_s
|
338
338
|
when /x-www-form-urlencoded/
|
data/lib/iodine/http/response.rb
CHANGED
@@ -14,8 +14,6 @@ module Iodine
|
|
14
14
|
attr_reader :flash
|
15
15
|
# the response's body buffer container (an array). This object is removed once the headers are sent and all write operations hang after that point.
|
16
16
|
attr_accessor :body
|
17
|
-
# the io through which the response will be sent.
|
18
|
-
attr_reader :io
|
19
17
|
# the request.
|
20
18
|
attr_accessor :request
|
21
19
|
# Logs the number of bytes written.
|
@@ -34,7 +32,6 @@ module Iodine
|
|
34
32
|
@body = content || []
|
35
33
|
@request.cookies.set_response self
|
36
34
|
@cookies = {}
|
37
|
-
@io = request.io
|
38
35
|
@bytes_written = 0
|
39
36
|
@keep_alive = @http_sblocks_count = false
|
40
37
|
# propegate flash object
|
@@ -46,6 +43,11 @@ module Iodine
|
|
46
43
|
end
|
47
44
|
end
|
48
45
|
|
46
|
+
# returns the active protocol for the request.
|
47
|
+
def io
|
48
|
+
@request[:io]
|
49
|
+
end
|
50
|
+
|
49
51
|
# returns true if headers were already sent
|
50
52
|
def headers_sent?
|
51
53
|
@headers.frozen?
|
@@ -79,7 +81,7 @@ module Iodine
|
|
79
81
|
raise "Block required." unless block
|
80
82
|
start_streaming unless @http_sblocks_count
|
81
83
|
@http_sblocks_count += 1
|
82
|
-
@stream_proc ||= Proc.new { |block| raise "IO closed. Streaming failed." if io.io.closed?; block.call; @http_sblocks_count -= 1; finish_streaming }
|
84
|
+
@stream_proc ||= Proc.new { |block| raise "IO closed. Streaming failed." if request[:io].io.closed?; block.call; @http_sblocks_count -= 1; finish_streaming }
|
83
85
|
Iodine.run block, &@stream_proc
|
84
86
|
end
|
85
87
|
|
@@ -150,7 +152,7 @@ module Iodine
|
|
150
152
|
#
|
151
153
|
# If the headers were already sent, this will also send the data and hang until the data was sent.
|
152
154
|
def << str
|
153
|
-
( @body ? @body.push(str) : ( (@body = str.dup) &&
|
155
|
+
( @body ? @body.push(str) : ( (@body = str.dup) && request[:io].stream_response(self) ) ) if str
|
154
156
|
self
|
155
157
|
end
|
156
158
|
|
@@ -234,12 +236,12 @@ module Iodine
|
|
234
236
|
|
235
237
|
# attempts to write a non-streaming response to the IO. This can be done only once and will quitely fail subsequently.
|
236
238
|
def finish
|
237
|
-
|
239
|
+
request[:io].send_response self
|
238
240
|
end
|
239
241
|
|
240
242
|
# Returns the connection's UUID.
|
241
243
|
def uuid
|
242
|
-
io.id
|
244
|
+
request[:io].id
|
243
245
|
end
|
244
246
|
|
245
247
|
# response status codes, as defined.
|
@@ -338,7 +340,7 @@ module Iodine
|
|
338
340
|
def start_streaming
|
339
341
|
raise "Cannot start streaming after headers were sent!" if headers_sent?
|
340
342
|
@http_sblocks_count ||= 0
|
341
|
-
|
343
|
+
request[:io].stream_response self
|
342
344
|
end
|
343
345
|
|
344
346
|
# Sends the complete response signal for a streaming response.
|
@@ -346,7 +348,7 @@ module Iodine
|
|
346
348
|
# Careful - sending the completed response signal more than once might case disruption to the HTTP connection.
|
347
349
|
def finish_streaming
|
348
350
|
return unless @http_sblocks_count == 0
|
349
|
-
|
351
|
+
request[:io].stream_response self, true
|
350
352
|
end
|
351
353
|
end
|
352
354
|
end
|
data/lib/iodine/http/session.rb
CHANGED
@@ -1,78 +1,78 @@
|
|
1
1
|
module Iodine
|
2
|
-
|
3
|
-
module
|
4
|
-
@mem_storage = {}
|
5
|
-
def self.fetch key
|
6
|
-
@mem_storage[key] ||= {}
|
7
|
-
end
|
8
|
-
end
|
9
|
-
module FileSessionStorage
|
10
|
-
class SessionObject
|
11
|
-
# called by the Plezi framework to initiate a session with the id requested
|
12
|
-
def initialize id
|
13
|
-
@filename = File.join Dir.tmpdir, "iodine_#{Iodine::Http.session_token}_#{id}"
|
14
|
-
@data ||= {}
|
15
|
-
end
|
16
|
-
# Get a key from the session data store.
|
17
|
-
#
|
18
|
-
# Due to different considirations, all keys will be converted to strings, so that `"name" == :name` and `1234 == "1234"`.
|
19
|
-
# If you store two keys that evaluate as the same string, they WILL override each other.
|
20
|
-
def [] key
|
21
|
-
key = key.to_s
|
22
|
-
load
|
23
|
-
@data[key]
|
24
|
-
end
|
25
|
-
alias :fetch :[]
|
2
|
+
class Http < ::Iodine::Protocol
|
3
|
+
module SessionManager
|
26
4
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
def []= key, value
|
32
|
-
key = key.to_s
|
33
|
-
load
|
34
|
-
@data[key] = value
|
35
|
-
save
|
36
|
-
value
|
5
|
+
module MemSessionStorage
|
6
|
+
@mem_storage = {}
|
7
|
+
def self.fetch key
|
8
|
+
@mem_storage[key] ||= {}
|
37
9
|
end
|
38
|
-
|
10
|
+
end
|
11
|
+
module FileSessionStorage
|
12
|
+
class SessionObject
|
13
|
+
# called by the Plezi framework to initiate a session with the id requested
|
14
|
+
def initialize id
|
15
|
+
@filename = File.join Dir.tmpdir, "iodine_#{Iodine::Http.session_token}_#{id}"
|
16
|
+
@data ||= {}
|
17
|
+
end
|
18
|
+
# Get a key from the session data store.
|
19
|
+
#
|
20
|
+
# Due to different considirations, all keys will be converted to strings, so that `"name" == :name` and `1234 == "1234"`.
|
21
|
+
# If you store two keys that evaluate as the same string, they WILL override each other.
|
22
|
+
def [] key
|
23
|
+
key = key.to_s
|
24
|
+
load
|
25
|
+
@data[key]
|
26
|
+
end
|
27
|
+
alias :fetch :[]
|
39
28
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
29
|
+
# Stores a key in the session's data store.
|
30
|
+
#
|
31
|
+
# Due to different considirations, all keys will be converted to strings, so that `"name" == :name` and `1234 == "1234"`.
|
32
|
+
# If you store two keys that evaluate as the same string, they WILL override each other.
|
33
|
+
def []= key, value
|
34
|
+
key = key.to_s
|
35
|
+
load
|
36
|
+
@data[key] = value
|
37
|
+
save
|
38
|
+
value
|
39
|
+
end
|
40
|
+
alias :store :[]=
|
45
41
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
ret
|
52
|
-
end
|
42
|
+
# @return [Hash] returns a shallow copy of the current session data as a Hash.
|
43
|
+
def to_h
|
44
|
+
load
|
45
|
+
@data.dup
|
46
|
+
end
|
53
47
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
#
|
63
|
-
|
48
|
+
# Removes a key from the session's data store.
|
49
|
+
def delete key
|
50
|
+
load
|
51
|
+
ret = @data.delete key
|
52
|
+
save
|
53
|
+
ret
|
54
|
+
end
|
55
|
+
|
56
|
+
# Clears the session's data.
|
57
|
+
def clear
|
58
|
+
@data.clear
|
59
|
+
save
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
protected
|
63
|
+
def save
|
64
|
+
# save data to tmp-file
|
65
|
+
IO.write @filename, @data.to_yaml
|
66
|
+
end
|
67
|
+
def load
|
68
|
+
@data = YAML.load IO.read(@filename) if File.exists?(@filename)
|
69
|
+
end
|
64
70
|
end
|
65
|
-
def
|
66
|
-
|
71
|
+
def self.fetch key
|
72
|
+
SessionObject.new key
|
67
73
|
end
|
68
74
|
end
|
69
|
-
|
70
|
-
SessionObject.new key
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
class Http < Iodine::Protocol
|
75
|
-
module SessionManager
|
75
|
+
|
76
76
|
module_function
|
77
77
|
# returns a session object
|
78
78
|
def get id
|
@@ -89,9 +89,9 @@ module Iodine
|
|
89
89
|
def storage= session_storage = nil
|
90
90
|
case session_storage
|
91
91
|
when :file, nil
|
92
|
-
@storage = Iodine::
|
92
|
+
@storage = Iodine::Http::SessionManager::FileSessionStorage
|
93
93
|
when :mem
|
94
|
-
@storage = Iodine::
|
94
|
+
@storage = Iodine::Http::SessionManager::MemSessionStorage
|
95
95
|
else
|
96
96
|
@storage = session_storage
|
97
97
|
end
|
@@ -99,7 +99,7 @@ module Iodine
|
|
99
99
|
|
100
100
|
# returns the current session storage system.
|
101
101
|
def storage
|
102
|
-
@storage ||= Iodine::
|
102
|
+
@storage ||= Iodine::Http::SessionManager::FileSessionStorage
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|