iodine 0.1.12 → 0.1.13
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 +12 -0
- data/lib/iodine/core.rb +1 -1
- data/lib/iodine/core_init.rb +3 -3
- data/lib/iodine/http/hpack.rb +12 -12
- data/lib/iodine/http/http1.rb +13 -13
- data/lib/iodine/http/http2.rb +8 -8
- data/lib/iodine/http/rack_support.rb +13 -13
- data/lib/iodine/http/request.rb +16 -16
- data/lib/iodine/http/response.rb +50 -22
- data/lib/iodine/http/websocket_client.rb +14 -19
- data/lib/iodine/http/websockets.rb +7 -7
- data/lib/iodine/protocol.rb +2 -2
- data/lib/iodine/settings.rb +1 -1
- data/lib/iodine/ssl_connector.rb +1 -1
- data/lib/iodine/timers.rb +1 -1
- 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: 7fbbba2f03bc0eb7a52c6516a640eda4094230b7
|
4
|
+
data.tar.gz: bb2b8b42038b32af81a6fa63b8ee3627fc47ef69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8f093d5101e34538a205a2f4aa996781c6bde02838cde091885ae37c6d8bcfd346590824d6ea15ec825194d713eb30cea0b9cf8d1c256dde8c30da372019cd8
|
7
|
+
data.tar.gz: e432d26f6af2a463737adff4ffbe8abf54486f61a4d9a475c544ee2c2316c2d8d72fe97fe486a2d701619e73a45afc041c2b2ad2b6bc800901f923192e1a9976
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,18 @@ 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.13
|
12
|
+
|
13
|
+
**Change**: Session cookie lifetime is now limited to the browser's session. The local data will still persist until the tmp-folder is cleared (when using session file storage).
|
14
|
+
|
15
|
+
**Fix**: renamed the SSL session token so that the SSL session id isn't lost when a non-secure session is used.
|
16
|
+
|
17
|
+
**Fix**: The `flash` cookie-jar will now actively prevent Symbol and String keys from overlapping.
|
18
|
+
|
19
|
+
**Compatibility**: minor fixes and changes in preperation for Ruby 2.3.0.
|
20
|
+
|
21
|
+
***
|
22
|
+
|
11
23
|
Change log v.0.1.12
|
12
24
|
|
13
25
|
**Update**: Passing a hash as the cookie value will allow to set cookie parameters using the {Response#set_cookie} options. i.e.: `cookies['key']= {value: "lock", max_age: 20}`.
|
data/lib/iodine/core.rb
CHANGED
data/lib/iodine/core_init.rb
CHANGED
@@ -55,8 +55,8 @@ module Iodine
|
|
55
55
|
if @queue.empty?
|
56
56
|
#clear any closed IO objects.
|
57
57
|
@time = Time.now
|
58
|
-
@ios.keys.each
|
59
|
-
@ios.values.each
|
58
|
+
@ios.keys.each(&@status_loop)
|
59
|
+
@ios.values.each(&@timeout_proc)
|
60
60
|
until @io_in.empty?
|
61
61
|
n_io = @io_in.pop
|
62
62
|
@ios[n_io[0]] = n_io[1]
|
@@ -70,7 +70,7 @@ module Iodine
|
|
70
70
|
begin
|
71
71
|
r = IO.select(@ios.keys, nil, nil, 0.15)
|
72
72
|
r[0].each {|io| @queue << [@ios[io]] } if r
|
73
|
-
rescue
|
73
|
+
rescue
|
74
74
|
|
75
75
|
end
|
76
76
|
unless @stop && @queue.empty?
|
data/lib/iodine/http/hpack.rb
CHANGED
@@ -66,13 +66,13 @@ module Iodine
|
|
66
66
|
data = StringIO.new data
|
67
67
|
results = {}
|
68
68
|
while (field = decode_field(data))
|
69
|
-
name = (field[0].is_a?(String) && field[0][0] == ':') ? field[0][1..-1].to_sym : field[0]
|
69
|
+
name = (field[0].is_a?(String) && field[0][0] == ':'.freeze) ? field[0][1..-1].to_sym : field[0]
|
70
70
|
results[name] ? (results[name].is_a?(String) ? (results[name] = [results[name], field[1]]) : (results[name] << field[1]) ) : (results[name] = field[1]) if field[1]
|
71
71
|
end
|
72
72
|
results
|
73
73
|
end
|
74
74
|
def encode headers = {}
|
75
|
-
buffer =
|
75
|
+
buffer = String.new.force_encoding(::Encoding::ASCII_8BIT)
|
76
76
|
headers.each {|k, v| buffer << encode_field( (k.is_a?(String) ? k : ":#{k.to_s}".freeze) ,v) if v}
|
77
77
|
buffer.force_encoding(::Encoding::ASCII_8BIT)
|
78
78
|
end
|
@@ -121,10 +121,10 @@ module Iodine
|
|
121
121
|
if value.is_a?(Array)
|
122
122
|
return (value.map {|v| encode_field name, v} .join)
|
123
123
|
end
|
124
|
-
raise "Http/2 headers must be LOWERCASE Strings!" if name[0] =~ /[A-Z]/n
|
124
|
+
raise "Http/2 headers must be LOWERCASE Strings!" if name[0] =~ /[A-Z]/n.freeze
|
125
125
|
value = value.to_s
|
126
|
-
if name == 'set-cookie'
|
127
|
-
buffer =
|
126
|
+
if name == 'set-cookie'.freeze
|
127
|
+
buffer = String.new.force_encoding ::Encoding::ASCII_8BIT
|
128
128
|
buffer << pack_number( 55, 1, 4)
|
129
129
|
buffer << pack_string(value)
|
130
130
|
return buffer
|
@@ -132,11 +132,11 @@ module Iodine
|
|
132
132
|
index = @encoding_list.find(name, value)
|
133
133
|
return pack_number( index, 1, 1) if index
|
134
134
|
index = @encoding_list.find_name name
|
135
|
-
buffer =
|
135
|
+
buffer = String.new.force_encoding(::Encoding::ASCII_8BIT)
|
136
136
|
if index
|
137
137
|
buffer << pack_number( index, 1, 2)
|
138
138
|
else
|
139
|
-
raise "Http/2 headers whould be Strings! or allowed Psedo-Header Symbol Only!" if name[0] == ':'
|
139
|
+
raise "Http/2 headers whould be Strings! or allowed Psedo-Header Symbol Only!" if name[0] == ':'.freeze
|
140
140
|
buffer << pack_number( 0, 1, 2)
|
141
141
|
buffer << pack_string(name)
|
142
142
|
end
|
@@ -193,8 +193,8 @@ module Iodine
|
|
193
193
|
end
|
194
194
|
def inflate data
|
195
195
|
data = StringIO.new data
|
196
|
-
str =
|
197
|
-
buffer =
|
196
|
+
str = String.new
|
197
|
+
buffer = String.new
|
198
198
|
until data.eof?
|
199
199
|
byte = data.getbyte
|
200
200
|
8.times do |i|
|
@@ -209,8 +209,8 @@ module Iodine
|
|
209
209
|
str
|
210
210
|
end
|
211
211
|
def deflate data
|
212
|
-
str =
|
213
|
-
buffer =
|
212
|
+
str = String.new.force_encoding ::Encoding::ASCII_8BIT
|
213
|
+
buffer = String.new.force_encoding ::Encoding::ASCII_8BIT
|
214
214
|
data.bytes.each do |i|
|
215
215
|
buffer << HUFFMAN.key(i)
|
216
216
|
if (buffer.bytesize % 8) == 0
|
@@ -219,7 +219,7 @@ module Iodine
|
|
219
219
|
end
|
220
220
|
end
|
221
221
|
unless buffer.empty?
|
222
|
-
(8-(buffer.bytesize % 8)).times { buffer << '1'} if (buffer.bytesize % 8)
|
222
|
+
(8-(buffer.bytesize % 8)).times { buffer << '1'.freeze} if (buffer.bytesize % 8)
|
223
223
|
str << [buffer].pack('B*'.freeze)
|
224
224
|
buffer.clear
|
225
225
|
end
|
data/lib/iodine/http/http1.rb
CHANGED
@@ -22,22 +22,22 @@ module Iodine
|
|
22
22
|
return close
|
23
23
|
end
|
24
24
|
next if l.empty?
|
25
|
-
request[:method], request[:query], request[:version] = l.split(/[\s]
|
25
|
+
request[:method], request[:query], request[:version] = l.split(/[\s]+/.freeze, 3)
|
26
26
|
return (Iodine.warn('Htt1 Protocol Error, closing connection.') && close) unless request[:method] =~ HTTP_METHODS_REGEXP
|
27
|
-
request[:version] = (request[:version] || '1.1'.freeze).match(/[\d\.]
|
27
|
+
request[:version] = (request[:version] || '1.1'.freeze).match(/[\d\.]+/.freeze)[0]
|
28
28
|
request[:time_recieved] = Time.now
|
29
29
|
end
|
30
30
|
until request[:headers_complete] || (l = data.gets).nil?
|
31
|
-
if l.include? ':'
|
31
|
+
if l.include? ':'.freeze
|
32
32
|
# n = l.slice!(0, l.index(':')); l.slice! 0
|
33
33
|
# n.strip! ; n.downcase!; n.freeze
|
34
34
|
# request[n] ? (request[n].is_a?(Array) ? (request[n] << l) : request[n] = [request[n], l ]) : (request[n] = l)
|
35
35
|
request[:headers_size] ||= 0
|
36
36
|
request[:headers_size] += l.bytesize
|
37
|
-
l = l.strip.split(/:[\s]
|
37
|
+
l = l.strip.split(/:[\s]?/.freeze, 2)
|
38
38
|
l[0].strip! ; l[0].downcase!;
|
39
39
|
request[l[0]] ? (request[l[0]].is_a?(Array) ? (request[l[0]] << l[1]) : request[l[0]] = [request[l[0]], l[1] ]) : (request[l[0]] = l[1])
|
40
|
-
elsif l =~ /^[\r]?\n
|
40
|
+
elsif l =~ /^[\r]?\n/.freeze
|
41
41
|
request[:headers_complete] = true
|
42
42
|
else
|
43
43
|
#protocol error
|
@@ -102,10 +102,10 @@ module Iodine
|
|
102
102
|
headers['content-length'.freeze] ||= body.size if body
|
103
103
|
|
104
104
|
keep_alive = response.keep_alive
|
105
|
-
if (request[:version].to_f > 1 && request['connection'.freeze].nil?) || request['connection'.freeze].to_s =~ /ke/i || (headers['connection'.freeze] && headers['connection'.freeze] =~ /^ke/i)
|
105
|
+
if (request[:version].to_f > 1 && request['connection'.freeze].nil?) || request['connection'.freeze].to_s =~ /ke/i.freeze || (headers['connection'.freeze] && headers['connection'.freeze] =~ /^ke/i.freeze)
|
106
106
|
keep_alive = true
|
107
107
|
headers['connection'.freeze] ||= 'keep-alive'.freeze
|
108
|
-
headers['keep-alive'.freeze] ||= "timeout=#{(@timeout ||= 3).to_s}"
|
108
|
+
headers['keep-alive'.freeze] ||= "timeout=#{(@timeout ||= 3).to_s}".freeze
|
109
109
|
else
|
110
110
|
headers['connection'.freeze] ||= 'close'.freeze
|
111
111
|
end
|
@@ -115,7 +115,7 @@ module Iodine
|
|
115
115
|
buffer = String.new
|
116
116
|
until body.eof?
|
117
117
|
written = write(body.read 65_536, buffer)
|
118
|
-
return Iodine.warn("Http/1 couldn't send response because connection was lost.") && body.close unless written
|
118
|
+
return Iodine.warn("Http/1 couldn't send response because connection was lost.".freeze) && body.close unless written
|
119
119
|
response.bytes_written += written
|
120
120
|
end
|
121
121
|
body.close
|
@@ -124,9 +124,9 @@ module Iodine
|
|
124
124
|
log_finished response
|
125
125
|
end
|
126
126
|
def stream_response response, finish = false
|
127
|
-
|
127
|
+
set_timeout 15
|
128
128
|
unless response.headers.frozen?
|
129
|
-
response['transfer-encoding'.freeze] = 'chunked'
|
129
|
+
response['transfer-encoding'.freeze] = 'chunked'.freeze
|
130
130
|
response.headers['connection'.freeze] = 'close'.freeze
|
131
131
|
send_headers response
|
132
132
|
@refuse_requests = true
|
@@ -136,11 +136,11 @@ module Iodine
|
|
136
136
|
buffer = String.new
|
137
137
|
until body.eof?
|
138
138
|
written = stream_data(body.read 65_536, buffer)
|
139
|
-
return Iodine.warn("Http/1 couldn't send response because connection was lost.") && body.close unless written
|
139
|
+
return Iodine.warn("Http/1 couldn't send response because connection was lost.".freeze) && body.close unless written
|
140
140
|
response.bytes_written += written
|
141
141
|
end if body
|
142
142
|
if finish
|
143
|
-
response.bytes_written += stream_data('')
|
143
|
+
response.bytes_written += stream_data(''.freeze)
|
144
144
|
log_finished response
|
145
145
|
close unless response.keep_alive
|
146
146
|
end
|
@@ -166,7 +166,7 @@ module Iodine
|
|
166
166
|
when 'OPTIONS'.freeze
|
167
167
|
response = ::Iodine::Http::Response.new request
|
168
168
|
response[:Allow] = 'GET,HEAD,POST,PUT,DELETE,OPTIONS'.freeze
|
169
|
-
response['access-control-allow-origin'.freeze] = '*'
|
169
|
+
response['access-control-allow-origin'.freeze] = '*'.freeze
|
170
170
|
response['content-length'.freeze] = 0
|
171
171
|
send_response response
|
172
172
|
return false
|
data/lib/iodine/http/http2.rb
CHANGED
@@ -12,7 +12,7 @@ module Iodine
|
|
12
12
|
@hpack = ::Iodine::Http::Http2::HPACK.new
|
13
13
|
|
14
14
|
# the header-stream cache
|
15
|
-
@header_buffer =
|
15
|
+
@header_buffer = String.new
|
16
16
|
@header_end_stream = false
|
17
17
|
@header_sid = nil
|
18
18
|
@frame_locker = Mutex.new
|
@@ -74,7 +74,7 @@ module Iodine
|
|
74
74
|
body.close
|
75
75
|
buffer.clear
|
76
76
|
else
|
77
|
-
emit_payload('', request[:sid], 0, 1)
|
77
|
+
emit_payload(''.freeze, request[:sid], 0, 1)
|
78
78
|
end
|
79
79
|
log_finished response
|
80
80
|
end
|
@@ -92,7 +92,7 @@ module Iodine
|
|
92
92
|
buffer.clear
|
93
93
|
body.close
|
94
94
|
elsif finish
|
95
|
-
emit_payload('', request[:sid], 0, 1)
|
95
|
+
emit_payload(''.freeze, request[:sid], 0, 1)
|
96
96
|
end
|
97
97
|
log_finished response if finish
|
98
98
|
end
|
@@ -195,7 +195,7 @@ module Iodine
|
|
195
195
|
return (connection_error(PROTOCOL_ERROR) && Iodine.warn("Preface not given"))
|
196
196
|
end
|
197
197
|
@connected = true
|
198
|
-
emit_frame '', 0, 0x4
|
198
|
+
emit_frame ''.freeze, 0, 0x4
|
199
199
|
true
|
200
200
|
end
|
201
201
|
|
@@ -222,14 +222,14 @@ module Iodine
|
|
222
222
|
frame[:flags] = tmp.ord
|
223
223
|
end
|
224
224
|
unless frame[:sid]
|
225
|
-
tmp = (frame[:sid_bytes] ||=
|
225
|
+
tmp = (frame[:sid_bytes] ||= String.new)
|
226
226
|
tmp << data.read(4 - tmp.bytesize).to_s
|
227
227
|
return false if tmp.bytesize < 4
|
228
228
|
tmp = frame.delete(:sid_bytes).unpack('N')[0]
|
229
229
|
frame[:sid] = tmp & 2147483647
|
230
230
|
frame[:R] = tmp & 2147483648
|
231
231
|
end
|
232
|
-
tmp = (frame[:body] ||=
|
232
|
+
tmp = (frame[:body] ||= String.new)
|
233
233
|
tmp << data.read(frame[:length] - tmp.bytesize).to_s
|
234
234
|
return false if tmp.bytesize < frame[:length]
|
235
235
|
#TODO: something - Async?
|
@@ -257,7 +257,7 @@ module Iodine
|
|
257
257
|
process_ping frame
|
258
258
|
when 7 # GOAWAY
|
259
259
|
go_away NO_ERROR
|
260
|
-
Iodine.error "Http2 Disconnection with error (#{frame[:flags].to_s}): #{frame[:body].strip}" unless frame[:flags] == 0 && frame[:body] == ''
|
260
|
+
Iodine.error "Http2 Disconnection with error (#{frame[:flags].to_s}): #{frame[:body].strip}" unless frame[:flags] == 0 && frame[:body] == ''.freeze
|
261
261
|
when 8 # WINDOW_UPDATE
|
262
262
|
else # Error, frame not recognized
|
263
263
|
end
|
@@ -402,7 +402,7 @@ module Iodine
|
|
402
402
|
# Unsupported parameters MUST be ignored
|
403
403
|
end
|
404
404
|
end
|
405
|
-
emit_frame '', 0, 4, 1
|
405
|
+
emit_frame ''.freeze, 0, 4, 1
|
406
406
|
end
|
407
407
|
|
408
408
|
def process_request request
|
@@ -8,7 +8,7 @@ module Iodine
|
|
8
8
|
@app = app
|
9
9
|
Iodine.threads ||= 18
|
10
10
|
Iodine.port = options[:Port]
|
11
|
-
RACK_DICTIONARY['rack.multiprocess'] = Iodine.processes.to_i > 1
|
11
|
+
RACK_DICTIONARY['rack.multiprocess'.freeze] = Iodine.processes.to_i > 1
|
12
12
|
Iodine.protocol ||= Iodine::Http::Http1
|
13
13
|
@pre_rack_handler = Iodine::Http.on_http unless Iodine::Http.on_http == Iodine::Http::NOT_IMPLEMENTED
|
14
14
|
Iodine::Http.on_http self
|
@@ -27,7 +27,7 @@ module Iodine
|
|
27
27
|
res[1].each {|k, v| response.headers[k.to_s.downcase] = v }
|
28
28
|
response.body = res[2]
|
29
29
|
response.raw_cookies.clear
|
30
|
-
response.headers['set-cookie'] = response.headers.delete('set-cookie').split("\n").join("\r\nset-cookie: ") if request[:io].is_a?(Iodine::Http::Http1) && response.headers['set-cookie']
|
30
|
+
response.headers['set-cookie'.freeze] = response.headers.delete('set-cookie'.freeze).split("\n".freeze).join("\r\nset-cookie: ".freeze) if request[:io].is_a?(Iodine::Http::Http1) && response.headers['set-cookie'.freeze]
|
31
31
|
response.request[:no_log] = true
|
32
32
|
true
|
33
33
|
end
|
@@ -41,12 +41,12 @@ module Iodine
|
|
41
41
|
# env.each {|k, v| env[k] = @request[v] if v.is_a?(Symbol)}
|
42
42
|
RACK_ADDON.each {|k, v| env[k] = (request[v].is_a?(String) ? ( request[v].frozen? ? request[v].dup.force_encoding('ASCII-8BIT') : request[v].force_encoding('ASCII-8BIT') ): request[v])}
|
43
43
|
request.each {|k, v| env["HTTP_#{k.upcase.tr('-', '_')}"] = v if k.is_a?(String) }
|
44
|
-
env['rack.input'.freeze] ||= request[:body] || StringIO.new(''.force_encoding('ASCII-8BIT'.freeze))
|
44
|
+
env['rack.input'.freeze] ||= request[:body] || StringIO.new(''.force_encoding('ASCII-8BIT'.freeze).freeze)
|
45
45
|
env['CONTENT_LENGTH'.freeze] = env.delete 'HTTP_CONTENT_LENGTH'.freeze if env['HTTP_CONTENT_LENGTH'.freeze]
|
46
46
|
env['CONTENT_TYPE'.freeze] = env.delete 'HTTP_CONTENT_TYPE'.freeze if env['HTTP_CONTENT_TYPE'.freeze]
|
47
|
-
env['HTTP_VERSION'.freeze] = "HTTP/#{request[:version].to_s}"
|
48
|
-
env['QUERY_STRING'.freeze] ||= ''
|
49
|
-
env['rack.errors'.freeze] = StringIO.new('')
|
47
|
+
env['HTTP_VERSION'.freeze] = "HTTP/#{request[:version].to_s}".freeze
|
48
|
+
env['QUERY_STRING'.freeze] ||= ''.freeze
|
49
|
+
env['rack.errors'.freeze] = StringIO.new(''.freeze)
|
50
50
|
# should unchain cookies from Array to String
|
51
51
|
env['HTTP_COOKIE'] = env['HTTP_COOKIE'].join '; ' if env['HTTP_COOKIE'].is_a?(Array)
|
52
52
|
env
|
@@ -68,9 +68,9 @@ module Iodine
|
|
68
68
|
}
|
69
69
|
|
70
70
|
RACK_DICTIONARY = {
|
71
|
-
"GATEWAY_INTERFACE" =>"CGI/1.2",
|
72
|
-
'SERVER_SOFTWARE' => "Iodine v. #{Iodine::VERSION}",
|
73
|
-
'SCRIPT_NAME' => ''.force_encoding('ASCII-8BIT'),
|
71
|
+
"GATEWAY_INTERFACE" =>"CGI/1.2".freeze,
|
72
|
+
'SERVER_SOFTWARE' => "Iodine v. #{Iodine::VERSION}".freeze,
|
73
|
+
'SCRIPT_NAME' => ''.force_encoding('ASCII-8BIT'.freeze).freeze,
|
74
74
|
'rack.logger' => Iodine,
|
75
75
|
'rack.multithread' => true,
|
76
76
|
'rack.multiprocess' => false,
|
@@ -78,19 +78,19 @@ module Iodine
|
|
78
78
|
# 'rack.hijack_io' => nil,
|
79
79
|
'rack.run_once' => false
|
80
80
|
}
|
81
|
-
RACK_DICTIONARY['rack.version'] = ::Rack.version.split('.') if defined?(::Rack)
|
82
|
-
HASH_SYM_PROC = Proc.new {|h,k| k = (Symbol === k ? k.to_s : k.to_s.to_sym); h.has_key?(k) ? h[k] : (h["
|
81
|
+
RACK_DICTIONARY['rack.version'.freeze] = ::Rack.version.split('.'.freeze) if defined?(::Rack)
|
82
|
+
HASH_SYM_PROC = Proc.new {|h,k| k = (Symbol === k ? k.to_s : k.to_s.to_sym); h.has_key?(k) ? h[k] : (h["iodine.#{k.to_s}"] if h.has_key?("iodine.#{k.to_s}") ) }
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
-
# ENV["RACK_HANDLER"] = '
|
87
|
+
# ENV["RACK_HANDLER"] = 'iodine'
|
88
88
|
|
89
89
|
# make Iodine the default fallback position for Rack.
|
90
90
|
begin
|
91
91
|
require 'rack/handler'
|
92
92
|
Rack::Handler::WEBrick = Rack::Handler.get(:iodine)
|
93
|
-
rescue Exception
|
93
|
+
rescue Exception
|
94
94
|
|
95
95
|
end
|
96
96
|
::Rack::Handler.register( 'iodine', 'Iodine::Http::Rack') if defined?(::Rack)
|
data/lib/iodine/http/request.rb
CHANGED
@@ -22,7 +22,7 @@ module Iodine
|
|
22
22
|
end
|
23
23
|
# overrides the []= method to set the cookie for the response (by encoding it and preparing it to be sent), as well as to save the cookie in the combined cookie jar (unencoded and available).
|
24
24
|
def []= key, val
|
25
|
-
return super unless @response
|
25
|
+
return super unless instance_variable_defined?(:@response) && @response
|
26
26
|
if key.is_a?(Symbol) && self.has_key?( key.to_s)
|
27
27
|
key = key.to_s
|
28
28
|
elsif self.has_key?( key.to_s.to_sym)
|
@@ -98,12 +98,12 @@ module Iodine
|
|
98
98
|
|
99
99
|
# the base url ([http/https]://host[:port])
|
100
100
|
def base_url switch_scheme = nil
|
101
|
-
"#{switch_scheme || self[:scheme]}://#{self[:host_name]}#{self[:port]? ":#{self[:port]}" : ''}"
|
101
|
+
"#{switch_scheme || self[:scheme]}://#{self[:host_name]}#{self[:port]? ":#{self[:port]}" : ''.freeze}".freeze
|
102
102
|
end
|
103
103
|
|
104
104
|
# the request's url, without any GET parameters ([http/https]://host[:port]/path)
|
105
105
|
def request_url switch_scheme = nil
|
106
|
-
"#{base_url switch_scheme}#{self[:original_path]}"
|
106
|
+
"#{base_url switch_scheme}#{self[:original_path]}".freeze
|
107
107
|
end
|
108
108
|
|
109
109
|
# the protocol's scheme (http/https/ws/wss) managing this request
|
@@ -213,12 +213,12 @@ module Iodine
|
|
213
213
|
request[:version] ||= '1'
|
214
214
|
|
215
215
|
request[:scheme] ||= request['x-forwarded-proto'.freeze] ? request['x-forwarded-proto'.freeze].downcase : ( request[:io].ssl? ? 'https'.freeze : 'http'.freeze)
|
216
|
-
tmp = (request['host'.freeze] || request[:authority] || ''.freeze).split(':')
|
216
|
+
tmp = (request['host'.freeze] || request[:authority] || ''.freeze).split(':'.freeze)
|
217
217
|
request[:host_name] = tmp[0]
|
218
218
|
request[:port] = tmp[1] || nil
|
219
219
|
|
220
|
-
tmp = (request[:query] ||= request[:path] ).split('?', 2)
|
221
|
-
request[:path] = tmp[0].chomp('/')
|
220
|
+
tmp = (request[:query] ||= request[:path] ).split('?'.freeze, 2)
|
221
|
+
request[:path] = tmp[0].chomp('/'.freeze)
|
222
222
|
request[:original_path] = tmp[0].freeze
|
223
223
|
request[:quary_params] = tmp[1]
|
224
224
|
extract_params tmp[1].split(/[&;]/.freeze), (request[:params] ||= {}) if tmp[1]
|
@@ -313,7 +313,7 @@ module Iodine
|
|
313
313
|
end
|
314
314
|
# decode form / uri data (including the '+' sign as a space (%20) replacement).
|
315
315
|
def self.uri_decode! s
|
316
|
-
s.gsub!('+'.freeze, '%20'.freeze); s.gsub!(/\%[0-9a-f]{2}/i) {|m| m[1..2].to_i(16).chr}; s.gsub!(/&#[0-9]{4};/i) {|m| [m[2..5].to_i].pack 'U'.freeze }; s
|
316
|
+
s.gsub!('+'.freeze, '%20'.freeze); s.gsub!(/\%[0-9a-f]{2}/i.freeze) {|m| m[1..2].to_i(16).chr}; s.gsub!(/&#[0-9]{4};/i.freeze) {|m| [m[2..5].to_i].pack 'U'.freeze }; s
|
317
317
|
end
|
318
318
|
# extracts parameters from header data
|
319
319
|
def self.extract_header data, target_hash
|
@@ -325,7 +325,7 @@ module Iodine
|
|
325
325
|
end
|
326
326
|
# decode percent-encoded data (excluding the '+' sign for encoding).
|
327
327
|
def self.form_decode! s
|
328
|
-
s.gsub!(/\%[0-9a-f]{2}/i) {|m| m[1..2].to_i(16).chr}; s.gsub!(/&#[0-9]{4};/i) {|m| [m[2..5].to_i].pack 'U'.freeze }; s
|
328
|
+
s.gsub!(/\%[0-9a-f]{2}/i.freeze) {|m| m[1..2].to_i(16).chr}; s.gsub!(/&#[0-9]{4};/i.freeze) {|m| [m[2..5].to_i].pack 'U'.freeze }; s
|
329
329
|
end
|
330
330
|
# Changes String to a Ruby Object, if it's a special string...
|
331
331
|
def self.rubyfy!(string)
|
@@ -348,32 +348,32 @@ module Iodine
|
|
348
348
|
# parse content
|
349
349
|
request[:body].rewind
|
350
350
|
case request['content-type'.freeze].to_s
|
351
|
-
when /x-www-form-urlencoded
|
351
|
+
when /x-www-form-urlencoded/.freeze
|
352
352
|
extract_params request[:body].read.split(/[&;]/), request[:params] #, :form # :uri
|
353
|
-
when /multipart\/form-data
|
353
|
+
when /multipart\/form-data/.freeze
|
354
354
|
read_multipart request, request
|
355
|
-
when /text\/xml
|
355
|
+
when /text\/xml/.freeze
|
356
356
|
# to-do support xml?
|
357
357
|
# request[:xml] = make_utf8! request[:body].read
|
358
358
|
nil
|
359
|
-
when /application\/json
|
359
|
+
when /application\/json/.freeze
|
360
360
|
JSON.parse(make_utf8! request[:body].read).each {|k, v| add_param_to_hash k, v, request[:params]} rescue true
|
361
361
|
end
|
362
362
|
request[:body].rewind if request[:body]
|
363
363
|
end
|
364
364
|
|
365
365
|
# parse a mime/multipart body or part.
|
366
|
-
def self.read_multipart request, headers = {}, boundary = [], name_prefix =
|
366
|
+
def self.read_multipart request, headers = {}, boundary = [], name_prefix = String.new
|
367
367
|
body = request[:body]
|
368
|
-
return unless headers['content-type'].to_s =~ /multipart/i
|
368
|
+
return unless headers['content-type'.freeze].to_s =~ /multipart/i.freeze
|
369
369
|
part_headers = {}
|
370
|
-
extract_header headers['content-type'].split(/[;,][\s]
|
370
|
+
extract_header headers['content-type'.freeze].split(/[;,][\s]?/.freeze), part_headers
|
371
371
|
boundary << part_headers[:boundary]
|
372
372
|
if part_headers[:name]
|
373
373
|
if name_prefix.empty?
|
374
374
|
name_prefix << part_headers[:name]
|
375
375
|
else
|
376
|
-
name_prefix << "[#{part_headers[:name]}]"
|
376
|
+
name_prefix << "[#{part_headers[:name]}]".freeze
|
377
377
|
end
|
378
378
|
end
|
379
379
|
part_headers.delete :name
|
data/lib/iodine/http/response.rb
CHANGED
@@ -4,6 +4,30 @@ module Iodine
|
|
4
4
|
#
|
5
5
|
# The response can be sent in stages but should complete within the scope of the connecton's message. Please notice that headers and status cannot be changed once the response started sending data.
|
6
6
|
class Response
|
7
|
+
# Makes sure that the `flash` cookie-jar doesn't have Symbols and Strings overlapping.
|
8
|
+
class Flash < ::Hash
|
9
|
+
# overrides the []= method to set the cookie for the response (by encoding it and preparing it to be sent), as well as to save the cookie in the combined cookie jar (unencoded and available).
|
10
|
+
def []= key, val
|
11
|
+
if key.is_a?(Symbol) && self.has_key?( key.to_s)
|
12
|
+
key = key.to_s
|
13
|
+
elsif self.has_key?( key.to_s.to_sym)
|
14
|
+
key = key.to_s.to_sym
|
15
|
+
end
|
16
|
+
super
|
17
|
+
end
|
18
|
+
# overrides th [] method to allow Symbols and Strings to mix and match
|
19
|
+
def [] key
|
20
|
+
if key.is_a?(Symbol) && self.has_key?( key.to_s)
|
21
|
+
key = key.to_s
|
22
|
+
elsif self.has_key?( key.to_s.to_sym)
|
23
|
+
key = key.to_s.to_sym
|
24
|
+
elsif self.has_key? "magic_flash_#{key.to_s}".freeze.to_sym
|
25
|
+
key = "magic_flash_#{key.to_s}".freeze.to_sym
|
26
|
+
end
|
27
|
+
super
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
7
31
|
# the response's status code
|
8
32
|
attr_accessor :status
|
9
33
|
# the response's headers
|
@@ -33,11 +57,9 @@ module Iodine
|
|
33
57
|
@bytes_written = 0
|
34
58
|
@keep_alive = @http_sblocks_count = false
|
35
59
|
# propegate flash object
|
36
|
-
@flash =
|
37
|
-
hs["magic_flash_#{k.to_s}".to_sym] if hs.has_key? "magic_flash_#{k.to_s}".to_sym
|
38
|
-
end
|
60
|
+
@flash = ::Iodine::Http::Response::Flash.new
|
39
61
|
request.cookies.each do |k,v|
|
40
|
-
@flash[k] = v if k.to_s.start_with? 'magic_flash_'
|
62
|
+
@flash[k] = v if k.to_s.start_with? 'magic_flash_'.freeze
|
41
63
|
end
|
42
64
|
end
|
43
65
|
|
@@ -83,7 +105,7 @@ module Iodine
|
|
83
105
|
Iodine.run block, &@stream_proc
|
84
106
|
end
|
85
107
|
|
86
|
-
# Creates nested streaming blocks for an Array
|
108
|
+
# Creates nested streaming blocks for an Array object (an object answering `#shift`). Once all streaming blocks are done, the response will automatically finish.
|
87
109
|
#
|
88
110
|
# Since streaming blocks might run in parallel, nesting the streaming blocks is important...
|
89
111
|
#
|
@@ -124,9 +146,15 @@ module Iodine
|
|
124
146
|
#
|
125
147
|
# @return [Hash like storage] creates and returns the session storage object with all the data from a previous connection.
|
126
148
|
def session
|
127
|
-
return @session if @session
|
128
|
-
|
129
|
-
|
149
|
+
return @session if instance_variable_defined?(:@session) && @session
|
150
|
+
if @request.ssl?
|
151
|
+
@@sec_session_token ||= "#{::Iodine::Http.session_token}_enc".freeze
|
152
|
+
id = @request.cookies[@@sec_session_token.to_sym] || SecureRandom.uuid
|
153
|
+
set_cookie @@sec_session_token, id, expires: :session, secure: true, http_only: true
|
154
|
+
else
|
155
|
+
id = @request.cookies[::Iodine::Http.session_token.to_sym] || SecureRandom.uuid
|
156
|
+
set_cookie ::Iodine::Http.session_token, id, expires: :session, http_only: true
|
157
|
+
end
|
130
158
|
@request[:session] = @session = ::Iodine::Http::SessionManager.get(id)
|
131
159
|
end
|
132
160
|
|
@@ -177,7 +205,7 @@ module Iodine
|
|
177
205
|
end
|
178
206
|
|
179
207
|
|
180
|
-
COOKIE_NAME_REGEXP = /[\x00-\x20\(\)\<\>@,;:\\\"\/\[\]\?\=\{\}\s]
|
208
|
+
COOKIE_NAME_REGEXP = /[\x00-\x20\(\)\<\>@,;:\\\"\/\[\]\?\=\{\}\s]/.freeze
|
181
209
|
|
182
210
|
# Sets/deletes cookies when headers are sent.
|
183
211
|
#
|
@@ -206,20 +234,20 @@ module Iodine
|
|
206
234
|
name = name.to_s
|
207
235
|
raise 'Illegal cookie name' if name =~ COOKIE_NAME_REGEXP
|
208
236
|
if value.nil?
|
209
|
-
params[:expires] = (
|
237
|
+
params[:expires] = (Iodine.time - 315360000)
|
210
238
|
value = 'deleted'.freeze
|
211
239
|
else
|
212
|
-
params[:expires] ||= (
|
240
|
+
params[:expires] ||= (Iodine.time + 315360000) unless params[:max_age]
|
213
241
|
end
|
214
242
|
params[:path] ||= '/'.freeze
|
215
243
|
value = Iodine::Http::Request.encode_url(value) # this dups the string
|
216
244
|
if params[:max_age]
|
217
|
-
value << ('; Max-Age=%s' % params[:max_age])
|
245
|
+
value << ('; Max-Age=%s'.freeze % params[:max_age])
|
218
246
|
else
|
219
|
-
value << ('; Expires=%s' % params[:expires].httpdate)
|
247
|
+
value << ('; Expires=%s'.freeze % params[:expires].httpdate) if params[:expires].is_a?(::Time)
|
220
248
|
end
|
221
|
-
value << "; Path=#{params[:path]}"
|
222
|
-
value << "; Domain=#{params[:domain]}" if params[:domain]
|
249
|
+
value << "; Path=#{params[:path]}".freeze
|
250
|
+
value << "; Domain=#{params[:domain]}".freeze if params[:domain]
|
223
251
|
value << '; Secure'.freeze if params[:secure]
|
224
252
|
value << '; HttpOnly'.freeze if params[:http_only]
|
225
253
|
@cookies[name.to_sym] = value
|
@@ -245,7 +273,7 @@ module Iodine
|
|
245
273
|
request.delete(:body).tap {|f| f.close unless f.respond_to?(:close) && f.closed? rescue false } if request[:body] && @http_sblocks_count.to_i == 0
|
246
274
|
end
|
247
275
|
|
248
|
-
# Returns the connection's UUID.
|
276
|
+
# Returns the connection's LOCAL UUID.
|
249
277
|
def uuid
|
250
278
|
request[:io].id
|
251
279
|
end
|
@@ -311,7 +339,7 @@ module Iodine
|
|
311
339
|
511=>"Network Authentication Required".freeze
|
312
340
|
}
|
313
341
|
|
314
|
-
# This will return the Body object as an IO like object, such as StringIO (or File)
|
342
|
+
# This will return the Body object as an IO like object, such as StringIO (or File) and set the body to `nil` (seeing as it was extracted from the response).
|
315
343
|
#
|
316
344
|
# This method will also attempts to set headers and update the response status in relation to the body, if applicable. Call this BEFORE getting any final data about the response or sending the headers.
|
317
345
|
def extract_body
|
@@ -327,7 +355,7 @@ module Iodine
|
|
327
355
|
elsif @body.is_a?(File) || @body.is_a?(Tempfile) || @body.is_a?(StringIO)
|
328
356
|
@body
|
329
357
|
elsif @body.respond_to? :each
|
330
|
-
tmp =
|
358
|
+
tmp = String.new
|
331
359
|
@body.each {|s| tmp << s}
|
332
360
|
@body.close if @body.respond_to? :close
|
333
361
|
@body = nil
|
@@ -338,7 +366,7 @@ module Iodine
|
|
338
366
|
body_io.rewind
|
339
367
|
|
340
368
|
if !(@headers.frozen?) && @request['range'.freeze] && @request.get? && @status == 200 && @headers['content-length'.freeze].nil?
|
341
|
-
r = @request['range'.freeze].match(/^bytes=([\d]+)\-([\d]+)?$/i)
|
369
|
+
r = @request['range'.freeze].match(/^bytes=([\d]+)\-([\d]+)?$/i.freeze)
|
342
370
|
if r
|
343
371
|
old_size = body_io.size
|
344
372
|
start_pos = r[1].to_i
|
@@ -353,9 +381,9 @@ module Iodine
|
|
353
381
|
body_io.rewind
|
354
382
|
end
|
355
383
|
@headers['content-range'.freeze] = "bytes #{start_pos}-#{end_pos}/#{old_size}"
|
356
|
-
@headers['accept-ranges'.freeze] ||= 'bytes'
|
384
|
+
@headers['accept-ranges'.freeze] ||= 'bytes'.freeze
|
357
385
|
else
|
358
|
-
@headers['accept-ranges'.freeze] ||= 'none'
|
386
|
+
@headers['accept-ranges'.freeze] ||= 'none'.freeze
|
359
387
|
end
|
360
388
|
end
|
361
389
|
|
@@ -374,7 +402,7 @@ module Iodine
|
|
374
402
|
end
|
375
403
|
#set new flash cookies
|
376
404
|
@flash.each do |k,v|
|
377
|
-
set_cookie "magic_flash_#{k.to_s}", v
|
405
|
+
set_cookie "magic_flash_#{k.to_s}".freeze, v
|
378
406
|
end
|
379
407
|
@cookies.freeze
|
380
408
|
# response.cookies.set_response nil
|
@@ -133,10 +133,6 @@ module Iodine
|
|
133
133
|
@request.ssl?
|
134
134
|
end
|
135
135
|
|
136
|
-
# return the HTTP's handshake data, including any cookies sent by the server.
|
137
|
-
def request
|
138
|
-
@request
|
139
|
-
end
|
140
136
|
# return a Hash with the HTTP cookies recieved during the HTTP's handshake.
|
141
137
|
def cookies
|
142
138
|
@request.cookies
|
@@ -154,7 +150,7 @@ module Iodine
|
|
154
150
|
end
|
155
151
|
byte_size = data.bytesize
|
156
152
|
if byte_size > (::Iodine::Http::Websockets::FRAME_SIZE_LIMIT+2)
|
157
|
-
sections = byte_size/FRAME_SIZE_LIMIT + (byte_size % ::Iodine::Http::Websockets::FRAME_SIZE_LIMIT ? 1 : 0)
|
153
|
+
# sections = byte_size/FRAME_SIZE_LIMIT + (byte_size % ::Iodine::Http::Websockets::FRAME_SIZE_LIMIT ? 1 : 0)
|
158
154
|
ret = write( data.slice!( 0...::Iodine::Http::Websockets::FRAME_SIZE_LIMIT ), op_code, data.empty?, ext) && (ext = op_code = 0) until data.empty?
|
159
155
|
return ret # avoid sending an empty frame.
|
160
156
|
end
|
@@ -205,20 +201,19 @@ module Iodine
|
|
205
201
|
ssl.connect
|
206
202
|
end
|
207
203
|
# prep custom headers
|
208
|
-
custom_headers =
|
204
|
+
custom_headers = String.new
|
209
205
|
custom_headers = @options[:headers] if @options[:headers].is_a?(String)
|
210
206
|
@options[:headers].each {|k, v| custom_headers << "#{k.to_s}: #{v.to_s}\r\n"} if @options[:headers].is_a?(Hash)
|
211
|
-
@options[:cookies].each {|k, v| raise 'Illegal cookie name' if k.to_s.match(/[\x00-\x20\(\)<>@,;:\\\"\/\[\]\?\=\{\}\s]
|
207
|
+
@options[:cookies].each {|k, v| raise 'Illegal cookie name' if k.to_s.match(/[\x00-\x20\(\)<>@,;:\\\"\/\[\]\?\=\{\}\s]/.freeze); custom_headers << "Cookie: #{ k }=#{ Iodine::Http::Request.encode_url v }\r\n"} if @options[:cookies].is_a?(Hash)
|
212
208
|
|
213
209
|
# send protocol upgrade request
|
214
|
-
websocket_key = [(Array.new(16) {rand 255} .pack 'c*' )].pack('m0*')
|
215
|
-
(ssl || socket).write "GET #{url.path}#{url.query.to_s.empty? ? '' : (
|
210
|
+
websocket_key = [(Array.new(16) {rand 255} .pack 'c*'.freeze )].pack('m0*'.freeze)
|
211
|
+
(ssl || socket).write "GET #{url.path}#{url.query.to_s.empty? ? ''.freeze : ("?#{url.query}")} HTTP/1.1\r\nHost: #{url.host}#{url.port ? (":#{url.port.to_s}") : ''.freeze}\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nOrigin: #{ssl ? 'https'.freeze : 'http'.freeze}://#{url.host}\r\nSec-WebSocket-Key: #{websocket_key}\r\nSec-WebSocket-Version: 13\r\n#{custom_headers}\r\n"
|
216
212
|
# wait for answer - make sure we don't over-read
|
217
213
|
# (a websocket message might be sent immidiately after connection is established)
|
218
|
-
reply =
|
219
|
-
reply.force_encoding(::Encoding::ASCII_8BIT)
|
214
|
+
reply = String.new.force_encoding(::Encoding::ASCII_8BIT)
|
220
215
|
stop_time = Time.now + (@options[:timeout] || 5)
|
221
|
-
stop_reply = "\r\n\r\n"
|
216
|
+
stop_reply = "\r\n\r\n".freeze
|
222
217
|
until reply[-4..-1] == stop_reply
|
223
218
|
begin
|
224
219
|
reply << ( ssl ? ssl.read_nonblock(1) : socket.recv_nonblock(1) )
|
@@ -230,24 +225,24 @@ module Iodine
|
|
230
225
|
raise "Connection failed" if socket.closed?
|
231
226
|
end
|
232
227
|
# review reply
|
233
|
-
raise "Connection Refused. Reply was:\r\n #{reply}" unless reply.lines[0].match(/^HTTP\/[\d\.]+ 101/i)
|
234
|
-
raise 'Websocket Key Authentication failed.' unless reply.match(/^Sec-WebSocket-Accept:[\s]*([^\s]*)/i) && reply.match(/^Sec-WebSocket-Accept:[\s]*([^\s]*)/i)[1] == Digest::SHA1.base64digest(websocket_key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
|
228
|
+
raise "Connection Refused. Reply was:\r\n #{reply}" unless reply.lines[0].match(/^HTTP\/[\d\.]+ 101/i.freeze)
|
229
|
+
raise 'Websocket Key Authentication failed.' unless reply.match(/^Sec-WebSocket-Accept:[\s]*([^\s]*)/i.freeze) && reply.match(/^Sec-WebSocket-Accept:[\s]*([^\s]*)/i.freeze)[1] == Digest::SHA1.base64digest(websocket_key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
|
235
230
|
# read the body's data and parse any incoming data.
|
236
231
|
@request = Iodine::Http::Request.new
|
237
|
-
@request[:method] = 'GET'
|
238
|
-
@request['host'] = "#{url.host}:#{url.port}"
|
232
|
+
@request[:method] = 'GET'.freeze
|
233
|
+
@request['host'.freeze] = "#{url.host}:#{url.port}"
|
239
234
|
@request[:query] = url.path
|
240
|
-
@request[:version] = '1.1'
|
235
|
+
@request[:version] = '1.1'.freeze
|
241
236
|
reply = StringIO.new reply
|
242
237
|
reply.gets
|
243
238
|
|
244
239
|
until reply.eof?
|
245
240
|
until @request[:headers_complete] || (l = reply.gets).nil?
|
246
241
|
if l.include? ':'
|
247
|
-
l = l.strip.split(/:[\s]
|
242
|
+
l = l.strip.split(/:[\s]?/.freeze, 2)
|
248
243
|
l[0].strip! ; l[0].downcase!;
|
249
244
|
@request[l[0]] ? (@request[l[0]].is_a?(Array) ? (@request[l[0]] << l[1]) : @request[l[0]] = [@request[l[0]], l[1] ]) : (@request[l[0]] = l[1])
|
250
|
-
elsif l =~ /^[\r]?\n
|
245
|
+
elsif l =~ /^[\r]?\n/.freeze
|
251
246
|
@request[:headers_complete] = true
|
252
247
|
else
|
253
248
|
#protocol error
|
@@ -6,8 +6,8 @@ module Iodine
|
|
6
6
|
@handler = @options[:handler]
|
7
7
|
@ws_extentions = @options[:ext]
|
8
8
|
@options[:request][:io] = self
|
9
|
-
@parser = {body:
|
10
|
-
set_timeout
|
9
|
+
@parser = {body: String.new, stage: 0, step: 0, mask_key: [], len_bytes: []}
|
10
|
+
set_timeout self.class.default_timeout
|
11
11
|
@handler.on_open if @handler.respond_to? :on_open
|
12
12
|
end
|
13
13
|
# parse and handle messages.
|
@@ -60,7 +60,7 @@ module Iodine
|
|
60
60
|
end
|
61
61
|
byte_size = data.bytesize
|
62
62
|
if byte_size > (FRAME_SIZE_LIMIT+2)
|
63
|
-
sections = byte_size/FRAME_SIZE_LIMIT + (byte_size%FRAME_SIZE_LIMIT ? 1 : 0)
|
63
|
+
# sections = byte_size/FRAME_SIZE_LIMIT + (byte_size%FRAME_SIZE_LIMIT ? 1 : 0)
|
64
64
|
send_data( data.slice!( 0...FRAME_SIZE_LIMIT ), op_code, data.empty?, ext) && (ext = op_code = 0) until data.empty?
|
65
65
|
return true # avoid sending an empty frame.
|
66
66
|
end
|
@@ -149,10 +149,10 @@ module Iodine
|
|
149
149
|
# and MUST NOT use them unless the server indicates that it wishes to use the extension.
|
150
150
|
ws_extentions = []
|
151
151
|
ext = []
|
152
|
-
request['sec-websocket-extensions'.freeze].to_s.split(/[\s]*[,][\s]
|
152
|
+
request['sec-websocket-extensions'.freeze].to_s.split(/[\s]*[,][\s]*/.freeze).each {|ex| ex = ex.split(/[\s]*;[\s]*/.freeze); ( ( tmp = SUPPORTED_EXTENTIONS[ ex[0] ].call(ex[1..-1]) ) && (ws_extentions << tmp) && (ext << tmp.name) ) if SUPPORTED_EXTENTIONS[ ex[0] ] }
|
153
153
|
ext.compact!
|
154
154
|
if ext.any?
|
155
|
-
response['sec-websocket-extensions'.freeze] = ext.join(', ')
|
155
|
+
response['sec-websocket-extensions'.freeze] = ext.join(', '.freeze)
|
156
156
|
else
|
157
157
|
ws_extentions = nil
|
158
158
|
end
|
@@ -200,7 +200,7 @@ module Iodine
|
|
200
200
|
|
201
201
|
def self.refuse response
|
202
202
|
response.status = 400
|
203
|
-
response['sec-websocket-extensions'.freeze] = SUPPORTED_EXTENTIONS.keys.join(', ')
|
203
|
+
response['sec-websocket-extensions'.freeze] = SUPPORTED_EXTENTIONS.keys.join(', '.freeze)
|
204
204
|
response['sec-websocket-version'.freeze] = '13'.freeze
|
205
205
|
false
|
206
206
|
end
|
@@ -298,7 +298,7 @@ module Iodine
|
|
298
298
|
close
|
299
299
|
parser[:p_op_code] = nil if parser[:p_op_code] == 8
|
300
300
|
else
|
301
|
-
parser[:message] ? ((parser[:message] << parser[:body]) && parser[:body].clear) : ((parser[:message] = parser[:body]) && parser[:body] =
|
301
|
+
parser[:message] ? ((parser[:message] << parser[:body]) && parser[:body].clear) : ((parser[:message] = parser[:body]) && parser[:body] = String.new)
|
302
302
|
# handle parser[:op_code] == 0 / fin == false (continue a frame that hasn't ended yet)
|
303
303
|
if parser[:fin]
|
304
304
|
@ws_extentions.each {|ex| ex.parse_message(parser) } if @ws_extentions
|
data/lib/iodine/protocol.rb
CHANGED
@@ -125,7 +125,7 @@ module Iodine
|
|
125
125
|
touch
|
126
126
|
r
|
127
127
|
end
|
128
|
-
rescue => e
|
128
|
+
rescue # => e
|
129
129
|
# Iodine.info e.message
|
130
130
|
close
|
131
131
|
end
|
@@ -214,7 +214,7 @@ module Iodine
|
|
214
214
|
# reads from the IO up to the specified number of bytes (defaults to ~1Mb).
|
215
215
|
def read_ssl size
|
216
216
|
@send_locker.synchronize do
|
217
|
-
data =
|
217
|
+
data = String.new
|
218
218
|
begin
|
219
219
|
(data << @io.read_nonblock(size).to_s) until data.bytesize >= size
|
220
220
|
rescue OpenSSL::SSL::SSLErrorWaitReadable, IO::WaitReadable, IO::WaitWritable
|
data/lib/iodine/settings.rb
CHANGED
@@ -120,7 +120,7 @@ module Iodine
|
|
120
120
|
def create_cert bits=2048, cn=nil, comment='a self signed certificate for when we only need encryption and no more.'
|
121
121
|
unless cn
|
122
122
|
host_name = Socket::gethostbyname(Socket::gethostname)[0].split('.')
|
123
|
-
cn =
|
123
|
+
cn = String.new
|
124
124
|
host_name.each {|n| cn << "/DC=#{n}"}
|
125
125
|
cn << "/CN=Iodine.#{host_name.join('.')}"
|
126
126
|
end
|
data/lib/iodine/ssl_connector.rb
CHANGED
data/lib/iodine/timers.rb
CHANGED
@@ -42,7 +42,7 @@ module Iodine
|
|
42
42
|
return false unless @next <= @reactor.time
|
43
43
|
return true if @repeat_limit == 0
|
44
44
|
@repeat_limit -= 1 if @repeat_limit.to_i > 0
|
45
|
-
@reactor.run
|
45
|
+
@reactor.run(*@args, &@job)
|
46
46
|
@next = @reactor.time + @interval
|
47
47
|
@repeat_limit == 0
|
48
48
|
end
|
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.13
|
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-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|