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 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.read(@buffer)
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
- raise 'SYN_REPLY not handled yet'
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..pckt.num_bytes)
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
- self.header.type = 2
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
@@ -1,3 +1,3 @@
1
1
  module Spdy
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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.1
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-07 00:00:00 -04:00
13
+ date: 2011-04-23 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency