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 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