iodine 0.0.1 → 0.0.2
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 +86 -8
- data/lib/iodine.rb +45 -2
- data/lib/iodine/core.rb +9 -37
- data/lib/iodine/http.rb +135 -0
- data/lib/iodine/http/hpack.rb +543 -0
- data/lib/iodine/http/http1.rb +217 -0
- data/lib/iodine/http/http2.rb +465 -0
- data/lib/iodine/http/rack_support.rb +105 -0
- data/lib/iodine/http/request.rb +413 -0
- data/lib/iodine/http/response.rb +355 -0
- data/lib/iodine/http/session.rb +110 -0
- data/lib/iodine/http/websocket_client.rb +224 -0
- data/lib/iodine/http/websocket_handler.rb +40 -0
- data/lib/iodine/http/websockets.rb +319 -0
- data/lib/iodine/io.rb +71 -28
- data/lib/iodine/protocol.rb +74 -25
- data/lib/iodine/settings.rb +44 -3
- data/lib/iodine/ssl_connector.rb +47 -0
- data/lib/iodine/timers.rb +5 -21
- data/lib/iodine/version.rb +1 -1
- data/lib/rack/handler/iodine.rb +3 -0
- data/{bin/http_test → manual tests/core_http_test } +6 -2
- data/bin/echo b/data/manual → tests/echo +0 -0
- data/bin/em playground b/data/manual tests/em → playground +0 -0
- data/manual tests/hello_world +56 -0
- metadata +20 -6
- data/lib/iodine/ssl_protocol.rb +0 -108
data/lib/iodine/timers.rb
CHANGED
@@ -24,7 +24,7 @@ module Iodine
|
|
24
24
|
end
|
25
25
|
|
26
26
|
# stops a timed event.
|
27
|
-
# @return [
|
27
|
+
# @return [Iodine::TimedEvent] returns the TimedEvent object.
|
28
28
|
def stop!
|
29
29
|
@repeat_limit = 0
|
30
30
|
self
|
@@ -38,7 +38,7 @@ module Iodine
|
|
38
38
|
return false unless @next <= Iodine.time
|
39
39
|
return true if @repeat_limit == 0
|
40
40
|
@repeat_limit -= 1 if @repeat_limit.to_i > 0
|
41
|
-
Iodine.
|
41
|
+
Iodine.run *@args, &@job
|
42
42
|
@next = Iodine.time + @interval
|
43
43
|
@repeat_limit == 0
|
44
44
|
end
|
@@ -59,28 +59,11 @@ module Iodine
|
|
59
59
|
#
|
60
60
|
# Timed event's time of execution is dependant on the workload and continuous uptime of the process (timed events AREN'T persistent).
|
61
61
|
#
|
62
|
-
# @return [
|
62
|
+
# @return [Iodine::TimedEvent] returns the new TimedEvent object.
|
63
63
|
def run_after seconds, *args, &block
|
64
64
|
timed_job seconds, 1, args, block
|
65
65
|
end
|
66
66
|
|
67
|
-
# pushes a timed event to the timers's stack
|
68
|
-
#
|
69
|
-
# accepts:
|
70
|
-
# time:: the time at which the job should be executed.
|
71
|
-
# *arg:: any arguments that will be passed to the handler's `call` method.
|
72
|
-
# &block:: the block to execute.
|
73
|
-
#
|
74
|
-
# A block is required.
|
75
|
-
#
|
76
|
-
# On top of the arguments passed to the `run_after` method, the timer object will be passed as the last agrument to the receiving block.
|
77
|
-
#
|
78
|
-
# Timed event's time of execution is dependant on the workload and continuous uptime of the process (timed events AREN'T persistent).
|
79
|
-
#
|
80
|
-
# @return [GReactor::TimedEvent] returns the new TimedEvent object.
|
81
|
-
def run_at run_time, *args, &block
|
82
|
-
timed_job( (@time - run_time), 1, args, block)
|
83
|
-
end
|
84
67
|
# pushes a repeated timed event to the timers's stack
|
85
68
|
#
|
86
69
|
# accepts:
|
@@ -95,7 +78,7 @@ module Iodine
|
|
95
78
|
#
|
96
79
|
# Timed event's time of execution is dependant on the workload and continuous uptime of the process (timed events AREN'T persistent unless you save and reload them yourself).
|
97
80
|
#
|
98
|
-
# @return [
|
81
|
+
# @return [Iodine::TimedEvent] returns the new TimedEvent object.
|
99
82
|
def run_every seconds, limit = -1, *args, &block
|
100
83
|
timed_job seconds, limit, args, block
|
101
84
|
end
|
@@ -112,5 +95,6 @@ module Iodine
|
|
112
95
|
@check_timers = Proc.new do
|
113
96
|
@timer_locker.synchronize { @timers.delete_if {|t| t.done? } }
|
114
97
|
end
|
98
|
+
@check_timers = [@check_timers]
|
115
99
|
|
116
100
|
end
|
data/lib/iodine/version.rb
CHANGED
@@ -14,7 +14,7 @@ require 'stringio'
|
|
14
14
|
|
15
15
|
|
16
16
|
|
17
|
-
class MiniServer < Iodine::
|
17
|
+
class MiniServer < Iodine::Protocol
|
18
18
|
def on_open
|
19
19
|
@headers = {}
|
20
20
|
set_timeout 1
|
@@ -46,4 +46,8 @@ class MiniServer < Iodine::SSLProtocol
|
|
46
46
|
|
47
47
|
end
|
48
48
|
|
49
|
-
Iodine.
|
49
|
+
Iodine.threads = 1
|
50
|
+
# Iodine.ssl = 1
|
51
|
+
Iodine.protocol = MiniServer
|
52
|
+
|
53
|
+
|
File without changes
|
File without changes
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
Root ||= Pathname.new(File.dirname(__FILE__)).expand_path
|
5
|
+
Dir.chdir Root.join('..').to_s
|
6
|
+
|
7
|
+
require "bundler/setup"
|
8
|
+
require "iodine/http"
|
9
|
+
|
10
|
+
# Iodine.ssl = true
|
11
|
+
# Iodine.treads = 8
|
12
|
+
# Iodine.protocol.on_http do |req, res|
|
13
|
+
# res.session[:count] ||= 0
|
14
|
+
# res.session[:count] += 1
|
15
|
+
# res << "Visits: #{res.session[:count]}\n\nRequest object:\n\n#{req.to_s}"
|
16
|
+
# end
|
17
|
+
|
18
|
+
# Iodine.processes = 4
|
19
|
+
|
20
|
+
Iodine.protocol.on_http { "Hello World!" }
|
21
|
+
|
22
|
+
|
23
|
+
class WSChatServer
|
24
|
+
def initialize nickname
|
25
|
+
@nickname = nickname || "unknown"
|
26
|
+
end
|
27
|
+
def on_open protocol
|
28
|
+
@io = protocol
|
29
|
+
@io.broadcast "#{@nickname} has joined the chat!"
|
30
|
+
@io << "Welcome #{@nickname}, you have joined the chat!"
|
31
|
+
end
|
32
|
+
def on_message data
|
33
|
+
@io.broadcast "#{@nickname} >> #{data}"
|
34
|
+
@io << ">> #{data}"
|
35
|
+
end
|
36
|
+
def on_broadcast data
|
37
|
+
@io << data
|
38
|
+
end
|
39
|
+
def on_close
|
40
|
+
@io.broadcast "#{@nickname} has left the chat!"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Iodine::Http.on_websocket { |request, response| WSChatServer.new request.params[:name]}
|
45
|
+
|
46
|
+
Process.fork do
|
47
|
+
|
48
|
+
Iodine.ssl = true
|
49
|
+
Iodine.port = 3030
|
50
|
+
Iodine.protocol.on_http do |req, res|
|
51
|
+
res.session[:count] ||= 0
|
52
|
+
res.session[:count] += 1
|
53
|
+
res << "Visits: #{res.session[:count]}\n\nRequest object:\n\n#{req.to_s}"
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iodine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,20 +66,33 @@ files:
|
|
66
66
|
- README.md
|
67
67
|
- Rakefile
|
68
68
|
- bin/console
|
69
|
-
- bin/echo
|
70
|
-
- bin/em playground
|
71
|
-
- bin/http_test
|
72
69
|
- bin/setup
|
73
70
|
- iodine.gemspec
|
74
71
|
- lib/iodine.rb
|
75
72
|
- lib/iodine/core.rb
|
73
|
+
- lib/iodine/http.rb
|
74
|
+
- lib/iodine/http/hpack.rb
|
75
|
+
- lib/iodine/http/http1.rb
|
76
|
+
- lib/iodine/http/http2.rb
|
77
|
+
- lib/iodine/http/rack_support.rb
|
78
|
+
- lib/iodine/http/request.rb
|
79
|
+
- lib/iodine/http/response.rb
|
80
|
+
- lib/iodine/http/session.rb
|
81
|
+
- lib/iodine/http/websocket_client.rb
|
82
|
+
- lib/iodine/http/websocket_handler.rb
|
83
|
+
- lib/iodine/http/websockets.rb
|
76
84
|
- lib/iodine/io.rb
|
77
85
|
- lib/iodine/logging.rb
|
78
86
|
- lib/iodine/protocol.rb
|
79
87
|
- lib/iodine/settings.rb
|
80
|
-
- lib/iodine/
|
88
|
+
- lib/iodine/ssl_connector.rb
|
81
89
|
- lib/iodine/timers.rb
|
82
90
|
- lib/iodine/version.rb
|
91
|
+
- lib/rack/handler/iodine.rb
|
92
|
+
- manual tests/core_http_test
|
93
|
+
- manual tests/echo
|
94
|
+
- manual tests/em playground
|
95
|
+
- manual tests/hello_world
|
83
96
|
homepage: https://github.com/boazsegev/iodine
|
84
97
|
licenses:
|
85
98
|
- MIT
|
@@ -106,3 +119,4 @@ signing_key:
|
|
106
119
|
specification_version: 4
|
107
120
|
summary: IOdine makes writing evented server applications easy to write.
|
108
121
|
test_files: []
|
122
|
+
has_rdoc:
|
data/lib/iodine/ssl_protocol.rb
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
module Iodine
|
2
|
-
|
3
|
-
# This class inherits from Protocol, but it includes some adjustments related to SSL connection handling.
|
4
|
-
class SSLProtocol < Protocol
|
5
|
-
|
6
|
-
# This is a mini-protocol used only to implement the SSL Handshake in a non-blocking manner,
|
7
|
-
# allowing for a hardcoded timeout (which you can monkey patch) of 3 seconds.
|
8
|
-
class SSLWait < Protocol
|
9
|
-
TIMEOUT = 3 # hardcoded SSL/TLS handshake timeout
|
10
|
-
def on_open
|
11
|
-
timeout = TIMEOUT
|
12
|
-
@ssl_socket = OpenSSL::SSL::SSLSocket.new(@io, Iodine.ssl_context)
|
13
|
-
@ssl_socket.sync_close = true
|
14
|
-
end
|
15
|
-
|
16
|
-
# atempt an SSL Handshale
|
17
|
-
def call
|
18
|
-
return if @locker.locked?
|
19
|
-
return unless @locker.try_lock
|
20
|
-
begin
|
21
|
-
@ssl_socket.accept_nonblock
|
22
|
-
@locker.unlock
|
23
|
-
rescue IO::WaitReadable, IO::WaitWritable
|
24
|
-
@locker.unlock
|
25
|
-
return
|
26
|
-
rescue OpenSSL::SSL::SSLError
|
27
|
-
@e = Exception.new "Self-signed Certificate?".freeze
|
28
|
-
@locker.unlock
|
29
|
-
return
|
30
|
-
rescue => e
|
31
|
-
Iodine.warn "SSL Handshake failed with: #{e.message}".freeze
|
32
|
-
@e = e
|
33
|
-
close
|
34
|
-
@locker.unlock
|
35
|
-
return
|
36
|
-
end
|
37
|
-
Iodine.protocol.new @ssl_socket
|
38
|
-
end
|
39
|
-
def on_close
|
40
|
-
# inform
|
41
|
-
Iodine.warn "SSL Handshake #{@e ? "failed with: #{@e.message} (#{@e.class.name})" : 'timed-out.'}".freeze
|
42
|
-
# the core @io is already closed, but let's make sure the SSL object is closed as well.
|
43
|
-
@ssl_socket.close unless @ssl_socket.closed?
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
|
-
attr_reader :ssl_socket
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# reads from the IO up to the specified number of bytes (defaults to ~1Mb).
|
53
|
-
def read size = 1048576
|
54
|
-
@send_locker.synchronize do
|
55
|
-
data = ''
|
56
|
-
begin
|
57
|
-
(data << @ssl_socket.read_nonblock(size).to_s) until data.bytesize >= size
|
58
|
-
rescue OpenSSL::SSL::SSLErrorWaitReadable, IO::WaitReadable, IO::WaitWritable
|
59
|
-
|
60
|
-
rescue IOError
|
61
|
-
close
|
62
|
-
rescue => e
|
63
|
-
Iodine.warn "SSL Protocol read error: #{e.class.name} #{e.message} (closing connection)"
|
64
|
-
close
|
65
|
-
end
|
66
|
-
return false if data.to_s.empty?
|
67
|
-
touch
|
68
|
-
data
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def write data
|
73
|
-
begin
|
74
|
-
@send_locker.synchronize do
|
75
|
-
r = @ssl_socket.write data
|
76
|
-
touch
|
77
|
-
r
|
78
|
-
end
|
79
|
-
rescue => e
|
80
|
-
close
|
81
|
-
false
|
82
|
-
end
|
83
|
-
end
|
84
|
-
alias :send :write
|
85
|
-
alias :<< :write
|
86
|
-
|
87
|
-
def on_close
|
88
|
-
@ssl_socket.close unless @ssl_socket.closed?
|
89
|
-
super
|
90
|
-
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
# This method initializes the SSL Protocol
|
97
|
-
def initialize ssl_socket
|
98
|
-
@ssl_socket = ssl_socket
|
99
|
-
super(ssl_socket.io)
|
100
|
-
end
|
101
|
-
|
102
|
-
def self.accept io
|
103
|
-
SSLWait.new(io)
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
end
|
108
|
-
end
|