em-ws-client 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.markdown +86 -20
- data/Rakefile +9 -1
- data/autobahn/fuzzer.rb +94 -0
- data/autobahn/report.html +3615 -0
- data/em-ws-client.gemspec +6 -3
- data/lib/em-ws-client.rb +10 -190
- data/lib/em-ws-client/client.rb +300 -0
- data/lib/em-ws-client/decoder.rb +238 -0
- data/lib/em-ws-client/encoder.rb +74 -0
- data/lib/em-ws-client/handshake.rb +97 -0
- data/lib/em-ws-client/protocol.rb +12 -0
- data/spec/codec_spec.rb +15 -0
- data/spec/handshake_spec.rb +96 -0
- data/spec/helper.rb +3 -0
- metadata +16 -20
- data/example/echo.rb +0 -33
- data/lib/codec/draft10decoder.rb +0 -122
- data/lib/codec/draft10encoder.rb +0 -45
- data/spec/em-ws-client.rb +0 -0
data/spec/helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-ws-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-04-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
16
|
-
requirement: &
|
16
|
+
requirement: &11601440 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,18 +21,7 @@ dependencies:
|
|
21
21
|
version: 1.0.0.beta.4
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: state_machine
|
27
|
-
requirement: &19649660 !ruby/object:Gem::Requirement
|
28
|
-
none: false
|
29
|
-
requirements:
|
30
|
-
- - ~>
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 1.0.2
|
33
|
-
type: :runtime
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *19649660
|
24
|
+
version_requirements: *11601440
|
36
25
|
description: A simple, fun, evented WebSocket client for your ruby projects
|
37
26
|
email: dan@shove.io
|
38
27
|
executables: []
|
@@ -41,14 +30,21 @@ extra_rdoc_files: []
|
|
41
30
|
files:
|
42
31
|
- .gitignore
|
43
32
|
- Gemfile
|
33
|
+
- LICENSE
|
44
34
|
- README.markdown
|
45
35
|
- Rakefile
|
36
|
+
- autobahn/fuzzer.rb
|
37
|
+
- autobahn/report.html
|
46
38
|
- em-ws-client.gemspec
|
47
|
-
- example/echo.rb
|
48
|
-
- lib/codec/draft10decoder.rb
|
49
|
-
- lib/codec/draft10encoder.rb
|
50
39
|
- lib/em-ws-client.rb
|
51
|
-
-
|
40
|
+
- lib/em-ws-client/client.rb
|
41
|
+
- lib/em-ws-client/decoder.rb
|
42
|
+
- lib/em-ws-client/encoder.rb
|
43
|
+
- lib/em-ws-client/handshake.rb
|
44
|
+
- lib/em-ws-client/protocol.rb
|
45
|
+
- spec/codec_spec.rb
|
46
|
+
- spec/handshake_spec.rb
|
47
|
+
- spec/helper.rb
|
52
48
|
homepage: https://github.com/dansimpson/em-ws-client
|
53
49
|
licenses: []
|
54
50
|
post_install_message:
|
@@ -69,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
65
|
version: '0'
|
70
66
|
requirements: []
|
71
67
|
rubyforge_project:
|
72
|
-
rubygems_version: 1.8.
|
68
|
+
rubygems_version: 1.8.11
|
73
69
|
signing_key:
|
74
70
|
specification_version: 3
|
75
71
|
summary: EventMachine WebSocket Client
|
data/example/echo.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
$: << File.dirname(__FILE__) + "/../lib/"
|
2
|
-
|
3
|
-
require "em-ws-client"
|
4
|
-
|
5
|
-
|
6
|
-
dec = EM::Draft10Decoder.new
|
7
|
-
enc = EM::Draft10Encoder.new
|
8
|
-
|
9
|
-
puts dec.decode(enc.encode("monkey"))
|
10
|
-
|
11
|
-
EM.run do
|
12
|
-
|
13
|
-
conn = EM::WebSocketClient.new("ws://localhost:8080/test")
|
14
|
-
puts conn.state
|
15
|
-
puts conn.disconnected?
|
16
|
-
|
17
|
-
conn.onopen do
|
18
|
-
puts "Opened"
|
19
|
-
|
20
|
-
EM.add_periodic_timer(2) do
|
21
|
-
conn.send_data "Ping!"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
conn.onclose do
|
26
|
-
puts "Closed"
|
27
|
-
end
|
28
|
-
|
29
|
-
conn.onmessage do |msg|
|
30
|
-
puts msg
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
data/lib/codec/draft10decoder.rb
DELETED
@@ -1,122 +0,0 @@
|
|
1
|
-
module EM
|
2
|
-
|
3
|
-
# A replaying decoder for the IETF Hybi
|
4
|
-
# WebSocket protocol specification
|
5
|
-
class Draft10Decoder
|
6
|
-
|
7
|
-
CONTINUATION = 0x0
|
8
|
-
TEXT_FRAME = 0x1
|
9
|
-
BINARY_FRAME = 0x2
|
10
|
-
CLOSE = 0x8
|
11
|
-
PING = 0x9
|
12
|
-
PONG = 0xA
|
13
|
-
|
14
|
-
def initialize
|
15
|
-
@buffer = ""
|
16
|
-
@chunks = ""
|
17
|
-
end
|
18
|
-
|
19
|
-
# Decode a WebSocket frame
|
20
|
-
# +data+ the frame data
|
21
|
-
# returns false if the packet is incomplete
|
22
|
-
# and a decoded message otherwise
|
23
|
-
def decode data
|
24
|
-
|
25
|
-
# broken frame
|
26
|
-
if data && data.length < 2
|
27
|
-
return false
|
28
|
-
end
|
29
|
-
|
30
|
-
# put the data into the buffer, as
|
31
|
-
# we might be replaying
|
32
|
-
@buffer << data
|
33
|
-
|
34
|
-
# decode the first 2 bytes, with
|
35
|
-
# opcode, lengthgth, masking bit, and frag bit
|
36
|
-
h1, h2 = @buffer.unpack("CC")
|
37
|
-
|
38
|
-
# check the fragmentation bit to see
|
39
|
-
# if this is a message fragment
|
40
|
-
@chunked = ((h1 & 0x80) != 0x80)
|
41
|
-
|
42
|
-
# used to keep track of our position in the buffer
|
43
|
-
offset = 2
|
44
|
-
|
45
|
-
# see above for possible opcodes
|
46
|
-
opcode = (h1 & 0x0F)
|
47
|
-
|
48
|
-
# the leading length idicator
|
49
|
-
length = (h2 & 0x7F)
|
50
|
-
|
51
|
-
# masking bit, is the data masked with
|
52
|
-
# a specified masking key?
|
53
|
-
masked = ((h2 & 0x80) == 0x80)
|
54
|
-
|
55
|
-
# spare no bytes hybi!
|
56
|
-
if length > 125
|
57
|
-
if length == 126
|
58
|
-
length = @buffer.unpack("@#{offset}n").first
|
59
|
-
offset += 2
|
60
|
-
else
|
61
|
-
length1, length2 = @buffer.unpack("@#{offset}NN")
|
62
|
-
# TODO.. bigint?
|
63
|
-
offset += 8
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# unpack the masking key
|
68
|
-
if masked
|
69
|
-
key = @buffer.unpack("@#{offset}N").first
|
70
|
-
offset += 4
|
71
|
-
end
|
72
|
-
|
73
|
-
# replay on next frame
|
74
|
-
if @buffer.size < (length + offset)
|
75
|
-
return false
|
76
|
-
end
|
77
|
-
|
78
|
-
# Read the important bits
|
79
|
-
payload = @buffer.unpack("@#{offset}C#{length}")
|
80
|
-
|
81
|
-
# Unmask the data if it's masked
|
82
|
-
if masked
|
83
|
-
payload.size.times do |i|
|
84
|
-
payload[i] = ((payload[i] ^ (key >> ((3 - (i % 4)) * 8))) & 0xFF)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# finally, extract the message!
|
89
|
-
payload = payload.pack("C*")
|
90
|
-
|
91
|
-
case opcode
|
92
|
-
when CONTINUATION
|
93
|
-
@chunks << payload
|
94
|
-
unless @chunked
|
95
|
-
result = @chunks
|
96
|
-
@chunks = ""
|
97
|
-
return result
|
98
|
-
end
|
99
|
-
false
|
100
|
-
when TEXT_FRAME
|
101
|
-
unless @chunked
|
102
|
-
@buffer = ""
|
103
|
-
@buffer.slice!(offset + length)
|
104
|
-
return payload
|
105
|
-
end
|
106
|
-
false
|
107
|
-
when BINARY_FRAME
|
108
|
-
false #TODO
|
109
|
-
when CLOSE
|
110
|
-
false #TODO
|
111
|
-
when PING
|
112
|
-
false #TODO send pong
|
113
|
-
when PONG
|
114
|
-
false
|
115
|
-
else
|
116
|
-
false
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
|
121
|
-
end
|
122
|
-
end
|
data/lib/codec/draft10encoder.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
module EM
|
2
|
-
class Draft10Encoder
|
3
|
-
|
4
|
-
# Encode a standard payload to a hybi10
|
5
|
-
# WebSocket frame
|
6
|
-
def encode data
|
7
|
-
frame = []
|
8
|
-
frame << (0x1 | 0x80)
|
9
|
-
|
10
|
-
packr = "CC"
|
11
|
-
|
12
|
-
# append frame length and mask bit 0x80
|
13
|
-
len = data.size
|
14
|
-
if len <= 125
|
15
|
-
frame << (len | 0x80)
|
16
|
-
elsif length < 65536
|
17
|
-
frame << (126 | 0x80)
|
18
|
-
frame << (len)
|
19
|
-
packr << "n"
|
20
|
-
else
|
21
|
-
frame << (127 | 0x80)
|
22
|
-
frame << (len >> 32)
|
23
|
-
frame << (len & 0xFFFFFFFF)
|
24
|
-
packr << "NN"
|
25
|
-
end
|
26
|
-
|
27
|
-
# generate a masking key
|
28
|
-
key = rand(2 ** 31)
|
29
|
-
|
30
|
-
# mask each byte with the key
|
31
|
-
frame << key
|
32
|
-
packr << "N"
|
33
|
-
|
34
|
-
# The spec says we have to waste cycles and
|
35
|
-
# impact the atmosphere with a small amount of
|
36
|
-
# heat dissapation
|
37
|
-
data.size.times do |i|
|
38
|
-
frame << ((data.getbyte(i) ^ (key >> ((3 - (i % 4)) * 8))) & 0xFF)
|
39
|
-
end
|
40
|
-
|
41
|
-
frame.pack("#{packr}C*")
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
data/spec/em-ws-client.rb
DELETED
File without changes
|