biryani 0.0.8 → 0.0.10

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/README.md +2 -2
  4. data/biryani.gemspec +5 -2
  5. data/example/echo.rb +2 -2
  6. data/example/hello_world.rb +2 -2
  7. data/lib/biryani/connection.rb +62 -47
  8. data/lib/biryani/connection_error.rb +1 -1
  9. data/lib/biryani/frame/goaway.rb +5 -3
  10. data/lib/biryani/hpack/field.rb +5 -9
  11. data/lib/biryani/http/error.rb +10 -0
  12. data/lib/biryani/http/request.rb +97 -0
  13. data/lib/biryani/http/response.rb +68 -0
  14. data/lib/biryani/http.rb +3 -0
  15. data/lib/biryani/state.rb +1 -1
  16. data/lib/biryani/stream.rb +3 -3
  17. data/lib/biryani/streams_context.rb +16 -16
  18. data/lib/biryani/version.rb +1 -1
  19. data/lib/biryani.rb +1 -3
  20. metadata +7 -77
  21. data/.github/workflows/ci.yml +0 -30
  22. data/.github/workflows/conformance.yml +0 -46
  23. data/.gitignore +0 -18
  24. data/lib/biryani/error.rb +0 -8
  25. data/lib/biryani/http_request.rb +0 -95
  26. data/lib/biryani/http_response.rb +0 -66
  27. data/spec/connection/handle_connection_window_update_spec.rb +0 -16
  28. data/spec/connection/handle_data_spec.rb +0 -58
  29. data/spec/connection/handle_headers_spec.rb +0 -19
  30. data/spec/connection/handle_ping_spec.rb +0 -21
  31. data/spec/connection/handle_rst_stream_spec.rb +0 -16
  32. data/spec/connection/handle_settings_spec.rb +0 -37
  33. data/spec/connection/handle_stream_window_update_spec.rb +0 -20
  34. data/spec/connection/read_http2_magic_spec.rb +0 -26
  35. data/spec/connection/send_spec.rb +0 -104
  36. data/spec/connection/transition_stream_state_send_spec.rb +0 -39
  37. data/spec/data_buffer_spec.rb +0 -135
  38. data/spec/frame/continuation_spec.rb +0 -39
  39. data/spec/frame/data_spec.rb +0 -25
  40. data/spec/frame/goaway_spec.rb +0 -23
  41. data/spec/frame/headers_spec.rb +0 -52
  42. data/spec/frame/ping_spec.rb +0 -22
  43. data/spec/frame/priority_spec.rb +0 -22
  44. data/spec/frame/push_promise_spec.rb +0 -24
  45. data/spec/frame/read_spec.rb +0 -30
  46. data/spec/frame/rst_stream_spec.rb +0 -21
  47. data/spec/frame/settings_spec.rb +0 -23
  48. data/spec/frame/window_update_spec.rb +0 -21
  49. data/spec/hpack/decoder_spec.rb +0 -170
  50. data/spec/hpack/encoder_spec.rb +0 -48
  51. data/spec/hpack/field_spec.rb +0 -43
  52. data/spec/hpack/fields_spec.rb +0 -17
  53. data/spec/hpack/huffman_spec.rb +0 -20
  54. data/spec/hpack/integer_spec.rb +0 -27
  55. data/spec/hpack/string_spec.rb +0 -19
  56. data/spec/http_request_spec.rb +0 -62
  57. data/spec/http_response_spec.rb +0 -12
  58. data/spec/spec_helper.rb +0 -9
  59. data/spec/streams_context_spec.rb +0 -79
  60. data/spec/utils_spec.rb +0 -41
data/lib/biryani.rb CHANGED
@@ -3,11 +3,9 @@ require 'uri'
3
3
  require_relative 'biryani/connection_error'
4
4
  require_relative 'biryani/connection'
5
5
  require_relative 'biryani/data_buffer'
6
- require_relative 'biryani/error'
7
6
  require_relative 'biryani/frame'
8
7
  require_relative 'biryani/hpack'
9
- require_relative 'biryani/http_request'
10
- require_relative 'biryani/http_response'
8
+ require_relative 'biryani/http'
11
9
  require_relative 'biryani/server'
12
10
  require_relative 'biryani/state'
13
11
  require_relative 'biryani/stream_error'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: biryani
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - thekuwayama
@@ -30,9 +30,6 @@ executables: []
30
30
  extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
- - ".github/workflows/ci.yml"
34
- - ".github/workflows/conformance.yml"
35
- - ".gitignore"
36
33
  - ".rubocop.yml"
37
34
  - ".ruby-version"
38
35
  - Gemfile
@@ -49,7 +46,6 @@ files:
49
46
  - lib/biryani/connection.rb
50
47
  - lib/biryani/connection_error.rb
51
48
  - lib/biryani/data_buffer.rb
52
- - lib/biryani/error.rb
53
49
  - lib/biryani/frame.rb
54
50
  - lib/biryani/frame/continuation.rb
55
51
  - lib/biryani/frame/data.rb
@@ -73,8 +69,10 @@ files:
73
69
  - lib/biryani/hpack/integer.rb
74
70
  - lib/biryani/hpack/option.rb
75
71
  - lib/biryani/hpack/string.rb
76
- - lib/biryani/http_request.rb
77
- - lib/biryani/http_response.rb
72
+ - lib/biryani/http.rb
73
+ - lib/biryani/http/error.rb
74
+ - lib/biryani/http/request.rb
75
+ - lib/biryani/http/response.rb
78
76
  - lib/biryani/server.rb
79
77
  - lib/biryani/state.rb
80
78
  - lib/biryani/stream.rb
@@ -83,40 +81,6 @@ files:
83
81
  - lib/biryani/utils.rb
84
82
  - lib/biryani/version.rb
85
83
  - lib/biryani/window.rb
86
- - spec/connection/handle_connection_window_update_spec.rb
87
- - spec/connection/handle_data_spec.rb
88
- - spec/connection/handle_headers_spec.rb
89
- - spec/connection/handle_ping_spec.rb
90
- - spec/connection/handle_rst_stream_spec.rb
91
- - spec/connection/handle_settings_spec.rb
92
- - spec/connection/handle_stream_window_update_spec.rb
93
- - spec/connection/read_http2_magic_spec.rb
94
- - spec/connection/send_spec.rb
95
- - spec/connection/transition_stream_state_send_spec.rb
96
- - spec/data_buffer_spec.rb
97
- - spec/frame/continuation_spec.rb
98
- - spec/frame/data_spec.rb
99
- - spec/frame/goaway_spec.rb
100
- - spec/frame/headers_spec.rb
101
- - spec/frame/ping_spec.rb
102
- - spec/frame/priority_spec.rb
103
- - spec/frame/push_promise_spec.rb
104
- - spec/frame/read_spec.rb
105
- - spec/frame/rst_stream_spec.rb
106
- - spec/frame/settings_spec.rb
107
- - spec/frame/window_update_spec.rb
108
- - spec/hpack/decoder_spec.rb
109
- - spec/hpack/encoder_spec.rb
110
- - spec/hpack/field_spec.rb
111
- - spec/hpack/fields_spec.rb
112
- - spec/hpack/huffman_spec.rb
113
- - spec/hpack/integer_spec.rb
114
- - spec/hpack/string_spec.rb
115
- - spec/http_request_spec.rb
116
- - spec/http_response_spec.rb
117
- - spec/spec_helper.rb
118
- - spec/streams_context_spec.rb
119
- - spec/utils_spec.rb
120
84
  homepage: https://github.com/thekuwayama/biryani
121
85
  licenses:
122
86
  - MIT
@@ -135,41 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
99
  - !ruby/object:Gem::Version
136
100
  version: '0'
137
101
  requirements: []
138
- rubygems_version: 4.0.6
102
+ rubygems_version: 4.0.8
139
103
  specification_version: 4
140
104
  summary: An HTTP/2 server implemented using Ruby Ractor
141
- test_files:
142
- - spec/connection/handle_connection_window_update_spec.rb
143
- - spec/connection/handle_data_spec.rb
144
- - spec/connection/handle_headers_spec.rb
145
- - spec/connection/handle_ping_spec.rb
146
- - spec/connection/handle_rst_stream_spec.rb
147
- - spec/connection/handle_settings_spec.rb
148
- - spec/connection/handle_stream_window_update_spec.rb
149
- - spec/connection/read_http2_magic_spec.rb
150
- - spec/connection/send_spec.rb
151
- - spec/connection/transition_stream_state_send_spec.rb
152
- - spec/data_buffer_spec.rb
153
- - spec/frame/continuation_spec.rb
154
- - spec/frame/data_spec.rb
155
- - spec/frame/goaway_spec.rb
156
- - spec/frame/headers_spec.rb
157
- - spec/frame/ping_spec.rb
158
- - spec/frame/priority_spec.rb
159
- - spec/frame/push_promise_spec.rb
160
- - spec/frame/read_spec.rb
161
- - spec/frame/rst_stream_spec.rb
162
- - spec/frame/settings_spec.rb
163
- - spec/frame/window_update_spec.rb
164
- - spec/hpack/decoder_spec.rb
165
- - spec/hpack/encoder_spec.rb
166
- - spec/hpack/field_spec.rb
167
- - spec/hpack/fields_spec.rb
168
- - spec/hpack/huffman_spec.rb
169
- - spec/hpack/integer_spec.rb
170
- - spec/hpack/string_spec.rb
171
- - spec/http_request_spec.rb
172
- - spec/http_response_spec.rb
173
- - spec/spec_helper.rb
174
- - spec/streams_context_spec.rb
175
- - spec/utils_spec.rb
105
+ test_files: []
@@ -1,30 +0,0 @@
1
- name: lint & test
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
- pull_request:
8
- branches:
9
- - '*'
10
-
11
- jobs:
12
- ci:
13
- runs-on: ubuntu-latest
14
- strategy:
15
- matrix:
16
- ruby-version: ['4.0']
17
- steps:
18
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
19
- - name: Set up Ruby
20
- uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0
21
- with:
22
- ruby-version: ${{ matrix.ruby-version }}
23
- - name: Install dependencies
24
- run: |
25
- gem --version
26
- gem install bundler
27
- bundle --version
28
- bundle install
29
- - name: Run rubocop & rspec
30
- run: bundle exec rake
@@ -1,46 +0,0 @@
1
- name: h2spec
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
- pull_request:
8
- branches:
9
- - '*'
10
-
11
- jobs:
12
- conformance:
13
- runs-on: ubuntu-latest
14
- permissions:
15
- contents: read
16
- checks: write
17
- strategy:
18
- matrix:
19
- ruby-version: ['4.0']
20
- steps:
21
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
22
- - name: Set up Ruby
23
- uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0
24
- with:
25
- ruby-version: ${{ matrix.ruby-version }}
26
- - name: Install dependencies
27
- run: |
28
- gem --version
29
- gem install bundler
30
- bundle --version
31
- bundle install
32
- - name: Install h2spec
33
- run: |
34
- set -eu
35
- curl -Ls https://github.com/summerwind/h2spec/releases/download/v2.6.0/h2spec_linux_amd64.tar.gz | tar xz
36
- mkdir -p $GITHUB_WORKSPACE/bin
37
- mv h2spec $GITHUB_WORKSPACE/bin/h2spec
38
- chmod +x $GITHUB_WORKSPACE/bin/h2spec
39
- echo $GITHUB_WORKSPACE/bin >> $GITHUB_PATH
40
- - name: Run conformance test
41
- run: bundle exec rake conformance
42
- - uses: mikepenz/action-junit-report@a294a61c909bd8a4b563024a2faa28897fd53ebc # v6.1.0
43
- if: success()
44
- with:
45
- report_paths: conformance/reports/h2spec.xml
46
- detailed_summary: true
data/.gitignore DELETED
@@ -1,18 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .config
4
- .rvmrc
5
- /.bundle/
6
- /vendor/
7
- /lib/bundler/man/
8
- /pkg/
9
- /.yardoc/
10
- /_yardoc/
11
- /doc/
12
- /rdoc/
13
- /coverage/
14
- /spec/reports/
15
- /conformance/reports/
16
- /tmp/
17
- .DS_Store
18
- Gemfile.lock
data/lib/biryani/error.rb DELETED
@@ -1,8 +0,0 @@
1
- module Biryani
2
- module Error
3
- # Generic error, common for all classes under Biryani::Error module.
4
- class Error < StandardError; end
5
-
6
- class InvalidHTTPResponseError < Error; end
7
- end
8
- end
@@ -1,95 +0,0 @@
1
- module Biryani
2
- class HTTPRequest
3
- attr_accessor :method, :uri, :fields, :content
4
-
5
- # @param method [String]
6
- # @param uri [URI]
7
- # @param fields [Hash<String, Array<String>>]
8
- # @param content [String]
9
- def initialize(method, uri, fields, content)
10
- @method = method
11
- @uri = uri
12
- @fields = fields
13
- @content = content
14
- end
15
-
16
- # @return [Array<String>, nil]
17
- def trailers
18
- # https://datatracker.ietf.org/doc/html/rfc9110#section-6.6.2-4
19
- keys = (@fields['trailer'] || []).flat_map { |x| x.split(',').map(&:strip) }
20
- @fields.slice(*keys)
21
- end
22
- end
23
-
24
- class HTTPRequestBuilder
25
- PSEUDO_HEADER_FIELDS = [':authority', ':method', ':path', ':scheme'].freeze
26
- Ractor.make_shareable(PSEUDO_HEADER_FIELDS)
27
-
28
- def initialize
29
- @h = {}
30
- end
31
-
32
- # @param name [String]
33
- # @param value [String]
34
- #
35
- # @return [nil, ConnectioError]
36
- # rubocop: disable Metrics/AbcSize
37
- # rubocop: disable Metrics/CyclomaticComplexity
38
- # rubocop: disable Metrics/PerceivedComplexity
39
- def field(name, value)
40
- return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, 'field name has uppercase letter') if name.downcase != name
41
- return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, 'unknown pseudo-header field name') if name[0] == ':' && !PSEUDO_HEADER_FIELDS.include?(name)
42
- return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, 'appear pseudo-header fields after regular fields') if name[0] == ':' && @h.any? { |name_, _| name_[0] != ':' }
43
- return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, 'duplicated pseudo-header fields') if PSEUDO_HEADER_FIELDS.include?(name) && @h.key?(name)
44
- return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, "invalid `#{name}` field") if PSEUDO_HEADER_FIELDS.include?(name) && value.empty?
45
- return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, 'connection-specific field is forbidden') if name == 'connection'
46
- return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, '`TE` field has a value other than `trailers`') if name == 'te' && value != 'trailers'
47
-
48
- @h[name] = [] unless @h.key?(name)
49
- @h[name] << value
50
-
51
- nil
52
- end
53
- # rubocop: enable Metrics/AbcSize
54
- # rubocop: enable Metrics/CyclomaticComplexity
55
- # rubocop: enable Metrics/PerceivedComplexity
56
-
57
- # @param arr [Array]
58
- #
59
- # @return [nil, ConnectioError]
60
- def fields(arr)
61
- arr.each do |name, value|
62
- err = field(name, value)
63
- return err unless err.nil?
64
- end
65
-
66
- nil
67
- end
68
-
69
- # @param s [String]
70
- #
71
- # @return [HTTPRequest]
72
- def build(s)
73
- # `Ractor.send(req, move: true)` moves entries in HPACK::DynamicTable; therefore, a `dup` call is required.
74
- h = @h.transform_values { |x| x.map(&:dup) }
75
- self.class.http_request(h, s)
76
- end
77
-
78
- # @param h [Hash<String, Array<String>>]
79
- # @param s [String]
80
- #
81
- # @return [HTTPRequest, ConnectionError]
82
- def self.http_request(h, s)
83
- return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, 'missing pseudo-header fields') unless PSEUDO_HEADER_FIELDS.all? { |x| h.key?(x) }
84
- return ConnectionError.new(ErrorCode::PROTOCOL_ERROR, 'invalid content-length') if h.key?('content-length') && !s.empty? && s.length != h['content-length'].to_i
85
-
86
- scheme = h[':scheme'][0]
87
- domain = h[':authority'][0]
88
- path = h[':path'][0]
89
- uri = URI("#{scheme}://#{domain}#{path}")
90
- method = h[':method'][0]
91
- h['cookie'] = [h['cookie'].join('; ')] if h.key?('cookie')
92
- HTTPRequest.new(method, uri, h, s)
93
- end
94
- end
95
- end
@@ -1,66 +0,0 @@
1
- module Biryani
2
- class HTTPResponse
3
- FORBIDDEN_KEY_CHARS = (0x00..0x20).chain([0x3a]).chain(0x41..0x5a).chain(0x7f..0xff).to_a.freeze
4
- FORBIDDEN_VALUE_CHARS = [0x00, 0x0a, 0x0d].freeze
5
-
6
- attr_accessor :status, :fields, :content
7
-
8
- # @param status [Integer]
9
- # @param fields [Hash]
10
- # @param content [String, nil]
11
- def initialize(status, fields, content)
12
- @status = status
13
- @fields = fields
14
- @content = content
15
- end
16
-
17
- # @raise [InvalidHTTPResponseError]
18
- # rubocop: disable Metrics/CyclomaticComplexity
19
- def validate
20
- # https://datatracker.ietf.org/doc/html/rfc9113#section-8.2.1
21
- raise Error::InvalidHTTPResponseError, 'invalid HTTP status' if @status < 100 || @status >= 600
22
- raise Error::InvalidHTTPResponseError, 'HTTP field name contains invalid characters' if (@fields.keys.join.downcase.bytes.uniq & FORBIDDEN_KEY_CHARS).any?
23
- raise Error::InvalidHTTPResponseError, 'HTTP field value contains NUL, LF or CR' if (@fields.values.join.bytes.uniq & FORBIDDEN_VALUE_CHARS).any?
24
- raise Error::InvalidHTTPResponseError, 'HTTP field value starts/ends with SP or HTAB' if @fields.values.filter { |s| s.start_with?("\t", ' ') || s.end_with?("\t", ' ') }.any?
25
- end
26
- # rubocop: enable Metrics/CyclomaticComplexity
27
-
28
- def self.default
29
- HTTPResponse.new(0, {}, nil)
30
- end
31
-
32
- def self.internal_server_error
33
- HTTPResponse.new(500, {}, 'Internal Server Error')
34
- end
35
- end
36
-
37
- class HTTPResponseParser
38
- # @param res [HTTPResponse]
39
- def initialize(res)
40
- @res = res
41
- end
42
-
43
- # @return [Array]
44
- def fields
45
- fields = [[':status', @res.status.to_s]]
46
- @res.fields.each do |name, value|
47
- fields << [name.to_s.downcase, value.to_s]
48
- end
49
-
50
- fields
51
- end
52
-
53
- # @return [String]
54
- def content
55
- @res.content
56
- end
57
-
58
- # @param encoder [Encoder]
59
- #
60
- # @return [String] fragment
61
- # @return [String] data
62
- def parse(encoder)
63
- [encoder.encode(fields), content]
64
- end
65
- end
66
- end
@@ -1,16 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- RSpec.describe Connection do
4
- context 'handle_connection_window_update' do
5
- let(:window_update) do
6
- Frame::WindowUpdate.new(0, 1000)
7
- end
8
- let(:send_window) do
9
- Window.new(65_535)
10
- end
11
- it 'should handle' do
12
- expect { Connection.handle_connection_window_update(window_update, send_window) }.not_to raise_error
13
- expect(send_window.length).to eq 2**16 - 1 + 1000
14
- end
15
- end
16
- end
@@ -1,58 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- RSpec.describe Connection do
4
- context 'handle_data' do
5
- let(:decoder) do
6
- HPACK::Decoder.new(4_096)
7
- end
8
-
9
- let(:recv_window1) do
10
- Window.new(65_535)
11
- end
12
- let(:streams_ctx1) do
13
- streams_ctx = StreamsContext.new(do_nothing_proc)
14
- streams_ctx.new_context(1, 65_535, 65_535)
15
- streams_ctx.new_context(2, 65_535, 65_535)
16
- streams_ctx
17
- end
18
- it 'should handle' do
19
- expect(Connection.handle_data(2, 'Hello, world!', recv_window1, streams_ctx1, decoder)).to eq []
20
- expect(streams_ctx1[2].content).to eq 'Hello, world!'
21
- end
22
-
23
- let(:recv_window2) do
24
- recv_window = Window.new(65_535)
25
- recv_window.consume!(65_535 / 2)
26
- recv_window
27
- end
28
- let(:streams_ctx2) do
29
- streams_ctx = StreamsContext.new(do_nothing_proc)
30
- streams_ctx.new_context(1, 65_535, 65_535)
31
- streams_ctx.new_context(2, 65_535, 65_535)
32
- streams_ctx[2].recv_window.consume!(65_535 / 2)
33
- streams_ctx
34
- end
35
- it 'should handle' do
36
- frames = Connection.handle_data(2, 'Hello, world!', recv_window2, streams_ctx2, decoder)
37
- expect(frames.map(&:f_type)).to eq [FrameType::WINDOW_UPDATE, FrameType::WINDOW_UPDATE]
38
- expect(frames.map(&:stream_id)).to eq [0, 2]
39
- expect(frames.map(&:window_size_increment)).to eq [65_535 / 2 + 13, 65_535 / 2 + 13]
40
- expect(streams_ctx2[2].content).to eq 'Hello, world!'
41
- end
42
-
43
- let(:recv_window3) do
44
- recv_window = Window.new(65_535)
45
- recv_window.consume!(65_535)
46
- recv_window
47
- end
48
- let(:streams_ctx3) do
49
- streams_ctx = StreamsContext.new(do_nothing_proc)
50
- streams_ctx.new_context(1, 65_535, 65_535)
51
- streams_ctx.new_context(2, 65_535, 65_535)
52
- streams_ctx
53
- end
54
- it 'should not handle' do
55
- expect(Connection.handle_data(2, 'Hello, world!', recv_window3, streams_ctx3, decoder)).to be_kind_of ConnectionError
56
- end
57
- end
58
- end
@@ -1,19 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- RSpec.describe Connection do
4
- context 'handle_headers' do
5
- let(:headers) do
6
- Frame::Headers.new(true, false, 2, nil, nil, 'this is dummy', nil)
7
- end
8
- let(:ctx) do
9
- StreamContext.new(2, 65_535, 65_535, do_nothing_proc)
10
- end
11
- let(:decoder) do
12
- HPACK::Decoder.new(4_096)
13
- end
14
- it 'should handle' do
15
- expect(Connection.handle_headers(headers, ctx, decoder)).to eq nil
16
- expect(ctx.fragment).to eq 'this is dummy'
17
- end
18
- end
19
- end
@@ -1,21 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- RSpec.describe Connection do
4
- context 'handle_ping' do
5
- let(:ping1) do
6
- Frame::Ping.new(true, 0, "\x00" * 8)
7
- end
8
- it 'should handle' do
9
- expect(Connection.handle_ping(ping1)).to eq nil
10
- end
11
-
12
- let(:ping2) do
13
- Frame::Ping.new(false, 0, "\x00" * 8)
14
- end
15
- it 'should handle' do
16
- expect(Connection.handle_ping(ping2)).to_not eq nil
17
- expect(Connection.handle_ping(ping2).ack?).to eq true
18
- expect(Connection.handle_ping(ping2).opaque).to eq "\x00" * 8
19
- end
20
- end
21
- end
@@ -1,16 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- RSpec.describe Connection do
4
- context 'handle_rst_stream' do
5
- let(:rst_stream) do
6
- Frame::RstStream.new(2, 0)
7
- end
8
- let(:ctx) do
9
- StreamContext.new(2, 65_535, 65_535, do_nothing_proc)
10
- end
11
- it 'should handle' do
12
- Connection.handle_rst_stream(rst_stream, ctx)
13
- expect(ctx.closed?).to eq true
14
- end
15
- end
16
- end
@@ -1,37 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- RSpec.describe Connection do
4
- context 'handle_settings' do
5
- let(:send_settings) do
6
- Connection.default_settings
7
- end
8
- let(:decoder) do
9
- HPACK::Decoder.new(4_096)
10
- end
11
- let(:streams_ctx) do
12
- streams_ctx = StreamsContext.new(do_nothing_proc)
13
- streams_ctx.new_context(1, 65_535, 65_535)
14
- streams_ctx.new_context(2, 65_535, 65_535)
15
- streams_ctx
16
- end
17
-
18
- let(:settings1) do
19
- Frame::Settings.new(false, 0, { SettingsID::SETTINGS_HEADER_TABLE_SIZE => 8_192 })
20
- end
21
- it 'should handle' do
22
- reply_settings = Connection.handle_settings(settings1, send_settings, decoder, streams_ctx)
23
- expect(reply_settings.ack?).to eq true
24
- expect(reply_settings.setting.empty?).to eq true
25
- expect(send_settings[SettingsID::SETTINGS_MAX_CONCURRENT_STREAMS]).to eq 0xffffffff
26
- expect(send_settings[SettingsID::SETTINGS_MAX_FRAME_SIZE]).to eq 16_384
27
- expect(send_settings[SettingsID::SETTINGS_HEADER_TABLE_SIZE]).to eq 8_192
28
- end
29
-
30
- let(:settings2) do
31
- Frame::Settings.new(true, 0, {})
32
- end
33
- it 'should handle' do
34
- expect(Connection.handle_settings(settings2, send_settings, decoder, streams_ctx)).to eq nil
35
- end
36
- end
37
- end
@@ -1,20 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- RSpec.describe Connection do
4
- context 'handle_stream_window_update' do
5
- let(:window_update) do
6
- Frame::WindowUpdate.new(1, 1000)
7
- end
8
- let(:streams_ctx) do
9
- streams_ctx = StreamsContext.new(do_nothing_proc)
10
- streams_ctx.new_context(1, 65_535, 65_535)
11
- streams_ctx.new_context(2, 65_535, 65_535)
12
- streams_ctx
13
- end
14
- it 'should handle' do
15
- expect { Connection.handle_stream_window_update(window_update, streams_ctx) }.not_to raise_error
16
- expect(streams_ctx[1].send_window.length).to eq 65_535 + 1000
17
- expect(streams_ctx[2].send_window.length).to eq 65_535
18
- end
19
- end
20
- end
@@ -1,26 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- RSpec.describe Connection do
4
- context 'read_http2_magic' do
5
- let(:io1) do
6
- StringIO.new("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n")
7
- end
8
- it 'should read' do
9
- expect(Connection.read_http2_magic(io1)).to eq nil
10
- end
11
-
12
- let(:io2) do
13
- StringIO.new("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n\x00xff")
14
- end
15
- it 'should read' do
16
- expect(Connection.read_http2_magic(io2)).to eq nil
17
- end
18
-
19
- let(:io3) do
20
- StringIO.new("\x00xffPRI * HTTP/2.0\r\n\r\nSM\r\n\r\n")
21
- end
22
- it 'should not read' do
23
- expect(Connection.read_http2_magic(io3)).to be_kind_of ConnectionError
24
- end
25
- end
26
- end