spdy 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|