iodine 0.1.16 → 0.1.17
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/CHANGELOG.md +14 -0
- data/README.md +3 -3
- data/bin/hello_world +1 -0
- data/lib/iodine/http/http2.rb +16 -18
- data/lib/iodine/http/response.rb +10 -0
- data/lib/iodine/protocol.rb +8 -2
- data/lib/iodine/version.rb +1 -1
- 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: 2f3c4befa23f4edb3a43a751b7b9b9a0834411b1
|
4
|
+
data.tar.gz: 59be563a5d91a4dbdc72b06dd282d8acf9f96ad2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebb7e22141e7c3f96ff23c8a7923026193e14409bd00746c84acde2258951eb6ef272ad713db79d93e40541d98a07680fe5a5deab52eea2a067922d550504bd2
|
7
|
+
data.tar.gz: 94e92158a092f1799b74500b9500c5a22b205d21ef13cc36f8cc589e6eaac618ca13f592b6dde45cbda16a698c0d1e23e197ec9702d8e96e085b59dca4cb4991
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,20 @@ Please notice that this change log contains changes for upcoming releases as wel
|
|
8
8
|
|
9
9
|
***
|
10
10
|
|
11
|
+
Change log v.0.1.17
|
12
|
+
|
13
|
+
**Credit**: thanks you @frozenfoxx for going through the readme and fixing my broken grammer.
|
14
|
+
|
15
|
+
**Fix**: fixed an issue where multiple Pings might get sent when pinging takes time. Now pings are exclusive (run within their own Mutex).
|
16
|
+
|
17
|
+
**Fix**: Http/2 is back... sorry about breaking it in the 0.1.16 version. When I updated the write buffer I forgot to write the status of the response, causing a protocol error related with the headers. It's now working again.
|
18
|
+
|
19
|
+
**Update**: by default and for security reasons, session id's created through a secure connection (SSL) will NOT be available on a non secure connection (SSL/TLS). However, while upgrading to the encrypted connection, the non_encrypted session storage is now available for review using the `Response#session_old` method.
|
20
|
+
|
21
|
+
* Remember that sessions are never really safe, no matter how much we guard them. Session hijacking is far too easy. This is why Iodine stores the session data locally and not within the session cookie. This is also why you should review any authentication before performing sensitive tasks based on session stored authentication data.
|
22
|
+
|
23
|
+
***
|
24
|
+
|
11
25
|
Change log v.0.1.16
|
12
26
|
|
13
27
|
**Performance**: Http/1 and Http/2 connections now share and recycle their write buffer when while reading the response body and writing it to the IO. This (hopefuly) prevents excess `malloc` calls by the interperter.
|
data/README.md
CHANGED
@@ -56,15 +56,15 @@ Iodine.threads = 5
|
|
56
56
|
exit
|
57
57
|
```
|
58
58
|
|
59
|
-
In this mode, Iodine will continue running until all the tasks have completed and
|
59
|
+
In this mode, Iodine will continue running until all the tasks have completed and then it will quit. Timer-based tasks will be ignored.
|
60
60
|
|
61
61
|
## Simple Usage: Task polling
|
62
62
|
|
63
|
-
This mode of operation is effective if want Iodine to periodically
|
63
|
+
This mode of operation is effective if you want Iodine to periodically initiate new tasks such as when you are not able to use `cron`.
|
64
64
|
|
65
65
|
To initiate this mode, simply set: `Iodine.protocol = :timers` OR create a TimedEvent.
|
66
66
|
|
67
|
-
In example:
|
67
|
+
In example form:
|
68
68
|
|
69
69
|
|
70
70
|
```ruby
|
data/bin/hello_world
CHANGED
@@ -59,6 +59,7 @@ Process.fork do
|
|
59
59
|
res.stream_async { sleep 2; res << "I was sleeping..."}
|
60
60
|
next
|
61
61
|
end
|
62
|
+
res << "Old session visits: #{res.session_old[:count]}\n\n" if res.session_old
|
62
63
|
res.session[:count] ||= 0
|
63
64
|
res.session[:count] += 1
|
64
65
|
res['content-type'] = 'text/plain'
|
data/lib/iodine/http/http2.rb
CHANGED
@@ -82,9 +82,7 @@ module Iodine
|
|
82
82
|
send_headers response, request
|
83
83
|
return body && body.close if request.head?
|
84
84
|
if body
|
85
|
-
|
86
|
-
response.bytes_written += emit_payload(body.read(@settings[SETTINGS_MAX_FRAME_SIZE], Thread.current[:write_buffer]), request[:sid], 0, ((finish && body.eof?) ? 1 : 0))
|
87
|
-
end
|
85
|
+
response.bytes_written += emit_payload body, request[:sid], 0,(finish ? 1 : 0)
|
88
86
|
body.close
|
89
87
|
elsif finish
|
90
88
|
emit_payload(''.freeze, request[:sid], 0, 1)
|
@@ -93,7 +91,7 @@ module Iodine
|
|
93
91
|
end
|
94
92
|
|
95
93
|
def ping
|
96
|
-
@frame_locker.synchronize { emit_frame "pniodine", 0, 6 }
|
94
|
+
@frame_locker.synchronize { emit_frame "pniodine".freeze, 0, 6 }
|
97
95
|
end
|
98
96
|
|
99
97
|
def push request
|
@@ -102,7 +100,7 @@ module Iodine
|
|
102
100
|
# emit push promise
|
103
101
|
emit_payload @hpack.encode(path: request[:path], method: request[:method], scheme: request[:scheme], authority: request[:authority]), (request[:sid] = (@last_push += 2)), 5, 4
|
104
102
|
# queue for app dispatch
|
105
|
-
Iodine.run request, &::Iodine::Http::Http2.dispatch
|
103
|
+
Iodine.run( request, &::Iodine::Http::Http2.dispatch)
|
106
104
|
end
|
107
105
|
|
108
106
|
def go_away error_code
|
@@ -119,8 +117,8 @@ module Iodine
|
|
119
117
|
|
120
118
|
# clear text handshake
|
121
119
|
def self.handshake request, io, data
|
122
|
-
return false unless request['upgrade'] =~ /h2c
|
123
|
-
io.write "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nUpgrade: h2c\r\n\r\n"
|
120
|
+
return false unless request['upgrade'.freeze] =~ /h2c/.freeze && request['http2-settings'.freeze]
|
121
|
+
io.write "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nUpgrade: h2c\r\n\r\n".freeze
|
124
122
|
http_2 = self.new(io, request)
|
125
123
|
unless data.eof?
|
126
124
|
http_2.on_message data.read
|
@@ -150,12 +148,12 @@ module Iodine
|
|
150
148
|
return false if response.headers.frozen?
|
151
149
|
headers = response.headers
|
152
150
|
# headers[:status] = response.status.to_s
|
153
|
-
headers['set-cookie'] = response.extract_cookies
|
151
|
+
headers['set-cookie'.freeze] = response.extract_cookies
|
154
152
|
headers.freeze
|
155
|
-
(
|
156
|
-
|
157
|
-
|
158
|
-
|
153
|
+
(Thread.current[:headers_buffer] ||= String.new).clear
|
154
|
+
Thread.current[:headers_buffer] << @hpack.encode(status: response.status)
|
155
|
+
Thread.current[:headers_buffer] << @hpack.encode(headers)
|
156
|
+
emit_payload Thread.current[:headers_buffer], request[:sid], 1, (request.head? ? 1 : 0)
|
159
157
|
return true
|
160
158
|
end
|
161
159
|
|
@@ -175,17 +173,17 @@ module Iodine
|
|
175
173
|
max_frame_size = 131_072 if max_frame_size > 131_072
|
176
174
|
return @frame_locker.synchronize { emit_frame(payload, sid, type, ( (type == 0x1 || type == 0x5) ? (flags | 0x4) : flags ) ) } if payload.bytesize <= max_frame_size
|
177
175
|
sent = 0
|
178
|
-
payload = StringIO.new payload
|
176
|
+
payload = StringIO.new payload unless payload.respond_to? :read
|
179
177
|
if type == 0x1 || type == 0x5
|
180
178
|
@frame_locker.synchronize do
|
181
|
-
sent += emit_frame(payload.read(max_frame_size), sid, 0x1, flags & 254)
|
182
|
-
sent += emit_frame(payload.read(max_frame_size), sid, 0x9, 0) while payload.size - payload.pos > max_frame_size
|
183
|
-
sent += emit_frame(payload.read(max_frame_size), sid, 0x9, (0x4 | (flags & 0x1)) )
|
179
|
+
sent += emit_frame(payload.read(max_frame_size, Thread.current[:write_buffer]), sid, 0x1, flags & 254)
|
180
|
+
sent += emit_frame(payload.read(max_frame_size, Thread.current[:write_buffer]), sid, 0x9, 0) while payload.size - payload.pos > max_frame_size
|
181
|
+
sent += emit_frame(payload.read(max_frame_size, Thread.current[:write_buffer]), sid, 0x9, (0x4 | (flags & 0x1)) )
|
184
182
|
end
|
185
183
|
return sent
|
186
184
|
end
|
187
|
-
sent += @frame_locker.synchronize { emit_frame(payload.read(max_frame_size), sid, type, (flags & 254)) } while payload.size - payload.pos > max_frame_size
|
188
|
-
sent += @frame_locker.synchronize { emit_frame(payload.read(max_frame_size), sid, type, flags) }
|
185
|
+
sent += @frame_locker.synchronize { emit_frame(payload.read(max_frame_size, Thread.current[:write_buffer]), sid, type, (flags & 254)) } while payload.size - payload.pos > max_frame_size
|
186
|
+
sent += @frame_locker.synchronize { emit_frame(payload.read(max_frame_size, Thread.current[:write_buffer]), sid, type, flags) }
|
189
187
|
end
|
190
188
|
|
191
189
|
def parse_preface data
|
data/lib/iodine/http/response.rb
CHANGED
@@ -158,6 +158,16 @@ module Iodine
|
|
158
158
|
@request[:session] = @session = ::Iodine::Http::SessionManager.get(id)
|
159
159
|
end
|
160
160
|
|
161
|
+
# Returns the OLD session storage object when the connection was upgraded to SSL.
|
162
|
+
#
|
163
|
+
# By default and for security reasons, session id's created on a secure connection will NOT be available on a non secure connection (SSL/TLS).
|
164
|
+
# However, while upgrading to the encrypted connection, the non_encrypted session storage is still available for review.
|
165
|
+
#
|
166
|
+
# @return [nil, "Hash like storage"] returns the non-encypeted connection's session storage object, if it exists. This method will NOT create a new sesssion if it didn't exist.
|
167
|
+
def session_old
|
168
|
+
::Iodine::Http::SessionManager.get(@request.cookies[::Iodine::Http.session_token.to_sym]) if @request.cookies[::Iodine::Http.session_token.to_sym]
|
169
|
+
end
|
170
|
+
|
161
171
|
# Returns a writable combined hash of the request's cookies and the response cookie values.
|
162
172
|
#
|
163
173
|
# Any cookies writen to this hash (`response.cookies[:name] = value` will be set using default values).
|
data/lib/iodine/protocol.rb
CHANGED
@@ -166,6 +166,7 @@ module Iodine
|
|
166
166
|
def initialize io, options = nil
|
167
167
|
@timeout ||= nil
|
168
168
|
@send_locker = Mutex.new
|
169
|
+
@ping_locker = Mutex.new
|
169
170
|
@locker = Mutex.new
|
170
171
|
@io = io
|
171
172
|
@options = options
|
@@ -193,11 +194,16 @@ module Iodine
|
|
193
194
|
end
|
194
195
|
|
195
196
|
|
196
|
-
# This method is used by Iodine
|
197
|
+
# This method is used by Iodine invoke a timeout review.
|
197
198
|
#
|
198
199
|
# Normally you won't need to override this method. See {#ping}
|
199
200
|
def timeout? time
|
200
|
-
|
201
|
+
return unless @ping_locker.try_lock
|
202
|
+
begin
|
203
|
+
touch && ping if @timeout && !@send_locker.locked? && ( (time - @last_active) > @timeout )
|
204
|
+
ensure
|
205
|
+
@ping_locker.unlock
|
206
|
+
end
|
201
207
|
end
|
202
208
|
|
203
209
|
protected
|
data/lib/iodine/version.rb
CHANGED
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.1.
|
4
|
+
version: 0.1.17
|
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-11-
|
11
|
+
date: 2015-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|