mieps_http-2 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.autotest +20 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +17 -0
- data/.gitmodules +3 -0
- data/.rspec +4 -0
- data/.rubocop.yml +18 -0
- data/.rubocop_todo.yml +46 -0
- data/.travis.yml +13 -0
- data/Gemfile +18 -0
- data/README.md +285 -0
- data/Rakefile +11 -0
- data/example/README.md +40 -0
- data/example/client.rb +117 -0
- data/example/helper.rb +19 -0
- data/example/keys/mycert.pem +23 -0
- data/example/keys/mykey.pem +27 -0
- data/example/server.rb +97 -0
- data/example/upgrade_server.rb +193 -0
- data/http-2.gemspec +23 -0
- data/lib/http/2/buffer.rb +34 -0
- data/lib/http/2/client.rb +51 -0
- data/lib/http/2/compressor.rb +557 -0
- data/lib/http/2/connection.rb +654 -0
- data/lib/http/2/emitter.rb +45 -0
- data/lib/http/2/error.rb +44 -0
- data/lib/http/2/flow_buffer.rb +67 -0
- data/lib/http/2/framer.rb +440 -0
- data/lib/http/2/huffman.rb +323 -0
- data/lib/http/2/huffman_statemachine.rb +272 -0
- data/lib/http/2/server.rb +132 -0
- data/lib/http/2/stream.rb +576 -0
- data/lib/http/2/version.rb +3 -0
- data/lib/http/2.rb +13 -0
- data/lib/tasks/generate_huffman_table.rb +166 -0
- data/spec/buffer_spec.rb +21 -0
- data/spec/client_spec.rb +92 -0
- data/spec/compressor_spec.rb +535 -0
- data/spec/connection_spec.rb +581 -0
- data/spec/emitter_spec.rb +54 -0
- data/spec/framer_spec.rb +487 -0
- data/spec/helper.rb +128 -0
- data/spec/hpack_test_spec.rb +79 -0
- data/spec/huffman_spec.rb +68 -0
- data/spec/server_spec.rb +51 -0
- data/spec/stream_spec.rb +794 -0
- metadata +116 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
RSpec.describe HTTP2::Header::Huffman do
|
4
|
+
huffman_examples = [ # plain, encoded
|
5
|
+
['www.example.com', 'f1e3c2e5f23a6ba0ab90f4ff'],
|
6
|
+
['no-cache', 'a8eb10649cbf'],
|
7
|
+
['Mon, 21 Oct 2013 20:13:21 GMT', 'd07abe941054d444a8200595040b8166e082a62d1bff'],
|
8
|
+
]
|
9
|
+
context 'encode' do
|
10
|
+
before(:all) { @encoder = HTTP2::Header::Huffman.new }
|
11
|
+
huffman_examples.each do |plain, encoded|
|
12
|
+
it "should encode #{plain} into #{encoded}" do
|
13
|
+
expect(@encoder.encode(plain).unpack('H*').first).to eq encoded
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
context 'decode' do
|
18
|
+
before(:all) { @encoder = HTTP2::Header::Huffman.new }
|
19
|
+
huffman_examples.each do |plain, encoded|
|
20
|
+
it "should decode #{encoded} into #{plain}" do
|
21
|
+
expect(@encoder.decode(HTTP2::Buffer.new([encoded].pack('H*')))).to eq plain
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
[
|
26
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0',
|
27
|
+
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
28
|
+
'http://www.craigslist.org/about/sites/',
|
29
|
+
'cl_b=AB2BKbsl4hGM7M4nH5PYWghTM5A; cl_def_lang=en; cl_def_hp=shoals',
|
30
|
+
'image/png,image/*;q=0.8,*/*;q=0.5',
|
31
|
+
'BX=c99r6jp89a7no&b=3&s=q4; localization=en-us%3Bus%3Bus',
|
32
|
+
'UTF-8でエンコードした日本語文字列',
|
33
|
+
].each do |string|
|
34
|
+
it "should encode then decode '#{string}' into the same" do
|
35
|
+
s = string.dup.force_encoding(Encoding::BINARY)
|
36
|
+
encoded = @encoder.encode(s)
|
37
|
+
expect(@encoder.decode(HTTP2::Buffer.new(encoded))).to eq s
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should encode/decode all_possible 2-byte sequences' do
|
42
|
+
(2**16).times do |n|
|
43
|
+
str = [n].pack('V')[0, 2].force_encoding(Encoding::BINARY)
|
44
|
+
expect(@encoder.decode(HTTP2::Buffer.new(@encoder.encode(str)))).to eq str
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should raise when input is shorter than expected' do
|
49
|
+
encoded = huffman_examples.first.last
|
50
|
+
encoded = [encoded].pack('H*')
|
51
|
+
expect { @encoder.decode(HTTP2::Buffer.new(encoded[0...-1])) }.to raise_error(/EOS invalid/)
|
52
|
+
end
|
53
|
+
it 'should raise when input is not padded by 1s' do
|
54
|
+
encoded = 'f1e3c2e5f23a6ba0ab90f4fe' # note the fe at end
|
55
|
+
encoded = [encoded].pack('H*')
|
56
|
+
expect { @encoder.decode(HTTP2::Buffer.new(encoded)) }.to raise_error(/EOS invalid/)
|
57
|
+
end
|
58
|
+
it 'should raise when exceedingly padded' do
|
59
|
+
encoded = 'e7cf9bebe89b6fb16fa9b6ffff' # note the extra ff
|
60
|
+
encoded = [encoded].pack('H*')
|
61
|
+
expect { @encoder.decode(HTTP2::Buffer.new(encoded)) }.to raise_error(/EOS invalid/)
|
62
|
+
end
|
63
|
+
it 'should raise when EOS is explicitly encoded' do
|
64
|
+
encoded = ['1c7fffffffff'].pack('H*') # a b EOS
|
65
|
+
expect { @encoder.decode(HTTP2::Buffer.new(encoded)) }.to raise_error(/EOS found/)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/spec/server_spec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
RSpec.describe HTTP2::Server do
|
4
|
+
before(:each) do
|
5
|
+
@srv = Server.new
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:f) { Framer.new }
|
9
|
+
|
10
|
+
context 'initialization and settings' do
|
11
|
+
it 'should return even stream IDs' do
|
12
|
+
expect(@srv.new_stream.id).to be_even
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should emit SETTINGS on new connection' do
|
16
|
+
frames = []
|
17
|
+
@srv.on(:frame) { |recv| frames << recv }
|
18
|
+
@srv << CONNECTION_PREFACE_MAGIC
|
19
|
+
|
20
|
+
expect(f.parse(frames[0])[:type]).to eq :settings
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should initialize client with custom connection settings' do
|
24
|
+
frames = []
|
25
|
+
|
26
|
+
@srv = Server.new(settings_max_concurrent_streams: 200,
|
27
|
+
settings_initial_window_size: 2**10)
|
28
|
+
@srv.on(:frame) { |recv| frames << recv }
|
29
|
+
@srv << CONNECTION_PREFACE_MAGIC
|
30
|
+
|
31
|
+
frame = f.parse(frames[0])
|
32
|
+
expect(frame[:type]).to eq :settings
|
33
|
+
expect(frame[:payload]).to include([:settings_max_concurrent_streams, 200])
|
34
|
+
expect(frame[:payload]).to include([:settings_initial_window_size, 2**10])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should allow server push' do
|
39
|
+
client = Client.new
|
40
|
+
client.on(:frame) { |bytes| @srv << bytes }
|
41
|
+
|
42
|
+
@srv.on(:stream) do |stream|
|
43
|
+
expect do
|
44
|
+
stream.promise(':method' => 'GET') {}
|
45
|
+
end.to_not raise_error
|
46
|
+
end
|
47
|
+
|
48
|
+
client.new_stream
|
49
|
+
client.send HEADERS.deep_dup
|
50
|
+
end
|
51
|
+
end
|