http-2 0.11.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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