iodine 0.1.5 → 0.1.6

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: 3a9f87061376cb31f4e3d6b1cc7fd9dcca401151
4
- data.tar.gz: 2cde195704434f6ff3af7b4a98a35c3b06f637af
3
+ metadata.gz: 636347aa715abdbf11841686f90c2880483e914f
4
+ data.tar.gz: 73264587c620ce8493c2eb5f9e3c5c229f51a21c
5
5
  SHA512:
6
- metadata.gz: 0bb1203ab2d5d5ab58ec4b6dd97146b0328802db7b426031319a5e8be6936826811e43a86ae6326bbe86f0811a3013656d15a56fdfb0f29a1d0046d6bf9b485a
7
- data.tar.gz: 773e868701784aca9b5a5899f0d027cafab8e586f50acf43a40f2efb51252350d689f0af6bc90caeff6f79a6a1e4a0d0bc5a683ca4b0003dde1be3182326d866
6
+ metadata.gz: e60f7d4a0f98caaaa8afcf1b4755af8c8e3b4a1878dc62c84071a5f5b3b0a68b5b5c8fa5432750a7c3db35b61d33f7782b0dd43e0bff7c151be8a4cbbc745d5f
7
+ data.tar.gz: 4d2a3b8d9f9a77b5352917bbbe4da91577e86e1bb58c580a84b74c9aaa0c1703d6dc4e6506b14026c5a975ab6794bd936ee548061d89c9f48e13949531de15fa
@@ -4,10 +4,30 @@
4
4
 
5
5
  Please notice that this change log contains changes for upcoming releases as well. Please refer to the current gem version to review the current release.
6
6
 
7
+ **Deprecation Notice**:
8
+
9
+ It is unlikely that Iodine 0.2.0 will support a blocking websocket client API.
10
+
7
11
  ## Changes:
8
12
 
9
13
  ***
10
14
 
15
+ Change log v.0.1.6
16
+
17
+ **Fix**: fixed an issue where a session key-value pair might not get deleted when using `session.delete key` and the `key` is not a String object. Also, now setting a key's value to `nil` should delete the key-value pair.
18
+
19
+ **Fix**: fixed an issue where WebsocketClient wouldn't mask outgoing data, causing some servers to respond badly.
20
+
21
+ **Performance**: minor performance improvements to the websocket parser, for unmasking messages.
22
+
23
+ **Deprecation notice**:
24
+
25
+ Iodine will soon add a core client protocol API and the WebsocketClient will be adjusted to take advantage of that API.
26
+
27
+ This will mean that WebsocketClient will no longer block when connecting directly using the `Iodine::Http::WebsocketClient.connect` method... make sure to use `Iodine::Http.ws_connect` and to define an `:on_open` callback.
28
+
29
+ ***
30
+
11
31
  Change log v.0.1.5
12
32
 
13
33
  **Feature**: The Response#body can now be set to a File object, allowing Iodine to preserve memory when serving large static files from disc. Limited Range requests are also supported - together, these changes allow Iodine to serve media files (such as movies) while suffering a smaller memory penalty and supporting a wider variaty of players (Safari requires Range request support for it's media player).
@@ -1,4 +1,4 @@
1
- require 'iodine/http'
1
+ Iodine.protocol = :client if require('iodine/http') && Iodine.protocol == Iodine::Http::Http1
2
2
 
3
3
  module Iodine
4
4
  # # Connect to a remote server or network socket
@@ -8,5 +8,3 @@ module Iodine
8
8
  # end
9
9
  end
10
10
 
11
- Iodine.protocol = :client
12
-
@@ -180,4 +180,4 @@ module Iodine
180
180
  q << arr.shift until arr.empty?
181
181
  end
182
182
  end
183
- Iodine.protocol = ::Iodine::Http::Http1
183
+ Iodine.protocol = ::Iodine::Http::Http1 unless Iodine.protocol
@@ -32,6 +32,7 @@ module Iodine
32
32
  # Due to different considirations, all keys will be converted to strings, so that `"name" == :name` and `1234 == "1234"`.
33
33
  # If you store two keys that evaluate as the same string, they WILL override each other.
34
34
  def []= key, value
35
+ return delete key if value.nil?
35
36
  key = key.to_s
36
37
  load
37
38
  @data[key] = value
@@ -46,10 +47,16 @@ module Iodine
46
47
  @data.dup
47
48
  end
48
49
 
50
+ # @return [String] returns the Session data in YAML format.
51
+ def to_s
52
+ load
53
+ @data.to_yaml
54
+ end
55
+
49
56
  # Removes a key from the session's data store.
50
57
  def delete key
51
58
  load
52
- ret = @data.delete key
59
+ ret = @data.delete key.to_s
53
60
  save
54
61
  ret
55
62
  end
@@ -57,16 +64,19 @@ module Iodine
57
64
  # Clears the session's data.
58
65
  def clear
59
66
  @data.clear
60
- save
61
67
  nil
62
68
  end
63
69
  protected
70
+ # def destroy
71
+ # # save data to tmp-file
72
+ # File.delete @filename if ::File.file?(@filename) # && !::File.directory?(@filename)
73
+ # end
64
74
  def save
65
75
  # save data to tmp-file
66
76
  IO.write @filename, @data.to_yaml
67
77
  end
68
78
  def load
69
- @data = YAML.load IO.read(@filename) if File.exists?(@filename)
79
+ @data = YAML.load IO.read(@filename) if ::File.file?(@filename)
70
80
  end
71
81
  end
72
82
  def self.fetch key
@@ -91,15 +91,6 @@ module Iodine
91
91
  @renew = 0
92
92
  end
93
93
 
94
- # Sends data through the socket. a shortcut for ws_client.response <<
95
- #
96
- # @return [true, false] Returns the true if the data was actually sent or nil if no data was sent.
97
- def << data
98
- raise 'Cannot send data when the connection is closed.' if closed?
99
- @io << data
100
- end
101
- alias :write :<<
102
-
103
94
  # closes the connection, if open
104
95
  def close
105
96
  @io.close if @io
@@ -124,6 +115,44 @@ module Iodine
124
115
  @request.cookies
125
116
  end
126
117
 
118
+ # Sends data through the websocket, after client side masking.
119
+ #
120
+ # @return [true, false] Returns the true if the data was actually sent or nil if no data was sent.
121
+ def write data, op_code = nil, fin = true, ext = 0
122
+ return false if !data || data.empty?
123
+ return false if @io.closed?
124
+ data = data.dup # needed?
125
+ unless op_code # apply extenetions to the message as a whole
126
+ op_code = (data.encoding == ::Encoding::UTF_8 ? 1 : 2)
127
+ # @ws_extentions.each { |ex| ext |= ex.edit_message data } if @ws_extentions
128
+ end
129
+ byte_size = data.bytesize
130
+ if byte_size > (::Iodine::Http::Websockets::FRAME_SIZE_LIMIT+2)
131
+ sections = byte_size/FRAME_SIZE_LIMIT + (byte_size % ::Iodine::Http::Websockets::FRAME_SIZE_LIMIT ? 1 : 0)
132
+ send_data( data.slice!( 0...::Iodine::Http::Websockets::FRAME_SIZE_LIMIT ), op_code, data.empty?, ext) && (ext = op_code = 0) until data.empty?
133
+ return true # avoid sending an empty frame.
134
+ end
135
+ # @ws_extentions.each { |ex| ext |= ex.edit_frame data } if @ws_extentions
136
+ header = ( (fin ? 0b10000000 : 0) | (op_code & 0b00001111) | ext).chr.force_encoding(::Encoding::ASCII_8BIT)
137
+
138
+ if byte_size < 125
139
+ header << (byte_size | 128).chr
140
+ elsif byte_size.bit_length <= 16
141
+ header << 254.chr
142
+ header << [byte_size].pack('S>'.freeze)
143
+ else
144
+ header << 255.chr
145
+ header << [byte_size].pack('Q>'.freeze)
146
+ end
147
+ @@make_mask_proc ||= Proc.new {Random.rand(251) + 1}
148
+ mask = Array.new(4, &(@@make_mask_proc))
149
+ header << mask.pack('C*'.freeze)
150
+ @io.write header
151
+ i = -1;
152
+ @io.write(data.bytes.map! {|b| (b ^ mask[i = (i + 1)%4]) } .pack('C*'.freeze)) && true
153
+ end
154
+ alias :<< :write
155
+
127
156
  # Create a simple Websocket Client(!).
128
157
  #
129
158
  # This method accepts two parameters:
@@ -179,6 +208,7 @@ module Iodine
179
208
  #
180
209
  # @return [Iodine::Http::WebsocketClient] this method returns the connected {Iodine::Http::WebsocketClient} or raises an exception if something went wrong (such as a connection timeout).
181
210
  def self.connect url, options={}, &block
211
+ @message ||= Iodine.warn("Deprecation Notice:\nIt is unlikely that Iodine 0.2.0 will support a blocking websocket client API.\nMake sure to use Iodine::Http.ws_connect and define an 'on_open' callback.") && true
182
212
  socket = nil
183
213
  options = options.dup
184
214
  options[:on_message] ||= block
@@ -262,7 +262,9 @@ module Iodine
262
262
  parser[:body] << tmp
263
263
  end
264
264
  if parser[:body].bytesize >= parser[:len]
265
- parser[:body].bytesize.times {|i| parser[:body][i] = (parser[:body][i].ord ^ parser[:mask_key][i % 4]).chr} if parser[:mask] == 1
265
+ tmp = -1
266
+ parser[:body] = parser[:body].bytes.map! {|b| (b ^ parser[:mask_key][tmp = (tmp + 1)%4]) } .pack('C*'.freeze) if parser[:mask] == 1
267
+ # parser[:body].bytesize.times {|i| parser[:body][i] = (parser[:body][i].ord ^ parser[:mask_key][i % 4]).chr} if parser[:mask] == 1
266
268
  parser[:stage] = 99
267
269
  end
268
270
  end
@@ -1,3 +1,3 @@
1
1
  module Iodine
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
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.5
4
+ version: 0.1.6
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-26 00:00:00.000000000 Z
11
+ date: 2015-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler