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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b4d5413250301e7bf147d2768d9989815d00ea67
4
- data.tar.gz: a4225e75c91425af46c034a37db12fdfca468a3c
3
+ metadata.gz: 2f3c4befa23f4edb3a43a751b7b9b9a0834411b1
4
+ data.tar.gz: 59be563a5d91a4dbdc72b06dd282d8acf9f96ad2
5
5
  SHA512:
6
- metadata.gz: 8e41378d248d5607120b26d96c2b94ad85de20ced37e9ac2091afe4dd8c618e04ffe427a319cd70febae126bfcb79a3a33e7979d5ca291141fac1263a2b7399e
7
- data.tar.gz: a6b209fc737a540af696e11c85a981fae392e83e46325e2b3b10dd6fcea9bbc111043313a3ae4af3c3ab7480092458b381074693aa293adfa69d2047b328ab57
6
+ metadata.gz: ebb7e22141e7c3f96ff23c8a7923026193e14409bd00746c84acde2258951eb6ef272ad713db79d93e40541d98a07680fe5a5deab52eea2a067922d550504bd2
7
+ data.tar.gz: 94e92158a092f1799b74500b9500c5a22b205d21ef13cc36f8cc589e6eaac618ca13f592b6dde45cbda16a698c0d1e23e197ec9702d8e96e085b59dca4cb4991
@@ -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 than it will quite. Timer based tasks will be ignored.
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 initiates new tasks, for instance if you cannot use `cron`.
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
@@ -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'
@@ -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
- until body.eof?
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/ && request['http2-settings']
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
- (out = (Thread.current[:headers_buffer] ||= String.new)).clear
156
- out << @hpack.encode(headers)
157
- emit_payload (out), request[:sid], 1, (request.head? ? 1 : 0)
158
- out.clear
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
@@ -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).
@@ -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 to ask whether a timeout has occured.
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
- ping if @timeout && !@send_locker.locked? && ( (time - @last_active) > @timeout )
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
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = "0.1.16"
2
+ VERSION = "0.1.17"
3
3
  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.1.16
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-15 00:00:00.000000000 Z
11
+ date: 2015-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler