http-2 0.11.0 → 1.0.0

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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -9
  3. data/lib/http/2/base64.rb +45 -0
  4. data/lib/http/2/client.rb +19 -6
  5. data/lib/http/2/connection.rb +235 -163
  6. data/lib/http/2/emitter.rb +7 -5
  7. data/lib/http/2/error.rb +24 -1
  8. data/lib/http/2/extensions.rb +53 -0
  9. data/lib/http/2/flow_buffer.rb +91 -33
  10. data/lib/http/2/framer.rb +184 -157
  11. data/lib/http/2/header/compressor.rb +157 -0
  12. data/lib/http/2/header/decompressor.rb +144 -0
  13. data/lib/http/2/header/encoding_context.rb +337 -0
  14. data/lib/http/2/{huffman.rb → header/huffman.rb} +25 -19
  15. data/lib/http/2/{huffman_statemachine.rb → header/huffman_statemachine.rb} +2 -0
  16. data/lib/http/2/header.rb +35 -0
  17. data/lib/http/2/server.rb +47 -20
  18. data/lib/http/2/stream.rb +130 -61
  19. data/lib/http/2/version.rb +3 -1
  20. data/lib/http/2.rb +14 -13
  21. data/sig/client.rbs +9 -0
  22. data/sig/connection.rbs +93 -0
  23. data/sig/emitter.rbs +13 -0
  24. data/sig/error.rbs +35 -0
  25. data/sig/extensions.rbs +5 -0
  26. data/sig/flow_buffer.rbs +21 -0
  27. data/sig/frame_buffer.rbs +13 -0
  28. data/sig/framer.rbs +54 -0
  29. data/sig/header/compressor.rbs +27 -0
  30. data/sig/header/decompressor.rbs +22 -0
  31. data/sig/header/encoding_context.rbs +34 -0
  32. data/sig/header/huffman.rbs +9 -0
  33. data/sig/header.rbs +27 -0
  34. data/sig/next.rbs +101 -0
  35. data/sig/server.rbs +12 -0
  36. data/sig/stream.rbs +91 -0
  37. metadata +38 -79
  38. data/.autotest +0 -20
  39. data/.coveralls.yml +0 -1
  40. data/.gitignore +0 -20
  41. data/.gitmodules +0 -3
  42. data/.rspec +0 -5
  43. data/.rubocop.yml +0 -93
  44. data/.rubocop_todo.yml +0 -131
  45. data/.travis.yml +0 -17
  46. data/Gemfile +0 -16
  47. data/Guardfile +0 -18
  48. data/Guardfile.h2spec +0 -12
  49. data/LICENSE +0 -21
  50. data/Rakefile +0 -49
  51. data/example/Gemfile +0 -3
  52. data/example/README.md +0 -44
  53. data/example/client.rb +0 -122
  54. data/example/helper.rb +0 -19
  55. data/example/keys/server.crt +0 -20
  56. data/example/keys/server.key +0 -27
  57. data/example/server.rb +0 -139
  58. data/example/upgrade_client.rb +0 -153
  59. data/example/upgrade_server.rb +0 -203
  60. data/http-2.gemspec +0 -22
  61. data/lib/http/2/buffer.rb +0 -76
  62. data/lib/http/2/compressor.rb +0 -572
  63. data/lib/tasks/generate_huffman_table.rb +0 -166
  64. data/spec/buffer_spec.rb +0 -28
  65. data/spec/client_spec.rb +0 -188
  66. data/spec/compressor_spec.rb +0 -666
  67. data/spec/connection_spec.rb +0 -681
  68. data/spec/emitter_spec.rb +0 -54
  69. data/spec/framer_spec.rb +0 -487
  70. data/spec/h2spec/h2spec.darwin +0 -0
  71. data/spec/h2spec/output/non_secure.txt +0 -317
  72. data/spec/helper.rb +0 -147
  73. data/spec/hpack_test_spec.rb +0 -84
  74. data/spec/huffman_spec.rb +0 -68
  75. data/spec/server_spec.rb +0 -52
  76. data/spec/stream_spec.rb +0 -878
  77. data/spec/support/deep_dup.rb +0 -55
  78. data/spec/support/duplicable.rb +0 -98
@@ -0,0 +1,93 @@
1
+ module HTTP2
2
+ class Connection
3
+ include FlowBuffer
4
+ include Emitter
5
+
6
+ REQUEST_MANDATORY_HEADERS: Array[String]
7
+ RESPONSE_MANDATORY_HEADERS: Array[String]
8
+
9
+ attr_reader state: Symbol
10
+
11
+ attr_reader local_window: Integer
12
+ attr_reader remote_window: Integer
13
+
14
+ alias window local_window
15
+
16
+ attr_reader remote_settings: settings_hash
17
+ attr_reader local_settings: settings_hash
18
+ attr_reader pending_settings: settings_ary
19
+
20
+ attr_accessor active_stream_count: Integer
21
+
22
+ @stream_id: Integer
23
+ @active_stream_count: Integer
24
+ @last_activated_stream: Integer
25
+ @last_stream_id: Integer
26
+
27
+ @streams: Hash[Integer, Stream]
28
+ @streams_recently_closed: Hash[Integer, Stream]
29
+
30
+ @framer: Framer
31
+
32
+ @local_window_limit: Integer
33
+ @remote_window_limit: Integer
34
+
35
+ @compressor: Header::Compressor
36
+ @decompressor: Header::Decompressor
37
+ @error: Symbol?
38
+
39
+ @recv_buffer: String
40
+ @continuation: Array[frame]
41
+
42
+ @closed_since: Float?
43
+ @received_frame: bool
44
+
45
+ def closed?: () -> bool
46
+
47
+ def new_stream: (**untyped) -> Stream
48
+
49
+ def ping: (String) -> void
50
+ | (String) { () -> void } -> void
51
+
52
+ def goaway: (?Symbol, ?String) -> void
53
+
54
+ def window_update: (Integer increment) -> void
55
+
56
+ def settings: (settings_enum) -> void
57
+
58
+ def receive: (string data) -> void
59
+ alias << receive
60
+
61
+ def initialize: (?settings_hash) -> void
62
+
63
+ private
64
+
65
+ def send: (frame) -> void
66
+
67
+ def encode: (frame) -> Array[String]
68
+
69
+ def connection_frame?: (frame) -> bool
70
+
71
+ def connection_management: (frame) -> void
72
+
73
+ def ping_management: (frame) -> void
74
+
75
+ def validate_settings: (:client | :server, settings_enum) -> void
76
+
77
+ def connection_settings: (frame) -> void
78
+
79
+ def decode_headers: (frame) -> void
80
+
81
+ def encode_headers: (frame) -> Array[frame]
82
+
83
+ def activate_stream: (id: Integer, **untyped) -> Stream
84
+
85
+ def verify_stream_order: (Integer id) -> void
86
+
87
+ def verify_pseudo_headers: (frame) -> void
88
+
89
+ def _verify_pseudo_headers: (frame, Array[String]) -> void
90
+
91
+ def connection_error: (?Symbol error, ?msg: String?, ?e: StandardError?) -> void
92
+ end
93
+ end
data/sig/emitter.rbs ADDED
@@ -0,0 +1,13 @@
1
+ module HTTP2
2
+ module Emitter
3
+ def on: (Symbol event) { (*untyped) -> void } -> void
4
+
5
+ def once: (Symbol event) { (*untyped) -> void } -> void
6
+
7
+ def emit: (Symbol event, *untyped args) ?{ (*untyped) -> void } -> void
8
+
9
+ private
10
+
11
+ def listeners: (Symbol event) -> Array[Proc]
12
+ end
13
+ end
data/sig/error.rbs ADDED
@@ -0,0 +1,35 @@
1
+ module HTTP2
2
+ module Error
3
+ def self?.types: () -> Hash[Symbol, singleton(Error)]
4
+
5
+ class Error < StandardError
6
+ end
7
+
8
+ class HandshakeError < Error
9
+ end
10
+
11
+ class ProtocolError < Error
12
+ end
13
+
14
+ class CompressionError < ProtocolError
15
+ end
16
+
17
+ class FlowControlError < ProtocolError
18
+ end
19
+
20
+ class InternalError < ProtocolError
21
+ end
22
+
23
+ class StreamClosed < Error
24
+ end
25
+
26
+ class ConnectionClosed < Error
27
+ end
28
+
29
+ class StreamLimitExceeded < Error
30
+ end
31
+
32
+ class FrameSizeError < Error
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,5 @@
1
+ module HTTP2
2
+ module PackingExtensions
3
+ def pack: (Array[Integer] array_to_pack, String template, buffer: String, ?offset: Integer) -> String
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ module HTTP2
2
+ module FlowBuffer
3
+ MAX_WINDOW_SIZE: Integer
4
+
5
+ def buffered_amount: () -> Integer
6
+
7
+ def flush: () -> void
8
+
9
+ private
10
+
11
+ def send_buffer: () -> FrameBuffer
12
+
13
+ def update_local_window: (frame) -> void
14
+
15
+ def calculate_window_update: (Integer) -> void
16
+
17
+ def send_data: (?frame? frame, ?bool encode) -> void
18
+
19
+ def process_window_update: (frame: frame, ?encode: bool) -> void
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module HTTP2
2
+ class FrameBuffer
3
+ attr_reader bytesize: Integer
4
+
5
+ @buffer: Array[data_frame]
6
+
7
+ def <<: (data_frame) -> void
8
+
9
+ def empty?: () -> bool
10
+
11
+ def retrieve: (Integer) -> data_frame?
12
+ end
13
+ end
data/sig/framer.rbs ADDED
@@ -0,0 +1,54 @@
1
+ module HTTP2
2
+ class Framer
3
+ include PackingExtensions
4
+
5
+ DEFAULT_MAX_FRAME_SIZE: Integer
6
+
7
+ MAX_STREAM_ID: Integer
8
+
9
+ MAX_WINDOWINC: Integer
10
+
11
+ FRAME_TYPES: Hash[Symbol, Integer]
12
+
13
+ FRAME_TYPES_WITH_PADDING: Array[Symbol]
14
+
15
+ FRAME_FLAGS: Hash[Symbol, Hash[Symbol, Integer]]
16
+
17
+ DEFINED_SETTINGS: Hash[Symbol, Integer]
18
+
19
+ DEFINED_ERRORS: Hash[Symbol, Integer]
20
+
21
+ RBIT: Integer
22
+ RBYTE: Integer
23
+ EBIT: Integer
24
+ UINT32: String
25
+ UINT16: String
26
+ UINT8: String
27
+ HEADERPACK: String
28
+ FRAME_LENGTH_HISHIFT: Integer
29
+ FRAME_LENGTH_LOMASK: Integer
30
+
31
+ @local_max_frame_size: Integer
32
+ @remote_max_frame_size: Integer
33
+
34
+ attr_accessor local_max_frame_size: Integer
35
+
36
+ attr_accessor remote_max_frame_size: Integer
37
+
38
+ def common_header: (frame, buffer: String) -> String
39
+
40
+ def read_common_frame: (String) -> frame
41
+
42
+ def generate: (frame) -> String
43
+
44
+ def parse: (String) -> frame?
45
+
46
+ private
47
+
48
+ def initialize: (?Integer local_max_frame_size, ?Integer remote_max_frame_size) -> untyped
49
+
50
+ def pack_error: (Integer | Symbol error, buffer: String) -> String
51
+
52
+ def unpack_error: (Integer) -> (Symbol | Integer)
53
+ end
54
+ end
@@ -0,0 +1,27 @@
1
+ module HTTP2
2
+ module Header
3
+ class Compressor
4
+ include PackingExtensions
5
+
6
+ @cc: EncodingContext
7
+
8
+ def table_size=: (Integer) -> void
9
+
10
+ def integer: (Integer, Integer, buffer: String, ?offset: Integer) -> String
11
+
12
+ def string: (String) -> String
13
+
14
+ def header: (header_command, ?String) -> String
15
+
16
+ def encode: (Enumerable[header_pair]) -> String
17
+
18
+ private
19
+
20
+ def initialize: (?context_hash options) -> void
21
+
22
+ def huffman_string: (String str) -> String
23
+
24
+ def plain_string: (String str) -> String
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ module HTTP2
2
+ module Header
3
+ class Decompressor
4
+ @cc: EncodingContext
5
+
6
+ def table_size=: (Integer) -> void
7
+
8
+ def integer: (String, Integer) -> Integer
9
+
10
+ def string: (String) -> String
11
+
12
+ def header: (String) -> header_command
13
+
14
+ def decode: (String, frame?) -> Array[header_pair]
15
+ | (String) -> Array[header_pair]
16
+ private
17
+
18
+ def initialize: (context_hash options) -> untyped
19
+ | () -> untyped
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,34 @@
1
+ module HTTP2
2
+ module Header
3
+ class EncodingContext
4
+ STATIC_TABLE: Array[header_pair]
5
+
6
+ attr_reader table: Array[header_pair]
7
+
8
+ attr_reader options: context_hash
9
+
10
+ def dup: () -> EncodingContext
11
+
12
+ def dereference: (Integer) -> header_pair
13
+
14
+ def process: (header_command cmd) -> header_pair?
15
+
16
+ def encode: (_Each[header_pair]) -> Array[header_command]
17
+
18
+ def addcmd: (String name, String value) -> header_command
19
+
20
+ def table_size=: (Integer) -> void
21
+
22
+ def current_table_size: () -> Integer
23
+
24
+ private
25
+
26
+ def initialize: (context_hash options) -> untyped
27
+ | () -> untyped
28
+
29
+ def add_to_table: (header_pair) -> void
30
+
31
+ def size_check: (header_pair?) -> bool
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ module HTTP2
2
+ module Header
3
+ class Huffman
4
+ def encode: (String str) -> String
5
+
6
+ def decode: (String str) -> String
7
+ end
8
+ end
9
+ end
data/sig/header.rbs ADDED
@@ -0,0 +1,27 @@
1
+ module HTTP2
2
+ module Header
3
+ type header_key = :type | :name | :value | :index
4
+ type header_value = Integer | String | :indexed | :changetablesize | :incremental | :noindex | :neverindexed
5
+
6
+ #type context_hash = {
7
+ # huffman?: (:always | :never | :shorter),
8
+ # index?: (:all | :static | :never),
9
+ # table_size?: Integer
10
+ #}
11
+ type context_hash = Hash[Symbol, Symbol | Integer]
12
+
13
+ type header_command = Hash[header_key, header_value]
14
+
15
+ HEADREP: Hash[Symbol, Hash[Symbol, Integer]]
16
+
17
+ NAIVE: Hash[Symbol, Symbol]
18
+ LINEAR: Hash[Symbol, Symbol]
19
+ STATIC: Hash[Symbol, Symbol]
20
+ SHORTER: Hash[Symbol, Symbol]
21
+ NAIVEH: Hash[Symbol, Symbol]
22
+ LINEARH: Hash[Symbol, Symbol]
23
+ STATICH: Hash[Symbol, Symbol]
24
+ SHORTERH: Hash[Symbol, Symbol]
25
+
26
+ end
27
+ end
data/sig/next.rbs ADDED
@@ -0,0 +1,101 @@
1
+ module HTTP2
2
+ VERSION: String
3
+
4
+ DEFAULT_FLOW_WINDOW: Integer
5
+
6
+ DEFAULT_HEADER_SIZE: Integer
7
+
8
+ DEFAULT_MAX_CONCURRENT_STREAMS: Integer
9
+
10
+ type settings_hash = Hash[Symbol, Integer]
11
+
12
+ type settings_ary = Array[settings_enum]
13
+
14
+ type settings_enum = Enumerable[[Symbol, Integer]]
15
+
16
+ SPEC_DEFAULT_CONNECTION_SETTINGS: settings_hash
17
+
18
+ DEFAULT_CONNECTION_SETTINGS: settings_hash
19
+
20
+ DEFAULT_WEIGHT: Integer
21
+
22
+ CONNECTION_PREFACE_MAGIC: String
23
+
24
+ REQUEST_MANDATORY_HEADERS: Array[String]
25
+
26
+ RESPONSE_MANDATORY_HEADERS: Array[String]
27
+
28
+ type header_pair = [string, string]
29
+
30
+ # # FRAMES
31
+ type frame_control_flags = Array[:end_headers | :end_stream]
32
+
33
+ # # HEADERS
34
+ # type headers_frame = {
35
+ # type: :headers, flags: frame_control_flags, stream: Integer, payload: Enumerable[header_pair],
36
+ # ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, ?padding: Integer
37
+ # }
38
+
39
+ # # DATA
40
+ type data_frame = { type: :data, flags: frame_control_flags, stream: Integer, length: Integer, payload: String, padding: Integer }
41
+ | { type: :data, flags: frame_control_flags, stream: Integer, length: Integer, payload: String }
42
+ | { type: :data, flags: frame_control_flags, payload: String }
43
+
44
+ # # PUSH_PROMISE
45
+ # type push_promise_frame = { type: :push_promise, promise_stream: Integer, flags: frame_control_flags, stream: Integer, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair], ?padding: Integer }
46
+
47
+ # # SETTINGS
48
+ # type settings_frame = { type: :settings, stream: 0, payload: Array[[Symbol | Integer, Integer]] }
49
+
50
+ # # WINDOW_UPDATE
51
+ # type window_update_frame = { type: :window_update, stream: Integer, increment: Integer }
52
+
53
+ # # PRIORITY
54
+ type priority_frame = { type: :priority, stream: Integer, dependency: Integer, exclusive: bool, weight: Integer }
55
+
56
+ # # ALTSVC
57
+ # type altsvc_frame = { type: :altsvc, stream: 0, max_age: Integer, port: Integer, proto: "String", host: String }
58
+
59
+ # # ORIGIN
60
+ # type origin_frame = { type: :origin, stream: 0, origin: Array[String] }
61
+
62
+ # # PING
63
+ # type ping_frame = { type: :ping, payload: String, length: Integer }
64
+
65
+ # # GOAWAY
66
+ # type goaway_frame = { type: :goaway, stream: 0, last_stream: Integer, error: Symbol? }
67
+
68
+ # type frame = headers_frame | data_frame | push_promise_frame |
69
+ # settings_frame | window_update_frame | priority_frame | altsvc_frame |
70
+ # origin_frame | ping_frame | goaway_frame
71
+
72
+ type frame_key = :type | :flags | :stream | :padding | :ignore |
73
+ # headers
74
+ :method | :trailer | :content_length | :status |
75
+ # data, settings, ping
76
+ :payload | :length |
77
+ # promise
78
+ :promise_stream |
79
+ # window_update
80
+ :increment |
81
+ # priority
82
+ :dependency | :exclusive | :weight |
83
+ # altsvc
84
+ :max_age | :port | :proto | :host |
85
+ # origin
86
+ :origin |
87
+ # goaway
88
+ :last_stream | :error
89
+
90
+ type frame_value = Integer |
91
+ Symbol | # type (:data, :headers)
92
+ Array[Symbol] |
93
+ String |
94
+ bool |
95
+ Array[String] |
96
+ Array[[Symbol | Integer, Integer]] |
97
+ Enumerable[header_pair] |
98
+ nil
99
+
100
+ type frame = Hash[frame_key, frame_value]
101
+ end
data/sig/server.rbs ADDED
@@ -0,0 +1,12 @@
1
+ module HTTP2
2
+ class Server < Connection
3
+
4
+ def upgrade: (String settings, Enumerable[header_pair] headers, String body) -> void
5
+
6
+ def origin_set=: (Array[_ToS]) -> void
7
+
8
+ private
9
+
10
+ def promise: (Stream parent, Enumerable[header_pair] headers, Array[Symbol] flags) { (Stream) -> void } -> void
11
+ end
12
+ end
data/sig/stream.rbs ADDED
@@ -0,0 +1,91 @@
1
+ module HTTP2
2
+ class Stream
3
+ include FlowBuffer
4
+ include Emitter
5
+
6
+ attr_reader id: Integer
7
+ attr_reader state: Symbol
8
+ attr_reader parent: Stream?
9
+ attr_reader weight: Integer
10
+ attr_reader dependency: Integer
11
+ attr_reader remote_window: Integer
12
+ attr_reader local_window: Integer
13
+ attr_reader closed: Symbol?
14
+
15
+ @connection: Connection
16
+ @local_window_max_size: Integer
17
+ @error: bool
18
+ @_method: String?
19
+ @_content_length: Integer?
20
+ @_status_code: Integer?
21
+ @_waiting_on_trailers: bool
22
+ @received_data: bool
23
+ @activated: bool
24
+
25
+ alias window local_window
26
+
27
+ def closed?: () -> bool
28
+
29
+ def receive: (frame) -> void
30
+
31
+ alias << receive
32
+
33
+ def verify_trailers: (frame) -> void
34
+
35
+ def calculate_content_length: (Integer?) -> void
36
+
37
+ def send: (frame) -> void
38
+
39
+ def headers: (Enumerable[header_pair] headers, ?end_headers: bool, ?end_stream: bool) -> void
40
+
41
+ def promise: (Enumerable[header_pair] headers, ?end_headers: bool) { (Stream) -> void } -> void
42
+
43
+ def reprioritize: (?weight: Integer, ?dependency: Integer, ?exclusive: bool) -> void
44
+
45
+ def data: (String payload, ?end_stream: bool) -> void
46
+
47
+ def chunk_data: (String payload, Integer max_size) { (String) -> void } -> String
48
+
49
+ def close: (Symbol error) -> void
50
+ | () -> void
51
+
52
+ def cancel: () -> void
53
+
54
+ def refuse: () -> void
55
+
56
+ def window_update: (Integer increment) -> void
57
+
58
+ private
59
+
60
+ def initialize: (
61
+ connection: Connection,
62
+ id: Integer,
63
+ ?weight: Integer,
64
+ ?dependency: Integer,
65
+ ?exclusive: bool,
66
+ ?parent: Stream?,
67
+ ?state: Symbol
68
+ ) -> untyped
69
+
70
+ def transition: (frame, bool sending) -> void
71
+
72
+ def event: (Symbol newstate) -> void
73
+
74
+ def activate_stream_in_conn: () -> void
75
+
76
+ def close_stream_in_conn: (*untyped) -> void
77
+
78
+ def complete_transition: (frame) -> void
79
+
80
+ def process_priority: ({weight: Integer, dependency: Integer, exclusive: bool}) -> void
81
+
82
+ def end_frame?: () -> bool
83
+
84
+ def stream_error: (Symbol error, ?msg: String?) -> void
85
+ | () -> void
86
+
87
+ alias error stream_error
88
+
89
+ def manage_state: (frame) { () -> void } -> void
90
+ end
91
+ end