spdy 0.0.1 → 0.0.2
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/lib/spdy/parser.rb +23 -17
- data/lib/spdy/protocol.rb +38 -22
- data/lib/spdy/version.rb +1 -1
- data/spec/protocol_spec.rb +46 -0
- metadata +2 -2
data/lib/spdy/parser.rb
CHANGED
@@ -25,6 +25,23 @@ module SPDY
|
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
|
+
def unpack_control(pckt, data)
|
29
|
+
pckt.read(data)
|
30
|
+
|
31
|
+
headers = {}
|
32
|
+
if pckt.data.size > 0
|
33
|
+
data = Zlib.inflate(pckt.data.to_s)
|
34
|
+
headers = NV.new.read(data).to_h
|
35
|
+
end
|
36
|
+
|
37
|
+
if @on_headers_complete
|
38
|
+
@on_headers_complete.call(pckt.header.stream_id.to_i,
|
39
|
+
(pckt.associated_to_stream_id.to_i rescue nil),
|
40
|
+
(pckt.pri.to_i rescue nil),
|
41
|
+
headers)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
28
45
|
def try_parse
|
29
46
|
type = @buffer[0,1].unpack('C').first >> 7 & 0x01
|
30
47
|
pckt = nil
|
@@ -37,23 +54,12 @@ module SPDY
|
|
37
54
|
case pckt.type.to_i
|
38
55
|
when 1 then # SYN_STREAM
|
39
56
|
pckt = Control::SynStream.new
|
40
|
-
pckt
|
41
|
-
|
42
|
-
headers = {}
|
43
|
-
if pckt.data.size > 0
|
44
|
-
data = Zlib.inflate(pckt.data.to_s)
|
45
|
-
headers = NV.new.read(data).to_h
|
46
|
-
end
|
47
|
-
|
48
|
-
if @on_headers_complete
|
49
|
-
@on_headers_complete.call(pckt.header.stream_id.to_i,
|
50
|
-
pckt.associated_to_stream_id.to_i,
|
51
|
-
pckt.pri.to_i,
|
52
|
-
headers)
|
53
|
-
end
|
57
|
+
unpack_control(pckt, @buffer)
|
54
58
|
|
55
59
|
when 2 then # SYN_REPLY
|
56
|
-
|
60
|
+
pckt = Control::SynReply.new
|
61
|
+
unpack_control(pckt, @buffer)
|
62
|
+
|
57
63
|
else
|
58
64
|
raise 'invalid control frame'
|
59
65
|
end
|
@@ -72,9 +78,9 @@ module SPDY
|
|
72
78
|
end
|
73
79
|
|
74
80
|
# remove parsed data from the buffer
|
75
|
-
@buffer.slice!(0
|
81
|
+
@buffer.slice!(0...pckt.num_bytes)
|
76
82
|
|
77
|
-
rescue IOError
|
83
|
+
rescue IOError => e
|
78
84
|
# rescue partial parse and wait for more data
|
79
85
|
end
|
80
86
|
|
data/lib/spdy/protocol.rb
CHANGED
@@ -6,6 +6,35 @@ module SPDY
|
|
6
6
|
VERSION = 2
|
7
7
|
|
8
8
|
module Control
|
9
|
+
module Helpers
|
10
|
+
def parse(chunk)
|
11
|
+
head = Control::Header.new.read(chunk)
|
12
|
+
self.read(chunk)
|
13
|
+
|
14
|
+
data = Zlib.inflate(self.data.to_s)
|
15
|
+
self.uncompressed_data = NV.new.read(data)
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def build(opts = {})
|
20
|
+
self.header.type = opts[:type]
|
21
|
+
self.header.len = opts[:len]
|
22
|
+
|
23
|
+
self.header.flags = opts[:flags] || 0
|
24
|
+
self.header.stream_id = opts[:stream_id]
|
25
|
+
|
26
|
+
nv = SPDY::Protocol::NV.new
|
27
|
+
nv.create(opts[:headers])
|
28
|
+
|
29
|
+
nv = SPDY::Zlib.deflate(nv.to_binary_s)
|
30
|
+
self.header.len = self.header.len.to_i + nv.size
|
31
|
+
|
32
|
+
self.data = nv
|
33
|
+
|
34
|
+
self
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
9
38
|
class Header < BinData::Record
|
10
39
|
hide :u1
|
11
40
|
|
@@ -21,6 +50,9 @@ module SPDY
|
|
21
50
|
end
|
22
51
|
|
23
52
|
class SynStream < BinData::Record
|
53
|
+
attr_accessor :uncompressed_data
|
54
|
+
include Helpers
|
55
|
+
|
24
56
|
hide :u1, :u2
|
25
57
|
|
26
58
|
header :header
|
@@ -32,38 +64,22 @@ module SPDY
|
|
32
64
|
bit14 :u2
|
33
65
|
|
34
66
|
string :data, :read_length => lambda { header.len - 10 }
|
67
|
+
|
68
|
+
def create(opts = {})
|
69
|
+
build({:type => 1, :len => 10}.merge(opts))
|
70
|
+
end
|
35
71
|
end
|
36
72
|
|
37
73
|
class SynReply < BinData::Record
|
38
74
|
attr_accessor :uncompressed_data
|
75
|
+
include Helpers
|
39
76
|
|
40
77
|
header :header
|
41
78
|
bit16 :unused
|
42
79
|
string :data, :read_length => lambda { header.len - 6 }
|
43
80
|
|
44
|
-
def parse(chunk)
|
45
|
-
self.read(chunk)
|
46
|
-
|
47
|
-
data = Zlib.inflate(self.data.to_s)
|
48
|
-
self.uncompressed_data = NV.new.read(data)
|
49
|
-
self
|
50
|
-
end
|
51
|
-
|
52
81
|
def create(opts = {})
|
53
|
-
|
54
|
-
self.header.len = 6
|
55
|
-
|
56
|
-
self.header.flags = opts[:flags] || 0
|
57
|
-
self.header.stream_id = opts[:stream_id]
|
58
|
-
|
59
|
-
nv = SPDY::Protocol::NV.new
|
60
|
-
nv.create(opts[:headers])
|
61
|
-
|
62
|
-
nv = SPDY::Zlib.deflate(nv.to_binary_s)
|
63
|
-
self.header.len = self.header.len.to_i + nv.size
|
64
|
-
self.data = nv
|
65
|
-
|
66
|
-
self
|
82
|
+
build({:type => 2, :len => 6}.merge(opts))
|
67
83
|
end
|
68
84
|
end
|
69
85
|
end
|
data/lib/spdy/version.rb
CHANGED
data/spec/protocol_spec.rb
CHANGED
@@ -11,6 +11,42 @@ describe SPDY::Protocol do
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
context "SYN_STREAM" do
|
15
|
+
it "should create a SYN_STREAM packet" do
|
16
|
+
sr = SPDY::Protocol::Control::SynStream.new
|
17
|
+
|
18
|
+
headers = {
|
19
|
+
"accept"=>"application/xml", "host"=>"127.0.0.1:9000",
|
20
|
+
"method"=>"GET", "scheme"=>"https",
|
21
|
+
"url"=>"/?echo=a&format=json","version"=>"HTTP/1.1"
|
22
|
+
}
|
23
|
+
|
24
|
+
sr.create(:stream_id => 1, :headers => headers)
|
25
|
+
sr.header.version.should == 2
|
26
|
+
sr.pri.should == 0
|
27
|
+
|
28
|
+
sr.header.len.should > 50
|
29
|
+
sr.data.should_not be_nil
|
30
|
+
|
31
|
+
st = SPDY::Protocol::Control::SynStream.new
|
32
|
+
st.parse(sr.to_binary_s)
|
33
|
+
st.num_bytes.should == sr.to_binary_s.size
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should parse SYN_STREAM packet" do
|
37
|
+
sr = SPDY::Protocol::Control::SynStream.new
|
38
|
+
sr.parse(SYN_STREAM)
|
39
|
+
|
40
|
+
sr.num_bytes.should == SYN_STREAM.size
|
41
|
+
|
42
|
+
sr.header.type.should == 1
|
43
|
+
sr.uncompressed_data.to_h.class.should == Hash
|
44
|
+
sr.uncompressed_data.to_h['method'].should == 'GET'
|
45
|
+
|
46
|
+
sr.to_binary_s.should == SYN_STREAM
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
14
50
|
context "SYN_REPLY" do
|
15
51
|
it "should create a SYN_REPLY packet" do
|
16
52
|
sr = SPDY::Protocol::Control::SynReply.new
|
@@ -55,6 +91,16 @@ describe SPDY::Protocol do
|
|
55
91
|
|
56
92
|
d.to_binary_s.should == DATA_FIN
|
57
93
|
end
|
94
|
+
|
95
|
+
it "should read a FIN data frame" do
|
96
|
+
d = SPDY::Protocol::Data::Frame.new
|
97
|
+
d.create(:stream_id => 1, :flags => 1)
|
98
|
+
|
99
|
+
d.to_binary_s.should == DATA_FIN
|
100
|
+
pckt = SPDY::Protocol::Data::Frame.new.read(d.to_binary_s)
|
101
|
+
pckt.flags.should == 1
|
102
|
+
end
|
103
|
+
|
58
104
|
end
|
59
105
|
|
60
106
|
# context "RST_STREAM" do
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: spdy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ilya Grigorik
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-04-
|
13
|
+
date: 2011-04-23 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|