http-2 0.8.2 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.rubocop.yml +41 -2
- data/.rubocop_todo.yml +85 -12
- data/Gemfile +1 -2
- data/Guardfile +19 -0
- data/Guardfile.h2spec +12 -0
- data/README.md +18 -9
- data/Rakefile +39 -1
- data/example/Gemfile +3 -0
- data/example/README.md +4 -0
- data/example/client.rb +10 -9
- data/example/helper.rb +1 -1
- data/example/keys/server.crt +20 -0
- data/example/keys/server.key +27 -0
- data/example/server.rb +48 -4
- data/example/upgrade_server.rb +20 -10
- data/lib/http/2/buffer.rb +42 -14
- data/lib/http/2/compressor.rb +2 -2
- data/lib/http/2/connection.rb +38 -16
- data/lib/http/2/emitter.rb +1 -1
- data/lib/http/2/framer.rb +12 -7
- data/lib/http/2/server.rb +2 -1
- data/lib/http/2/stream.rb +25 -11
- data/lib/http/2/version.rb +1 -1
- data/lib/tasks/generate_huffman_table.rb +3 -3
- data/spec/client_spec.rb +3 -3
- data/spec/connection_spec.rb +0 -1
- data/spec/h2spec/h2spec.darwin +0 -0
- data/spec/h2spec/output/non_secure.txt +317 -0
- data/spec/helper.rb +1 -1
- data/spec/hpack_test_spec.rb +1 -1
- data/spec/stream_spec.rb +22 -1
- data/spec/support/deep_dup.rb +55 -0
- data/spec/support/duplicable.rb +98 -0
- metadata +16 -5
- data/example/keys/mycert.pem +0 -23
- data/example/keys/mykey.pem +0 -27
data/spec/helper.rb
CHANGED
data/spec/hpack_test_spec.rb
CHANGED
@@ -24,7 +24,7 @@ RSpec.describe HTTP2::Header do
|
|
24
24
|
next if folder =~ /#/
|
25
25
|
path = File.expand_path("hpack-test-case/#{folder}", File.dirname(__FILE__))
|
26
26
|
next unless Dir.exist?(path)
|
27
|
-
context
|
27
|
+
context folder.to_s do
|
28
28
|
Dir.foreach(path) do |file|
|
29
29
|
next if file !~ /\.json/
|
30
30
|
it "should decode #{file}" do
|
data/spec/stream_spec.rb
CHANGED
@@ -651,7 +651,28 @@ RSpec.describe HTTP2::Stream do
|
|
651
651
|
expect(@stream).to receive(:send) do |frame|
|
652
652
|
expect(frame[:type]).to eq w[:type]
|
653
653
|
expect(frame[:flags]).to eq w[:flags]
|
654
|
-
expect(frame[:payload].
|
654
|
+
expect(frame[:payload].bytesize).to eq w[:length]
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
@stream.data(data + 'x')
|
659
|
+
end
|
660
|
+
|
661
|
+
it '.data should split large multibyte DATA frames' do
|
662
|
+
data = '🐼' * 16_384
|
663
|
+
|
664
|
+
want = [
|
665
|
+
{ type: :data, flags: [], length: 16_384 },
|
666
|
+
{ type: :data, flags: [], length: 16_384 },
|
667
|
+
{ type: :data, flags: [], length: 16_384 },
|
668
|
+
{ type: :data, flags: [], length: 16_384 },
|
669
|
+
{ type: :data, flags: [:end_stream], length: 1 },
|
670
|
+
]
|
671
|
+
want.each do |w|
|
672
|
+
expect(@stream).to receive(:send) do |frame|
|
673
|
+
expect(frame[:type]).to eq w[:type]
|
674
|
+
expect(frame[:flags]).to eq w[:flags]
|
675
|
+
expect(frame[:payload].bytesize).to eq w[:length]
|
655
676
|
end
|
656
677
|
end
|
657
678
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/deep_dup.rb
|
2
|
+
|
3
|
+
require_relative 'duplicable'
|
4
|
+
|
5
|
+
class Object
|
6
|
+
# Returns a deep copy of object if it's duplicable. If it's
|
7
|
+
# not duplicable, returns +self+.
|
8
|
+
#
|
9
|
+
# object = Object.new
|
10
|
+
# dup = object.deep_dup
|
11
|
+
# dup.instance_variable_set(:@a, 1)
|
12
|
+
#
|
13
|
+
# object.instance_variable_defined?(:@a) # => false
|
14
|
+
# dup.instance_variable_defined?(:@a) # => true
|
15
|
+
def deep_dup
|
16
|
+
duplicable? ? dup : self
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Array
|
21
|
+
# Returns a deep copy of array.
|
22
|
+
#
|
23
|
+
# array = [1, [2, 3]]
|
24
|
+
# dup = array.deep_dup
|
25
|
+
# dup[1][2] = 4
|
26
|
+
#
|
27
|
+
# array[1][2] # => nil
|
28
|
+
# dup[1][2] # => 4
|
29
|
+
def deep_dup
|
30
|
+
map(&:deep_dup)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Hash
|
35
|
+
# Returns a deep copy of hash.
|
36
|
+
#
|
37
|
+
# hash = { a: { b: 'b' } }
|
38
|
+
# dup = hash.deep_dup
|
39
|
+
# dup[:a][:c] = 'c'
|
40
|
+
#
|
41
|
+
# hash[:a][:c] # => nil
|
42
|
+
# dup[:a][:c] # => "c"
|
43
|
+
def deep_dup
|
44
|
+
hash = dup
|
45
|
+
each_pair do |key, value|
|
46
|
+
if key.frozen? && ::String == key # changed === to == for rubocop
|
47
|
+
hash[key] = value.deep_dup
|
48
|
+
else
|
49
|
+
hash.delete(key)
|
50
|
+
hash[key.deep_dup] = value.deep_dup
|
51
|
+
end
|
52
|
+
end
|
53
|
+
hash
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#--
|
2
|
+
# Most objects are cloneable, but not all. For example you can't dup +nil+:
|
3
|
+
#
|
4
|
+
# nil.dup # => TypeError: can't dup NilClass
|
5
|
+
#
|
6
|
+
# Classes may signal their instances are not duplicable removing +dup+/+clone+
|
7
|
+
# or raising exceptions from them. So, to dup an arbitrary object you normally
|
8
|
+
# use an optimistic approach and are ready to catch an exception, say:
|
9
|
+
#
|
10
|
+
# arbitrary_object.dup rescue object
|
11
|
+
#
|
12
|
+
# Rails dups objects in a few critical spots where they are not that arbitrary.
|
13
|
+
# That rescue is very expensive (like 40 times slower than a predicate), and it
|
14
|
+
# is often triggered.
|
15
|
+
#
|
16
|
+
# That's why we hardcode the following cases and check duplicable? instead of
|
17
|
+
# using that rescue idiom.
|
18
|
+
#++
|
19
|
+
class Object
|
20
|
+
# Can you safely dup this object?
|
21
|
+
#
|
22
|
+
# False for +nil+, +false+, +true+, symbol, number, method objects;
|
23
|
+
# true otherwise.
|
24
|
+
def duplicable?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class NilClass
|
30
|
+
# +nil+ is not duplicable:
|
31
|
+
#
|
32
|
+
# nil.duplicable? # => false
|
33
|
+
# nil.dup # => TypeError: can't dup NilClass
|
34
|
+
def duplicable?
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class FalseClass
|
40
|
+
# +false+ is not duplicable:
|
41
|
+
#
|
42
|
+
# false.duplicable? # => false
|
43
|
+
# false.dup # => TypeError: can't dup FalseClass
|
44
|
+
def duplicable?
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class TrueClass
|
50
|
+
# +true+ is not duplicable:
|
51
|
+
#
|
52
|
+
# true.duplicable? # => false
|
53
|
+
# true.dup # => TypeError: can't dup TrueClass
|
54
|
+
def duplicable?
|
55
|
+
false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class Symbol
|
60
|
+
# Symbols are not duplicable:
|
61
|
+
#
|
62
|
+
# :my_symbol.duplicable? # => false
|
63
|
+
# :my_symbol.dup # => TypeError: can't dup Symbol
|
64
|
+
def duplicable?
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Numeric
|
70
|
+
# Numbers are not duplicable:
|
71
|
+
#
|
72
|
+
# 3.duplicable? # => false
|
73
|
+
# 3.dup # => TypeError: can't dup Integer
|
74
|
+
def duplicable?
|
75
|
+
false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
require 'bigdecimal'
|
80
|
+
class BigDecimal
|
81
|
+
# BigDecimals are duplicable:
|
82
|
+
#
|
83
|
+
# BigDecimal.new("1.2").duplicable? # => true
|
84
|
+
# BigDecimal.new("1.2").dup # => #<BigDecimal:...,'0.12E1',18(18)>
|
85
|
+
def duplicable?
|
86
|
+
true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class Method
|
91
|
+
# Methods are not duplicable:
|
92
|
+
#
|
93
|
+
# method(:puts).duplicable? # => false
|
94
|
+
# method(:puts).dup # => TypeError: allocator undefined for Method
|
95
|
+
def duplicable?
|
96
|
+
false
|
97
|
+
end
|
98
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http-2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ilya Grigorik
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-12-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -41,13 +41,16 @@ files:
|
|
41
41
|
- ".rubocop_todo.yml"
|
42
42
|
- ".travis.yml"
|
43
43
|
- Gemfile
|
44
|
+
- Guardfile
|
45
|
+
- Guardfile.h2spec
|
44
46
|
- README.md
|
45
47
|
- Rakefile
|
48
|
+
- example/Gemfile
|
46
49
|
- example/README.md
|
47
50
|
- example/client.rb
|
48
51
|
- example/helper.rb
|
49
|
-
- example/keys/
|
50
|
-
- example/keys/
|
52
|
+
- example/keys/server.crt
|
53
|
+
- example/keys/server.key
|
51
54
|
- example/server.rb
|
52
55
|
- example/upgrade_server.rb
|
53
56
|
- http-2.gemspec
|
@@ -72,11 +75,15 @@ files:
|
|
72
75
|
- spec/connection_spec.rb
|
73
76
|
- spec/emitter_spec.rb
|
74
77
|
- spec/framer_spec.rb
|
78
|
+
- spec/h2spec/h2spec.darwin
|
79
|
+
- spec/h2spec/output/non_secure.txt
|
75
80
|
- spec/helper.rb
|
76
81
|
- spec/hpack_test_spec.rb
|
77
82
|
- spec/huffman_spec.rb
|
78
83
|
- spec/server_spec.rb
|
79
84
|
- spec/stream_spec.rb
|
85
|
+
- spec/support/deep_dup.rb
|
86
|
+
- spec/support/duplicable.rb
|
80
87
|
homepage: https://github.com/igrigorik/http-2
|
81
88
|
licenses:
|
82
89
|
- MIT
|
@@ -97,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
104
|
version: '0'
|
98
105
|
requirements: []
|
99
106
|
rubyforge_project:
|
100
|
-
rubygems_version: 2.
|
107
|
+
rubygems_version: 2.5.1
|
101
108
|
signing_key:
|
102
109
|
specification_version: 4
|
103
110
|
summary: Pure-ruby HTTP 2.0 protocol implementation
|
@@ -108,9 +115,13 @@ test_files:
|
|
108
115
|
- spec/connection_spec.rb
|
109
116
|
- spec/emitter_spec.rb
|
110
117
|
- spec/framer_spec.rb
|
118
|
+
- spec/h2spec/h2spec.darwin
|
119
|
+
- spec/h2spec/output/non_secure.txt
|
111
120
|
- spec/helper.rb
|
112
121
|
- spec/hpack_test_spec.rb
|
113
122
|
- spec/huffman_spec.rb
|
114
123
|
- spec/server_spec.rb
|
115
124
|
- spec/stream_spec.rb
|
125
|
+
- spec/support/deep_dup.rb
|
126
|
+
- spec/support/duplicable.rb
|
116
127
|
has_rdoc:
|
data/example/keys/mycert.pem
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
2
|
-
MIID1zCCAr+gAwIBAgIJANjbVITTVqaAMA0GCSqGSIb3DQEBBQUAMFAxCzAJBgNV
|
3
|
-
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgwFgYDVQQKEw9TUERZIFByb3h5
|
4
|
-
IERlbW8xEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xNDEwMTQwNDUwMTJaFw0xNTEw
|
5
|
-
MTQwNDUwMTJaMFAxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMRgw
|
6
|
-
FgYDVQQKEw9TUERZIFByb3h5IERlbW8xEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
|
7
|
-
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMxv7mqzNMVVFoBjqOSUy2cNM9c6
|
8
|
-
6gTgVLr9ssoLU0TC4biY1B/KoD7G9Ive6PwfdpipgGY+tuPHfEzBCCHD7exER1NL
|
9
|
-
npWauo6Lwh3wOjuo5Er6klgBGFuHYx8jJ2jBwCFvTcG2zJRedU/Pby6Fa27X6acw
|
10
|
-
faAtReG5YOHs8YRmg4ErWqfRucoM3zj8vvMWnushMhYQxo1EVLJ2EvvbHEkip4ap
|
11
|
-
pro+2Ql0KY4XT3EoMTRHICbolK/uQYoe0musKnwCGPg2NL6e27uvi47G7GrIpcf3
|
12
|
-
HN4HZMoOzJ8ti7IIEkF0fVTgQEVkluInfned69WCwxecMQZs5sdBuwE3Kh0CAwEA
|
13
|
-
AaOBszCBsDAdBgNVHQ4EFgQU86bqiYciIYDN+KAPlnJL6tSbH6IwgYAGA1UdIwR5
|
14
|
-
MHeAFPOm6omHIiGAzfigD5ZyS+rUmx+ioVSkUjBQMQswCQYDVQQGEwJBVTETMBEG
|
15
|
-
A1UECBMKU29tZS1TdGF0ZTEYMBYGA1UEChMPU1BEWSBQcm94eSBEZW1vMRIwEAYD
|
16
|
-
VQQDEwlsb2NhbGhvc3SCCQDY21SE01amgDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3
|
17
|
-
DQEBBQUAA4IBAQCkcr0DLPCbP5l9G0YI/XKVsUW9fXcTvge6Eko0R8qAkzTcsZQv
|
18
|
-
DbKcIM3z52QguCuJ9k63X4p174FKq7+qmieqaifosGKV03pyyxWLMpRooUUVXEBM
|
19
|
-
gZaRfp9VG2N4zrRaIklOSkAscnwybv2U3LZhKDlc7Yatsr1/TFkbCnzll514UnTz
|
20
|
-
ewjrlzVitUSEkwEGvLhKQuVPM9/3MAm+ztFpx846/GZ2XJSAFQLtHudjMXnFLihA
|
21
|
-
7nGZvE4rudyT70YsKu0BP0KjVZXrxTh81C4kyJu9xo4YuiDCFtvwtjoty0ygbuQN
|
22
|
-
a38i0bxFlYFmbWHooNCPUWVy59MOnW9zxaTV
|
23
|
-
-----END CERTIFICATE-----
|
data/example/keys/mykey.pem
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
-----BEGIN RSA PRIVATE KEY-----
|
2
|
-
MIIEowIBAAKCAQEAzG/uarM0xVUWgGOo5JTLZw0z1zrqBOBUuv2yygtTRMLhuJjU
|
3
|
-
H8qgPsb0i97o/B92mKmAZj6248d8TMEIIcPt7ERHU0uelZq6jovCHfA6O6jkSvqS
|
4
|
-
WAEYW4djHyMnaMHAIW9NwbbMlF51T89vLoVrbtfppzB9oC1F4blg4ezxhGaDgSta
|
5
|
-
p9G5ygzfOPy+8xae6yEyFhDGjURUsnYS+9scSSKnhqmmuj7ZCXQpjhdPcSgxNEcg
|
6
|
-
JuiUr+5Bih7Sa6wqfAIY+DY0vp7bu6+Ljsbsasilx/cc3gdkyg7Mny2LsggSQXR9
|
7
|
-
VOBARWSW4id+d53r1YLDF5wxBmzmx0G7ATcqHQIDAQABAoIBACybj85AZBdaxZom
|
8
|
-
JMgbn3ZQ7yrbdAy0Vkim6sgjSHwMeewpjL+TGvwXtWx/qx64Tsxoz9d/f7Cb6odk
|
9
|
-
5z1W3ydajqWiLmw+Ys6PuD+IF2zFIWsq2ZvSQVpXZE17AjJddGrXOoQ2OtV09uv/
|
10
|
-
OydPfW2mNxl//ylgN4tVQ8qIRPq6b1GWWZvjTw4K3jPrlAifobYBBR+BSk446O7F
|
11
|
-
iGvax5lNNCDMN2y+6hlnhlTHuvc0DXQA0XBhWTNYu8BNNrvC3I31RmxdY7Frm7IA
|
12
|
-
RUGy/l2kLHCRCTF8Q0C4ydpE5ZFgpxkWK7p3QEv/gnVAwsOSN/nThdoorWWHTbNl
|
13
|
-
pA5l1RECgYEA/ASaS9mqWWthUkOW51L6c7IIiRPAhrbPnx1mkAtUPeehHn1+G8Qu
|
14
|
-
upUEXslWokhmQ3UAGhrId6FVYsfftNPMNck9mv4ntW7MoZLXZqTiFSqx4pQTjoYg
|
15
|
-
PQ4c/jrQLsmislcKTiVx6kFYFcnI1ayXXEtaby0lri8XsAR5F90OpycCgYEAz6re
|
16
|
-
DR5EZZKx61wyEfuPWE6aACWlEqlbTa8nTMddxnZUZXtzbwRFapGfs+uHCURF0dGj
|
17
|
-
37cl4q8JdGbbYePk9nlOC4RoSw8Zh3fB4yRSZocB4yB047ofpBmt4BigGtgZ5BLZ
|
18
|
-
zqVREgBUI+tFPPHkMmBY4lCaUsCe11SEwyZFzxsCgYEA3nRNonBy/tVbJZtFw9Eq
|
19
|
-
BB/9isolooQRxrjUBIgLh01Dmj9ZprbILKhHIEgGsd7IbfkD6wcDNx3w2e3mGJ7v
|
20
|
-
3fZR69M2R9+Sv3h3rEIU0mxKct8UWDUqldo0W3CcvP/9HgDYttw0rnuZfjoMjhf3
|
21
|
-
z18wZ3xpi1RES3nXTeox+fcCgYBlPxkjrC4Ml4jHBxwiSFOK6keK6s+gWZF6Pnsa
|
22
|
-
o9jEecyL7bRJ2/s8CeOjBKHBkte3hE4xNEn0SwKBDeTHxSRMRrgWRWfTsHjx4yFU
|
23
|
-
bND/y7LP2XMj1Aq5JwvuxhLJA7Mbz1UBuvfbnu1m1b3cCNMI/JBZRpL25ZKLyVkx
|
24
|
-
C+fdIQKBgA+tLeF10zqGGc4269b6nQWplc5E/qnIRK0cfnKb9BtffmA4FbjUpZKj
|
25
|
-
+cGmbtbw7ySkAIKLp4HoJmzkXJageGTSEb/sQIodxMiJCGvvgJmPPnGzU8OiUGAl
|
26
|
-
VmRjuAQ2eCcsUyvrJYgKW9UWskqSe6z5w/Uxo/sZdHlaGljNdKcn
|
27
|
-
-----END RSA PRIVATE KEY-----
|