Bump httpx from 1.7.8 to 1.8.0#1004
Open
dependabot[bot] wants to merge 1 commit into
Open
Conversation
Bumps [httpx](https://gitlab.com/os85/httpx) from 1.7.8 to 1.8.0. - [Commits](https://gitlab.com/os85/httpx/compare/v1.7.8...v1.8.0) --- updated-dependencies: - dependency-name: httpx dependency-version: 1.8.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Contributor
3 similar comments
Contributor
Contributor
Contributor
Contributor
gem compare http-2 1.1.3 1.2.0Compared versions: ["1.1.3", "1.2.0"]
DIFFERENT version:
1.1.3: 1.1.3
1.2.0: 1.2.0
DIFFERENT files:
1.1.3->1.2.0:
* Added:
lib/http/2/settings.rb +42/-0
* Changed:
lib/http/2/client.rb +1/-1
lib/http/2/connection.rb +79/-62
lib/http/2/extensions.rb +16/-10
lib/http/2/flow_buffer.rb +7/-7
lib/http/2/framer.rb +98/-98
lib/http/2/header/compressor.rb +15/-4
lib/http/2/header/decompressor.rb +11/-10
lib/http/2/header/encoding_context.rb +18/-6
lib/http/2/header/huffman.rb +6/-4
lib/http/2/server.rb +12/-18
lib/http/2/stream.rb +19/-12
lib/http/2/version.rb +1/-1
sig/2.rbs +64/-15
sig/connection.rbs +11/-9
sig/flow_buffer.rbs +2/-2
sig/frame_buffer.rbs +4/-2
sig/framer.rbs +8/-4
sig/header/compressor.rbs +1/-0
sig/header/encoding_context.rbs +4/-0
sig/header/huffman.rbs +2/-0
sig/server.rbs +1/-1
sig/stream.rbs +7/-8 |
3 similar comments
Contributor
gem compare http-2 1.1.3 1.2.0Compared versions: ["1.1.3", "1.2.0"]
DIFFERENT version:
1.1.3: 1.1.3
1.2.0: 1.2.0
DIFFERENT files:
1.1.3->1.2.0:
* Added:
lib/http/2/settings.rb +42/-0
* Changed:
lib/http/2/client.rb +1/-1
lib/http/2/connection.rb +79/-62
lib/http/2/extensions.rb +16/-10
lib/http/2/flow_buffer.rb +7/-7
lib/http/2/framer.rb +98/-98
lib/http/2/header/compressor.rb +15/-4
lib/http/2/header/decompressor.rb +11/-10
lib/http/2/header/encoding_context.rb +18/-6
lib/http/2/header/huffman.rb +6/-4
lib/http/2/server.rb +12/-18
lib/http/2/stream.rb +19/-12
lib/http/2/version.rb +1/-1
sig/2.rbs +64/-15
sig/connection.rbs +11/-9
sig/flow_buffer.rbs +2/-2
sig/frame_buffer.rbs +4/-2
sig/framer.rbs +8/-4
sig/header/compressor.rbs +1/-0
sig/header/encoding_context.rbs +4/-0
sig/header/huffman.rbs +2/-0
sig/server.rbs +1/-1
sig/stream.rbs +7/-8 |
Contributor
gem compare http-2 1.1.3 1.2.0Compared versions: ["1.1.3", "1.2.0"]
DIFFERENT version:
1.1.3: 1.1.3
1.2.0: 1.2.0
DIFFERENT files:
1.1.3->1.2.0:
* Added:
lib/http/2/settings.rb +42/-0
* Changed:
lib/http/2/client.rb +1/-1
lib/http/2/connection.rb +79/-62
lib/http/2/extensions.rb +16/-10
lib/http/2/flow_buffer.rb +7/-7
lib/http/2/framer.rb +98/-98
lib/http/2/header/compressor.rb +15/-4
lib/http/2/header/decompressor.rb +11/-10
lib/http/2/header/encoding_context.rb +18/-6
lib/http/2/header/huffman.rb +6/-4
lib/http/2/server.rb +12/-18
lib/http/2/stream.rb +19/-12
lib/http/2/version.rb +1/-1
sig/2.rbs +64/-15
sig/connection.rbs +11/-9
sig/flow_buffer.rbs +2/-2
sig/frame_buffer.rbs +4/-2
sig/framer.rbs +8/-4
sig/header/compressor.rbs +1/-0
sig/header/encoding_context.rbs +4/-0
sig/header/huffman.rbs +2/-0
sig/server.rbs +1/-1
sig/stream.rbs +7/-8 |
Contributor
gem compare http-2 1.1.3 1.2.0Compared versions: ["1.1.3", "1.2.0"]
DIFFERENT version:
1.1.3: 1.1.3
1.2.0: 1.2.0
DIFFERENT files:
1.1.3->1.2.0:
* Added:
lib/http/2/settings.rb +42/-0
* Changed:
lib/http/2/client.rb +1/-1
lib/http/2/connection.rb +79/-62
lib/http/2/extensions.rb +16/-10
lib/http/2/flow_buffer.rb +7/-7
lib/http/2/framer.rb +98/-98
lib/http/2/header/compressor.rb +15/-4
lib/http/2/header/decompressor.rb +11/-10
lib/http/2/header/encoding_context.rb +18/-6
lib/http/2/header/huffman.rb +6/-4
lib/http/2/server.rb +12/-18
lib/http/2/stream.rb +19/-12
lib/http/2/version.rb +1/-1
sig/2.rbs +64/-15
sig/connection.rbs +11/-9
sig/flow_buffer.rbs +2/-2
sig/frame_buffer.rbs +4/-2
sig/framer.rbs +8/-4
sig/header/compressor.rbs +1/-0
sig/header/encoding_context.rbs +4/-0
sig/header/huffman.rbs +2/-0
sig/server.rbs +1/-1
sig/stream.rbs +7/-8 |
Contributor
gem compare --diff http-2 1.1.3 1.2.0Compared versions: ["1.1.3", "1.2.0"]
DIFFERENT files:
1.1.3->1.2.0:
* Added:
lib/http/2/settings.rb
--- /tmp/20260617-488-nbl71w 2026-06-17 02:34:11.859641898 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/settings.rb 2026-06-17 02:34:11.857641904 +0000
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module HTTP2
+ # Default values for SETTINGS frame, as defined by the spec.
+ SPEC_DEFAULT_CONNECTION_SETTINGS = {
+ settings_header_table_size: 4096,
+ settings_enable_push: 1, # enabled for servers
+ settings_max_concurrent_streams: Framer::MAX_STREAM_ID, # unlimited
+ settings_initial_window_size: 65_535,
+ settings_max_frame_size: 16_384,
+ settings_max_header_list_size: (2 << 30) - 1 # unlimited
+ }.freeze
+
+ Settings = Struct.new(
+ :settings_header_table_size,
+ :settings_enable_push,
+ :settings_max_concurrent_streams,
+ :settings_initial_window_size,
+ :settings_max_frame_size,
+ :settings_max_header_list_size,
+ keyword_init: true
+ ) do
+ def initialize(
+ settings_header_table_size: 4096,
+ settings_enable_push: 1,
+ settings_max_concurrent_streams: 100,
+ settings_initial_window_size: 65_535,
+ settings_max_frame_size: 16_384,
+ settings_max_header_list_size: (2 << 30) - 1
+ )
+ super
+ end
+
+ def each_setting
+ each_pair do |k, v|
+ next if v == SPEC_DEFAULT_CONNECTION_SETTINGS[k]
+
+ yield k, v
+ end
+ end
+ end
+end
* Changed:
lib/http/2/client.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/client.rb 2026-06-17 02:34:11.851641922 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/client.rb 2026-06-17 02:34:11.856641907 +0000
@@ -72 +72 @@
- frame = Framer.new.generate(type: :settings, stream: 0, payload: settings)
+ frame = Framer.new.generate(type: :settings, stream: 0, flags: 0, payload: settings)
lib/http/2/connection.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/connection.rb 2026-06-17 02:34:11.851641922 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/connection.rb 2026-06-17 02:34:11.856641907 +0000
@@ -44,2 +43,0 @@
- HEADERS_FRAME_TYPES = %i[headers push_promise].freeze
-
@@ -93,0 +92 @@
+ @oldest_stream_recently_closed = nil
@@ -104,0 +104 @@
+ @continuation_size = 0
@@ -159 +159 @@
- send(type: :goaway, last_stream: @last_stream_id,
+ send(type: :goaway, stream: 0, last_stream: @last_stream_id,
@@ -181 +180,0 @@
- @pending_settings << payload
@@ -215,3 +214,2 @@
- # @type var stream_id: Integer
- stream_id = frame[:stream]
- frame_type = frame[:type]
+ stream_id = frame[:stream] #: Integer
+ frame_type = frame[:type] #: Symbol?
@@ -239,0 +238 @@
+ # @type var frame: continuation_frame
@@ -243,2 +242,2 @@
- unless frame[:flags].include? :end_headers
- buffered_payload = @continuation.sum { |f| f[:payload].bytesize }
+ @continuation_size += frame[:payload].bytesize
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -248 +247 @@
- unless buffered_payload < @local_settings[:settings_max_frame_size]
+ unless @continuation_size < @local_settings[:settings_max_frame_size]
@@ -261,0 +261 @@
+ @continuation_size = 0
@@ -265 +265 @@
- frame[:flags] << :end_headers
+ frame[:flags] |= END_HEADERS
@@ -273,0 +274 @@
+ # @type var frame: connection_frame
@@ -278,0 +280 @@
+ # @type var frame: headers_frame
@@ -285 +287 @@
- unless frame[:flags].include? :end_headers
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -314,0 +317 @@
+ # @type var frame: push_promise_frame
@@ -317 +320 @@
- unless frame[:flags].include? :end_headers
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -437,2 +439,0 @@
- frame_type = frame[:type]
-
@@ -440,2 +440,0 @@
- if frame_type == :data
- send_data(frame, true)
@@ -443,3 +442 @@
- elsif frame_type == :rst_stream && frame[:error] == :protocol_error
- # An endpoint can end a connection at any time. In particular, an
- # endpoint MAY choose to treat a stream error as a connection error.
+ frame_type = frame[:type] #: Symbol
@@ -447,2 +444,5 @@
- goaway(:protocol_error)
- else
+ case frame_type
+ when :data
+ #: @type var frame: data_frame
+ send_data(frame, true)
+ when :headers, :push_promise
@@ -450,0 +451,10 @@
+ #: @type var frame: headers_frame | push_promise_frame
+ encode_headers(frame) # HEADERS and PUSH_PROMISE may create more than one frame
+ else
+ if frame_type == :rst_stream && frame[:error] == :protocol_error
+ # An endpoint can end a connection at any time. In particular, an
+ # endpoint MAY choose to treat a stream error as a connection error.
+
+ goaway(:protocol_error)
+ end
+ #: @type var frame: connection_frame
@@ -459,5 +469 @@
- if HEADERS_FRAME_TYPES.include?(frame[:type])
- encode_headers(frame) # HEADERS and PUSH_PROMISE may create more than one frame
- else
- emit(:frame, @framer.generate(frame))
- end
+ emit(:frame, @framer.generate(frame))
@@ -495,0 +502 @@
+ # @type var frame: settings_frame
@@ -497,0 +505 @@
+ # @type var frame: window_update_frame
@@ -501,0 +510 @@
+ # @type var frame: goaway_frame
@@ -508,0 +518 @@
+ # @type var frame: altsvc_frame
@@ -515 +525,2 @@
- return if @h2c_upgrade || !frame[:flags].empty?
+ # @type var frame: origin_frame
+ return if @h2c_upgrade || !frame[:flags].zero?
@@ -520,2 +530,0 @@
- when :blocked
- emit(:blocked, frame)
@@ -541 +550 @@
- if frame[:flags].include? :ack
+ if frame[:flags].anybits?(ACK)
@@ -544,2 +553 @@
- send(type: :ping, stream: 0,
- flags: [:ack], payload: frame[:payload])
+ send(type: :ping, stream: 0, flags: ACK, payload: frame[:payload])
@@ -608 +616 @@
- if frame[:flags].include?(:ack)
+ if frame[:flags].anybits?(ACK)
@@ -613 +620,0 @@
- validate_settings(@remote_role, frame[:payload])
@@ -614,0 +622 @@
+ validate_settings(@remote_role, settings)
@@ -684 +692 @@
- send(type: :settings, stream: 0, payload: [], flags: [:ack])
+ send(type: :settings, stream: 0, payload: EMPTY, flags: ACK)
@@ -714 +722 @@
- payload = headers_frame[:payload]
+ headers_payload = headers_frame[:payload]
@@ -716 +724 @@
- payload = headers_frame[:payload] = @compressor.encode(payload) unless payload.is_a?(String)
+ payload = headers_payload.is_a?(String) ? headers_payload : @compressor.encode(headers_payload)
@@ -720,0 +729,3 @@
+ #: @type var payload: String
+ headers_frame[:payload] = payload
+
@@ -725 +736 @@
- emit(:frame, @framer.generate(headers_frame))
+ encode(headers_frame)
@@ -730 +741,2 @@
- headers_frame[:flags].delete(:end_headers)
+ total = payload.bytesize
+ headers_frame[:flags] ^= END_HEADERS
@@ -732 +744,2 @@
- payload = payload.byteslice(max_frame_size..-1)
+ # payload = payload.byteslice(max_frame_size..-1)
+ offset = max_frame_size
@@ -735 +748 @@
- emit(:frame, @framer.generate(headers_frame))
+ encode(headers_frame)
@@ -737,6 +750 @@
- loop do
- continuation_frame = headers_frame.merge(
- type: :continuation,
- flags: EMPTY,
- payload: payload.byteslice(0, max_frame_size)
- )
+ stream_id = headers_frame[:stream]
@@ -744 +752,3 @@
- payload = payload.byteslice(max_frame_size..-1)
+ while offset < total
+ chunk_end = offset + max_frame_size
+ is_last = chunk_end >= total
@@ -746,5 +756,6 @@
- if payload.nil? || payload.empty?
- continuation_frame[:flags] = [:end_headers]
- emit(:frame, @framer.generate(continuation_frame))
- break
- end
+ continuation_frame = {
+ type: :continuation,
+ flags: is_last ? END_HEADERS : 0,
+ stream: stream_id,
+ payload: payload.byteslice(offset, max_frame_size)
+ } #: continuation_frame
@@ -752 +763,2 @@
- emit(:frame, @framer.generate(continuation_frame))
+ encode(continuation_frame)
+ offset = chunk_end
@@ -779,2 +790,0 @@
- _, closed_since = @streams_recently_closed.first
-
@@ -783 +793,2 @@
- if closed_since && (now - closed_since) > 15
+ if @oldest_stream_recently_closed && (now - @oldest_stream_recently_closed) > 15
+ new_oldest = nil
@@ -786,3 +797,9 @@
- @streams_recently_closed = @streams_recently_closed.drop_while do |_, since|
- (now - since) > 15
- end.to_h
+ @streams_recently_closed.delete_if do |_, since|
+ unless (now - since) > 15
+ new_oldest ||= since
+ break
+ end
+
+ true
+ end
+ @oldest_stream_recently_closed = new_oldest
@@ -791 +808 @@
- @streams_recently_closed[id] = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ @streams_recently_closed[id] = now
lib/http/2/extensions.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/extensions.rb 2026-06-17 02:34:11.851641922 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/extensions.rb 2026-06-17 02:34:11.856641907 +0000
@@ -25,2 +25,3 @@
- def read_str(str, n)
- return "".b if n == 0
+ if String.method_defined?(:bytesplice)
+ def read_str(str, n)
+ return "".b if n == 0
@@ -28,4 +29,13 @@
- chunk = str.byteslice(0..(n - 1))
- remaining = str.byteslice(n..-1)
- remaining ? str.replace(remaining) : str.clear
- chunk
+ chunk = str.byteslice(0, n)
+ str.bytesplice(0, chunk.length, "")
+ chunk
+ end
+ else
+ def read_str(str, n)
+ return "".b if n == 0
+
+ chunk = str.byteslice(0, n)
+ remaining = str.byteslice(n, str.size - n)
+ remaining ? str.replace(remaining) : str.clear
+ chunk
+ end
@@ -36,4 +45,0 @@
- end
-
- def shift_byte(str)
- read_str(str, 1).ord
lib/http/2/flow_buffer.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/flow_buffer.rb 2026-06-17 02:34:11.852641919 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/flow_buffer.rb 2026-06-17 02:34:11.856641907 +0000
@@ -73 +73 @@
- end_stream = frame[:flags].include?(:end_stream)
+ end_stream = frame[:flags].anybits?(END_STREAM)
@@ -117,0 +118,2 @@
+ include BufferUtils
+
@@ -143 +145 @@
- end_stream = frame[:flags].include?(:end_stream)
+ end_stream = frame[:flags].anybits?(END_STREAM)
@@ -151,2 +153 @@
- chunk = frame.dup
- payload = frame[:payload]
+ chunk = frame.dup
@@ -157 +158 @@
- chunk[:payload] = payload.byteslice(0, window_size)
+ chunk[:payload] = read_str(frame[:payload], window_size) # mutates frame[:payload]
@@ -159 +159,0 @@
- frame[:payload] = payload.byteslice(window_size..-1)
@@ -163 +163 @@
- chunk[:flags] -= [:end_stream] if end_stream
+ chunk[:flags] ^= END_STREAM if end_stream
lib/http/2/framer.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/framer.rb 2026-06-17 02:34:11.852641919 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/framer.rb 2026-06-17 02:34:11.856641907 +0000
@@ -3,0 +4,19 @@
+ # Frame flags as defined by the spec (max 255 bits)
+ # DATA: ( X X COMPRESSED X PADDED X X END_STREAM )
+ # HEADERS: ( X X PRIORITY X PADDED END_HEADERS X END_STREAM )
+ # PRIORITY: ( X X X X X X X X )
+ # RST_STREAM: ( X X X X X X X X )
+ # SETTINGS: ( X X X X X X X ACK )
+ # PUSH_PROMISE: ( X X X X PADDED END_HEADERS X X )
+ # PING: ( X X X X X X X ACK )
+ # GOAWAY: ( X X X X X X X X )
+ # WINDOW_UPDATE: ( X X X X X X X X )
+ # CONTINUATION: ( X X X X X END_HEADERS X X )
+ # ALTSVC: ( X X X X X X X X )
+ # ORIGIN: ( RESERVED4 X X RESERVED3 X RESERVED2 RESERVED X )
+ END_STREAM = ACK = 0b0001 # 1
+ RESERVED = 0b0010 # 2
+ END_HEADERS = 0b0100 # 4
+ PADDED = 0b1000 # 8
+ PRIORITY = 0b0010_0000 # 32
+
@@ -43,33 +61,0 @@
- # Per frame flags as defined by the spec
- FRAME_FLAGS = {
- data: {
- end_stream: 0,
- padded: 3,
- compressed: 5
- },
- headers: {
- end_stream: 0,
- end_headers: 2,
- padded: 3,
- priority: 5
- },
- priority: {},
- rst_stream: {},
- settings: { ack: 0 },
- push_promise: {
- end_headers: 2,
- padded: 3
- },
- ping: { ack: 0 },
- goaway: {},
- window_update: {},
- continuation: { end_headers: 2 },
- altsvc: {},
- origin: {
- reserved: 1,
- reserved2: 2,
- reserved3: 4,
- reserved4: 8
- }
- }.each_value(&:freeze).freeze
-
@@ -86,17 +72,19 @@
- # Default error types as defined by the spec
- DEFINED_ERRORS = {
- no_error: 0,
- protocol_error: 1,
- internal_error: 2,
- flow_control_error: 3,
- settings_timeout: 4,
- stream_closed: 5,
- frame_size_error: 6,
- refused_stream: 7,
- cancel: 8,
- compression_error: 9,
- connect_error: 10,
- enhance_your_calm: 11,
- inadequate_security: 12,
- http_1_1_required: 13
- }.freeze
+ DEFINED_SETTINGS_BY_ID = DEFINED_SETTINGS.invert.freeze
+
+ # Default error types as defined by the spec (the code is the array index)
+ DEFINED_ERRORS = %i[
+ no_error
+ protocol_error
+ internal_error
+ flow_control_error
+ settings_timeout
+ stream_closed
+ frame_size_error
+ refused_stream
+ cancel
+ compression_error
+ connect_error
+ enhance_your_calm
+ inadequate_security
+ http_1_1_required
+ ].freeze
@@ -110,0 +99,2 @@
+ PRIORITYPACK = (UINT32 + UINT8).freeze
+ ALTSVCPACK = (UINT32 + UINT16).freeze
@@ -114 +104 @@
- private_constant :RBIT, :RBYTE, :EBIT, :HEADERPACK, :UINT32, :UINT16, :UINT8
+ private_constant :RBIT, :RBYTE, :EBIT, :HEADERPACK, :PRIORITYPACK, :UINT32, :UINT16, :UINT8
@@ -148,0 +139,4 @@
+ flags = frame[:flags]
+
+ raise CompressionError, "Invalid frame flag (#{flags}) for #{type}" unless flags.between?(0, 255)
+
@@ -163,6 +157 @@
- frame[:flags].reduce(0) do |acc, f|
- position = FRAME_FLAGS[type][f]
- raise CompressionError, "Invalid frame flag (#{f}) for #{type}" unless position
-
- acc | (1 << position)
- end,
+ flags,
@@ -187,3 +176 @@
- flags: FRAME_FLAGS[type].filter_map do |name, pos|
- name if flags.anybits?(1 << pos)
- end,
+ flags: flags,
@@ -201 +188 @@
- frame[:flags] ||= EMPTY
+ frame[:flags] ||= 0
@@ -204,0 +192 @@
+ # @type var frame: data_frame | continuation_frame
@@ -216 +204 @@
- frame[:flags] += [:priority] unless frame[:flags].include?(:priority)
+ frame[:flags] |= PRIORITY
@@ -219 +207 @@
- if frame[:flags].include?(:priority)
+ if frame[:flags].anybits?(PRIORITY)
@@ -222,2 +210,4 @@
- pack([(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT)], UINT32, buffer: bytes)
- pack([frame[:weight] - 1], UINT8, buffer: bytes)
+ pack(
+ [(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT), frame[:weight] - 1],
+ PRIORITYPACK, buffer: bytes
+ )
@@ -237,2 +227,4 @@
- pack([(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT)], UINT32, buffer: bytes)
- pack([frame[:weight] - 1], UINT8, buffer: bytes)
+ pack(
+ [(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT), frame[:weight] - 1],
+ PRIORITYPACK, buffer: bytes
+ )
@@ -251 +242,0 @@
- bytes = String.new("", encoding: Encoding::BINARY, capacity: length)
@@ -253,5 +244,6 @@
- settings.each do |(k, v)|
- if k.is_a? Integer # rubocop:disable Style/GuardClause
- DEFINED_SETTINGS.value?(k) || next
- else
- k = DEFINED_SETTINGS[k]
+ case settings
+ when String
+ length = settings.bytesize
+ bytes = settings
+ else
+ bytes = String.new("", encoding: Encoding::BINARY, capacity: settings.size * 6)
@@ -259 +251,12 @@
- raise CompressionError, "Unknown settings ID for #{k}" if k.nil?
+ settings.each do |(k, v)|
+ if k.is_a? Integer # rubocop:disable Style/GuardClause
+ DEFINED_SETTINGS.value?(k) || next
+ else
+ k = DEFINED_SETTINGS[k]
+
+ raise CompressionError, "Unknown settings ID for #{k}" if k.nil?
+ end
+
+ pack([k], UINT16, buffer: bytes)
+ pack([v], UINT32, buffer: bytes)
+ length += 6
@@ -261,4 +263,0 @@
-
- pack([k], UINT16, buffer: bytes)
- pack([v], UINT32, buffer: bytes)
- length += 6
@@ -298 +297 @@
- pack([frame[:max_age], frame[:port]], UINT32 + UINT16, buffer: bytes)
+ pack([frame[:max_age], frame[:port]], ALTSVCPACK, buffer: bytes)
@@ -357 +356 @@
- frame[:flags] += [:padded]
+ frame[:flags] |= PADDED
@@ -378,3 +377,3 @@
- type = frame[:type]
- length = frame[:length]
- flags = frame[:flags]
+ type = frame[:type] #: Symbol
+ length = frame[:length] #: Integer
+ flags = frame[:flags] #: Integer
@@ -397 +396 @@
- padded = flags.include?(:padded)
+ padded = flags.anybits?(PADDED)
@@ -400 +398,0 @@
- frame[:padding] = padlen + 1
@@ -402,0 +401,2 @@
+ frame[:padding] = padlen + 1
+
@@ -405 +405 @@
- flags.delete(:padded)
+ frame[:flags] ^= PADDED
@@ -413 +413 @@
- if flags.include?(:priority)
+ if flags.anybits?(PRIORITY)
@@ -417 +417 @@
- weight = payload.byteslice(0, 1).ord + 1
+ weight = payload.getbyte(0) + 1
@@ -428 +428 @@
- weight = payload.byteslice(0, 1).ord + 1
+ weight = payload.getbyte(0) + 1
@@ -439 +438,0 @@
- frame[:payload] = []
@@ -444 +443 @@
- (frame[:length] / 6).times do
+ frame[:payload] = (frame[:length] / 6).times.filter_map do
@@ -450,2 +449,3 @@
- name, = DEFINED_SETTINGS.find { |_name, v| v == id }
- frame[:payload] << [name, val] if name
+ if (name = DEFINED_SETTINGS_BY_ID[id])
+ [name, val]
+ end
@@ -467 +467 @@
- frame[:max_age], frame[:port] = read_str(payload, 6).unpack(UINT32 + UINT16)
+ frame[:max_age], frame[:port] = read_str(payload, 6).unpack(ALTSVCPACK)
@@ -469 +469 @@
- len = payload.byteslice(0, 1).ord
+ len = payload.getbyte(0)
@@ -473 +473 @@
- len = payload.byteslice(0, 1).ord
+ len = payload.getbyte(0)
@@ -498 +498 @@
- error = DEFINED_ERRORS[error]
+ error = DEFINED_ERRORS.index(error)
@@ -507 +507 @@
- DEFINED_ERRORS.key(error) || error
+ DEFINED_ERRORS.fetch(error, error)
lib/http/2/header/compressor.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/header/compressor.rb 2026-06-17 02:34:11.852641919 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/header/compressor.rb 2026-06-17 02:34:11.857641904 +0000
@@ -85,0 +86,2 @@
+ integer(huffman.bytesize, 7, buffer: buffer)
+ buffer.setbyte(huffman_offset, buffer.getbyte(huffman_offset) | 0x80)
@@ -87 +89 @@
- set_huffman_size(buffer, huffman_offset)
+ buffer
@@ -122 +124 @@
- fb = buffer[offset].ord | rep[:pattern]
+ fb = buffer.getbyte(offset) | rep[:pattern]
@@ -149,0 +152 @@
+ buffer << "\x00".b
@@ -151 +154,9 @@
- set_huffman_size(buffer, huffman_offset)
+ size = buffer.bytesize - huffman_offset - 1
+
+ if size < 127
+ buffer.setbyte(huffman_offset, 0x80 | size)
+ else
+ buffer.slice!(huffman_offset, 1)
+ set_huffman_size(buffer, huffman_offset)
+ end
+ buffer
@@ -168 +179 @@
- buffer.setbyte(huffman_offset, buffer[huffman_offset].ord | 0x80)
+ buffer.setbyte(huffman_offset, buffer.getbyte(huffman_offset) | 0x80)
lib/http/2/header/decompressor.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/header/decompressor.rb 2026-06-17 02:34:11.852641919 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/header/decompressor.rb 2026-06-17 02:34:11.857641904 +0000
@@ -36 +36,7 @@
- i = n.zero? ? 0 : (shift_byte(buf) & limit)
+ if n.zero?
+ i = 0
+ consumed = 0
+ else
+ i = buf.getbyte(0) & limit
+ consumed = 1
+ end
@@ -38 +43,0 @@
- m = 0
@@ -40,5 +45,2 @@
- offset = 0
-
- buf.each_byte.with_index do |byte, idx|
- offset = idx
- # while (byte = shift_byte(buf))
+ m = 0
+ while (byte = buf.getbyte(consumed))
@@ -47 +49 @@
-
+ consumed += 1
@@ -50,2 +51,0 @@
-
- read_str(buf, offset + 1)
@@ -53,0 +54 @@
+ read_str(buf, consumed)
lib/http/2/header/encoding_context.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/header/encoding_context.rb 2026-06-17 02:34:11.852641919 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/header/encoding_context.rb 2026-06-17 02:34:11.857641904 +0000
@@ -120,0 +121,2 @@
+ @table_by_field = Hash.new { |hs, k| hs[k] = [] }
+ @unshifts = 0
@@ -131,0 +134,2 @@
+ tbf = @table_by_field.transform_values(&:dup)
+ unshifts = @unshifts
@@ -134,0 +139,2 @@
+ @table_by_field = tbf
+ @unshifts = unshifts
@@ -215,0 +222,2 @@
+ @unshifts += 1
+ @table_by_field[name].unshift([value, @unshifts])
@@ -282,2 +290 @@
- @table.each_with_index do |(hfield, hvalue), i|
- next unless field == hfield
+ field_entries = @table_by_field[field]
@@ -284,0 +292,3 @@
+ field_entries&.each do |hvalue, unshift_id|
+ abs_index = (@unshifts - unshift_id) + STATIC_TABLE_SIZE
+ name_only ||= abs_index
@@ -286 +296 @@
- exact = i + STATIC_TABLE_SIZE
+ exact = abs_index
@@ -288,2 +297,0 @@
- else
- name_only ||= i + STATIC_TABLE_SIZE
@@ -320 +327,0 @@
-
@@ -322,0 +330,5 @@
+
+ field_arr = @table_by_field[name]
+ field_arr.pop
+ @table_by_field.delete(name) if field_arr.empty?
+
lib/http/2/header/huffman.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/header/huffman.rb 2026-06-17 02:34:11.852641919 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/header/huffman.rb 2026-06-17 02:34:11.857641904 +0000
@@ -22,0 +23,2 @@
+ EOS_PADDING = (0..7).map { |n| ("1" * n).b.freeze }.freeze
+
@@ -32 +34 @@
- append_str(bitstring, "1" * ((8 - bitstring.size) % 8))
+ append_str(bitstring, EOS_PADDING[(8 - bitstring.size) % 8])
@@ -57 +59 @@
- append_str(emit, first.chr) if first
+ emit << first if first
@@ -63 +65 @@
- emit.force_encoding(Encoding::BINARY)
+ emit
@@ -328 +330 @@
- ENCODE_TABLE = CODES.map { |c, l| [c].pack("N").unpack1("B*")[-l..-1] }.each(&:freeze).freeze
+ ENCODE_TABLE = CODES.map { |c, l| [c].pack("N").unpack1("B*")[-l..-1].b.freeze }.freeze
lib/http/2/server.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/server.rb 2026-06-17 02:34:11.853641916 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/server.rb 2026-06-17 02:34:11.857641904 +0000
@@ -81,12 +81,6 @@
- buf = "".b
- append_str(buf, Base64.urlsafe_decode64(settings.to_s))
- @framer.common_header(
- {
- length: buf.bytesize,
- type: :settings,
- stream: 0,
- flags: []
- },
- buffer: buf
- )
- receive(buf)
+ receive(@framer.generate(
+ type: :settings,
+ stream: 0,
+ flags: 0,
+ payload: Base64.urlsafe_decode64(settings.to_s)
+ ))
@@ -100 +94 @@
- flags: [:end_headers],
+ flags: END_HEADERS,
@@ -109 +103 @@
- headers_frame[:flags] << [:end_stream]
+ headers_frame[:flags] |= END_HEADERS
@@ -113 +107 @@
- stream << { type: :data, stream: 1, payload: body, flags: [:end_stream] }
+ stream << { type: :data, stream: 1, payload: body, flags: END_STREAM }
@@ -138 +132 @@
- return unless frame[:flags].include?(:ack) && !@origins_sent
+ return unless frame[:flags].anybits?(ACK) && !@origins_sent
@@ -151 +145 @@
- # @param flags [Array[Symbol]]
+ # @param flags Integer
@@ -160 +154 @@
- payload: headers.to_a
+ payload: headers
lib/http/2/stream.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/stream.rb 2026-06-17 02:34:11.853641916 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/stream.rb 2026-06-17 02:34:11.858641901 +0000
@@ -117 +117,2 @@
- case frame[:type]
+ frame_type = frame[:type] #: Symbol
+ case frame_type
@@ -118,0 +120 @@
+ # @type var frame: data_frame
@@ -131,0 +134 @@
+ # @type var frame: headers_frame
@@ -153,0 +157 @@
+ # @type var frame: priority_frame
@@ -155,0 +160 @@
+ # @type var frame: window_update_frame
@@ -157,0 +163 @@
+ # @type var frame: origin_frame
@@ -162,3 +168 @@
- emit(frame[:type], frame) if !frame[:origin] || frame[:origin].empty?
- when :blocked
- emit(frame[:type], frame)
+ emit(frame_type, frame) if !frame[:origin] || frame[:origin].empty?
@@ -201,0 +206 @@
+ # @type var frame: data_frame
@@ -204,0 +210 @@
+ # @type var frame: window_update_frame
@@ -206,0 +213 @@
+ # @type var frame: priority_frame
@@ -222,3 +229,2 @@
- flags = []
- flags << :end_headers if end_headers
- flags << :end_stream if end_stream || @_method == "HEAD"
+ flags = end_headers ? END_HEADERS : 0
+ flags |= END_STREAM if end_stream || @_method == "HEAD"
@@ -232 +238 @@
- flags = end_headers ? [:end_headers] : []
+ flags = end_headers ? END_HEADERS : 0
@@ -257 +263 @@
- send(type: :data, flags: [], payload: chunk)
+ send(type: :data, flags: 0, payload: chunk)
@@ -261,2 +267,2 @@
- flags = []
- flags << :end_stream if end_stream
+ flags = 0
+ flags |= END_STREAM if end_stream
@@ -666 +672,2 @@
- frame[:flags] && frame[:flags].include?(:end_stream)
+ # @type var frame: data_frame | headers_frame | continuation_frame
+ frame[:flags] && frame[:flags].anybits?(END_STREAM)
lib/http/2/version.rb
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/lib/http/2/version.rb 2026-06-17 02:34:11.853641916 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/lib/http/2/version.rb 2026-06-17 02:34:11.858641901 +0000
@@ -4 +4 @@
- VERSION = "1.1.3"
+ VERSION = "1.2.0"
sig/2.rbs
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/sig/2.rbs 2026-06-17 02:34:11.853641916 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/sig/2.rbs 2026-06-17 02:34:11.858641901 +0000
@@ -38,0 +39,8 @@
+ # Frame flags
+ END_STREAM: Integer
+ ACK: Integer
+ RESERVED: Integer
+ END_HEADERS: Integer
+ PADDED: Integer
+ PRIORITY: Integer
+
@@ -42 +50,3 @@
- type frame_control_flags = Array[:end_headers | :end_stream]
+ type frame_control_flags = Integer
+
+ type common_frame = { stream: Integer, flags: frame_control_flags, ?length: Integer, ?ignore: bool }
@@ -44 +54 @@
- type common_frame = { stream: Integer }
+ type connection_frame = settings_frame | ping_frame | goaway_frame | window_update_frame | altsvc_frame | origin_frame
@@ -47,2 +57,2 @@
- type headers_frame = common_frame & {
- type: :headers, flags: frame_control_flags, payload: Enumerable[header_pair] | String,
+ type headers_frame_props = {
+ type: :headers, payload: Enumerable[header_pair] | String,
@@ -50,0 +61,5 @@
+ type headers_frame = common_frame & headers_frame_props
+
+ type continuation_frame_props = headers_frame_props | { type: :continuation }
+
+ type continuation_frame = common_frame & continuation_frame_props
@@ -53 +68,3 @@
- type data_frame = { type: :data, flags: frame_control_flags, ?length: Integer, payload: String, ?padding: Integer }
+ type data_frame_props = { type: :data, ?length: Integer, payload: String, ?padding: Integer }
+
+ type data_frame = common_frame & data_frame_props
@@ -56 +73,3 @@
- type push_promise_frame = { type: :push_promise, promise_stream: Integer, flags: frame_control_flags, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair], ?padding: Integer }
+ type push_promise_frame_props = { promise_stream: Integer, ?length: Integer, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair] | String, ?padding: Integer }
+
+ type push_promise_frame = common_frame & push_promise_frame_props
@@ -59 +78,3 @@
- type settings_frame = { type: :settings, payload: Array[[Symbol | Integer, Integer]] }
+ type settings_frame_props = { type: :settings, payload: (Enumerable[[Symbol | Integer, Integer]] | String) }
+
+ type settings_frame = common_frame & settings_frame_props
@@ -62 +83,3 @@
- type window_update_frame = { type: :window_update, increment: Integer }
+ type window_update_frame_props = { type: :window_update, increment: Integer }
+
+ type window_update_frame = common_frame & window_update_frame_props
@@ -65 +88,5 @@
- type priority_frame = { dependency: Integer, exclusive: bool, weight: Integer }
+ type priority_frame_inner_props = { dependency: Integer, exclusive: bool, weight: Integer }
+
+ type priority_frame_props = { type: :priority } & priority_frame_inner_props
+
+ type priority_frame = common_frame & priority_frame_props
@@ -68 +95,3 @@
- type altsvc_frame = { type: :altsvc, max_age: Integer, port: Integer, proto: "String", host: String }
+ type altsvc_frame_props = { type: :altsvc, max_age: Integer, port: Integer, proto: String, host: String }
+
+ type altsvc_frame = common_frame & altsvc_frame_props
@@ -71 +100,3 @@
- type origin_frame = { type: :origin, origin: Array[String] }
+ type origin_frame_props = { type: :origin, payload: Array[String] }
+
+ type origin_frame = common_frame & origin_frame_props
@@ -74 +105,3 @@
- type ping_frame = { type: :ping, payload: String, length: Integer }
+ type ping_frame_props = { type: :ping, payload: String }
+
+ type ping_frame = common_frame & ping_frame_props
@@ -77 +110,3 @@
- type goaway_frame = { type: :goaway, last_stream: Integer, error: Symbol? }
+ type goaway_frame_props = { type: :goaway, last_stream: Integer, error: (Symbol | Integer)? }
+
+ type goaway_frame = common_frame & goaway_frame_props
@@ -79 +114,6 @@
- # type frame = common_frame & (headers_frame | data_frame | push_promise_frame |
+ # # RST_STREAM
+ type rst_stream_frame_props = { type: :rst_stream, error: (Symbol | Integer)? }
+
+ type rst_stream_frame = common_frame & rst_stream_frame_props
+
+ # type frame = headers_frame | continuation_frame | push_promise_frame | data_frame |
@@ -81 +121,8 @@
- # origin_frame | ping_frame | goaway_frame)
+ # origin_frame | ping_frame | goaway_frame | rst_stream_frame
+
+ # type connection_frame_props = rst_stream_frame_props | ping_frame_props | goaway_frame_props
+ # | window_update_frame_props | settings_frame_props
+
+ # type stream_frame_props = headers_frame_props | continuation_frame_props | push_promise_frame_props
+ # | data_frame_props | rst_stream_frame_props | priority_frame_props
+ # | window_update_frame_props | origin_frame_props | altsvc_frame_props
@@ -111,0 +159,2 @@
+ type connection_frame_props = Hash[frame_key, frame_value]
+ type stream_frame_props = Hash[frame_key, frame_value]
sig/connection.rbs
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/sig/connection.rbs 2026-06-17 02:34:11.853641916 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/sig/connection.rbs 2026-06-17 02:34:11.858641901 +0000
@@ -35,0 +36 @@
+ @oldest_stream_recently_closed: Numeric
@@ -52,0 +54 @@
+ @continuation_size: Integer
@@ -71 +73 @@
- def receive: (string data) -> void
+ def receive: (String data) -> void
@@ -78 +80 @@
- def send: (frame frame) -> void
+ def send: (connection_frame_props | stream_frame_props frame) -> void
@@ -84 +86 @@
- def connection_management: (frame) -> void
+ def connection_management: (connection_frame frame) -> void
@@ -90 +92 @@
- def connection_settings: (frame) -> void
+ def connection_settings: (settings_frame) -> void
@@ -92 +94 @@
- def decode_headers: (frame) -> void
+ def decode_headers: (headers_frame | push_promise_frame) -> void
@@ -94 +96 @@
- def encode_headers: (frame headers_frame) -> void
+ def encode_headers: (headers_frame | push_promise_frame) -> void
@@ -100 +102 @@
- def verify_pseudo_headers: (frame) -> void
+ def verify_pseudo_headers: (headers_frame | push_promise_frame) -> void
@@ -102 +104 @@
- def _verify_pseudo_headers: (frame, Array[String]) -> void
+ def _verify_pseudo_headers: (headers_frame | push_promise_frame, Array[String]) -> void
@@ -106 +108 @@
-end
\ No newline at end of file
+end
sig/flow_buffer.rbs
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/sig/flow_buffer.rbs 2026-06-17 02:34:11.854641913 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/sig/flow_buffer.rbs 2026-06-17 02:34:11.858641901 +0000
@@ -17 +17 @@
- def send_data: (?data_frame? frame, ?bool encode) -> void
+ def send_data: (?data_frame_props? frame, ?bool encode) -> void
@@ -19 +19 @@
- def send_frame: (data_frame frame, bool encode) -> void
+ def send_frame: (data_frame_props frame, bool encode) -> void
sig/frame_buffer.rbs
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/sig/frame_buffer.rbs 2026-06-17 02:34:11.854641913 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/sig/frame_buffer.rbs 2026-06-17 02:34:11.858641901 +0000
@@ -2,0 +3,2 @@
+ include BufferUtils
+
@@ -9 +11 @@
- def <<: (data_frame frame) -> void
+ def <<: (data_frame_props frame) -> void
@@ -13 +15 @@
- def retrieve: (Integer) -> data_frame?
+ def retrieve: (Integer) -> data_frame_props?
sig/framer.rbs
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/sig/framer.rbs 2026-06-17 02:34:11.854641913 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/sig/framer.rbs 2026-06-17 02:34:11.858641901 +0000
@@ -23 +23,3 @@
- DEFINED_ERRORS: Hash[Symbol, Integer]
+ DEFINED_SETTINGS_BY_ID: Hash[Integer, Symbol]
+
+ DEFINED_ERRORS: Array[Symbol]
@@ -31,0 +34,2 @@
+ PRIORITYPACK: String
+ ALTSVCPACK: String
@@ -44 +48 @@
- def read_common_header: (String buf) -> frame
+ def read_common_header: (String buf) -> (common_frame | { length: Integer })
@@ -50 +54 @@
- def parse: (String) -> frame?
+ def parse: (String) -> (frame | { length: Integer })?
@@ -56 +60 @@
- def pack_error: (Integer | Symbol error, buffer: String) -> String
+ def pack_error: (Symbol | Integer error, buffer: String) -> String
sig/header/compressor.rbs
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/sig/header/compressor.rbs 2026-06-17 02:34:11.854641913 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/sig/header/compressor.rbs 2026-06-17 02:34:11.859641898 +0000
@@ -4,0 +5 @@
+ include BufferUtils
sig/header/encoding_context.rbs
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/sig/header/encoding_context.rbs 2026-06-17 02:34:11.855641910 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/sig/header/encoding_context.rbs 2026-06-17 02:34:11.859641898 +0000
@@ -24,0 +25,4 @@
+ @table_by_field: Hash[string, Array[[string, Integer]]]
+
+ @unshifts: Integer
+
sig/header/huffman.rbs
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/sig/header/huffman.rbs 2026-06-17 02:34:11.855641910 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/sig/header/huffman.rbs 2026-06-17 02:34:11.859641898 +0000
@@ -11,0 +12,2 @@
+ EOS_PADDING: Array[String]
+
sig/server.rbs
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/sig/server.rbs 2026-06-17 02:34:11.855641910 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/sig/server.rbs 2026-06-17 02:34:11.859641898 +0000
@@ -10 +10 @@
- def promise: (Stream parent, Enumerable[header_pair] headers, Array[Symbol] flags) { (Stream) -> void } -> void
+ def promise: (Stream parent, Enumerable[header_pair] headers, frame_control_flags flags) { (Stream) -> void } -> void
sig/stream.rbs
--- /tmp/d20260617-488-gyrnqn/http-2-1.1.3/sig/stream.rbs 2026-06-17 02:34:11.855641910 +0000
+++ /tmp/d20260617-488-gyrnqn/http-2-1.2.0/sig/stream.rbs 2026-06-17 02:34:11.859641898 +0000
@@ -40 +40 @@
- def send: (frame frame) -> void
+ def send: (stream_frame_props frame) -> void
@@ -73 +73 @@
- def transition: (frame, bool sending) -> void
+ def transition: (stream_frame_props frame, bool sending) -> void
@@ -83 +83 @@
- def process_priority: (priority_frame frame) -> void
+ def process_priority: (priority_frame_inner_props frame) -> void
@@ -85 +85 @@
- def end_stream?: (frame frame) -> boolish
+ def end_stream?: (stream_frame_props frame) -> boolish
@@ -87,2 +87 @@
- def stream_error: (Symbol error, ?msg: String?) -> void
- | () -> void
+ def stream_error: (?Symbol error, ?msg: String?) -> void
@@ -92 +91 @@
- def manage_state: (frame) { () -> void } -> void
+ def manage_state: (stream_frame_props frame) { () -> void } -> void
@@ -94 +93 @@
-end
\ No newline at end of file
+end |
Contributor
gem compare --diff http-2 1.1.3 1.2.0Compared versions: ["1.1.3", "1.2.0"]
DIFFERENT files:
1.1.3->1.2.0:
* Added:
lib/http/2/settings.rb
--- /tmp/20260617-525-72ejs 2026-06-17 02:34:12.823525970 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/settings.rb 2026-06-17 02:34:12.821525941 +0000
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module HTTP2
+ # Default values for SETTINGS frame, as defined by the spec.
+ SPEC_DEFAULT_CONNECTION_SETTINGS = {
+ settings_header_table_size: 4096,
+ settings_enable_push: 1, # enabled for servers
+ settings_max_concurrent_streams: Framer::MAX_STREAM_ID, # unlimited
+ settings_initial_window_size: 65_535,
+ settings_max_frame_size: 16_384,
+ settings_max_header_list_size: (2 << 30) - 1 # unlimited
+ }.freeze
+
+ Settings = Struct.new(
+ :settings_header_table_size,
+ :settings_enable_push,
+ :settings_max_concurrent_streams,
+ :settings_initial_window_size,
+ :settings_max_frame_size,
+ :settings_max_header_list_size,
+ keyword_init: true
+ ) do
+ def initialize(
+ settings_header_table_size: 4096,
+ settings_enable_push: 1,
+ settings_max_concurrent_streams: 100,
+ settings_initial_window_size: 65_535,
+ settings_max_frame_size: 16_384,
+ settings_max_header_list_size: (2 << 30) - 1
+ )
+ super
+ end
+
+ def each_setting
+ each_pair do |k, v|
+ next if v == SPEC_DEFAULT_CONNECTION_SETTINGS[k]
+
+ yield k, v
+ end
+ end
+ end
+end
* Changed:
lib/http/2/client.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/client.rb 2026-06-17 02:34:12.814525841 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/client.rb 2026-06-17 02:34:12.819525913 +0000
@@ -72 +72 @@
- frame = Framer.new.generate(type: :settings, stream: 0, payload: settings)
+ frame = Framer.new.generate(type: :settings, stream: 0, flags: 0, payload: settings)
lib/http/2/connection.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/connection.rb 2026-06-17 02:34:12.814525841 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/connection.rb 2026-06-17 02:34:12.819525913 +0000
@@ -44,2 +43,0 @@
- HEADERS_FRAME_TYPES = %i[headers push_promise].freeze
-
@@ -93,0 +92 @@
+ @oldest_stream_recently_closed = nil
@@ -104,0 +104 @@
+ @continuation_size = 0
@@ -159 +159 @@
- send(type: :goaway, last_stream: @last_stream_id,
+ send(type: :goaway, stream: 0, last_stream: @last_stream_id,
@@ -181 +180,0 @@
- @pending_settings << payload
@@ -215,3 +214,2 @@
- # @type var stream_id: Integer
- stream_id = frame[:stream]
- frame_type = frame[:type]
+ stream_id = frame[:stream] #: Integer
+ frame_type = frame[:type] #: Symbol?
@@ -239,0 +238 @@
+ # @type var frame: continuation_frame
@@ -243,2 +242,2 @@
- unless frame[:flags].include? :end_headers
- buffered_payload = @continuation.sum { |f| f[:payload].bytesize }
+ @continuation_size += frame[:payload].bytesize
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -248 +247 @@
- unless buffered_payload < @local_settings[:settings_max_frame_size]
+ unless @continuation_size < @local_settings[:settings_max_frame_size]
@@ -261,0 +261 @@
+ @continuation_size = 0
@@ -265 +265 @@
- frame[:flags] << :end_headers
+ frame[:flags] |= END_HEADERS
@@ -273,0 +274 @@
+ # @type var frame: connection_frame
@@ -278,0 +280 @@
+ # @type var frame: headers_frame
@@ -285 +287 @@
- unless frame[:flags].include? :end_headers
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -314,0 +317 @@
+ # @type var frame: push_promise_frame
@@ -317 +320 @@
- unless frame[:flags].include? :end_headers
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -437,2 +439,0 @@
- frame_type = frame[:type]
-
@@ -440,2 +440,0 @@
- if frame_type == :data
- send_data(frame, true)
@@ -443,3 +442 @@
- elsif frame_type == :rst_stream && frame[:error] == :protocol_error
- # An endpoint can end a connection at any time. In particular, an
- # endpoint MAY choose to treat a stream error as a connection error.
+ frame_type = frame[:type] #: Symbol
@@ -447,2 +444,5 @@
- goaway(:protocol_error)
- else
+ case frame_type
+ when :data
+ #: @type var frame: data_frame
+ send_data(frame, true)
+ when :headers, :push_promise
@@ -450,0 +451,10 @@
+ #: @type var frame: headers_frame | push_promise_frame
+ encode_headers(frame) # HEADERS and PUSH_PROMISE may create more than one frame
+ else
+ if frame_type == :rst_stream && frame[:error] == :protocol_error
+ # An endpoint can end a connection at any time. In particular, an
+ # endpoint MAY choose to treat a stream error as a connection error.
+
+ goaway(:protocol_error)
+ end
+ #: @type var frame: connection_frame
@@ -459,5 +469 @@
- if HEADERS_FRAME_TYPES.include?(frame[:type])
- encode_headers(frame) # HEADERS and PUSH_PROMISE may create more than one frame
- else
- emit(:frame, @framer.generate(frame))
- end
+ emit(:frame, @framer.generate(frame))
@@ -495,0 +502 @@
+ # @type var frame: settings_frame
@@ -497,0 +505 @@
+ # @type var frame: window_update_frame
@@ -501,0 +510 @@
+ # @type var frame: goaway_frame
@@ -508,0 +518 @@
+ # @type var frame: altsvc_frame
@@ -515 +525,2 @@
- return if @h2c_upgrade || !frame[:flags].empty?
+ # @type var frame: origin_frame
+ return if @h2c_upgrade || !frame[:flags].zero?
@@ -520,2 +530,0 @@
- when :blocked
- emit(:blocked, frame)
@@ -541 +550 @@
- if frame[:flags].include? :ack
+ if frame[:flags].anybits?(ACK)
@@ -544,2 +553 @@
- send(type: :ping, stream: 0,
- flags: [:ack], payload: frame[:payload])
+ send(type: :ping, stream: 0, flags: ACK, payload: frame[:payload])
@@ -608 +616 @@
- if frame[:flags].include?(:ack)
+ if frame[:flags].anybits?(ACK)
@@ -613 +620,0 @@
- validate_settings(@remote_role, frame[:payload])
@@ -614,0 +622 @@
+ validate_settings(@remote_role, settings)
@@ -684 +692 @@
- send(type: :settings, stream: 0, payload: [], flags: [:ack])
+ send(type: :settings, stream: 0, payload: EMPTY, flags: ACK)
@@ -714 +722 @@
- payload = headers_frame[:payload]
+ headers_payload = headers_frame[:payload]
@@ -716 +724 @@
- payload = headers_frame[:payload] = @compressor.encode(payload) unless payload.is_a?(String)
+ payload = headers_payload.is_a?(String) ? headers_payload : @compressor.encode(headers_payload)
@@ -720,0 +729,3 @@
+ #: @type var payload: String
+ headers_frame[:payload] = payload
+
@@ -725 +736 @@
- emit(:frame, @framer.generate(headers_frame))
+ encode(headers_frame)
@@ -730 +741,2 @@
- headers_frame[:flags].delete(:end_headers)
+ total = payload.bytesize
+ headers_frame[:flags] ^= END_HEADERS
@@ -732 +744,2 @@
- payload = payload.byteslice(max_frame_size..-1)
+ # payload = payload.byteslice(max_frame_size..-1)
+ offset = max_frame_size
@@ -735 +748 @@
- emit(:frame, @framer.generate(headers_frame))
+ encode(headers_frame)
@@ -737,6 +750 @@
- loop do
- continuation_frame = headers_frame.merge(
- type: :continuation,
- flags: EMPTY,
- payload: payload.byteslice(0, max_frame_size)
- )
+ stream_id = headers_frame[:stream]
@@ -744 +752,3 @@
- payload = payload.byteslice(max_frame_size..-1)
+ while offset < total
+ chunk_end = offset + max_frame_size
+ is_last = chunk_end >= total
@@ -746,5 +756,6 @@
- if payload.nil? || payload.empty?
- continuation_frame[:flags] = [:end_headers]
- emit(:frame, @framer.generate(continuation_frame))
- break
- end
+ continuation_frame = {
+ type: :continuation,
+ flags: is_last ? END_HEADERS : 0,
+ stream: stream_id,
+ payload: payload.byteslice(offset, max_frame_size)
+ } #: continuation_frame
@@ -752 +763,2 @@
- emit(:frame, @framer.generate(continuation_frame))
+ encode(continuation_frame)
+ offset = chunk_end
@@ -779,2 +790,0 @@
- _, closed_since = @streams_recently_closed.first
-
@@ -783 +793,2 @@
- if closed_since && (now - closed_since) > 15
+ if @oldest_stream_recently_closed && (now - @oldest_stream_recently_closed) > 15
+ new_oldest = nil
@@ -786,3 +797,9 @@
- @streams_recently_closed = @streams_recently_closed.drop_while do |_, since|
- (now - since) > 15
- end.to_h
+ @streams_recently_closed.delete_if do |_, since|
+ unless (now - since) > 15
+ new_oldest ||= since
+ break
+ end
+
+ true
+ end
+ @oldest_stream_recently_closed = new_oldest
@@ -791 +808 @@
- @streams_recently_closed[id] = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ @streams_recently_closed[id] = now
lib/http/2/extensions.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/extensions.rb 2026-06-17 02:34:12.814525841 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/extensions.rb 2026-06-17 02:34:12.820525927 +0000
@@ -25,2 +25,3 @@
- def read_str(str, n)
- return "".b if n == 0
+ if String.method_defined?(:bytesplice)
+ def read_str(str, n)
+ return "".b if n == 0
@@ -28,4 +29,13 @@
- chunk = str.byteslice(0..(n - 1))
- remaining = str.byteslice(n..-1)
- remaining ? str.replace(remaining) : str.clear
- chunk
+ chunk = str.byteslice(0, n)
+ str.bytesplice(0, chunk.length, "")
+ chunk
+ end
+ else
+ def read_str(str, n)
+ return "".b if n == 0
+
+ chunk = str.byteslice(0, n)
+ remaining = str.byteslice(n, str.size - n)
+ remaining ? str.replace(remaining) : str.clear
+ chunk
+ end
@@ -36,4 +45,0 @@
- end
-
- def shift_byte(str)
- read_str(str, 1).ord
lib/http/2/flow_buffer.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/flow_buffer.rb 2026-06-17 02:34:12.814525841 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/flow_buffer.rb 2026-06-17 02:34:12.820525927 +0000
@@ -73 +73 @@
- end_stream = frame[:flags].include?(:end_stream)
+ end_stream = frame[:flags].anybits?(END_STREAM)
@@ -117,0 +118,2 @@
+ include BufferUtils
+
@@ -143 +145 @@
- end_stream = frame[:flags].include?(:end_stream)
+ end_stream = frame[:flags].anybits?(END_STREAM)
@@ -151,2 +153 @@
- chunk = frame.dup
- payload = frame[:payload]
+ chunk = frame.dup
@@ -157 +158 @@
- chunk[:payload] = payload.byteslice(0, window_size)
+ chunk[:payload] = read_str(frame[:payload], window_size) # mutates frame[:payload]
@@ -159 +159,0 @@
- frame[:payload] = payload.byteslice(window_size..-1)
@@ -163 +163 @@
- chunk[:flags] -= [:end_stream] if end_stream
+ chunk[:flags] ^= END_STREAM if end_stream
lib/http/2/framer.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/framer.rb 2026-06-17 02:34:12.814525841 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/framer.rb 2026-06-17 02:34:12.820525927 +0000
@@ -3,0 +4,19 @@
+ # Frame flags as defined by the spec (max 255 bits)
+ # DATA: ( X X COMPRESSED X PADDED X X END_STREAM )
+ # HEADERS: ( X X PRIORITY X PADDED END_HEADERS X END_STREAM )
+ # PRIORITY: ( X X X X X X X X )
+ # RST_STREAM: ( X X X X X X X X )
+ # SETTINGS: ( X X X X X X X ACK )
+ # PUSH_PROMISE: ( X X X X PADDED END_HEADERS X X )
+ # PING: ( X X X X X X X ACK )
+ # GOAWAY: ( X X X X X X X X )
+ # WINDOW_UPDATE: ( X X X X X X X X )
+ # CONTINUATION: ( X X X X X END_HEADERS X X )
+ # ALTSVC: ( X X X X X X X X )
+ # ORIGIN: ( RESERVED4 X X RESERVED3 X RESERVED2 RESERVED X )
+ END_STREAM = ACK = 0b0001 # 1
+ RESERVED = 0b0010 # 2
+ END_HEADERS = 0b0100 # 4
+ PADDED = 0b1000 # 8
+ PRIORITY = 0b0010_0000 # 32
+
@@ -43,33 +61,0 @@
- # Per frame flags as defined by the spec
- FRAME_FLAGS = {
- data: {
- end_stream: 0,
- padded: 3,
- compressed: 5
- },
- headers: {
- end_stream: 0,
- end_headers: 2,
- padded: 3,
- priority: 5
- },
- priority: {},
- rst_stream: {},
- settings: { ack: 0 },
- push_promise: {
- end_headers: 2,
- padded: 3
- },
- ping: { ack: 0 },
- goaway: {},
- window_update: {},
- continuation: { end_headers: 2 },
- altsvc: {},
- origin: {
- reserved: 1,
- reserved2: 2,
- reserved3: 4,
- reserved4: 8
- }
- }.each_value(&:freeze).freeze
-
@@ -86,17 +72,19 @@
- # Default error types as defined by the spec
- DEFINED_ERRORS = {
- no_error: 0,
- protocol_error: 1,
- internal_error: 2,
- flow_control_error: 3,
- settings_timeout: 4,
- stream_closed: 5,
- frame_size_error: 6,
- refused_stream: 7,
- cancel: 8,
- compression_error: 9,
- connect_error: 10,
- enhance_your_calm: 11,
- inadequate_security: 12,
- http_1_1_required: 13
- }.freeze
+ DEFINED_SETTINGS_BY_ID = DEFINED_SETTINGS.invert.freeze
+
+ # Default error types as defined by the spec (the code is the array index)
+ DEFINED_ERRORS = %i[
+ no_error
+ protocol_error
+ internal_error
+ flow_control_error
+ settings_timeout
+ stream_closed
+ frame_size_error
+ refused_stream
+ cancel
+ compression_error
+ connect_error
+ enhance_your_calm
+ inadequate_security
+ http_1_1_required
+ ].freeze
@@ -110,0 +99,2 @@
+ PRIORITYPACK = (UINT32 + UINT8).freeze
+ ALTSVCPACK = (UINT32 + UINT16).freeze
@@ -114 +104 @@
- private_constant :RBIT, :RBYTE, :EBIT, :HEADERPACK, :UINT32, :UINT16, :UINT8
+ private_constant :RBIT, :RBYTE, :EBIT, :HEADERPACK, :PRIORITYPACK, :UINT32, :UINT16, :UINT8
@@ -148,0 +139,4 @@
+ flags = frame[:flags]
+
+ raise CompressionError, "Invalid frame flag (#{flags}) for #{type}" unless flags.between?(0, 255)
+
@@ -163,6 +157 @@
- frame[:flags].reduce(0) do |acc, f|
- position = FRAME_FLAGS[type][f]
- raise CompressionError, "Invalid frame flag (#{f}) for #{type}" unless position
-
- acc | (1 << position)
- end,
+ flags,
@@ -187,3 +176 @@
- flags: FRAME_FLAGS[type].filter_map do |name, pos|
- name if flags.anybits?(1 << pos)
- end,
+ flags: flags,
@@ -201 +188 @@
- frame[:flags] ||= EMPTY
+ frame[:flags] ||= 0
@@ -204,0 +192 @@
+ # @type var frame: data_frame | continuation_frame
@@ -216 +204 @@
- frame[:flags] += [:priority] unless frame[:flags].include?(:priority)
+ frame[:flags] |= PRIORITY
@@ -219 +207 @@
- if frame[:flags].include?(:priority)
+ if frame[:flags].anybits?(PRIORITY)
@@ -222,2 +210,4 @@
- pack([(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT)], UINT32, buffer: bytes)
- pack([frame[:weight] - 1], UINT8, buffer: bytes)
+ pack(
+ [(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT), frame[:weight] - 1],
+ PRIORITYPACK, buffer: bytes
+ )
@@ -237,2 +227,4 @@
- pack([(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT)], UINT32, buffer: bytes)
- pack([frame[:weight] - 1], UINT8, buffer: bytes)
+ pack(
+ [(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT), frame[:weight] - 1],
+ PRIORITYPACK, buffer: bytes
+ )
@@ -251 +242,0 @@
- bytes = String.new("", encoding: Encoding::BINARY, capacity: length)
@@ -253,5 +244,6 @@
- settings.each do |(k, v)|
- if k.is_a? Integer # rubocop:disable Style/GuardClause
- DEFINED_SETTINGS.value?(k) || next
- else
- k = DEFINED_SETTINGS[k]
+ case settings
+ when String
+ length = settings.bytesize
+ bytes = settings
+ else
+ bytes = String.new("", encoding: Encoding::BINARY, capacity: settings.size * 6)
@@ -259 +251,12 @@
- raise CompressionError, "Unknown settings ID for #{k}" if k.nil?
+ settings.each do |(k, v)|
+ if k.is_a? Integer # rubocop:disable Style/GuardClause
+ DEFINED_SETTINGS.value?(k) || next
+ else
+ k = DEFINED_SETTINGS[k]
+
+ raise CompressionError, "Unknown settings ID for #{k}" if k.nil?
+ end
+
+ pack([k], UINT16, buffer: bytes)
+ pack([v], UINT32, buffer: bytes)
+ length += 6
@@ -261,4 +263,0 @@
-
- pack([k], UINT16, buffer: bytes)
- pack([v], UINT32, buffer: bytes)
- length += 6
@@ -298 +297 @@
- pack([frame[:max_age], frame[:port]], UINT32 + UINT16, buffer: bytes)
+ pack([frame[:max_age], frame[:port]], ALTSVCPACK, buffer: bytes)
@@ -357 +356 @@
- frame[:flags] += [:padded]
+ frame[:flags] |= PADDED
@@ -378,3 +377,3 @@
- type = frame[:type]
- length = frame[:length]
- flags = frame[:flags]
+ type = frame[:type] #: Symbol
+ length = frame[:length] #: Integer
+ flags = frame[:flags] #: Integer
@@ -397 +396 @@
- padded = flags.include?(:padded)
+ padded = flags.anybits?(PADDED)
@@ -400 +398,0 @@
- frame[:padding] = padlen + 1
@@ -402,0 +401,2 @@
+ frame[:padding] = padlen + 1
+
@@ -405 +405 @@
- flags.delete(:padded)
+ frame[:flags] ^= PADDED
@@ -413 +413 @@
- if flags.include?(:priority)
+ if flags.anybits?(PRIORITY)
@@ -417 +417 @@
- weight = payload.byteslice(0, 1).ord + 1
+ weight = payload.getbyte(0) + 1
@@ -428 +428 @@
- weight = payload.byteslice(0, 1).ord + 1
+ weight = payload.getbyte(0) + 1
@@ -439 +438,0 @@
- frame[:payload] = []
@@ -444 +443 @@
- (frame[:length] / 6).times do
+ frame[:payload] = (frame[:length] / 6).times.filter_map do
@@ -450,2 +449,3 @@
- name, = DEFINED_SETTINGS.find { |_name, v| v == id }
- frame[:payload] << [name, val] if name
+ if (name = DEFINED_SETTINGS_BY_ID[id])
+ [name, val]
+ end
@@ -467 +467 @@
- frame[:max_age], frame[:port] = read_str(payload, 6).unpack(UINT32 + UINT16)
+ frame[:max_age], frame[:port] = read_str(payload, 6).unpack(ALTSVCPACK)
@@ -469 +469 @@
- len = payload.byteslice(0, 1).ord
+ len = payload.getbyte(0)
@@ -473 +473 @@
- len = payload.byteslice(0, 1).ord
+ len = payload.getbyte(0)
@@ -498 +498 @@
- error = DEFINED_ERRORS[error]
+ error = DEFINED_ERRORS.index(error)
@@ -507 +507 @@
- DEFINED_ERRORS.key(error) || error
+ DEFINED_ERRORS.fetch(error, error)
lib/http/2/header/compressor.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/header/compressor.rb 2026-06-17 02:34:12.815525855 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/header/compressor.rb 2026-06-17 02:34:12.820525927 +0000
@@ -85,0 +86,2 @@
+ integer(huffman.bytesize, 7, buffer: buffer)
+ buffer.setbyte(huffman_offset, buffer.getbyte(huffman_offset) | 0x80)
@@ -87 +89 @@
- set_huffman_size(buffer, huffman_offset)
+ buffer
@@ -122 +124 @@
- fb = buffer[offset].ord | rep[:pattern]
+ fb = buffer.getbyte(offset) | rep[:pattern]
@@ -149,0 +152 @@
+ buffer << "\x00".b
@@ -151 +154,9 @@
- set_huffman_size(buffer, huffman_offset)
+ size = buffer.bytesize - huffman_offset - 1
+
+ if size < 127
+ buffer.setbyte(huffman_offset, 0x80 | size)
+ else
+ buffer.slice!(huffman_offset, 1)
+ set_huffman_size(buffer, huffman_offset)
+ end
+ buffer
@@ -168 +179 @@
- buffer.setbyte(huffman_offset, buffer[huffman_offset].ord | 0x80)
+ buffer.setbyte(huffman_offset, buffer.getbyte(huffman_offset) | 0x80)
lib/http/2/header/decompressor.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/header/decompressor.rb 2026-06-17 02:34:12.815525855 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/header/decompressor.rb 2026-06-17 02:34:12.820525927 +0000
@@ -36 +36,7 @@
- i = n.zero? ? 0 : (shift_byte(buf) & limit)
+ if n.zero?
+ i = 0
+ consumed = 0
+ else
+ i = buf.getbyte(0) & limit
+ consumed = 1
+ end
@@ -38 +43,0 @@
- m = 0
@@ -40,5 +45,2 @@
- offset = 0
-
- buf.each_byte.with_index do |byte, idx|
- offset = idx
- # while (byte = shift_byte(buf))
+ m = 0
+ while (byte = buf.getbyte(consumed))
@@ -47 +49 @@
-
+ consumed += 1
@@ -50,2 +51,0 @@
-
- read_str(buf, offset + 1)
@@ -53,0 +54 @@
+ read_str(buf, consumed)
lib/http/2/header/encoding_context.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/header/encoding_context.rb 2026-06-17 02:34:12.815525855 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/header/encoding_context.rb 2026-06-17 02:34:12.820525927 +0000
@@ -120,0 +121,2 @@
+ @table_by_field = Hash.new { |hs, k| hs[k] = [] }
+ @unshifts = 0
@@ -131,0 +134,2 @@
+ tbf = @table_by_field.transform_values(&:dup)
+ unshifts = @unshifts
@@ -134,0 +139,2 @@
+ @table_by_field = tbf
+ @unshifts = unshifts
@@ -215,0 +222,2 @@
+ @unshifts += 1
+ @table_by_field[name].unshift([value, @unshifts])
@@ -282,2 +290 @@
- @table.each_with_index do |(hfield, hvalue), i|
- next unless field == hfield
+ field_entries = @table_by_field[field]
@@ -284,0 +292,3 @@
+ field_entries&.each do |hvalue, unshift_id|
+ abs_index = (@unshifts - unshift_id) + STATIC_TABLE_SIZE
+ name_only ||= abs_index
@@ -286 +296 @@
- exact = i + STATIC_TABLE_SIZE
+ exact = abs_index
@@ -288,2 +297,0 @@
- else
- name_only ||= i + STATIC_TABLE_SIZE
@@ -320 +327,0 @@
-
@@ -322,0 +330,5 @@
+
+ field_arr = @table_by_field[name]
+ field_arr.pop
+ @table_by_field.delete(name) if field_arr.empty?
+
lib/http/2/header/huffman.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/header/huffman.rb 2026-06-17 02:34:12.815525855 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/header/huffman.rb 2026-06-17 02:34:12.820525927 +0000
@@ -22,0 +23,2 @@
+ EOS_PADDING = (0..7).map { |n| ("1" * n).b.freeze }.freeze
+
@@ -32 +34 @@
- append_str(bitstring, "1" * ((8 - bitstring.size) % 8))
+ append_str(bitstring, EOS_PADDING[(8 - bitstring.size) % 8])
@@ -57 +59 @@
- append_str(emit, first.chr) if first
+ emit << first if first
@@ -63 +65 @@
- emit.force_encoding(Encoding::BINARY)
+ emit
@@ -328 +330 @@
- ENCODE_TABLE = CODES.map { |c, l| [c].pack("N").unpack1("B*")[-l..-1] }.each(&:freeze).freeze
+ ENCODE_TABLE = CODES.map { |c, l| [c].pack("N").unpack1("B*")[-l..-1].b.freeze }.freeze
lib/http/2/server.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/server.rb 2026-06-17 02:34:12.817525884 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/server.rb 2026-06-17 02:34:12.821525941 +0000
@@ -81,12 +81,6 @@
- buf = "".b
- append_str(buf, Base64.urlsafe_decode64(settings.to_s))
- @framer.common_header(
- {
- length: buf.bytesize,
- type: :settings,
- stream: 0,
- flags: []
- },
- buffer: buf
- )
- receive(buf)
+ receive(@framer.generate(
+ type: :settings,
+ stream: 0,
+ flags: 0,
+ payload: Base64.urlsafe_decode64(settings.to_s)
+ ))
@@ -100 +94 @@
- flags: [:end_headers],
+ flags: END_HEADERS,
@@ -109 +103 @@
- headers_frame[:flags] << [:end_stream]
+ headers_frame[:flags] |= END_HEADERS
@@ -113 +107 @@
- stream << { type: :data, stream: 1, payload: body, flags: [:end_stream] }
+ stream << { type: :data, stream: 1, payload: body, flags: END_STREAM }
@@ -138 +132 @@
- return unless frame[:flags].include?(:ack) && !@origins_sent
+ return unless frame[:flags].anybits?(ACK) && !@origins_sent
@@ -151 +145 @@
- # @param flags [Array[Symbol]]
+ # @param flags Integer
@@ -160 +154 @@
- payload: headers.to_a
+ payload: headers
lib/http/2/stream.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/stream.rb 2026-06-17 02:34:12.817525884 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/stream.rb 2026-06-17 02:34:12.821525941 +0000
@@ -117 +117,2 @@
- case frame[:type]
+ frame_type = frame[:type] #: Symbol
+ case frame_type
@@ -118,0 +120 @@
+ # @type var frame: data_frame
@@ -131,0 +134 @@
+ # @type var frame: headers_frame
@@ -153,0 +157 @@
+ # @type var frame: priority_frame
@@ -155,0 +160 @@
+ # @type var frame: window_update_frame
@@ -157,0 +163 @@
+ # @type var frame: origin_frame
@@ -162,3 +168 @@
- emit(frame[:type], frame) if !frame[:origin] || frame[:origin].empty?
- when :blocked
- emit(frame[:type], frame)
+ emit(frame_type, frame) if !frame[:origin] || frame[:origin].empty?
@@ -201,0 +206 @@
+ # @type var frame: data_frame
@@ -204,0 +210 @@
+ # @type var frame: window_update_frame
@@ -206,0 +213 @@
+ # @type var frame: priority_frame
@@ -222,3 +229,2 @@
- flags = []
- flags << :end_headers if end_headers
- flags << :end_stream if end_stream || @_method == "HEAD"
+ flags = end_headers ? END_HEADERS : 0
+ flags |= END_STREAM if end_stream || @_method == "HEAD"
@@ -232 +238 @@
- flags = end_headers ? [:end_headers] : []
+ flags = end_headers ? END_HEADERS : 0
@@ -257 +263 @@
- send(type: :data, flags: [], payload: chunk)
+ send(type: :data, flags: 0, payload: chunk)
@@ -261,2 +267,2 @@
- flags = []
- flags << :end_stream if end_stream
+ flags = 0
+ flags |= END_STREAM if end_stream
@@ -666 +672,2 @@
- frame[:flags] && frame[:flags].include?(:end_stream)
+ # @type var frame: data_frame | headers_frame | continuation_frame
+ frame[:flags] && frame[:flags].anybits?(END_STREAM)
lib/http/2/version.rb
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/lib/http/2/version.rb 2026-06-17 02:34:12.817525884 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/lib/http/2/version.rb 2026-06-17 02:34:12.821525941 +0000
@@ -4 +4 @@
- VERSION = "1.1.3"
+ VERSION = "1.2.0"
sig/2.rbs
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/sig/2.rbs 2026-06-17 02:34:12.817525884 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/sig/2.rbs 2026-06-17 02:34:12.821525941 +0000
@@ -38,0 +39,8 @@
+ # Frame flags
+ END_STREAM: Integer
+ ACK: Integer
+ RESERVED: Integer
+ END_HEADERS: Integer
+ PADDED: Integer
+ PRIORITY: Integer
+
@@ -42 +50,3 @@
- type frame_control_flags = Array[:end_headers | :end_stream]
+ type frame_control_flags = Integer
+
+ type common_frame = { stream: Integer, flags: frame_control_flags, ?length: Integer, ?ignore: bool }
@@ -44 +54 @@
- type common_frame = { stream: Integer }
+ type connection_frame = settings_frame | ping_frame | goaway_frame | window_update_frame | altsvc_frame | origin_frame
@@ -47,2 +57,2 @@
- type headers_frame = common_frame & {
- type: :headers, flags: frame_control_flags, payload: Enumerable[header_pair] | String,
+ type headers_frame_props = {
+ type: :headers, payload: Enumerable[header_pair] | String,
@@ -50,0 +61,5 @@
+ type headers_frame = common_frame & headers_frame_props
+
+ type continuation_frame_props = headers_frame_props | { type: :continuation }
+
+ type continuation_frame = common_frame & continuation_frame_props
@@ -53 +68,3 @@
- type data_frame = { type: :data, flags: frame_control_flags, ?length: Integer, payload: String, ?padding: Integer }
+ type data_frame_props = { type: :data, ?length: Integer, payload: String, ?padding: Integer }
+
+ type data_frame = common_frame & data_frame_props
@@ -56 +73,3 @@
- type push_promise_frame = { type: :push_promise, promise_stream: Integer, flags: frame_control_flags, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair], ?padding: Integer }
+ type push_promise_frame_props = { promise_stream: Integer, ?length: Integer, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair] | String, ?padding: Integer }
+
+ type push_promise_frame = common_frame & push_promise_frame_props
@@ -59 +78,3 @@
- type settings_frame = { type: :settings, payload: Array[[Symbol | Integer, Integer]] }
+ type settings_frame_props = { type: :settings, payload: (Enumerable[[Symbol | Integer, Integer]] | String) }
+
+ type settings_frame = common_frame & settings_frame_props
@@ -62 +83,3 @@
- type window_update_frame = { type: :window_update, increment: Integer }
+ type window_update_frame_props = { type: :window_update, increment: Integer }
+
+ type window_update_frame = common_frame & window_update_frame_props
@@ -65 +88,5 @@
- type priority_frame = { dependency: Integer, exclusive: bool, weight: Integer }
+ type priority_frame_inner_props = { dependency: Integer, exclusive: bool, weight: Integer }
+
+ type priority_frame_props = { type: :priority } & priority_frame_inner_props
+
+ type priority_frame = common_frame & priority_frame_props
@@ -68 +95,3 @@
- type altsvc_frame = { type: :altsvc, max_age: Integer, port: Integer, proto: "String", host: String }
+ type altsvc_frame_props = { type: :altsvc, max_age: Integer, port: Integer, proto: String, host: String }
+
+ type altsvc_frame = common_frame & altsvc_frame_props
@@ -71 +100,3 @@
- type origin_frame = { type: :origin, origin: Array[String] }
+ type origin_frame_props = { type: :origin, payload: Array[String] }
+
+ type origin_frame = common_frame & origin_frame_props
@@ -74 +105,3 @@
- type ping_frame = { type: :ping, payload: String, length: Integer }
+ type ping_frame_props = { type: :ping, payload: String }
+
+ type ping_frame = common_frame & ping_frame_props
@@ -77 +110,3 @@
- type goaway_frame = { type: :goaway, last_stream: Integer, error: Symbol? }
+ type goaway_frame_props = { type: :goaway, last_stream: Integer, error: (Symbol | Integer)? }
+
+ type goaway_frame = common_frame & goaway_frame_props
@@ -79 +114,6 @@
- # type frame = common_frame & (headers_frame | data_frame | push_promise_frame |
+ # # RST_STREAM
+ type rst_stream_frame_props = { type: :rst_stream, error: (Symbol | Integer)? }
+
+ type rst_stream_frame = common_frame & rst_stream_frame_props
+
+ # type frame = headers_frame | continuation_frame | push_promise_frame | data_frame |
@@ -81 +121,8 @@
- # origin_frame | ping_frame | goaway_frame)
+ # origin_frame | ping_frame | goaway_frame | rst_stream_frame
+
+ # type connection_frame_props = rst_stream_frame_props | ping_frame_props | goaway_frame_props
+ # | window_update_frame_props | settings_frame_props
+
+ # type stream_frame_props = headers_frame_props | continuation_frame_props | push_promise_frame_props
+ # | data_frame_props | rst_stream_frame_props | priority_frame_props
+ # | window_update_frame_props | origin_frame_props | altsvc_frame_props
@@ -111,0 +159,2 @@
+ type connection_frame_props = Hash[frame_key, frame_value]
+ type stream_frame_props = Hash[frame_key, frame_value]
sig/connection.rbs
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/sig/connection.rbs 2026-06-17 02:34:12.817525884 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/sig/connection.rbs 2026-06-17 02:34:12.822525956 +0000
@@ -35,0 +36 @@
+ @oldest_stream_recently_closed: Numeric
@@ -52,0 +54 @@
+ @continuation_size: Integer
@@ -71 +73 @@
- def receive: (string data) -> void
+ def receive: (String data) -> void
@@ -78 +80 @@
- def send: (frame frame) -> void
+ def send: (connection_frame_props | stream_frame_props frame) -> void
@@ -84 +86 @@
- def connection_management: (frame) -> void
+ def connection_management: (connection_frame frame) -> void
@@ -90 +92 @@
- def connection_settings: (frame) -> void
+ def connection_settings: (settings_frame) -> void
@@ -92 +94 @@
- def decode_headers: (frame) -> void
+ def decode_headers: (headers_frame | push_promise_frame) -> void
@@ -94 +96 @@
- def encode_headers: (frame headers_frame) -> void
+ def encode_headers: (headers_frame | push_promise_frame) -> void
@@ -100 +102 @@
- def verify_pseudo_headers: (frame) -> void
+ def verify_pseudo_headers: (headers_frame | push_promise_frame) -> void
@@ -102 +104 @@
- def _verify_pseudo_headers: (frame, Array[String]) -> void
+ def _verify_pseudo_headers: (headers_frame | push_promise_frame, Array[String]) -> void
@@ -106 +108 @@
-end
\ No newline at end of file
+end
sig/flow_buffer.rbs
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/sig/flow_buffer.rbs 2026-06-17 02:34:12.818525898 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/sig/flow_buffer.rbs 2026-06-17 02:34:12.822525956 +0000
@@ -17 +17 @@
- def send_data: (?data_frame? frame, ?bool encode) -> void
+ def send_data: (?data_frame_props? frame, ?bool encode) -> void
@@ -19 +19 @@
- def send_frame: (data_frame frame, bool encode) -> void
+ def send_frame: (data_frame_props frame, bool encode) -> void
sig/frame_buffer.rbs
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/sig/frame_buffer.rbs 2026-06-17 02:34:12.818525898 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/sig/frame_buffer.rbs 2026-06-17 02:34:12.822525956 +0000
@@ -2,0 +3,2 @@
+ include BufferUtils
+
@@ -9 +11 @@
- def <<: (data_frame frame) -> void
+ def <<: (data_frame_props frame) -> void
@@ -13 +15 @@
- def retrieve: (Integer) -> data_frame?
+ def retrieve: (Integer) -> data_frame_props?
sig/framer.rbs
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/sig/framer.rbs 2026-06-17 02:34:12.818525898 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/sig/framer.rbs 2026-06-17 02:34:12.822525956 +0000
@@ -23 +23,3 @@
- DEFINED_ERRORS: Hash[Symbol, Integer]
+ DEFINED_SETTINGS_BY_ID: Hash[Integer, Symbol]
+
+ DEFINED_ERRORS: Array[Symbol]
@@ -31,0 +34,2 @@
+ PRIORITYPACK: String
+ ALTSVCPACK: String
@@ -44 +48 @@
- def read_common_header: (String buf) -> frame
+ def read_common_header: (String buf) -> (common_frame | { length: Integer })
@@ -50 +54 @@
- def parse: (String) -> frame?
+ def parse: (String) -> (frame | { length: Integer })?
@@ -56 +60 @@
- def pack_error: (Integer | Symbol error, buffer: String) -> String
+ def pack_error: (Symbol | Integer error, buffer: String) -> String
sig/header/compressor.rbs
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/sig/header/compressor.rbs 2026-06-17 02:34:12.818525898 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/sig/header/compressor.rbs 2026-06-17 02:34:12.822525956 +0000
@@ -4,0 +5 @@
+ include BufferUtils
sig/header/encoding_context.rbs
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/sig/header/encoding_context.rbs 2026-06-17 02:34:12.818525898 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/sig/header/encoding_context.rbs 2026-06-17 02:34:12.823525970 +0000
@@ -24,0 +25,4 @@
+ @table_by_field: Hash[string, Array[[string, Integer]]]
+
+ @unshifts: Integer
+
sig/header/huffman.rbs
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/sig/header/huffman.rbs 2026-06-17 02:34:12.818525898 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/sig/header/huffman.rbs 2026-06-17 02:34:12.823525970 +0000
@@ -11,0 +12,2 @@
+ EOS_PADDING: Array[String]
+
sig/server.rbs
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/sig/server.rbs 2026-06-17 02:34:12.818525898 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/sig/server.rbs 2026-06-17 02:34:12.823525970 +0000
@@ -10 +10 @@
- def promise: (Stream parent, Enumerable[header_pair] headers, Array[Symbol] flags) { (Stream) -> void } -> void
+ def promise: (Stream parent, Enumerable[header_pair] headers, frame_control_flags flags) { (Stream) -> void } -> void
sig/stream.rbs
--- /tmp/d20260617-525-4i6s98/http-2-1.1.3/sig/stream.rbs 2026-06-17 02:34:12.818525898 +0000
+++ /tmp/d20260617-525-4i6s98/http-2-1.2.0/sig/stream.rbs 2026-06-17 02:34:12.823525970 +0000
@@ -40 +40 @@
- def send: (frame frame) -> void
+ def send: (stream_frame_props frame) -> void
@@ -73 +73 @@
- def transition: (frame, bool sending) -> void
+ def transition: (stream_frame_props frame, bool sending) -> void
@@ -83 +83 @@
- def process_priority: (priority_frame frame) -> void
+ def process_priority: (priority_frame_inner_props frame) -> void
@@ -85 +85 @@
- def end_stream?: (frame frame) -> boolish
+ def end_stream?: (stream_frame_props frame) -> boolish
@@ -87,2 +87 @@
- def stream_error: (Symbol error, ?msg: String?) -> void
- | () -> void
+ def stream_error: (?Symbol error, ?msg: String?) -> void
@@ -92 +91 @@
- def manage_state: (frame) { () -> void } -> void
+ def manage_state: (stream_frame_props frame) { () -> void } -> void
@@ -94 +93 @@
-end
\ No newline at end of file
+end |
Contributor
gem compare --diff http-2 1.1.3 1.2.0Compared versions: ["1.1.3", "1.2.0"]
DIFFERENT files:
1.1.3->1.2.0:
* Added:
lib/http/2/settings.rb
--- /tmp/20260617-1119-8c7kcw 2026-06-17 02:34:13.427590897 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/settings.rb 2026-06-17 02:34:13.425590891 +0000
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module HTTP2
+ # Default values for SETTINGS frame, as defined by the spec.
+ SPEC_DEFAULT_CONNECTION_SETTINGS = {
+ settings_header_table_size: 4096,
+ settings_enable_push: 1, # enabled for servers
+ settings_max_concurrent_streams: Framer::MAX_STREAM_ID, # unlimited
+ settings_initial_window_size: 65_535,
+ settings_max_frame_size: 16_384,
+ settings_max_header_list_size: (2 << 30) - 1 # unlimited
+ }.freeze
+
+ Settings = Struct.new(
+ :settings_header_table_size,
+ :settings_enable_push,
+ :settings_max_concurrent_streams,
+ :settings_initial_window_size,
+ :settings_max_frame_size,
+ :settings_max_header_list_size,
+ keyword_init: true
+ ) do
+ def initialize(
+ settings_header_table_size: 4096,
+ settings_enable_push: 1,
+ settings_max_concurrent_streams: 100,
+ settings_initial_window_size: 65_535,
+ settings_max_frame_size: 16_384,
+ settings_max_header_list_size: (2 << 30) - 1
+ )
+ super
+ end
+
+ def each_setting
+ each_pair do |k, v|
+ next if v == SPEC_DEFAULT_CONNECTION_SETTINGS[k]
+
+ yield k, v
+ end
+ end
+ end
+end
* Changed:
lib/http/2/client.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/client.rb 2026-06-17 02:34:13.418590872 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/client.rb 2026-06-17 02:34:13.423590886 +0000
@@ -72 +72 @@
- frame = Framer.new.generate(type: :settings, stream: 0, payload: settings)
+ frame = Framer.new.generate(type: :settings, stream: 0, flags: 0, payload: settings)
lib/http/2/connection.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/connection.rb 2026-06-17 02:34:13.419590875 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/connection.rb 2026-06-17 02:34:13.423590886 +0000
@@ -44,2 +43,0 @@
- HEADERS_FRAME_TYPES = %i[headers push_promise].freeze
-
@@ -93,0 +92 @@
+ @oldest_stream_recently_closed = nil
@@ -104,0 +104 @@
+ @continuation_size = 0
@@ -159 +159 @@
- send(type: :goaway, last_stream: @last_stream_id,
+ send(type: :goaway, stream: 0, last_stream: @last_stream_id,
@@ -181 +180,0 @@
- @pending_settings << payload
@@ -215,3 +214,2 @@
- # @type var stream_id: Integer
- stream_id = frame[:stream]
- frame_type = frame[:type]
+ stream_id = frame[:stream] #: Integer
+ frame_type = frame[:type] #: Symbol?
@@ -239,0 +238 @@
+ # @type var frame: continuation_frame
@@ -243,2 +242,2 @@
- unless frame[:flags].include? :end_headers
- buffered_payload = @continuation.sum { |f| f[:payload].bytesize }
+ @continuation_size += frame[:payload].bytesize
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -248 +247 @@
- unless buffered_payload < @local_settings[:settings_max_frame_size]
+ unless @continuation_size < @local_settings[:settings_max_frame_size]
@@ -261,0 +261 @@
+ @continuation_size = 0
@@ -265 +265 @@
- frame[:flags] << :end_headers
+ frame[:flags] |= END_HEADERS
@@ -273,0 +274 @@
+ # @type var frame: connection_frame
@@ -278,0 +280 @@
+ # @type var frame: headers_frame
@@ -285 +287 @@
- unless frame[:flags].include? :end_headers
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -314,0 +317 @@
+ # @type var frame: push_promise_frame
@@ -317 +320 @@
- unless frame[:flags].include? :end_headers
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -437,2 +439,0 @@
- frame_type = frame[:type]
-
@@ -440,2 +440,0 @@
- if frame_type == :data
- send_data(frame, true)
@@ -443,3 +442 @@
- elsif frame_type == :rst_stream && frame[:error] == :protocol_error
- # An endpoint can end a connection at any time. In particular, an
- # endpoint MAY choose to treat a stream error as a connection error.
+ frame_type = frame[:type] #: Symbol
@@ -447,2 +444,5 @@
- goaway(:protocol_error)
- else
+ case frame_type
+ when :data
+ #: @type var frame: data_frame
+ send_data(frame, true)
+ when :headers, :push_promise
@@ -450,0 +451,10 @@
+ #: @type var frame: headers_frame | push_promise_frame
+ encode_headers(frame) # HEADERS and PUSH_PROMISE may create more than one frame
+ else
+ if frame_type == :rst_stream && frame[:error] == :protocol_error
+ # An endpoint can end a connection at any time. In particular, an
+ # endpoint MAY choose to treat a stream error as a connection error.
+
+ goaway(:protocol_error)
+ end
+ #: @type var frame: connection_frame
@@ -459,5 +469 @@
- if HEADERS_FRAME_TYPES.include?(frame[:type])
- encode_headers(frame) # HEADERS and PUSH_PROMISE may create more than one frame
- else
- emit(:frame, @framer.generate(frame))
- end
+ emit(:frame, @framer.generate(frame))
@@ -495,0 +502 @@
+ # @type var frame: settings_frame
@@ -497,0 +505 @@
+ # @type var frame: window_update_frame
@@ -501,0 +510 @@
+ # @type var frame: goaway_frame
@@ -508,0 +518 @@
+ # @type var frame: altsvc_frame
@@ -515 +525,2 @@
- return if @h2c_upgrade || !frame[:flags].empty?
+ # @type var frame: origin_frame
+ return if @h2c_upgrade || !frame[:flags].zero?
@@ -520,2 +530,0 @@
- when :blocked
- emit(:blocked, frame)
@@ -541 +550 @@
- if frame[:flags].include? :ack
+ if frame[:flags].anybits?(ACK)
@@ -544,2 +553 @@
- send(type: :ping, stream: 0,
- flags: [:ack], payload: frame[:payload])
+ send(type: :ping, stream: 0, flags: ACK, payload: frame[:payload])
@@ -608 +616 @@
- if frame[:flags].include?(:ack)
+ if frame[:flags].anybits?(ACK)
@@ -613 +620,0 @@
- validate_settings(@remote_role, frame[:payload])
@@ -614,0 +622 @@
+ validate_settings(@remote_role, settings)
@@ -684 +692 @@
- send(type: :settings, stream: 0, payload: [], flags: [:ack])
+ send(type: :settings, stream: 0, payload: EMPTY, flags: ACK)
@@ -714 +722 @@
- payload = headers_frame[:payload]
+ headers_payload = headers_frame[:payload]
@@ -716 +724 @@
- payload = headers_frame[:payload] = @compressor.encode(payload) unless payload.is_a?(String)
+ payload = headers_payload.is_a?(String) ? headers_payload : @compressor.encode(headers_payload)
@@ -720,0 +729,3 @@
+ #: @type var payload: String
+ headers_frame[:payload] = payload
+
@@ -725 +736 @@
- emit(:frame, @framer.generate(headers_frame))
+ encode(headers_frame)
@@ -730 +741,2 @@
- headers_frame[:flags].delete(:end_headers)
+ total = payload.bytesize
+ headers_frame[:flags] ^= END_HEADERS
@@ -732 +744,2 @@
- payload = payload.byteslice(max_frame_size..-1)
+ # payload = payload.byteslice(max_frame_size..-1)
+ offset = max_frame_size
@@ -735 +748 @@
- emit(:frame, @framer.generate(headers_frame))
+ encode(headers_frame)
@@ -737,6 +750 @@
- loop do
- continuation_frame = headers_frame.merge(
- type: :continuation,
- flags: EMPTY,
- payload: payload.byteslice(0, max_frame_size)
- )
+ stream_id = headers_frame[:stream]
@@ -744 +752,3 @@
- payload = payload.byteslice(max_frame_size..-1)
+ while offset < total
+ chunk_end = offset + max_frame_size
+ is_last = chunk_end >= total
@@ -746,5 +756,6 @@
- if payload.nil? || payload.empty?
- continuation_frame[:flags] = [:end_headers]
- emit(:frame, @framer.generate(continuation_frame))
- break
- end
+ continuation_frame = {
+ type: :continuation,
+ flags: is_last ? END_HEADERS : 0,
+ stream: stream_id,
+ payload: payload.byteslice(offset, max_frame_size)
+ } #: continuation_frame
@@ -752 +763,2 @@
- emit(:frame, @framer.generate(continuation_frame))
+ encode(continuation_frame)
+ offset = chunk_end
@@ -779,2 +790,0 @@
- _, closed_since = @streams_recently_closed.first
-
@@ -783 +793,2 @@
- if closed_since && (now - closed_since) > 15
+ if @oldest_stream_recently_closed && (now - @oldest_stream_recently_closed) > 15
+ new_oldest = nil
@@ -786,3 +797,9 @@
- @streams_recently_closed = @streams_recently_closed.drop_while do |_, since|
- (now - since) > 15
- end.to_h
+ @streams_recently_closed.delete_if do |_, since|
+ unless (now - since) > 15
+ new_oldest ||= since
+ break
+ end
+
+ true
+ end
+ @oldest_stream_recently_closed = new_oldest
@@ -791 +808 @@
- @streams_recently_closed[id] = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ @streams_recently_closed[id] = now
lib/http/2/extensions.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/extensions.rb 2026-06-17 02:34:13.419590875 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/extensions.rb 2026-06-17 02:34:13.424590889 +0000
@@ -25,2 +25,3 @@
- def read_str(str, n)
- return "".b if n == 0
+ if String.method_defined?(:bytesplice)
+ def read_str(str, n)
+ return "".b if n == 0
@@ -28,4 +29,13 @@
- chunk = str.byteslice(0..(n - 1))
- remaining = str.byteslice(n..-1)
- remaining ? str.replace(remaining) : str.clear
- chunk
+ chunk = str.byteslice(0, n)
+ str.bytesplice(0, chunk.length, "")
+ chunk
+ end
+ else
+ def read_str(str, n)
+ return "".b if n == 0
+
+ chunk = str.byteslice(0, n)
+ remaining = str.byteslice(n, str.size - n)
+ remaining ? str.replace(remaining) : str.clear
+ chunk
+ end
@@ -36,4 +45,0 @@
- end
-
- def shift_byte(str)
- read_str(str, 1).ord
lib/http/2/flow_buffer.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/flow_buffer.rb 2026-06-17 02:34:13.419590875 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/flow_buffer.rb 2026-06-17 02:34:13.424590889 +0000
@@ -73 +73 @@
- end_stream = frame[:flags].include?(:end_stream)
+ end_stream = frame[:flags].anybits?(END_STREAM)
@@ -117,0 +118,2 @@
+ include BufferUtils
+
@@ -143 +145 @@
- end_stream = frame[:flags].include?(:end_stream)
+ end_stream = frame[:flags].anybits?(END_STREAM)
@@ -151,2 +153 @@
- chunk = frame.dup
- payload = frame[:payload]
+ chunk = frame.dup
@@ -157 +158 @@
- chunk[:payload] = payload.byteslice(0, window_size)
+ chunk[:payload] = read_str(frame[:payload], window_size) # mutates frame[:payload]
@@ -159 +159,0 @@
- frame[:payload] = payload.byteslice(window_size..-1)
@@ -163 +163 @@
- chunk[:flags] -= [:end_stream] if end_stream
+ chunk[:flags] ^= END_STREAM if end_stream
lib/http/2/framer.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/framer.rb 2026-06-17 02:34:13.419590875 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/framer.rb 2026-06-17 02:34:13.424590889 +0000
@@ -3,0 +4,19 @@
+ # Frame flags as defined by the spec (max 255 bits)
+ # DATA: ( X X COMPRESSED X PADDED X X END_STREAM )
+ # HEADERS: ( X X PRIORITY X PADDED END_HEADERS X END_STREAM )
+ # PRIORITY: ( X X X X X X X X )
+ # RST_STREAM: ( X X X X X X X X )
+ # SETTINGS: ( X X X X X X X ACK )
+ # PUSH_PROMISE: ( X X X X PADDED END_HEADERS X X )
+ # PING: ( X X X X X X X ACK )
+ # GOAWAY: ( X X X X X X X X )
+ # WINDOW_UPDATE: ( X X X X X X X X )
+ # CONTINUATION: ( X X X X X END_HEADERS X X )
+ # ALTSVC: ( X X X X X X X X )
+ # ORIGIN: ( RESERVED4 X X RESERVED3 X RESERVED2 RESERVED X )
+ END_STREAM = ACK = 0b0001 # 1
+ RESERVED = 0b0010 # 2
+ END_HEADERS = 0b0100 # 4
+ PADDED = 0b1000 # 8
+ PRIORITY = 0b0010_0000 # 32
+
@@ -43,33 +61,0 @@
- # Per frame flags as defined by the spec
- FRAME_FLAGS = {
- data: {
- end_stream: 0,
- padded: 3,
- compressed: 5
- },
- headers: {
- end_stream: 0,
- end_headers: 2,
- padded: 3,
- priority: 5
- },
- priority: {},
- rst_stream: {},
- settings: { ack: 0 },
- push_promise: {
- end_headers: 2,
- padded: 3
- },
- ping: { ack: 0 },
- goaway: {},
- window_update: {},
- continuation: { end_headers: 2 },
- altsvc: {},
- origin: {
- reserved: 1,
- reserved2: 2,
- reserved3: 4,
- reserved4: 8
- }
- }.each_value(&:freeze).freeze
-
@@ -86,17 +72,19 @@
- # Default error types as defined by the spec
- DEFINED_ERRORS = {
- no_error: 0,
- protocol_error: 1,
- internal_error: 2,
- flow_control_error: 3,
- settings_timeout: 4,
- stream_closed: 5,
- frame_size_error: 6,
- refused_stream: 7,
- cancel: 8,
- compression_error: 9,
- connect_error: 10,
- enhance_your_calm: 11,
- inadequate_security: 12,
- http_1_1_required: 13
- }.freeze
+ DEFINED_SETTINGS_BY_ID = DEFINED_SETTINGS.invert.freeze
+
+ # Default error types as defined by the spec (the code is the array index)
+ DEFINED_ERRORS = %i[
+ no_error
+ protocol_error
+ internal_error
+ flow_control_error
+ settings_timeout
+ stream_closed
+ frame_size_error
+ refused_stream
+ cancel
+ compression_error
+ connect_error
+ enhance_your_calm
+ inadequate_security
+ http_1_1_required
+ ].freeze
@@ -110,0 +99,2 @@
+ PRIORITYPACK = (UINT32 + UINT8).freeze
+ ALTSVCPACK = (UINT32 + UINT16).freeze
@@ -114 +104 @@
- private_constant :RBIT, :RBYTE, :EBIT, :HEADERPACK, :UINT32, :UINT16, :UINT8
+ private_constant :RBIT, :RBYTE, :EBIT, :HEADERPACK, :PRIORITYPACK, :UINT32, :UINT16, :UINT8
@@ -148,0 +139,4 @@
+ flags = frame[:flags]
+
+ raise CompressionError, "Invalid frame flag (#{flags}) for #{type}" unless flags.between?(0, 255)
+
@@ -163,6 +157 @@
- frame[:flags].reduce(0) do |acc, f|
- position = FRAME_FLAGS[type][f]
- raise CompressionError, "Invalid frame flag (#{f}) for #{type}" unless position
-
- acc | (1 << position)
- end,
+ flags,
@@ -187,3 +176 @@
- flags: FRAME_FLAGS[type].filter_map do |name, pos|
- name if flags.anybits?(1 << pos)
- end,
+ flags: flags,
@@ -201 +188 @@
- frame[:flags] ||= EMPTY
+ frame[:flags] ||= 0
@@ -204,0 +192 @@
+ # @type var frame: data_frame | continuation_frame
@@ -216 +204 @@
- frame[:flags] += [:priority] unless frame[:flags].include?(:priority)
+ frame[:flags] |= PRIORITY
@@ -219 +207 @@
- if frame[:flags].include?(:priority)
+ if frame[:flags].anybits?(PRIORITY)
@@ -222,2 +210,4 @@
- pack([(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT)], UINT32, buffer: bytes)
- pack([frame[:weight] - 1], UINT8, buffer: bytes)
+ pack(
+ [(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT), frame[:weight] - 1],
+ PRIORITYPACK, buffer: bytes
+ )
@@ -237,2 +227,4 @@
- pack([(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT)], UINT32, buffer: bytes)
- pack([frame[:weight] - 1], UINT8, buffer: bytes)
+ pack(
+ [(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT), frame[:weight] - 1],
+ PRIORITYPACK, buffer: bytes
+ )
@@ -251 +242,0 @@
- bytes = String.new("", encoding: Encoding::BINARY, capacity: length)
@@ -253,5 +244,6 @@
- settings.each do |(k, v)|
- if k.is_a? Integer # rubocop:disable Style/GuardClause
- DEFINED_SETTINGS.value?(k) || next
- else
- k = DEFINED_SETTINGS[k]
+ case settings
+ when String
+ length = settings.bytesize
+ bytes = settings
+ else
+ bytes = String.new("", encoding: Encoding::BINARY, capacity: settings.size * 6)
@@ -259 +251,12 @@
- raise CompressionError, "Unknown settings ID for #{k}" if k.nil?
+ settings.each do |(k, v)|
+ if k.is_a? Integer # rubocop:disable Style/GuardClause
+ DEFINED_SETTINGS.value?(k) || next
+ else
+ k = DEFINED_SETTINGS[k]
+
+ raise CompressionError, "Unknown settings ID for #{k}" if k.nil?
+ end
+
+ pack([k], UINT16, buffer: bytes)
+ pack([v], UINT32, buffer: bytes)
+ length += 6
@@ -261,4 +263,0 @@
-
- pack([k], UINT16, buffer: bytes)
- pack([v], UINT32, buffer: bytes)
- length += 6
@@ -298 +297 @@
- pack([frame[:max_age], frame[:port]], UINT32 + UINT16, buffer: bytes)
+ pack([frame[:max_age], frame[:port]], ALTSVCPACK, buffer: bytes)
@@ -357 +356 @@
- frame[:flags] += [:padded]
+ frame[:flags] |= PADDED
@@ -378,3 +377,3 @@
- type = frame[:type]
- length = frame[:length]
- flags = frame[:flags]
+ type = frame[:type] #: Symbol
+ length = frame[:length] #: Integer
+ flags = frame[:flags] #: Integer
@@ -397 +396 @@
- padded = flags.include?(:padded)
+ padded = flags.anybits?(PADDED)
@@ -400 +398,0 @@
- frame[:padding] = padlen + 1
@@ -402,0 +401,2 @@
+ frame[:padding] = padlen + 1
+
@@ -405 +405 @@
- flags.delete(:padded)
+ frame[:flags] ^= PADDED
@@ -413 +413 @@
- if flags.include?(:priority)
+ if flags.anybits?(PRIORITY)
@@ -417 +417 @@
- weight = payload.byteslice(0, 1).ord + 1
+ weight = payload.getbyte(0) + 1
@@ -428 +428 @@
- weight = payload.byteslice(0, 1).ord + 1
+ weight = payload.getbyte(0) + 1
@@ -439 +438,0 @@
- frame[:payload] = []
@@ -444 +443 @@
- (frame[:length] / 6).times do
+ frame[:payload] = (frame[:length] / 6).times.filter_map do
@@ -450,2 +449,3 @@
- name, = DEFINED_SETTINGS.find { |_name, v| v == id }
- frame[:payload] << [name, val] if name
+ if (name = DEFINED_SETTINGS_BY_ID[id])
+ [name, val]
+ end
@@ -467 +467 @@
- frame[:max_age], frame[:port] = read_str(payload, 6).unpack(UINT32 + UINT16)
+ frame[:max_age], frame[:port] = read_str(payload, 6).unpack(ALTSVCPACK)
@@ -469 +469 @@
- len = payload.byteslice(0, 1).ord
+ len = payload.getbyte(0)
@@ -473 +473 @@
- len = payload.byteslice(0, 1).ord
+ len = payload.getbyte(0)
@@ -498 +498 @@
- error = DEFINED_ERRORS[error]
+ error = DEFINED_ERRORS.index(error)
@@ -507 +507 @@
- DEFINED_ERRORS.key(error) || error
+ DEFINED_ERRORS.fetch(error, error)
lib/http/2/header/compressor.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/header/compressor.rb 2026-06-17 02:34:13.419590875 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/header/compressor.rb 2026-06-17 02:34:13.424590889 +0000
@@ -85,0 +86,2 @@
+ integer(huffman.bytesize, 7, buffer: buffer)
+ buffer.setbyte(huffman_offset, buffer.getbyte(huffman_offset) | 0x80)
@@ -87 +89 @@
- set_huffman_size(buffer, huffman_offset)
+ buffer
@@ -122 +124 @@
- fb = buffer[offset].ord | rep[:pattern]
+ fb = buffer.getbyte(offset) | rep[:pattern]
@@ -149,0 +152 @@
+ buffer << "\x00".b
@@ -151 +154,9 @@
- set_huffman_size(buffer, huffman_offset)
+ size = buffer.bytesize - huffman_offset - 1
+
+ if size < 127
+ buffer.setbyte(huffman_offset, 0x80 | size)
+ else
+ buffer.slice!(huffman_offset, 1)
+ set_huffman_size(buffer, huffman_offset)
+ end
+ buffer
@@ -168 +179 @@
- buffer.setbyte(huffman_offset, buffer[huffman_offset].ord | 0x80)
+ buffer.setbyte(huffman_offset, buffer.getbyte(huffman_offset) | 0x80)
lib/http/2/header/decompressor.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/header/decompressor.rb 2026-06-17 02:34:13.420590878 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/header/decompressor.rb 2026-06-17 02:34:13.424590889 +0000
@@ -36 +36,7 @@
- i = n.zero? ? 0 : (shift_byte(buf) & limit)
+ if n.zero?
+ i = 0
+ consumed = 0
+ else
+ i = buf.getbyte(0) & limit
+ consumed = 1
+ end
@@ -38 +43,0 @@
- m = 0
@@ -40,5 +45,2 @@
- offset = 0
-
- buf.each_byte.with_index do |byte, idx|
- offset = idx
- # while (byte = shift_byte(buf))
+ m = 0
+ while (byte = buf.getbyte(consumed))
@@ -47 +49 @@
-
+ consumed += 1
@@ -50,2 +51,0 @@
-
- read_str(buf, offset + 1)
@@ -53,0 +54 @@
+ read_str(buf, consumed)
lib/http/2/header/encoding_context.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/header/encoding_context.rb 2026-06-17 02:34:13.420590878 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/header/encoding_context.rb 2026-06-17 02:34:13.424590889 +0000
@@ -120,0 +121,2 @@
+ @table_by_field = Hash.new { |hs, k| hs[k] = [] }
+ @unshifts = 0
@@ -131,0 +134,2 @@
+ tbf = @table_by_field.transform_values(&:dup)
+ unshifts = @unshifts
@@ -134,0 +139,2 @@
+ @table_by_field = tbf
+ @unshifts = unshifts
@@ -215,0 +222,2 @@
+ @unshifts += 1
+ @table_by_field[name].unshift([value, @unshifts])
@@ -282,2 +290 @@
- @table.each_with_index do |(hfield, hvalue), i|
- next unless field == hfield
+ field_entries = @table_by_field[field]
@@ -284,0 +292,3 @@
+ field_entries&.each do |hvalue, unshift_id|
+ abs_index = (@unshifts - unshift_id) + STATIC_TABLE_SIZE
+ name_only ||= abs_index
@@ -286 +296 @@
- exact = i + STATIC_TABLE_SIZE
+ exact = abs_index
@@ -288,2 +297,0 @@
- else
- name_only ||= i + STATIC_TABLE_SIZE
@@ -320 +327,0 @@
-
@@ -322,0 +330,5 @@
+
+ field_arr = @table_by_field[name]
+ field_arr.pop
+ @table_by_field.delete(name) if field_arr.empty?
+
lib/http/2/header/huffman.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/header/huffman.rb 2026-06-17 02:34:13.420590878 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/header/huffman.rb 2026-06-17 02:34:13.425590891 +0000
@@ -22,0 +23,2 @@
+ EOS_PADDING = (0..7).map { |n| ("1" * n).b.freeze }.freeze
+
@@ -32 +34 @@
- append_str(bitstring, "1" * ((8 - bitstring.size) % 8))
+ append_str(bitstring, EOS_PADDING[(8 - bitstring.size) % 8])
@@ -57 +59 @@
- append_str(emit, first.chr) if first
+ emit << first if first
@@ -63 +65 @@
- emit.force_encoding(Encoding::BINARY)
+ emit
@@ -328 +330 @@
- ENCODE_TABLE = CODES.map { |c, l| [c].pack("N").unpack1("B*")[-l..-1] }.each(&:freeze).freeze
+ ENCODE_TABLE = CODES.map { |c, l| [c].pack("N").unpack1("B*")[-l..-1].b.freeze }.freeze
lib/http/2/server.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/server.rb 2026-06-17 02:34:13.420590878 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/server.rb 2026-06-17 02:34:13.425590891 +0000
@@ -81,12 +81,6 @@
- buf = "".b
- append_str(buf, Base64.urlsafe_decode64(settings.to_s))
- @framer.common_header(
- {
- length: buf.bytesize,
- type: :settings,
- stream: 0,
- flags: []
- },
- buffer: buf
- )
- receive(buf)
+ receive(@framer.generate(
+ type: :settings,
+ stream: 0,
+ flags: 0,
+ payload: Base64.urlsafe_decode64(settings.to_s)
+ ))
@@ -100 +94 @@
- flags: [:end_headers],
+ flags: END_HEADERS,
@@ -109 +103 @@
- headers_frame[:flags] << [:end_stream]
+ headers_frame[:flags] |= END_HEADERS
@@ -113 +107 @@
- stream << { type: :data, stream: 1, payload: body, flags: [:end_stream] }
+ stream << { type: :data, stream: 1, payload: body, flags: END_STREAM }
@@ -138 +132 @@
- return unless frame[:flags].include?(:ack) && !@origins_sent
+ return unless frame[:flags].anybits?(ACK) && !@origins_sent
@@ -151 +145 @@
- # @param flags [Array[Symbol]]
+ # @param flags Integer
@@ -160 +154 @@
- payload: headers.to_a
+ payload: headers
lib/http/2/stream.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/stream.rb 2026-06-17 02:34:13.420590878 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/stream.rb 2026-06-17 02:34:13.425590891 +0000
@@ -117 +117,2 @@
- case frame[:type]
+ frame_type = frame[:type] #: Symbol
+ case frame_type
@@ -118,0 +120 @@
+ # @type var frame: data_frame
@@ -131,0 +134 @@
+ # @type var frame: headers_frame
@@ -153,0 +157 @@
+ # @type var frame: priority_frame
@@ -155,0 +160 @@
+ # @type var frame: window_update_frame
@@ -157,0 +163 @@
+ # @type var frame: origin_frame
@@ -162,3 +168 @@
- emit(frame[:type], frame) if !frame[:origin] || frame[:origin].empty?
- when :blocked
- emit(frame[:type], frame)
+ emit(frame_type, frame) if !frame[:origin] || frame[:origin].empty?
@@ -201,0 +206 @@
+ # @type var frame: data_frame
@@ -204,0 +210 @@
+ # @type var frame: window_update_frame
@@ -206,0 +213 @@
+ # @type var frame: priority_frame
@@ -222,3 +229,2 @@
- flags = []
- flags << :end_headers if end_headers
- flags << :end_stream if end_stream || @_method == "HEAD"
+ flags = end_headers ? END_HEADERS : 0
+ flags |= END_STREAM if end_stream || @_method == "HEAD"
@@ -232 +238 @@
- flags = end_headers ? [:end_headers] : []
+ flags = end_headers ? END_HEADERS : 0
@@ -257 +263 @@
- send(type: :data, flags: [], payload: chunk)
+ send(type: :data, flags: 0, payload: chunk)
@@ -261,2 +267,2 @@
- flags = []
- flags << :end_stream if end_stream
+ flags = 0
+ flags |= END_STREAM if end_stream
@@ -666 +672,2 @@
- frame[:flags] && frame[:flags].include?(:end_stream)
+ # @type var frame: data_frame | headers_frame | continuation_frame
+ frame[:flags] && frame[:flags].anybits?(END_STREAM)
lib/http/2/version.rb
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/lib/http/2/version.rb 2026-06-17 02:34:13.420590878 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/lib/http/2/version.rb 2026-06-17 02:34:13.425590891 +0000
@@ -4 +4 @@
- VERSION = "1.1.3"
+ VERSION = "1.2.0"
sig/2.rbs
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/sig/2.rbs 2026-06-17 02:34:13.421590880 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/sig/2.rbs 2026-06-17 02:34:13.426590894 +0000
@@ -38,0 +39,8 @@
+ # Frame flags
+ END_STREAM: Integer
+ ACK: Integer
+ RESERVED: Integer
+ END_HEADERS: Integer
+ PADDED: Integer
+ PRIORITY: Integer
+
@@ -42 +50,3 @@
- type frame_control_flags = Array[:end_headers | :end_stream]
+ type frame_control_flags = Integer
+
+ type common_frame = { stream: Integer, flags: frame_control_flags, ?length: Integer, ?ignore: bool }
@@ -44 +54 @@
- type common_frame = { stream: Integer }
+ type connection_frame = settings_frame | ping_frame | goaway_frame | window_update_frame | altsvc_frame | origin_frame
@@ -47,2 +57,2 @@
- type headers_frame = common_frame & {
- type: :headers, flags: frame_control_flags, payload: Enumerable[header_pair] | String,
+ type headers_frame_props = {
+ type: :headers, payload: Enumerable[header_pair] | String,
@@ -50,0 +61,5 @@
+ type headers_frame = common_frame & headers_frame_props
+
+ type continuation_frame_props = headers_frame_props | { type: :continuation }
+
+ type continuation_frame = common_frame & continuation_frame_props
@@ -53 +68,3 @@
- type data_frame = { type: :data, flags: frame_control_flags, ?length: Integer, payload: String, ?padding: Integer }
+ type data_frame_props = { type: :data, ?length: Integer, payload: String, ?padding: Integer }
+
+ type data_frame = common_frame & data_frame_props
@@ -56 +73,3 @@
- type push_promise_frame = { type: :push_promise, promise_stream: Integer, flags: frame_control_flags, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair], ?padding: Integer }
+ type push_promise_frame_props = { promise_stream: Integer, ?length: Integer, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair] | String, ?padding: Integer }
+
+ type push_promise_frame = common_frame & push_promise_frame_props
@@ -59 +78,3 @@
- type settings_frame = { type: :settings, payload: Array[[Symbol | Integer, Integer]] }
+ type settings_frame_props = { type: :settings, payload: (Enumerable[[Symbol | Integer, Integer]] | String) }
+
+ type settings_frame = common_frame & settings_frame_props
@@ -62 +83,3 @@
- type window_update_frame = { type: :window_update, increment: Integer }
+ type window_update_frame_props = { type: :window_update, increment: Integer }
+
+ type window_update_frame = common_frame & window_update_frame_props
@@ -65 +88,5 @@
- type priority_frame = { dependency: Integer, exclusive: bool, weight: Integer }
+ type priority_frame_inner_props = { dependency: Integer, exclusive: bool, weight: Integer }
+
+ type priority_frame_props = { type: :priority } & priority_frame_inner_props
+
+ type priority_frame = common_frame & priority_frame_props
@@ -68 +95,3 @@
- type altsvc_frame = { type: :altsvc, max_age: Integer, port: Integer, proto: "String", host: String }
+ type altsvc_frame_props = { type: :altsvc, max_age: Integer, port: Integer, proto: String, host: String }
+
+ type altsvc_frame = common_frame & altsvc_frame_props
@@ -71 +100,3 @@
- type origin_frame = { type: :origin, origin: Array[String] }
+ type origin_frame_props = { type: :origin, payload: Array[String] }
+
+ type origin_frame = common_frame & origin_frame_props
@@ -74 +105,3 @@
- type ping_frame = { type: :ping, payload: String, length: Integer }
+ type ping_frame_props = { type: :ping, payload: String }
+
+ type ping_frame = common_frame & ping_frame_props
@@ -77 +110,3 @@
- type goaway_frame = { type: :goaway, last_stream: Integer, error: Symbol? }
+ type goaway_frame_props = { type: :goaway, last_stream: Integer, error: (Symbol | Integer)? }
+
+ type goaway_frame = common_frame & goaway_frame_props
@@ -79 +114,6 @@
- # type frame = common_frame & (headers_frame | data_frame | push_promise_frame |
+ # # RST_STREAM
+ type rst_stream_frame_props = { type: :rst_stream, error: (Symbol | Integer)? }
+
+ type rst_stream_frame = common_frame & rst_stream_frame_props
+
+ # type frame = headers_frame | continuation_frame | push_promise_frame | data_frame |
@@ -81 +121,8 @@
- # origin_frame | ping_frame | goaway_frame)
+ # origin_frame | ping_frame | goaway_frame | rst_stream_frame
+
+ # type connection_frame_props = rst_stream_frame_props | ping_frame_props | goaway_frame_props
+ # | window_update_frame_props | settings_frame_props
+
+ # type stream_frame_props = headers_frame_props | continuation_frame_props | push_promise_frame_props
+ # | data_frame_props | rst_stream_frame_props | priority_frame_props
+ # | window_update_frame_props | origin_frame_props | altsvc_frame_props
@@ -111,0 +159,2 @@
+ type connection_frame_props = Hash[frame_key, frame_value]
+ type stream_frame_props = Hash[frame_key, frame_value]
sig/connection.rbs
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/sig/connection.rbs 2026-06-17 02:34:13.421590880 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/sig/connection.rbs 2026-06-17 02:34:13.426590894 +0000
@@ -35,0 +36 @@
+ @oldest_stream_recently_closed: Numeric
@@ -52,0 +54 @@
+ @continuation_size: Integer
@@ -71 +73 @@
- def receive: (string data) -> void
+ def receive: (String data) -> void
@@ -78 +80 @@
- def send: (frame frame) -> void
+ def send: (connection_frame_props | stream_frame_props frame) -> void
@@ -84 +86 @@
- def connection_management: (frame) -> void
+ def connection_management: (connection_frame frame) -> void
@@ -90 +92 @@
- def connection_settings: (frame) -> void
+ def connection_settings: (settings_frame) -> void
@@ -92 +94 @@
- def decode_headers: (frame) -> void
+ def decode_headers: (headers_frame | push_promise_frame) -> void
@@ -94 +96 @@
- def encode_headers: (frame headers_frame) -> void
+ def encode_headers: (headers_frame | push_promise_frame) -> void
@@ -100 +102 @@
- def verify_pseudo_headers: (frame) -> void
+ def verify_pseudo_headers: (headers_frame | push_promise_frame) -> void
@@ -102 +104 @@
- def _verify_pseudo_headers: (frame, Array[String]) -> void
+ def _verify_pseudo_headers: (headers_frame | push_promise_frame, Array[String]) -> void
@@ -106 +108 @@
-end
\ No newline at end of file
+end
sig/flow_buffer.rbs
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/sig/flow_buffer.rbs 2026-06-17 02:34:13.422590883 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/sig/flow_buffer.rbs 2026-06-17 02:34:13.426590894 +0000
@@ -17 +17 @@
- def send_data: (?data_frame? frame, ?bool encode) -> void
+ def send_data: (?data_frame_props? frame, ?bool encode) -> void
@@ -19 +19 @@
- def send_frame: (data_frame frame, bool encode) -> void
+ def send_frame: (data_frame_props frame, bool encode) -> void
sig/frame_buffer.rbs
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/sig/frame_buffer.rbs 2026-06-17 02:34:13.422590883 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/sig/frame_buffer.rbs 2026-06-17 02:34:13.426590894 +0000
@@ -2,0 +3,2 @@
+ include BufferUtils
+
@@ -9 +11 @@
- def <<: (data_frame frame) -> void
+ def <<: (data_frame_props frame) -> void
@@ -13 +15 @@
- def retrieve: (Integer) -> data_frame?
+ def retrieve: (Integer) -> data_frame_props?
sig/framer.rbs
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/sig/framer.rbs 2026-06-17 02:34:13.422590883 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/sig/framer.rbs 2026-06-17 02:34:13.426590894 +0000
@@ -23 +23,3 @@
- DEFINED_ERRORS: Hash[Symbol, Integer]
+ DEFINED_SETTINGS_BY_ID: Hash[Integer, Symbol]
+
+ DEFINED_ERRORS: Array[Symbol]
@@ -31,0 +34,2 @@
+ PRIORITYPACK: String
+ ALTSVCPACK: String
@@ -44 +48 @@
- def read_common_header: (String buf) -> frame
+ def read_common_header: (String buf) -> (common_frame | { length: Integer })
@@ -50 +54 @@
- def parse: (String) -> frame?
+ def parse: (String) -> (frame | { length: Integer })?
@@ -56 +60 @@
- def pack_error: (Integer | Symbol error, buffer: String) -> String
+ def pack_error: (Symbol | Integer error, buffer: String) -> String
sig/header/compressor.rbs
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/sig/header/compressor.rbs 2026-06-17 02:34:13.422590883 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/sig/header/compressor.rbs 2026-06-17 02:34:13.427590897 +0000
@@ -4,0 +5 @@
+ include BufferUtils
sig/header/encoding_context.rbs
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/sig/header/encoding_context.rbs 2026-06-17 02:34:13.422590883 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/sig/header/encoding_context.rbs 2026-06-17 02:34:13.427590897 +0000
@@ -24,0 +25,4 @@
+ @table_by_field: Hash[string, Array[[string, Integer]]]
+
+ @unshifts: Integer
+
sig/header/huffman.rbs
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/sig/header/huffman.rbs 2026-06-17 02:34:13.422590883 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/sig/header/huffman.rbs 2026-06-17 02:34:13.427590897 +0000
@@ -11,0 +12,2 @@
+ EOS_PADDING: Array[String]
+
sig/server.rbs
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/sig/server.rbs 2026-06-17 02:34:13.422590883 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/sig/server.rbs 2026-06-17 02:34:13.427590897 +0000
@@ -10 +10 @@
- def promise: (Stream parent, Enumerable[header_pair] headers, Array[Symbol] flags) { (Stream) -> void } -> void
+ def promise: (Stream parent, Enumerable[header_pair] headers, frame_control_flags flags) { (Stream) -> void } -> void
sig/stream.rbs
--- /tmp/d20260617-1119-naqxpw/http-2-1.1.3/sig/stream.rbs 2026-06-17 02:34:13.422590883 +0000
+++ /tmp/d20260617-1119-naqxpw/http-2-1.2.0/sig/stream.rbs 2026-06-17 02:34:13.427590897 +0000
@@ -40 +40 @@
- def send: (frame frame) -> void
+ def send: (stream_frame_props frame) -> void
@@ -73 +73 @@
- def transition: (frame, bool sending) -> void
+ def transition: (stream_frame_props frame, bool sending) -> void
@@ -83 +83 @@
- def process_priority: (priority_frame frame) -> void
+ def process_priority: (priority_frame_inner_props frame) -> void
@@ -85 +85 @@
- def end_stream?: (frame frame) -> boolish
+ def end_stream?: (stream_frame_props frame) -> boolish
@@ -87,2 +87 @@
- def stream_error: (Symbol error, ?msg: String?) -> void
- | () -> void
+ def stream_error: (?Symbol error, ?msg: String?) -> void
@@ -92 +91 @@
- def manage_state: (frame) { () -> void } -> void
+ def manage_state: (stream_frame_props frame) { () -> void } -> void
@@ -94 +93 @@
-end
\ No newline at end of file
+end |
Contributor
gem compare --diff http-2 1.1.3 1.2.0Compared versions: ["1.1.3", "1.2.0"]
DIFFERENT files:
1.1.3->1.2.0:
* Added:
lib/http/2/settings.rb
--- /tmp/20260617-465-cjbxbu 2026-06-17 02:34:13.519772021 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/settings.rb 2026-06-17 02:34:13.518772025 +0000
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module HTTP2
+ # Default values for SETTINGS frame, as defined by the spec.
+ SPEC_DEFAULT_CONNECTION_SETTINGS = {
+ settings_header_table_size: 4096,
+ settings_enable_push: 1, # enabled for servers
+ settings_max_concurrent_streams: Framer::MAX_STREAM_ID, # unlimited
+ settings_initial_window_size: 65_535,
+ settings_max_frame_size: 16_384,
+ settings_max_header_list_size: (2 << 30) - 1 # unlimited
+ }.freeze
+
+ Settings = Struct.new(
+ :settings_header_table_size,
+ :settings_enable_push,
+ :settings_max_concurrent_streams,
+ :settings_initial_window_size,
+ :settings_max_frame_size,
+ :settings_max_header_list_size,
+ keyword_init: true
+ ) do
+ def initialize(
+ settings_header_table_size: 4096,
+ settings_enable_push: 1,
+ settings_max_concurrent_streams: 100,
+ settings_initial_window_size: 65_535,
+ settings_max_frame_size: 16_384,
+ settings_max_header_list_size: (2 << 30) - 1
+ )
+ super
+ end
+
+ def each_setting
+ each_pair do |k, v|
+ next if v == SPEC_DEFAULT_CONNECTION_SETTINGS[k]
+
+ yield k, v
+ end
+ end
+ end
+end
* Changed:
lib/http/2/client.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/client.rb 2026-06-17 02:34:13.509772066 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/client.rb 2026-06-17 02:34:13.515772039 +0000
@@ -72 +72 @@
- frame = Framer.new.generate(type: :settings, stream: 0, payload: settings)
+ frame = Framer.new.generate(type: :settings, stream: 0, flags: 0, payload: settings)
lib/http/2/connection.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/connection.rb 2026-06-17 02:34:13.510772062 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/connection.rb 2026-06-17 02:34:13.515772039 +0000
@@ -44,2 +43,0 @@
- HEADERS_FRAME_TYPES = %i[headers push_promise].freeze
-
@@ -93,0 +92 @@
+ @oldest_stream_recently_closed = nil
@@ -104,0 +104 @@
+ @continuation_size = 0
@@ -159 +159 @@
- send(type: :goaway, last_stream: @last_stream_id,
+ send(type: :goaway, stream: 0, last_stream: @last_stream_id,
@@ -181 +180,0 @@
- @pending_settings << payload
@@ -215,3 +214,2 @@
- # @type var stream_id: Integer
- stream_id = frame[:stream]
- frame_type = frame[:type]
+ stream_id = frame[:stream] #: Integer
+ frame_type = frame[:type] #: Symbol?
@@ -239,0 +238 @@
+ # @type var frame: continuation_frame
@@ -243,2 +242,2 @@
- unless frame[:flags].include? :end_headers
- buffered_payload = @continuation.sum { |f| f[:payload].bytesize }
+ @continuation_size += frame[:payload].bytesize
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -248 +247 @@
- unless buffered_payload < @local_settings[:settings_max_frame_size]
+ unless @continuation_size < @local_settings[:settings_max_frame_size]
@@ -261,0 +261 @@
+ @continuation_size = 0
@@ -265 +265 @@
- frame[:flags] << :end_headers
+ frame[:flags] |= END_HEADERS
@@ -273,0 +274 @@
+ # @type var frame: connection_frame
@@ -278,0 +280 @@
+ # @type var frame: headers_frame
@@ -285 +287 @@
- unless frame[:flags].include? :end_headers
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -314,0 +317 @@
+ # @type var frame: push_promise_frame
@@ -317 +320 @@
- unless frame[:flags].include? :end_headers
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -437,2 +439,0 @@
- frame_type = frame[:type]
-
@@ -440,2 +440,0 @@
- if frame_type == :data
- send_data(frame, true)
@@ -443,3 +442 @@
- elsif frame_type == :rst_stream && frame[:error] == :protocol_error
- # An endpoint can end a connection at any time. In particular, an
- # endpoint MAY choose to treat a stream error as a connection error.
+ frame_type = frame[:type] #: Symbol
@@ -447,2 +444,5 @@
- goaway(:protocol_error)
- else
+ case frame_type
+ when :data
+ #: @type var frame: data_frame
+ send_data(frame, true)
+ when :headers, :push_promise
@@ -450,0 +451,10 @@
+ #: @type var frame: headers_frame | push_promise_frame
+ encode_headers(frame) # HEADERS and PUSH_PROMISE may create more than one frame
+ else
+ if frame_type == :rst_stream && frame[:error] == :protocol_error
+ # An endpoint can end a connection at any time. In particular, an
+ # endpoint MAY choose to treat a stream error as a connection error.
+
+ goaway(:protocol_error)
+ end
+ #: @type var frame: connection_frame
@@ -459,5 +469 @@
- if HEADERS_FRAME_TYPES.include?(frame[:type])
- encode_headers(frame) # HEADERS and PUSH_PROMISE may create more than one frame
- else
- emit(:frame, @framer.generate(frame))
- end
+ emit(:frame, @framer.generate(frame))
@@ -495,0 +502 @@
+ # @type var frame: settings_frame
@@ -497,0 +505 @@
+ # @type var frame: window_update_frame
@@ -501,0 +510 @@
+ # @type var frame: goaway_frame
@@ -508,0 +518 @@
+ # @type var frame: altsvc_frame
@@ -515 +525,2 @@
- return if @h2c_upgrade || !frame[:flags].empty?
+ # @type var frame: origin_frame
+ return if @h2c_upgrade || !frame[:flags].zero?
@@ -520,2 +530,0 @@
- when :blocked
- emit(:blocked, frame)
@@ -541 +550 @@
- if frame[:flags].include? :ack
+ if frame[:flags].anybits?(ACK)
@@ -544,2 +553 @@
- send(type: :ping, stream: 0,
- flags: [:ack], payload: frame[:payload])
+ send(type: :ping, stream: 0, flags: ACK, payload: frame[:payload])
@@ -608 +616 @@
- if frame[:flags].include?(:ack)
+ if frame[:flags].anybits?(ACK)
@@ -613 +620,0 @@
- validate_settings(@remote_role, frame[:payload])
@@ -614,0 +622 @@
+ validate_settings(@remote_role, settings)
@@ -684 +692 @@
- send(type: :settings, stream: 0, payload: [], flags: [:ack])
+ send(type: :settings, stream: 0, payload: EMPTY, flags: ACK)
@@ -714 +722 @@
- payload = headers_frame[:payload]
+ headers_payload = headers_frame[:payload]
@@ -716 +724 @@
- payload = headers_frame[:payload] = @compressor.encode(payload) unless payload.is_a?(String)
+ payload = headers_payload.is_a?(String) ? headers_payload : @compressor.encode(headers_payload)
@@ -720,0 +729,3 @@
+ #: @type var payload: String
+ headers_frame[:payload] = payload
+
@@ -725 +736 @@
- emit(:frame, @framer.generate(headers_frame))
+ encode(headers_frame)
@@ -730 +741,2 @@
- headers_frame[:flags].delete(:end_headers)
+ total = payload.bytesize
+ headers_frame[:flags] ^= END_HEADERS
@@ -732 +744,2 @@
- payload = payload.byteslice(max_frame_size..-1)
+ # payload = payload.byteslice(max_frame_size..-1)
+ offset = max_frame_size
@@ -735 +748 @@
- emit(:frame, @framer.generate(headers_frame))
+ encode(headers_frame)
@@ -737,6 +750 @@
- loop do
- continuation_frame = headers_frame.merge(
- type: :continuation,
- flags: EMPTY,
- payload: payload.byteslice(0, max_frame_size)
- )
+ stream_id = headers_frame[:stream]
@@ -744 +752,3 @@
- payload = payload.byteslice(max_frame_size..-1)
+ while offset < total
+ chunk_end = offset + max_frame_size
+ is_last = chunk_end >= total
@@ -746,5 +756,6 @@
- if payload.nil? || payload.empty?
- continuation_frame[:flags] = [:end_headers]
- emit(:frame, @framer.generate(continuation_frame))
- break
- end
+ continuation_frame = {
+ type: :continuation,
+ flags: is_last ? END_HEADERS : 0,
+ stream: stream_id,
+ payload: payload.byteslice(offset, max_frame_size)
+ } #: continuation_frame
@@ -752 +763,2 @@
- emit(:frame, @framer.generate(continuation_frame))
+ encode(continuation_frame)
+ offset = chunk_end
@@ -779,2 +790,0 @@
- _, closed_since = @streams_recently_closed.first
-
@@ -783 +793,2 @@
- if closed_since && (now - closed_since) > 15
+ if @oldest_stream_recently_closed && (now - @oldest_stream_recently_closed) > 15
+ new_oldest = nil
@@ -786,3 +797,9 @@
- @streams_recently_closed = @streams_recently_closed.drop_while do |_, since|
- (now - since) > 15
- end.to_h
+ @streams_recently_closed.delete_if do |_, since|
+ unless (now - since) > 15
+ new_oldest ||= since
+ break
+ end
+
+ true
+ end
+ @oldest_stream_recently_closed = new_oldest
@@ -791 +808 @@
- @streams_recently_closed[id] = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ @streams_recently_closed[id] = now
lib/http/2/extensions.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/extensions.rb 2026-06-17 02:34:13.510772062 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/extensions.rb 2026-06-17 02:34:13.516772035 +0000
@@ -25,2 +25,3 @@
- def read_str(str, n)
- return "".b if n == 0
+ if String.method_defined?(:bytesplice)
+ def read_str(str, n)
+ return "".b if n == 0
@@ -28,4 +29,13 @@
- chunk = str.byteslice(0..(n - 1))
- remaining = str.byteslice(n..-1)
- remaining ? str.replace(remaining) : str.clear
- chunk
+ chunk = str.byteslice(0, n)
+ str.bytesplice(0, chunk.length, "")
+ chunk
+ end
+ else
+ def read_str(str, n)
+ return "".b if n == 0
+
+ chunk = str.byteslice(0, n)
+ remaining = str.byteslice(n, str.size - n)
+ remaining ? str.replace(remaining) : str.clear
+ chunk
+ end
@@ -36,4 +45,0 @@
- end
-
- def shift_byte(str)
- read_str(str, 1).ord
lib/http/2/flow_buffer.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/flow_buffer.rb 2026-06-17 02:34:13.510772062 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/flow_buffer.rb 2026-06-17 02:34:13.516772035 +0000
@@ -73 +73 @@
- end_stream = frame[:flags].include?(:end_stream)
+ end_stream = frame[:flags].anybits?(END_STREAM)
@@ -117,0 +118,2 @@
+ include BufferUtils
+
@@ -143 +145 @@
- end_stream = frame[:flags].include?(:end_stream)
+ end_stream = frame[:flags].anybits?(END_STREAM)
@@ -151,2 +153 @@
- chunk = frame.dup
- payload = frame[:payload]
+ chunk = frame.dup
@@ -157 +158 @@
- chunk[:payload] = payload.byteslice(0, window_size)
+ chunk[:payload] = read_str(frame[:payload], window_size) # mutates frame[:payload]
@@ -159 +159,0 @@
- frame[:payload] = payload.byteslice(window_size..-1)
@@ -163 +163 @@
- chunk[:flags] -= [:end_stream] if end_stream
+ chunk[:flags] ^= END_STREAM if end_stream
lib/http/2/framer.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/framer.rb 2026-06-17 02:34:13.510772062 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/framer.rb 2026-06-17 02:34:13.516772035 +0000
@@ -3,0 +4,19 @@
+ # Frame flags as defined by the spec (max 255 bits)
+ # DATA: ( X X COMPRESSED X PADDED X X END_STREAM )
+ # HEADERS: ( X X PRIORITY X PADDED END_HEADERS X END_STREAM )
+ # PRIORITY: ( X X X X X X X X )
+ # RST_STREAM: ( X X X X X X X X )
+ # SETTINGS: ( X X X X X X X ACK )
+ # PUSH_PROMISE: ( X X X X PADDED END_HEADERS X X )
+ # PING: ( X X X X X X X ACK )
+ # GOAWAY: ( X X X X X X X X )
+ # WINDOW_UPDATE: ( X X X X X X X X )
+ # CONTINUATION: ( X X X X X END_HEADERS X X )
+ # ALTSVC: ( X X X X X X X X )
+ # ORIGIN: ( RESERVED4 X X RESERVED3 X RESERVED2 RESERVED X )
+ END_STREAM = ACK = 0b0001 # 1
+ RESERVED = 0b0010 # 2
+ END_HEADERS = 0b0100 # 4
+ PADDED = 0b1000 # 8
+ PRIORITY = 0b0010_0000 # 32
+
@@ -43,33 +61,0 @@
- # Per frame flags as defined by the spec
- FRAME_FLAGS = {
- data: {
- end_stream: 0,
- padded: 3,
- compressed: 5
- },
- headers: {
- end_stream: 0,
- end_headers: 2,
- padded: 3,
- priority: 5
- },
- priority: {},
- rst_stream: {},
- settings: { ack: 0 },
- push_promise: {
- end_headers: 2,
- padded: 3
- },
- ping: { ack: 0 },
- goaway: {},
- window_update: {},
- continuation: { end_headers: 2 },
- altsvc: {},
- origin: {
- reserved: 1,
- reserved2: 2,
- reserved3: 4,
- reserved4: 8
- }
- }.each_value(&:freeze).freeze
-
@@ -86,17 +72,19 @@
- # Default error types as defined by the spec
- DEFINED_ERRORS = {
- no_error: 0,
- protocol_error: 1,
- internal_error: 2,
- flow_control_error: 3,
- settings_timeout: 4,
- stream_closed: 5,
- frame_size_error: 6,
- refused_stream: 7,
- cancel: 8,
- compression_error: 9,
- connect_error: 10,
- enhance_your_calm: 11,
- inadequate_security: 12,
- http_1_1_required: 13
- }.freeze
+ DEFINED_SETTINGS_BY_ID = DEFINED_SETTINGS.invert.freeze
+
+ # Default error types as defined by the spec (the code is the array index)
+ DEFINED_ERRORS = %i[
+ no_error
+ protocol_error
+ internal_error
+ flow_control_error
+ settings_timeout
+ stream_closed
+ frame_size_error
+ refused_stream
+ cancel
+ compression_error
+ connect_error
+ enhance_your_calm
+ inadequate_security
+ http_1_1_required
+ ].freeze
@@ -110,0 +99,2 @@
+ PRIORITYPACK = (UINT32 + UINT8).freeze
+ ALTSVCPACK = (UINT32 + UINT16).freeze
@@ -114 +104 @@
- private_constant :RBIT, :RBYTE, :EBIT, :HEADERPACK, :UINT32, :UINT16, :UINT8
+ private_constant :RBIT, :RBYTE, :EBIT, :HEADERPACK, :PRIORITYPACK, :UINT32, :UINT16, :UINT8
@@ -148,0 +139,4 @@
+ flags = frame[:flags]
+
+ raise CompressionError, "Invalid frame flag (#{flags}) for #{type}" unless flags.between?(0, 255)
+
@@ -163,6 +157 @@
- frame[:flags].reduce(0) do |acc, f|
- position = FRAME_FLAGS[type][f]
- raise CompressionError, "Invalid frame flag (#{f}) for #{type}" unless position
-
- acc | (1 << position)
- end,
+ flags,
@@ -187,3 +176 @@
- flags: FRAME_FLAGS[type].filter_map do |name, pos|
- name if flags.anybits?(1 << pos)
- end,
+ flags: flags,
@@ -201 +188 @@
- frame[:flags] ||= EMPTY
+ frame[:flags] ||= 0
@@ -204,0 +192 @@
+ # @type var frame: data_frame | continuation_frame
@@ -216 +204 @@
- frame[:flags] += [:priority] unless frame[:flags].include?(:priority)
+ frame[:flags] |= PRIORITY
@@ -219 +207 @@
- if frame[:flags].include?(:priority)
+ if frame[:flags].anybits?(PRIORITY)
@@ -222,2 +210,4 @@
- pack([(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT)], UINT32, buffer: bytes)
- pack([frame[:weight] - 1], UINT8, buffer: bytes)
+ pack(
+ [(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT), frame[:weight] - 1],
+ PRIORITYPACK, buffer: bytes
+ )
@@ -237,2 +227,4 @@
- pack([(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT)], UINT32, buffer: bytes)
- pack([frame[:weight] - 1], UINT8, buffer: bytes)
+ pack(
+ [(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT), frame[:weight] - 1],
+ PRIORITYPACK, buffer: bytes
+ )
@@ -251 +242,0 @@
- bytes = String.new("", encoding: Encoding::BINARY, capacity: length)
@@ -253,5 +244,6 @@
- settings.each do |(k, v)|
- if k.is_a? Integer # rubocop:disable Style/GuardClause
- DEFINED_SETTINGS.value?(k) || next
- else
- k = DEFINED_SETTINGS[k]
+ case settings
+ when String
+ length = settings.bytesize
+ bytes = settings
+ else
+ bytes = String.new("", encoding: Encoding::BINARY, capacity: settings.size * 6)
@@ -259 +251,12 @@
- raise CompressionError, "Unknown settings ID for #{k}" if k.nil?
+ settings.each do |(k, v)|
+ if k.is_a? Integer # rubocop:disable Style/GuardClause
+ DEFINED_SETTINGS.value?(k) || next
+ else
+ k = DEFINED_SETTINGS[k]
+
+ raise CompressionError, "Unknown settings ID for #{k}" if k.nil?
+ end
+
+ pack([k], UINT16, buffer: bytes)
+ pack([v], UINT32, buffer: bytes)
+ length += 6
@@ -261,4 +263,0 @@
-
- pack([k], UINT16, buffer: bytes)
- pack([v], UINT32, buffer: bytes)
- length += 6
@@ -298 +297 @@
- pack([frame[:max_age], frame[:port]], UINT32 + UINT16, buffer: bytes)
+ pack([frame[:max_age], frame[:port]], ALTSVCPACK, buffer: bytes)
@@ -357 +356 @@
- frame[:flags] += [:padded]
+ frame[:flags] |= PADDED
@@ -378,3 +377,3 @@
- type = frame[:type]
- length = frame[:length]
- flags = frame[:flags]
+ type = frame[:type] #: Symbol
+ length = frame[:length] #: Integer
+ flags = frame[:flags] #: Integer
@@ -397 +396 @@
- padded = flags.include?(:padded)
+ padded = flags.anybits?(PADDED)
@@ -400 +398,0 @@
- frame[:padding] = padlen + 1
@@ -402,0 +401,2 @@
+ frame[:padding] = padlen + 1
+
@@ -405 +405 @@
- flags.delete(:padded)
+ frame[:flags] ^= PADDED
@@ -413 +413 @@
- if flags.include?(:priority)
+ if flags.anybits?(PRIORITY)
@@ -417 +417 @@
- weight = payload.byteslice(0, 1).ord + 1
+ weight = payload.getbyte(0) + 1
@@ -428 +428 @@
- weight = payload.byteslice(0, 1).ord + 1
+ weight = payload.getbyte(0) + 1
@@ -439 +438,0 @@
- frame[:payload] = []
@@ -444 +443 @@
- (frame[:length] / 6).times do
+ frame[:payload] = (frame[:length] / 6).times.filter_map do
@@ -450,2 +449,3 @@
- name, = DEFINED_SETTINGS.find { |_name, v| v == id }
- frame[:payload] << [name, val] if name
+ if (name = DEFINED_SETTINGS_BY_ID[id])
+ [name, val]
+ end
@@ -467 +467 @@
- frame[:max_age], frame[:port] = read_str(payload, 6).unpack(UINT32 + UINT16)
+ frame[:max_age], frame[:port] = read_str(payload, 6).unpack(ALTSVCPACK)
@@ -469 +469 @@
- len = payload.byteslice(0, 1).ord
+ len = payload.getbyte(0)
@@ -473 +473 @@
- len = payload.byteslice(0, 1).ord
+ len = payload.getbyte(0)
@@ -498 +498 @@
- error = DEFINED_ERRORS[error]
+ error = DEFINED_ERRORS.index(error)
@@ -507 +507 @@
- DEFINED_ERRORS.key(error) || error
+ DEFINED_ERRORS.fetch(error, error)
lib/http/2/header/compressor.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/header/compressor.rb 2026-06-17 02:34:13.510772062 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/header/compressor.rb 2026-06-17 02:34:13.516772035 +0000
@@ -85,0 +86,2 @@
+ integer(huffman.bytesize, 7, buffer: buffer)
+ buffer.setbyte(huffman_offset, buffer.getbyte(huffman_offset) | 0x80)
@@ -87 +89 @@
- set_huffman_size(buffer, huffman_offset)
+ buffer
@@ -122 +124 @@
- fb = buffer[offset].ord | rep[:pattern]
+ fb = buffer.getbyte(offset) | rep[:pattern]
@@ -149,0 +152 @@
+ buffer << "\x00".b
@@ -151 +154,9 @@
- set_huffman_size(buffer, huffman_offset)
+ size = buffer.bytesize - huffman_offset - 1
+
+ if size < 127
+ buffer.setbyte(huffman_offset, 0x80 | size)
+ else
+ buffer.slice!(huffman_offset, 1)
+ set_huffman_size(buffer, huffman_offset)
+ end
+ buffer
@@ -168 +179 @@
- buffer.setbyte(huffman_offset, buffer[huffman_offset].ord | 0x80)
+ buffer.setbyte(huffman_offset, buffer.getbyte(huffman_offset) | 0x80)
lib/http/2/header/decompressor.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/header/decompressor.rb 2026-06-17 02:34:13.510772062 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/header/decompressor.rb 2026-06-17 02:34:13.516772035 +0000
@@ -36 +36,7 @@
- i = n.zero? ? 0 : (shift_byte(buf) & limit)
+ if n.zero?
+ i = 0
+ consumed = 0
+ else
+ i = buf.getbyte(0) & limit
+ consumed = 1
+ end
@@ -38 +43,0 @@
- m = 0
@@ -40,5 +45,2 @@
- offset = 0
-
- buf.each_byte.with_index do |byte, idx|
- offset = idx
- # while (byte = shift_byte(buf))
+ m = 0
+ while (byte = buf.getbyte(consumed))
@@ -47 +49 @@
-
+ consumed += 1
@@ -50,2 +51,0 @@
-
- read_str(buf, offset + 1)
@@ -53,0 +54 @@
+ read_str(buf, consumed)
lib/http/2/header/encoding_context.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/header/encoding_context.rb 2026-06-17 02:34:13.510772062 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/header/encoding_context.rb 2026-06-17 02:34:13.516772035 +0000
@@ -120,0 +121,2 @@
+ @table_by_field = Hash.new { |hs, k| hs[k] = [] }
+ @unshifts = 0
@@ -131,0 +134,2 @@
+ tbf = @table_by_field.transform_values(&:dup)
+ unshifts = @unshifts
@@ -134,0 +139,2 @@
+ @table_by_field = tbf
+ @unshifts = unshifts
@@ -215,0 +222,2 @@
+ @unshifts += 1
+ @table_by_field[name].unshift([value, @unshifts])
@@ -282,2 +290 @@
- @table.each_with_index do |(hfield, hvalue), i|
- next unless field == hfield
+ field_entries = @table_by_field[field]
@@ -284,0 +292,3 @@
+ field_entries&.each do |hvalue, unshift_id|
+ abs_index = (@unshifts - unshift_id) + STATIC_TABLE_SIZE
+ name_only ||= abs_index
@@ -286 +296 @@
- exact = i + STATIC_TABLE_SIZE
+ exact = abs_index
@@ -288,2 +297,0 @@
- else
- name_only ||= i + STATIC_TABLE_SIZE
@@ -320 +327,0 @@
-
@@ -322,0 +330,5 @@
+
+ field_arr = @table_by_field[name]
+ field_arr.pop
+ @table_by_field.delete(name) if field_arr.empty?
+
lib/http/2/header/huffman.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/header/huffman.rb 2026-06-17 02:34:13.510772062 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/header/huffman.rb 2026-06-17 02:34:13.516772035 +0000
@@ -22,0 +23,2 @@
+ EOS_PADDING = (0..7).map { |n| ("1" * n).b.freeze }.freeze
+
@@ -32 +34 @@
- append_str(bitstring, "1" * ((8 - bitstring.size) % 8))
+ append_str(bitstring, EOS_PADDING[(8 - bitstring.size) % 8])
@@ -57 +59 @@
- append_str(emit, first.chr) if first
+ emit << first if first
@@ -63 +65 @@
- emit.force_encoding(Encoding::BINARY)
+ emit
@@ -328 +330 @@
- ENCODE_TABLE = CODES.map { |c, l| [c].pack("N").unpack1("B*")[-l..-1] }.each(&:freeze).freeze
+ ENCODE_TABLE = CODES.map { |c, l| [c].pack("N").unpack1("B*")[-l..-1].b.freeze }.freeze
lib/http/2/server.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/server.rb 2026-06-17 02:34:13.511772057 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/server.rb 2026-06-17 02:34:13.517772030 +0000
@@ -81,12 +81,6 @@
- buf = "".b
- append_str(buf, Base64.urlsafe_decode64(settings.to_s))
- @framer.common_header(
- {
- length: buf.bytesize,
- type: :settings,
- stream: 0,
- flags: []
- },
- buffer: buf
- )
- receive(buf)
+ receive(@framer.generate(
+ type: :settings,
+ stream: 0,
+ flags: 0,
+ payload: Base64.urlsafe_decode64(settings.to_s)
+ ))
@@ -100 +94 @@
- flags: [:end_headers],
+ flags: END_HEADERS,
@@ -109 +103 @@
- headers_frame[:flags] << [:end_stream]
+ headers_frame[:flags] |= END_HEADERS
@@ -113 +107 @@
- stream << { type: :data, stream: 1, payload: body, flags: [:end_stream] }
+ stream << { type: :data, stream: 1, payload: body, flags: END_STREAM }
@@ -138 +132 @@
- return unless frame[:flags].include?(:ack) && !@origins_sent
+ return unless frame[:flags].anybits?(ACK) && !@origins_sent
@@ -151 +145 @@
- # @param flags [Array[Symbol]]
+ # @param flags Integer
@@ -160 +154 @@
- payload: headers.to_a
+ payload: headers
lib/http/2/stream.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/stream.rb 2026-06-17 02:34:13.511772057 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/stream.rb 2026-06-17 02:34:13.518772025 +0000
@@ -117 +117,2 @@
- case frame[:type]
+ frame_type = frame[:type] #: Symbol
+ case frame_type
@@ -118,0 +120 @@
+ # @type var frame: data_frame
@@ -131,0 +134 @@
+ # @type var frame: headers_frame
@@ -153,0 +157 @@
+ # @type var frame: priority_frame
@@ -155,0 +160 @@
+ # @type var frame: window_update_frame
@@ -157,0 +163 @@
+ # @type var frame: origin_frame
@@ -162,3 +168 @@
- emit(frame[:type], frame) if !frame[:origin] || frame[:origin].empty?
- when :blocked
- emit(frame[:type], frame)
+ emit(frame_type, frame) if !frame[:origin] || frame[:origin].empty?
@@ -201,0 +206 @@
+ # @type var frame: data_frame
@@ -204,0 +210 @@
+ # @type var frame: window_update_frame
@@ -206,0 +213 @@
+ # @type var frame: priority_frame
@@ -222,3 +229,2 @@
- flags = []
- flags << :end_headers if end_headers
- flags << :end_stream if end_stream || @_method == "HEAD"
+ flags = end_headers ? END_HEADERS : 0
+ flags |= END_STREAM if end_stream || @_method == "HEAD"
@@ -232 +238 @@
- flags = end_headers ? [:end_headers] : []
+ flags = end_headers ? END_HEADERS : 0
@@ -257 +263 @@
- send(type: :data, flags: [], payload: chunk)
+ send(type: :data, flags: 0, payload: chunk)
@@ -261,2 +267,2 @@
- flags = []
- flags << :end_stream if end_stream
+ flags = 0
+ flags |= END_STREAM if end_stream
@@ -666 +672,2 @@
- frame[:flags] && frame[:flags].include?(:end_stream)
+ # @type var frame: data_frame | headers_frame | continuation_frame
+ frame[:flags] && frame[:flags].anybits?(END_STREAM)
lib/http/2/version.rb
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/lib/http/2/version.rb 2026-06-17 02:34:13.511772057 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/lib/http/2/version.rb 2026-06-17 02:34:13.518772025 +0000
@@ -4 +4 @@
- VERSION = "1.1.3"
+ VERSION = "1.2.0"
sig/2.rbs
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/sig/2.rbs 2026-06-17 02:34:13.511772057 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/sig/2.rbs 2026-06-17 02:34:13.518772025 +0000
@@ -38,0 +39,8 @@
+ # Frame flags
+ END_STREAM: Integer
+ ACK: Integer
+ RESERVED: Integer
+ END_HEADERS: Integer
+ PADDED: Integer
+ PRIORITY: Integer
+
@@ -42 +50,3 @@
- type frame_control_flags = Array[:end_headers | :end_stream]
+ type frame_control_flags = Integer
+
+ type common_frame = { stream: Integer, flags: frame_control_flags, ?length: Integer, ?ignore: bool }
@@ -44 +54 @@
- type common_frame = { stream: Integer }
+ type connection_frame = settings_frame | ping_frame | goaway_frame | window_update_frame | altsvc_frame | origin_frame
@@ -47,2 +57,2 @@
- type headers_frame = common_frame & {
- type: :headers, flags: frame_control_flags, payload: Enumerable[header_pair] | String,
+ type headers_frame_props = {
+ type: :headers, payload: Enumerable[header_pair] | String,
@@ -50,0 +61,5 @@
+ type headers_frame = common_frame & headers_frame_props
+
+ type continuation_frame_props = headers_frame_props | { type: :continuation }
+
+ type continuation_frame = common_frame & continuation_frame_props
@@ -53 +68,3 @@
- type data_frame = { type: :data, flags: frame_control_flags, ?length: Integer, payload: String, ?padding: Integer }
+ type data_frame_props = { type: :data, ?length: Integer, payload: String, ?padding: Integer }
+
+ type data_frame = common_frame & data_frame_props
@@ -56 +73,3 @@
- type push_promise_frame = { type: :push_promise, promise_stream: Integer, flags: frame_control_flags, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair], ?padding: Integer }
+ type push_promise_frame_props = { promise_stream: Integer, ?length: Integer, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair] | String, ?padding: Integer }
+
+ type push_promise_frame = common_frame & push_promise_frame_props
@@ -59 +78,3 @@
- type settings_frame = { type: :settings, payload: Array[[Symbol | Integer, Integer]] }
+ type settings_frame_props = { type: :settings, payload: (Enumerable[[Symbol | Integer, Integer]] | String) }
+
+ type settings_frame = common_frame & settings_frame_props
@@ -62 +83,3 @@
- type window_update_frame = { type: :window_update, increment: Integer }
+ type window_update_frame_props = { type: :window_update, increment: Integer }
+
+ type window_update_frame = common_frame & window_update_frame_props
@@ -65 +88,5 @@
- type priority_frame = { dependency: Integer, exclusive: bool, weight: Integer }
+ type priority_frame_inner_props = { dependency: Integer, exclusive: bool, weight: Integer }
+
+ type priority_frame_props = { type: :priority } & priority_frame_inner_props
+
+ type priority_frame = common_frame & priority_frame_props
@@ -68 +95,3 @@
- type altsvc_frame = { type: :altsvc, max_age: Integer, port: Integer, proto: "String", host: String }
+ type altsvc_frame_props = { type: :altsvc, max_age: Integer, port: Integer, proto: String, host: String }
+
+ type altsvc_frame = common_frame & altsvc_frame_props
@@ -71 +100,3 @@
- type origin_frame = { type: :origin, origin: Array[String] }
+ type origin_frame_props = { type: :origin, payload: Array[String] }
+
+ type origin_frame = common_frame & origin_frame_props
@@ -74 +105,3 @@
- type ping_frame = { type: :ping, payload: String, length: Integer }
+ type ping_frame_props = { type: :ping, payload: String }
+
+ type ping_frame = common_frame & ping_frame_props
@@ -77 +110,3 @@
- type goaway_frame = { type: :goaway, last_stream: Integer, error: Symbol? }
+ type goaway_frame_props = { type: :goaway, last_stream: Integer, error: (Symbol | Integer)? }
+
+ type goaway_frame = common_frame & goaway_frame_props
@@ -79 +114,6 @@
- # type frame = common_frame & (headers_frame | data_frame | push_promise_frame |
+ # # RST_STREAM
+ type rst_stream_frame_props = { type: :rst_stream, error: (Symbol | Integer)? }
+
+ type rst_stream_frame = common_frame & rst_stream_frame_props
+
+ # type frame = headers_frame | continuation_frame | push_promise_frame | data_frame |
@@ -81 +121,8 @@
- # origin_frame | ping_frame | goaway_frame)
+ # origin_frame | ping_frame | goaway_frame | rst_stream_frame
+
+ # type connection_frame_props = rst_stream_frame_props | ping_frame_props | goaway_frame_props
+ # | window_update_frame_props | settings_frame_props
+
+ # type stream_frame_props = headers_frame_props | continuation_frame_props | push_promise_frame_props
+ # | data_frame_props | rst_stream_frame_props | priority_frame_props
+ # | window_update_frame_props | origin_frame_props | altsvc_frame_props
@@ -111,0 +159,2 @@
+ type connection_frame_props = Hash[frame_key, frame_value]
+ type stream_frame_props = Hash[frame_key, frame_value]
sig/connection.rbs
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/sig/connection.rbs 2026-06-17 02:34:13.511772057 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/sig/connection.rbs 2026-06-17 02:34:13.518772025 +0000
@@ -35,0 +36 @@
+ @oldest_stream_recently_closed: Numeric
@@ -52,0 +54 @@
+ @continuation_size: Integer
@@ -71 +73 @@
- def receive: (string data) -> void
+ def receive: (String data) -> void
@@ -78 +80 @@
- def send: (frame frame) -> void
+ def send: (connection_frame_props | stream_frame_props frame) -> void
@@ -84 +86 @@
- def connection_management: (frame) -> void
+ def connection_management: (connection_frame frame) -> void
@@ -90 +92 @@
- def connection_settings: (frame) -> void
+ def connection_settings: (settings_frame) -> void
@@ -92 +94 @@
- def decode_headers: (frame) -> void
+ def decode_headers: (headers_frame | push_promise_frame) -> void
@@ -94 +96 @@
- def encode_headers: (frame headers_frame) -> void
+ def encode_headers: (headers_frame | push_promise_frame) -> void
@@ -100 +102 @@
- def verify_pseudo_headers: (frame) -> void
+ def verify_pseudo_headers: (headers_frame | push_promise_frame) -> void
@@ -102 +104 @@
- def _verify_pseudo_headers: (frame, Array[String]) -> void
+ def _verify_pseudo_headers: (headers_frame | push_promise_frame, Array[String]) -> void
@@ -106 +108 @@
-end
\ No newline at end of file
+end
sig/flow_buffer.rbs
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/sig/flow_buffer.rbs 2026-06-17 02:34:13.511772057 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/sig/flow_buffer.rbs 2026-06-17 02:34:13.518772025 +0000
@@ -17 +17 @@
- def send_data: (?data_frame? frame, ?bool encode) -> void
+ def send_data: (?data_frame_props? frame, ?bool encode) -> void
@@ -19 +19 @@
- def send_frame: (data_frame frame, bool encode) -> void
+ def send_frame: (data_frame_props frame, bool encode) -> void
sig/frame_buffer.rbs
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/sig/frame_buffer.rbs 2026-06-17 02:34:13.511772057 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/sig/frame_buffer.rbs 2026-06-17 02:34:13.518772025 +0000
@@ -2,0 +3,2 @@
+ include BufferUtils
+
@@ -9 +11 @@
- def <<: (data_frame frame) -> void
+ def <<: (data_frame_props frame) -> void
@@ -13 +15 @@
- def retrieve: (Integer) -> data_frame?
+ def retrieve: (Integer) -> data_frame_props?
sig/framer.rbs
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/sig/framer.rbs 2026-06-17 02:34:13.514772044 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/sig/framer.rbs 2026-06-17 02:34:13.518772025 +0000
@@ -23 +23,3 @@
- DEFINED_ERRORS: Hash[Symbol, Integer]
+ DEFINED_SETTINGS_BY_ID: Hash[Integer, Symbol]
+
+ DEFINED_ERRORS: Array[Symbol]
@@ -31,0 +34,2 @@
+ PRIORITYPACK: String
+ ALTSVCPACK: String
@@ -44 +48 @@
- def read_common_header: (String buf) -> frame
+ def read_common_header: (String buf) -> (common_frame | { length: Integer })
@@ -50 +54 @@
- def parse: (String) -> frame?
+ def parse: (String) -> (frame | { length: Integer })?
@@ -56 +60 @@
- def pack_error: (Integer | Symbol error, buffer: String) -> String
+ def pack_error: (Symbol | Integer error, buffer: String) -> String
sig/header/compressor.rbs
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/sig/header/compressor.rbs 2026-06-17 02:34:13.514772044 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/sig/header/compressor.rbs 2026-06-17 02:34:13.519772021 +0000
@@ -4,0 +5 @@
+ include BufferUtils
sig/header/encoding_context.rbs
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/sig/header/encoding_context.rbs 2026-06-17 02:34:13.514772044 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/sig/header/encoding_context.rbs 2026-06-17 02:34:13.519772021 +0000
@@ -24,0 +25,4 @@
+ @table_by_field: Hash[string, Array[[string, Integer]]]
+
+ @unshifts: Integer
+
sig/header/huffman.rbs
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/sig/header/huffman.rbs 2026-06-17 02:34:13.514772044 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/sig/header/huffman.rbs 2026-06-17 02:34:13.519772021 +0000
@@ -11,0 +12,2 @@
+ EOS_PADDING: Array[String]
+
sig/server.rbs
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/sig/server.rbs 2026-06-17 02:34:13.514772044 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/sig/server.rbs 2026-06-17 02:34:13.519772021 +0000
@@ -10 +10 @@
- def promise: (Stream parent, Enumerable[header_pair] headers, Array[Symbol] flags) { (Stream) -> void } -> void
+ def promise: (Stream parent, Enumerable[header_pair] headers, frame_control_flags flags) { (Stream) -> void } -> void
sig/stream.rbs
--- /tmp/d20260617-465-g5hhde/http-2-1.1.3/sig/stream.rbs 2026-06-17 02:34:13.514772044 +0000
+++ /tmp/d20260617-465-g5hhde/http-2-1.2.0/sig/stream.rbs 2026-06-17 02:34:13.519772021 +0000
@@ -40 +40 @@
- def send: (frame frame) -> void
+ def send: (stream_frame_props frame) -> void
@@ -73 +73 @@
- def transition: (frame, bool sending) -> void
+ def transition: (stream_frame_props frame, bool sending) -> void
@@ -83 +83 @@
- def process_priority: (priority_frame frame) -> void
+ def process_priority: (priority_frame_inner_props frame) -> void
@@ -85 +85 @@
- def end_stream?: (frame frame) -> boolish
+ def end_stream?: (stream_frame_props frame) -> boolish
@@ -87,2 +87 @@
- def stream_error: (Symbol error, ?msg: String?) -> void
- | () -> void
+ def stream_error: (?Symbol error, ?msg: String?) -> void
@@ -92 +91 @@
- def manage_state: (frame) { () -> void } -> void
+ def manage_state: (stream_frame_props frame) { () -> void } -> void
@@ -94 +93 @@
-end
\ No newline at end of file
+end |
Contributor
Contributor
gem compare httpx 1.7.8 1.8.0Compared versions: ["1.7.8", "1.8.0"]
DIFFERENT version:
1.7.8: 1.7.8
1.8.0: 1.8.0
DIFFERENT files:
1.7.8->1.8.0:
* Deleted:
lib/httpx/plugins/response_cache/file_store.rb
lib/httpx/plugins/response_cache/store.rb
sig/plugins/response_cache/file_store.rbs
sig/plugins/response_cache/store.rbs
* Added:
doc/release_notes/1_8_0.md +100/-0
lib/httpx/plugins/cache.rb +221/-0
lib/httpx/plugins/cache/file_store.rb +141/-0
lib/httpx/plugins/cache/store.rb +33/-0
lib/httpx/plugins/ntlm_v2_auth.rb +92/-0
lib/httpx/plugins/server_sent_events.rb +158/-0
lib/httpx/resolver/cache/file.rb +56/-0
sig/plugins/cache.rbs +69/-0
sig/plugins/cache/file_store.rbs +21/-0
sig/plugins/cache/store.rbs +13/-0
sig/plugins/ntlm_v2_auth.rbs +36/-0
sig/plugins/server_sent_events.rbs +45/-0
sig/resolver/cache/file.rbs +13/-0
* Changed:
lib/httpx/adapters/datadog.rb +3/-1
lib/httpx/connection.rb +76/-7
lib/httpx/connection/http1.rb +10/-1
lib/httpx/connection/http2.rb +37/-4
lib/httpx/errors.rb +8/-1
lib/httpx/io/tcp.rb +11/-1
lib/httpx/options.rb +16/-4
lib/httpx/parser/http1.rb +8/-2
lib/httpx/plugins/auth.rb +52/-4
lib/httpx/plugins/fiber_concurrency.rb +50/-3
lib/httpx/plugins/oauth.rb +66/-14
lib/httpx/plugins/proxy.rb +5/-0
lib/httpx/plugins/response_cache.rb +26/-105
lib/httpx/plugins/retries.rb +7/-5
lib/httpx/plugins/ssrf_filter.rb +16/-1
lib/httpx/plugins/stream.rb +7/-3
lib/httpx/plugins/tracing.rb +15/-4
lib/httpx/request.rb +18/-1
lib/httpx/resolver/native.rb +14/-3
lib/httpx/response.rb +9/-1
lib/httpx/response/body.rb +4/-2
lib/httpx/selector.rb +7/-1
lib/httpx/version.rb +1/-1
sig/chainable.rbs +3/-0
sig/connection.rbs +11/-8
sig/connection/http1.rbs +1/-1
sig/connection/http2.rbs +1/-1
sig/errors.rbs +9/-3
sig/httpx.rbs +2/-0
sig/io/tcp.rbs +2/-0
sig/loggable.rbs +4/-0
sig/options.rbs +25/-12
sig/parser/http1.rbs +3/-1
sig/plugins/auth/ntlm.rbs +1/-1
sig/plugins/fiber_concurrency.rbs +4/-0
sig/plugins/response_cache.rbs +13/-38
sig/plugins/retries.rbs +5/-5
sig/plugins/ssrf_filter.rbs +5/-1
sig/plugins/stream.rbs +1/-1
sig/plugins/stream_bidi.rbs +0/-2
sig/plugins/webdav.rbs +1/-1
sig/pool.rbs +2/-2
sig/request.rbs +7/-3
sig/resolver.rbs +3/-0
sig/resolver/entry.rbs +1/-1
sig/resolver/https.rbs +3/-3
sig/resolver/multi.rbs +1/-1
sig/resolver/native.rbs +5/-5
sig/resolver/resolver.rbs +1/-3
sig/resolver/system.rbs +2/-2
sig/response.rbs +3/-0
sig/selector.rbs +11/-8
sig/timers.rbs +5/-5
sig/transcoder.rbs +2/-0
sig/transcoder/body.rbs +1/-1
sig/transcoder/gzip.rbs +3/-2
sig/transcoder/multipart.rbs +4/-1
sig/transcoder/utils/deflater.rbs +2/-0
sig/utils.rbs +1/-1
DIFFERENT extra_rdoc_files:
1.7.8->1.8.0:
* Added:
doc/release_notes/1_8_0.md +100/-0
DIFFERENT runtime dependencies:
1.7.8->1.8.0:
* Updated:
http-2 from: [">= 1.1.3"] to: [">= 1.2.0"] |
3 similar comments
Contributor
gem compare httpx 1.7.8 1.8.0Compared versions: ["1.7.8", "1.8.0"]
DIFFERENT version:
1.7.8: 1.7.8
1.8.0: 1.8.0
DIFFERENT files:
1.7.8->1.8.0:
* Deleted:
lib/httpx/plugins/response_cache/file_store.rb
lib/httpx/plugins/response_cache/store.rb
sig/plugins/response_cache/file_store.rbs
sig/plugins/response_cache/store.rbs
* Added:
doc/release_notes/1_8_0.md +100/-0
lib/httpx/plugins/cache.rb +221/-0
lib/httpx/plugins/cache/file_store.rb +141/-0
lib/httpx/plugins/cache/store.rb +33/-0
lib/httpx/plugins/ntlm_v2_auth.rb +92/-0
lib/httpx/plugins/server_sent_events.rb +158/-0
lib/httpx/resolver/cache/file.rb +56/-0
sig/plugins/cache.rbs +69/-0
sig/plugins/cache/file_store.rbs +21/-0
sig/plugins/cache/store.rbs +13/-0
sig/plugins/ntlm_v2_auth.rbs +36/-0
sig/plugins/server_sent_events.rbs +45/-0
sig/resolver/cache/file.rbs +13/-0
* Changed:
lib/httpx/adapters/datadog.rb +3/-1
lib/httpx/connection.rb +76/-7
lib/httpx/connection/http1.rb +10/-1
lib/httpx/connection/http2.rb +37/-4
lib/httpx/errors.rb +8/-1
lib/httpx/io/tcp.rb +11/-1
lib/httpx/options.rb +16/-4
lib/httpx/parser/http1.rb +8/-2
lib/httpx/plugins/auth.rb +52/-4
lib/httpx/plugins/fiber_concurrency.rb +50/-3
lib/httpx/plugins/oauth.rb +66/-14
lib/httpx/plugins/proxy.rb +5/-0
lib/httpx/plugins/response_cache.rb +26/-105
lib/httpx/plugins/retries.rb +7/-5
lib/httpx/plugins/ssrf_filter.rb +16/-1
lib/httpx/plugins/stream.rb +7/-3
lib/httpx/plugins/tracing.rb +15/-4
lib/httpx/request.rb +18/-1
lib/httpx/resolver/native.rb +14/-3
lib/httpx/response.rb +9/-1
lib/httpx/response/body.rb +4/-2
lib/httpx/selector.rb +7/-1
lib/httpx/version.rb +1/-1
sig/chainable.rbs +3/-0
sig/connection.rbs +11/-8
sig/connection/http1.rbs +1/-1
sig/connection/http2.rbs +1/-1
sig/errors.rbs +9/-3
sig/httpx.rbs +2/-0
sig/io/tcp.rbs +2/-0
sig/loggable.rbs +4/-0
sig/options.rbs +25/-12
sig/parser/http1.rbs +3/-1
sig/plugins/auth/ntlm.rbs +1/-1
sig/plugins/fiber_concurrency.rbs +4/-0
sig/plugins/response_cache.rbs +13/-38
sig/plugins/retries.rbs +5/-5
sig/plugins/ssrf_filter.rbs +5/-1
sig/plugins/stream.rbs +1/-1
sig/plugins/stream_bidi.rbs +0/-2
sig/plugins/webdav.rbs +1/-1
sig/pool.rbs +2/-2
sig/request.rbs +7/-3
sig/resolver.rbs +3/-0
sig/resolver/entry.rbs +1/-1
sig/resolver/https.rbs +3/-3
sig/resolver/multi.rbs +1/-1
sig/resolver/native.rbs +5/-5
sig/resolver/resolver.rbs +1/-3
sig/resolver/system.rbs +2/-2
sig/response.rbs +3/-0
sig/selector.rbs +11/-8
sig/timers.rbs +5/-5
sig/transcoder.rbs +2/-0
sig/transcoder/body.rbs +1/-1
sig/transcoder/gzip.rbs +3/-2
sig/transcoder/multipart.rbs +4/-1
sig/transcoder/utils/deflater.rbs +2/-0
sig/utils.rbs +1/-1
DIFFERENT extra_rdoc_files:
1.7.8->1.8.0:
* Added:
doc/release_notes/1_8_0.md +100/-0
DIFFERENT runtime dependencies:
1.7.8->1.8.0:
* Updated:
http-2 from: [">= 1.1.3"] to: [">= 1.2.0"] |
Contributor
gem compare httpx 1.7.8 1.8.0Compared versions: ["1.7.8", "1.8.0"]
DIFFERENT version:
1.7.8: 1.7.8
1.8.0: 1.8.0
DIFFERENT files:
1.7.8->1.8.0:
* Deleted:
lib/httpx/plugins/response_cache/file_store.rb
lib/httpx/plugins/response_cache/store.rb
sig/plugins/response_cache/file_store.rbs
sig/plugins/response_cache/store.rbs
* Added:
doc/release_notes/1_8_0.md +100/-0
lib/httpx/plugins/cache.rb +221/-0
lib/httpx/plugins/cache/file_store.rb +141/-0
lib/httpx/plugins/cache/store.rb +33/-0
lib/httpx/plugins/ntlm_v2_auth.rb +92/-0
lib/httpx/plugins/server_sent_events.rb +158/-0
lib/httpx/resolver/cache/file.rb +56/-0
sig/plugins/cache.rbs +69/-0
sig/plugins/cache/file_store.rbs +21/-0
sig/plugins/cache/store.rbs +13/-0
sig/plugins/ntlm_v2_auth.rbs +36/-0
sig/plugins/server_sent_events.rbs +45/-0
sig/resolver/cache/file.rbs +13/-0
* Changed:
lib/httpx/adapters/datadog.rb +3/-1
lib/httpx/connection.rb +76/-7
lib/httpx/connection/http1.rb +10/-1
lib/httpx/connection/http2.rb +37/-4
lib/httpx/errors.rb +8/-1
lib/httpx/io/tcp.rb +11/-1
lib/httpx/options.rb +16/-4
lib/httpx/parser/http1.rb +8/-2
lib/httpx/plugins/auth.rb +52/-4
lib/httpx/plugins/fiber_concurrency.rb +50/-3
lib/httpx/plugins/oauth.rb +66/-14
lib/httpx/plugins/proxy.rb +5/-0
lib/httpx/plugins/response_cache.rb +26/-105
lib/httpx/plugins/retries.rb +7/-5
lib/httpx/plugins/ssrf_filter.rb +16/-1
lib/httpx/plugins/stream.rb +7/-3
lib/httpx/plugins/tracing.rb +15/-4
lib/httpx/request.rb +18/-1
lib/httpx/resolver/native.rb +14/-3
lib/httpx/response.rb +9/-1
lib/httpx/response/body.rb +4/-2
lib/httpx/selector.rb +7/-1
lib/httpx/version.rb +1/-1
sig/chainable.rbs +3/-0
sig/connection.rbs +11/-8
sig/connection/http1.rbs +1/-1
sig/connection/http2.rbs +1/-1
sig/errors.rbs +9/-3
sig/httpx.rbs +2/-0
sig/io/tcp.rbs +2/-0
sig/loggable.rbs +4/-0
sig/options.rbs +25/-12
sig/parser/http1.rbs +3/-1
sig/plugins/auth/ntlm.rbs +1/-1
sig/plugins/fiber_concurrency.rbs +4/-0
sig/plugins/response_cache.rbs +13/-38
sig/plugins/retries.rbs +5/-5
sig/plugins/ssrf_filter.rbs +5/-1
sig/plugins/stream.rbs +1/-1
sig/plugins/stream_bidi.rbs +0/-2
sig/plugins/webdav.rbs +1/-1
sig/pool.rbs +2/-2
sig/request.rbs +7/-3
sig/resolver.rbs +3/-0
sig/resolver/entry.rbs +1/-1
sig/resolver/https.rbs +3/-3
sig/resolver/multi.rbs +1/-1
sig/resolver/native.rbs +5/-5
sig/resolver/resolver.rbs +1/-3
sig/resolver/system.rbs +2/-2
sig/response.rbs +3/-0
sig/selector.rbs +11/-8
sig/timers.rbs +5/-5
sig/transcoder.rbs +2/-0
sig/transcoder/body.rbs +1/-1
sig/transcoder/gzip.rbs +3/-2
sig/transcoder/multipart.rbs +4/-1
sig/transcoder/utils/deflater.rbs +2/-0
sig/utils.rbs +1/-1
DIFFERENT extra_rdoc_files:
1.7.8->1.8.0:
* Added:
doc/release_notes/1_8_0.md +100/-0
DIFFERENT runtime dependencies:
1.7.8->1.8.0:
* Updated:
http-2 from: [">= 1.1.3"] to: [">= 1.2.0"] |
Contributor
gem compare httpx 1.7.8 1.8.0Compared versions: ["1.7.8", "1.8.0"]
DIFFERENT version:
1.7.8: 1.7.8
1.8.0: 1.8.0
DIFFERENT files:
1.7.8->1.8.0:
* Deleted:
lib/httpx/plugins/response_cache/file_store.rb
lib/httpx/plugins/response_cache/store.rb
sig/plugins/response_cache/file_store.rbs
sig/plugins/response_cache/store.rbs
* Added:
doc/release_notes/1_8_0.md +100/-0
lib/httpx/plugins/cache.rb +221/-0
lib/httpx/plugins/cache/file_store.rb +141/-0
lib/httpx/plugins/cache/store.rb +33/-0
lib/httpx/plugins/ntlm_v2_auth.rb +92/-0
lib/httpx/plugins/server_sent_events.rb +158/-0
lib/httpx/resolver/cache/file.rb +56/-0
sig/plugins/cache.rbs +69/-0
sig/plugins/cache/file_store.rbs +21/-0
sig/plugins/cache/store.rbs +13/-0
sig/plugins/ntlm_v2_auth.rbs +36/-0
sig/plugins/server_sent_events.rbs +45/-0
sig/resolver/cache/file.rbs +13/-0
* Changed:
lib/httpx/adapters/datadog.rb +3/-1
lib/httpx/connection.rb +76/-7
lib/httpx/connection/http1.rb +10/-1
lib/httpx/connection/http2.rb +37/-4
lib/httpx/errors.rb +8/-1
lib/httpx/io/tcp.rb +11/-1
lib/httpx/options.rb +16/-4
lib/httpx/parser/http1.rb +8/-2
lib/httpx/plugins/auth.rb +52/-4
lib/httpx/plugins/fiber_concurrency.rb +50/-3
lib/httpx/plugins/oauth.rb +66/-14
lib/httpx/plugins/proxy.rb +5/-0
lib/httpx/plugins/response_cache.rb +26/-105
lib/httpx/plugins/retries.rb +7/-5
lib/httpx/plugins/ssrf_filter.rb +16/-1
lib/httpx/plugins/stream.rb +7/-3
lib/httpx/plugins/tracing.rb +15/-4
lib/httpx/request.rb +18/-1
lib/httpx/resolver/native.rb +14/-3
lib/httpx/response.rb +9/-1
lib/httpx/response/body.rb +4/-2
lib/httpx/selector.rb +7/-1
lib/httpx/version.rb +1/-1
sig/chainable.rbs +3/-0
sig/connection.rbs +11/-8
sig/connection/http1.rbs +1/-1
sig/connection/http2.rbs +1/-1
sig/errors.rbs +9/-3
sig/httpx.rbs +2/-0
sig/io/tcp.rbs +2/-0
sig/loggable.rbs +4/-0
sig/options.rbs +25/-12
sig/parser/http1.rbs +3/-1
sig/plugins/auth/ntlm.rbs +1/-1
sig/plugins/fiber_concurrency.rbs +4/-0
sig/plugins/response_cache.rbs +13/-38
sig/plugins/retries.rbs +5/-5
sig/plugins/ssrf_filter.rbs +5/-1
sig/plugins/stream.rbs +1/-1
sig/plugins/stream_bidi.rbs +0/-2
sig/plugins/webdav.rbs +1/-1
sig/pool.rbs +2/-2
sig/request.rbs +7/-3
sig/resolver.rbs +3/-0
sig/resolver/entry.rbs +1/-1
sig/resolver/https.rbs +3/-3
sig/resolver/multi.rbs +1/-1
sig/resolver/native.rbs +5/-5
sig/resolver/resolver.rbs +1/-3
sig/resolver/system.rbs +2/-2
sig/response.rbs +3/-0
sig/selector.rbs +11/-8
sig/timers.rbs +5/-5
sig/transcoder.rbs +2/-0
sig/transcoder/body.rbs +1/-1
sig/transcoder/gzip.rbs +3/-2
sig/transcoder/multipart.rbs +4/-1
sig/transcoder/utils/deflater.rbs +2/-0
sig/utils.rbs +1/-1
DIFFERENT extra_rdoc_files:
1.7.8->1.8.0:
* Added:
doc/release_notes/1_8_0.md +100/-0
DIFFERENT runtime dependencies:
1.7.8->1.8.0:
* Updated:
http-2 from: [">= 1.1.3"] to: [">= 1.2.0"] |
Contributor
gem compare http-2 1.1.3 1.2.0Compared versions: ["1.1.3", "1.2.0"]
DIFFERENT version:
1.1.3: 1.1.3
1.2.0: 1.2.0
DIFFERENT files:
1.1.3->1.2.0:
* Added:
lib/http/2/settings.rb +42/-0
* Changed:
lib/http/2/client.rb +1/-1
lib/http/2/connection.rb +79/-62
lib/http/2/extensions.rb +16/-10
lib/http/2/flow_buffer.rb +7/-7
lib/http/2/framer.rb +98/-98
lib/http/2/header/compressor.rb +15/-4
lib/http/2/header/decompressor.rb +11/-10
lib/http/2/header/encoding_context.rb +18/-6
lib/http/2/header/huffman.rb +6/-4
lib/http/2/server.rb +12/-18
lib/http/2/stream.rb +19/-12
lib/http/2/version.rb +1/-1
sig/2.rbs +64/-15
sig/connection.rbs +11/-9
sig/flow_buffer.rbs +2/-2
sig/frame_buffer.rbs +4/-2
sig/framer.rbs +8/-4
sig/header/compressor.rbs +1/-0
sig/header/encoding_context.rbs +4/-0
sig/header/huffman.rbs +2/-0
sig/server.rbs +1/-1
sig/stream.rbs +7/-8 |
Contributor
|
Contributor
|
Contributor
|
Contributor
|
Contributor
gem compare --diff http-2 1.1.3 1.2.0Compared versions: ["1.1.3", "1.2.0"]
DIFFERENT files:
1.1.3->1.2.0:
* Added:
lib/http/2/settings.rb
--- /tmp/20260617-505-rz27kn 2026-06-17 02:34:59.312220208 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/settings.rb 2026-06-17 02:34:59.311220188 +0000
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module HTTP2
+ # Default values for SETTINGS frame, as defined by the spec.
+ SPEC_DEFAULT_CONNECTION_SETTINGS = {
+ settings_header_table_size: 4096,
+ settings_enable_push: 1, # enabled for servers
+ settings_max_concurrent_streams: Framer::MAX_STREAM_ID, # unlimited
+ settings_initial_window_size: 65_535,
+ settings_max_frame_size: 16_384,
+ settings_max_header_list_size: (2 << 30) - 1 # unlimited
+ }.freeze
+
+ Settings = Struct.new(
+ :settings_header_table_size,
+ :settings_enable_push,
+ :settings_max_concurrent_streams,
+ :settings_initial_window_size,
+ :settings_max_frame_size,
+ :settings_max_header_list_size,
+ keyword_init: true
+ ) do
+ def initialize(
+ settings_header_table_size: 4096,
+ settings_enable_push: 1,
+ settings_max_concurrent_streams: 100,
+ settings_initial_window_size: 65_535,
+ settings_max_frame_size: 16_384,
+ settings_max_header_list_size: (2 << 30) - 1
+ )
+ super
+ end
+
+ def each_setting
+ each_pair do |k, v|
+ next if v == SPEC_DEFAULT_CONNECTION_SETTINGS[k]
+
+ yield k, v
+ end
+ end
+ end
+end
* Changed:
lib/http/2/client.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/client.rb 2026-06-17 02:34:59.305220066 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/client.rb 2026-06-17 02:34:59.309220147 +0000
@@ -72 +72 @@
- frame = Framer.new.generate(type: :settings, stream: 0, payload: settings)
+ frame = Framer.new.generate(type: :settings, stream: 0, flags: 0, payload: settings)
lib/http/2/connection.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/connection.rb 2026-06-17 02:34:59.305220066 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/connection.rb 2026-06-17 02:34:59.309220147 +0000
@@ -44,2 +43,0 @@
- HEADERS_FRAME_TYPES = %i[headers push_promise].freeze
-
@@ -93,0 +92 @@
+ @oldest_stream_recently_closed = nil
@@ -104,0 +104 @@
+ @continuation_size = 0
@@ -159 +159 @@
- send(type: :goaway, last_stream: @last_stream_id,
+ send(type: :goaway, stream: 0, last_stream: @last_stream_id,
@@ -181 +180,0 @@
- @pending_settings << payload
@@ -215,3 +214,2 @@
- # @type var stream_id: Integer
- stream_id = frame[:stream]
- frame_type = frame[:type]
+ stream_id = frame[:stream] #: Integer
+ frame_type = frame[:type] #: Symbol?
@@ -239,0 +238 @@
+ # @type var frame: continuation_frame
@@ -243,2 +242,2 @@
- unless frame[:flags].include? :end_headers
- buffered_payload = @continuation.sum { |f| f[:payload].bytesize }
+ @continuation_size += frame[:payload].bytesize
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -248 +247 @@
- unless buffered_payload < @local_settings[:settings_max_frame_size]
+ unless @continuation_size < @local_settings[:settings_max_frame_size]
@@ -261,0 +261 @@
+ @continuation_size = 0
@@ -265 +265 @@
- frame[:flags] << :end_headers
+ frame[:flags] |= END_HEADERS
@@ -273,0 +274 @@
+ # @type var frame: connection_frame
@@ -278,0 +280 @@
+ # @type var frame: headers_frame
@@ -285 +287 @@
- unless frame[:flags].include? :end_headers
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -314,0 +317 @@
+ # @type var frame: push_promise_frame
@@ -317 +320 @@
- unless frame[:flags].include? :end_headers
+ unless frame[:flags].anybits?(END_HEADERS)
@@ -437,2 +439,0 @@
- frame_type = frame[:type]
-
@@ -440,2 +440,0 @@
- if frame_type == :data
- send_data(frame, true)
@@ -443,3 +442 @@
- elsif frame_type == :rst_stream && frame[:error] == :protocol_error
- # An endpoint can end a connection at any time. In particular, an
- # endpoint MAY choose to treat a stream error as a connection error.
+ frame_type = frame[:type] #: Symbol
@@ -447,2 +444,5 @@
- goaway(:protocol_error)
- else
+ case frame_type
+ when :data
+ #: @type var frame: data_frame
+ send_data(frame, true)
+ when :headers, :push_promise
@@ -450,0 +451,10 @@
+ #: @type var frame: headers_frame | push_promise_frame
+ encode_headers(frame) # HEADERS and PUSH_PROMISE may create more than one frame
+ else
+ if frame_type == :rst_stream && frame[:error] == :protocol_error
+ # An endpoint can end a connection at any time. In particular, an
+ # endpoint MAY choose to treat a stream error as a connection error.
+
+ goaway(:protocol_error)
+ end
+ #: @type var frame: connection_frame
@@ -459,5 +469 @@
- if HEADERS_FRAME_TYPES.include?(frame[:type])
- encode_headers(frame) # HEADERS and PUSH_PROMISE may create more than one frame
- else
- emit(:frame, @framer.generate(frame))
- end
+ emit(:frame, @framer.generate(frame))
@@ -495,0 +502 @@
+ # @type var frame: settings_frame
@@ -497,0 +505 @@
+ # @type var frame: window_update_frame
@@ -501,0 +510 @@
+ # @type var frame: goaway_frame
@@ -508,0 +518 @@
+ # @type var frame: altsvc_frame
@@ -515 +525,2 @@
- return if @h2c_upgrade || !frame[:flags].empty?
+ # @type var frame: origin_frame
+ return if @h2c_upgrade || !frame[:flags].zero?
@@ -520,2 +530,0 @@
- when :blocked
- emit(:blocked, frame)
@@ -541 +550 @@
- if frame[:flags].include? :ack
+ if frame[:flags].anybits?(ACK)
@@ -544,2 +553 @@
- send(type: :ping, stream: 0,
- flags: [:ack], payload: frame[:payload])
+ send(type: :ping, stream: 0, flags: ACK, payload: frame[:payload])
@@ -608 +616 @@
- if frame[:flags].include?(:ack)
+ if frame[:flags].anybits?(ACK)
@@ -613 +620,0 @@
- validate_settings(@remote_role, frame[:payload])
@@ -614,0 +622 @@
+ validate_settings(@remote_role, settings)
@@ -684 +692 @@
- send(type: :settings, stream: 0, payload: [], flags: [:ack])
+ send(type: :settings, stream: 0, payload: EMPTY, flags: ACK)
@@ -714 +722 @@
- payload = headers_frame[:payload]
+ headers_payload = headers_frame[:payload]
@@ -716 +724 @@
- payload = headers_frame[:payload] = @compressor.encode(payload) unless payload.is_a?(String)
+ payload = headers_payload.is_a?(String) ? headers_payload : @compressor.encode(headers_payload)
@@ -720,0 +729,3 @@
+ #: @type var payload: String
+ headers_frame[:payload] = payload
+
@@ -725 +736 @@
- emit(:frame, @framer.generate(headers_frame))
+ encode(headers_frame)
@@ -730 +741,2 @@
- headers_frame[:flags].delete(:end_headers)
+ total = payload.bytesize
+ headers_frame[:flags] ^= END_HEADERS
@@ -732 +744,2 @@
- payload = payload.byteslice(max_frame_size..-1)
+ # payload = payload.byteslice(max_frame_size..-1)
+ offset = max_frame_size
@@ -735 +748 @@
- emit(:frame, @framer.generate(headers_frame))
+ encode(headers_frame)
@@ -737,6 +750 @@
- loop do
- continuation_frame = headers_frame.merge(
- type: :continuation,
- flags: EMPTY,
- payload: payload.byteslice(0, max_frame_size)
- )
+ stream_id = headers_frame[:stream]
@@ -744 +752,3 @@
- payload = payload.byteslice(max_frame_size..-1)
+ while offset < total
+ chunk_end = offset + max_frame_size
+ is_last = chunk_end >= total
@@ -746,5 +756,6 @@
- if payload.nil? || payload.empty?
- continuation_frame[:flags] = [:end_headers]
- emit(:frame, @framer.generate(continuation_frame))
- break
- end
+ continuation_frame = {
+ type: :continuation,
+ flags: is_last ? END_HEADERS : 0,
+ stream: stream_id,
+ payload: payload.byteslice(offset, max_frame_size)
+ } #: continuation_frame
@@ -752 +763,2 @@
- emit(:frame, @framer.generate(continuation_frame))
+ encode(continuation_frame)
+ offset = chunk_end
@@ -779,2 +790,0 @@
- _, closed_since = @streams_recently_closed.first
-
@@ -783 +793,2 @@
- if closed_since && (now - closed_since) > 15
+ if @oldest_stream_recently_closed && (now - @oldest_stream_recently_closed) > 15
+ new_oldest = nil
@@ -786,3 +797,9 @@
- @streams_recently_closed = @streams_recently_closed.drop_while do |_, since|
- (now - since) > 15
- end.to_h
+ @streams_recently_closed.delete_if do |_, since|
+ unless (now - since) > 15
+ new_oldest ||= since
+ break
+ end
+
+ true
+ end
+ @oldest_stream_recently_closed = new_oldest
@@ -791 +808 @@
- @streams_recently_closed[id] = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ @streams_recently_closed[id] = now
lib/http/2/extensions.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/extensions.rb 2026-06-17 02:34:59.305220066 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/extensions.rb 2026-06-17 02:34:59.309220147 +0000
@@ -25,2 +25,3 @@
- def read_str(str, n)
- return "".b if n == 0
+ if String.method_defined?(:bytesplice)
+ def read_str(str, n)
+ return "".b if n == 0
@@ -28,4 +29,13 @@
- chunk = str.byteslice(0..(n - 1))
- remaining = str.byteslice(n..-1)
- remaining ? str.replace(remaining) : str.clear
- chunk
+ chunk = str.byteslice(0, n)
+ str.bytesplice(0, chunk.length, "")
+ chunk
+ end
+ else
+ def read_str(str, n)
+ return "".b if n == 0
+
+ chunk = str.byteslice(0, n)
+ remaining = str.byteslice(n, str.size - n)
+ remaining ? str.replace(remaining) : str.clear
+ chunk
+ end
@@ -36,4 +45,0 @@
- end
-
- def shift_byte(str)
- read_str(str, 1).ord
lib/http/2/flow_buffer.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/flow_buffer.rb 2026-06-17 02:34:59.305220066 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/flow_buffer.rb 2026-06-17 02:34:59.309220147 +0000
@@ -73 +73 @@
- end_stream = frame[:flags].include?(:end_stream)
+ end_stream = frame[:flags].anybits?(END_STREAM)
@@ -117,0 +118,2 @@
+ include BufferUtils
+
@@ -143 +145 @@
- end_stream = frame[:flags].include?(:end_stream)
+ end_stream = frame[:flags].anybits?(END_STREAM)
@@ -151,2 +153 @@
- chunk = frame.dup
- payload = frame[:payload]
+ chunk = frame.dup
@@ -157 +158 @@
- chunk[:payload] = payload.byteslice(0, window_size)
+ chunk[:payload] = read_str(frame[:payload], window_size) # mutates frame[:payload]
@@ -159 +159,0 @@
- frame[:payload] = payload.byteslice(window_size..-1)
@@ -163 +163 @@
- chunk[:flags] -= [:end_stream] if end_stream
+ chunk[:flags] ^= END_STREAM if end_stream
lib/http/2/framer.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/framer.rb 2026-06-17 02:34:59.306220087 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/framer.rb 2026-06-17 02:34:59.310220168 +0000
@@ -3,0 +4,19 @@
+ # Frame flags as defined by the spec (max 255 bits)
+ # DATA: ( X X COMPRESSED X PADDED X X END_STREAM )
+ # HEADERS: ( X X PRIORITY X PADDED END_HEADERS X END_STREAM )
+ # PRIORITY: ( X X X X X X X X )
+ # RST_STREAM: ( X X X X X X X X )
+ # SETTINGS: ( X X X X X X X ACK )
+ # PUSH_PROMISE: ( X X X X PADDED END_HEADERS X X )
+ # PING: ( X X X X X X X ACK )
+ # GOAWAY: ( X X X X X X X X )
+ # WINDOW_UPDATE: ( X X X X X X X X )
+ # CONTINUATION: ( X X X X X END_HEADERS X X )
+ # ALTSVC: ( X X X X X X X X )
+ # ORIGIN: ( RESERVED4 X X RESERVED3 X RESERVED2 RESERVED X )
+ END_STREAM = ACK = 0b0001 # 1
+ RESERVED = 0b0010 # 2
+ END_HEADERS = 0b0100 # 4
+ PADDED = 0b1000 # 8
+ PRIORITY = 0b0010_0000 # 32
+
@@ -43,33 +61,0 @@
- # Per frame flags as defined by the spec
- FRAME_FLAGS = {
- data: {
- end_stream: 0,
- padded: 3,
- compressed: 5
- },
- headers: {
- end_stream: 0,
- end_headers: 2,
- padded: 3,
- priority: 5
- },
- priority: {},
- rst_stream: {},
- settings: { ack: 0 },
- push_promise: {
- end_headers: 2,
- padded: 3
- },
- ping: { ack: 0 },
- goaway: {},
- window_update: {},
- continuation: { end_headers: 2 },
- altsvc: {},
- origin: {
- reserved: 1,
- reserved2: 2,
- reserved3: 4,
- reserved4: 8
- }
- }.each_value(&:freeze).freeze
-
@@ -86,17 +72,19 @@
- # Default error types as defined by the spec
- DEFINED_ERRORS = {
- no_error: 0,
- protocol_error: 1,
- internal_error: 2,
- flow_control_error: 3,
- settings_timeout: 4,
- stream_closed: 5,
- frame_size_error: 6,
- refused_stream: 7,
- cancel: 8,
- compression_error: 9,
- connect_error: 10,
- enhance_your_calm: 11,
- inadequate_security: 12,
- http_1_1_required: 13
- }.freeze
+ DEFINED_SETTINGS_BY_ID = DEFINED_SETTINGS.invert.freeze
+
+ # Default error types as defined by the spec (the code is the array index)
+ DEFINED_ERRORS = %i[
+ no_error
+ protocol_error
+ internal_error
+ flow_control_error
+ settings_timeout
+ stream_closed
+ frame_size_error
+ refused_stream
+ cancel
+ compression_error
+ connect_error
+ enhance_your_calm
+ inadequate_security
+ http_1_1_required
+ ].freeze
@@ -110,0 +99,2 @@
+ PRIORITYPACK = (UINT32 + UINT8).freeze
+ ALTSVCPACK = (UINT32 + UINT16).freeze
@@ -114 +104 @@
- private_constant :RBIT, :RBYTE, :EBIT, :HEADERPACK, :UINT32, :UINT16, :UINT8
+ private_constant :RBIT, :RBYTE, :EBIT, :HEADERPACK, :PRIORITYPACK, :UINT32, :UINT16, :UINT8
@@ -148,0 +139,4 @@
+ flags = frame[:flags]
+
+ raise CompressionError, "Invalid frame flag (#{flags}) for #{type}" unless flags.between?(0, 255)
+
@@ -163,6 +157 @@
- frame[:flags].reduce(0) do |acc, f|
- position = FRAME_FLAGS[type][f]
- raise CompressionError, "Invalid frame flag (#{f}) for #{type}" unless position
-
- acc | (1 << position)
- end,
+ flags,
@@ -187,3 +176 @@
- flags: FRAME_FLAGS[type].filter_map do |name, pos|
- name if flags.anybits?(1 << pos)
- end,
+ flags: flags,
@@ -201 +188 @@
- frame[:flags] ||= EMPTY
+ frame[:flags] ||= 0
@@ -204,0 +192 @@
+ # @type var frame: data_frame | continuation_frame
@@ -216 +204 @@
- frame[:flags] += [:priority] unless frame[:flags].include?(:priority)
+ frame[:flags] |= PRIORITY
@@ -219 +207 @@
- if frame[:flags].include?(:priority)
+ if frame[:flags].anybits?(PRIORITY)
@@ -222,2 +210,4 @@
- pack([(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT)], UINT32, buffer: bytes)
- pack([frame[:weight] - 1], UINT8, buffer: bytes)
+ pack(
+ [(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT), frame[:weight] - 1],
+ PRIORITYPACK, buffer: bytes
+ )
@@ -237,2 +227,4 @@
- pack([(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT)], UINT32, buffer: bytes)
- pack([frame[:weight] - 1], UINT8, buffer: bytes)
+ pack(
+ [(frame[:exclusive] ? EBIT : 0) | (frame[:dependency] & RBIT), frame[:weight] - 1],
+ PRIORITYPACK, buffer: bytes
+ )
@@ -251 +242,0 @@
- bytes = String.new("", encoding: Encoding::BINARY, capacity: length)
@@ -253,5 +244,6 @@
- settings.each do |(k, v)|
- if k.is_a? Integer # rubocop:disable Style/GuardClause
- DEFINED_SETTINGS.value?(k) || next
- else
- k = DEFINED_SETTINGS[k]
+ case settings
+ when String
+ length = settings.bytesize
+ bytes = settings
+ else
+ bytes = String.new("", encoding: Encoding::BINARY, capacity: settings.size * 6)
@@ -259 +251,12 @@
- raise CompressionError, "Unknown settings ID for #{k}" if k.nil?
+ settings.each do |(k, v)|
+ if k.is_a? Integer # rubocop:disable Style/GuardClause
+ DEFINED_SETTINGS.value?(k) || next
+ else
+ k = DEFINED_SETTINGS[k]
+
+ raise CompressionError, "Unknown settings ID for #{k}" if k.nil?
+ end
+
+ pack([k], UINT16, buffer: bytes)
+ pack([v], UINT32, buffer: bytes)
+ length += 6
@@ -261,4 +263,0 @@
-
- pack([k], UINT16, buffer: bytes)
- pack([v], UINT32, buffer: bytes)
- length += 6
@@ -298 +297 @@
- pack([frame[:max_age], frame[:port]], UINT32 + UINT16, buffer: bytes)
+ pack([frame[:max_age], frame[:port]], ALTSVCPACK, buffer: bytes)
@@ -357 +356 @@
- frame[:flags] += [:padded]
+ frame[:flags] |= PADDED
@@ -378,3 +377,3 @@
- type = frame[:type]
- length = frame[:length]
- flags = frame[:flags]
+ type = frame[:type] #: Symbol
+ length = frame[:length] #: Integer
+ flags = frame[:flags] #: Integer
@@ -397 +396 @@
- padded = flags.include?(:padded)
+ padded = flags.anybits?(PADDED)
@@ -400 +398,0 @@
- frame[:padding] = padlen + 1
@@ -402,0 +401,2 @@
+ frame[:padding] = padlen + 1
+
@@ -405 +405 @@
- flags.delete(:padded)
+ frame[:flags] ^= PADDED
@@ -413 +413 @@
- if flags.include?(:priority)
+ if flags.anybits?(PRIORITY)
@@ -417 +417 @@
- weight = payload.byteslice(0, 1).ord + 1
+ weight = payload.getbyte(0) + 1
@@ -428 +428 @@
- weight = payload.byteslice(0, 1).ord + 1
+ weight = payload.getbyte(0) + 1
@@ -439 +438,0 @@
- frame[:payload] = []
@@ -444 +443 @@
- (frame[:length] / 6).times do
+ frame[:payload] = (frame[:length] / 6).times.filter_map do
@@ -450,2 +449,3 @@
- name, = DEFINED_SETTINGS.find { |_name, v| v == id }
- frame[:payload] << [name, val] if name
+ if (name = DEFINED_SETTINGS_BY_ID[id])
+ [name, val]
+ end
@@ -467 +467 @@
- frame[:max_age], frame[:port] = read_str(payload, 6).unpack(UINT32 + UINT16)
+ frame[:max_age], frame[:port] = read_str(payload, 6).unpack(ALTSVCPACK)
@@ -469 +469 @@
- len = payload.byteslice(0, 1).ord
+ len = payload.getbyte(0)
@@ -473 +473 @@
- len = payload.byteslice(0, 1).ord
+ len = payload.getbyte(0)
@@ -498 +498 @@
- error = DEFINED_ERRORS[error]
+ error = DEFINED_ERRORS.index(error)
@@ -507 +507 @@
- DEFINED_ERRORS.key(error) || error
+ DEFINED_ERRORS.fetch(error, error)
lib/http/2/header/compressor.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/header/compressor.rb 2026-06-17 02:34:59.306220087 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/header/compressor.rb 2026-06-17 02:34:59.310220168 +0000
@@ -85,0 +86,2 @@
+ integer(huffman.bytesize, 7, buffer: buffer)
+ buffer.setbyte(huffman_offset, buffer.getbyte(huffman_offset) | 0x80)
@@ -87 +89 @@
- set_huffman_size(buffer, huffman_offset)
+ buffer
@@ -122 +124 @@
- fb = buffer[offset].ord | rep[:pattern]
+ fb = buffer.getbyte(offset) | rep[:pattern]
@@ -149,0 +152 @@
+ buffer << "\x00".b
@@ -151 +154,9 @@
- set_huffman_size(buffer, huffman_offset)
+ size = buffer.bytesize - huffman_offset - 1
+
+ if size < 127
+ buffer.setbyte(huffman_offset, 0x80 | size)
+ else
+ buffer.slice!(huffman_offset, 1)
+ set_huffman_size(buffer, huffman_offset)
+ end
+ buffer
@@ -168 +179 @@
- buffer.setbyte(huffman_offset, buffer[huffman_offset].ord | 0x80)
+ buffer.setbyte(huffman_offset, buffer.getbyte(huffman_offset) | 0x80)
lib/http/2/header/decompressor.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/header/decompressor.rb 2026-06-17 02:34:59.306220087 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/header/decompressor.rb 2026-06-17 02:34:59.310220168 +0000
@@ -36 +36,7 @@
- i = n.zero? ? 0 : (shift_byte(buf) & limit)
+ if n.zero?
+ i = 0
+ consumed = 0
+ else
+ i = buf.getbyte(0) & limit
+ consumed = 1
+ end
@@ -38 +43,0 @@
- m = 0
@@ -40,5 +45,2 @@
- offset = 0
-
- buf.each_byte.with_index do |byte, idx|
- offset = idx
- # while (byte = shift_byte(buf))
+ m = 0
+ while (byte = buf.getbyte(consumed))
@@ -47 +49 @@
-
+ consumed += 1
@@ -50,2 +51,0 @@
-
- read_str(buf, offset + 1)
@@ -53,0 +54 @@
+ read_str(buf, consumed)
lib/http/2/header/encoding_context.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/header/encoding_context.rb 2026-06-17 02:34:59.306220087 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/header/encoding_context.rb 2026-06-17 02:34:59.310220168 +0000
@@ -120,0 +121,2 @@
+ @table_by_field = Hash.new { |hs, k| hs[k] = [] }
+ @unshifts = 0
@@ -131,0 +134,2 @@
+ tbf = @table_by_field.transform_values(&:dup)
+ unshifts = @unshifts
@@ -134,0 +139,2 @@
+ @table_by_field = tbf
+ @unshifts = unshifts
@@ -215,0 +222,2 @@
+ @unshifts += 1
+ @table_by_field[name].unshift([value, @unshifts])
@@ -282,2 +290 @@
- @table.each_with_index do |(hfield, hvalue), i|
- next unless field == hfield
+ field_entries = @table_by_field[field]
@@ -284,0 +292,3 @@
+ field_entries&.each do |hvalue, unshift_id|
+ abs_index = (@unshifts - unshift_id) + STATIC_TABLE_SIZE
+ name_only ||= abs_index
@@ -286 +296 @@
- exact = i + STATIC_TABLE_SIZE
+ exact = abs_index
@@ -288,2 +297,0 @@
- else
- name_only ||= i + STATIC_TABLE_SIZE
@@ -320 +327,0 @@
-
@@ -322,0 +330,5 @@
+
+ field_arr = @table_by_field[name]
+ field_arr.pop
+ @table_by_field.delete(name) if field_arr.empty?
+
lib/http/2/header/huffman.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/header/huffman.rb 2026-06-17 02:34:59.306220087 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/header/huffman.rb 2026-06-17 02:34:59.310220168 +0000
@@ -22,0 +23,2 @@
+ EOS_PADDING = (0..7).map { |n| ("1" * n).b.freeze }.freeze
+
@@ -32 +34 @@
- append_str(bitstring, "1" * ((8 - bitstring.size) % 8))
+ append_str(bitstring, EOS_PADDING[(8 - bitstring.size) % 8])
@@ -57 +59 @@
- append_str(emit, first.chr) if first
+ emit << first if first
@@ -63 +65 @@
- emit.force_encoding(Encoding::BINARY)
+ emit
@@ -328 +330 @@
- ENCODE_TABLE = CODES.map { |c, l| [c].pack("N").unpack1("B*")[-l..-1] }.each(&:freeze).freeze
+ ENCODE_TABLE = CODES.map { |c, l| [c].pack("N").unpack1("B*")[-l..-1].b.freeze }.freeze
lib/http/2/server.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/server.rb 2026-06-17 02:34:59.306220087 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/server.rb 2026-06-17 02:34:59.310220168 +0000
@@ -81,12 +81,6 @@
- buf = "".b
- append_str(buf, Base64.urlsafe_decode64(settings.to_s))
- @framer.common_header(
- {
- length: buf.bytesize,
- type: :settings,
- stream: 0,
- flags: []
- },
- buffer: buf
- )
- receive(buf)
+ receive(@framer.generate(
+ type: :settings,
+ stream: 0,
+ flags: 0,
+ payload: Base64.urlsafe_decode64(settings.to_s)
+ ))
@@ -100 +94 @@
- flags: [:end_headers],
+ flags: END_HEADERS,
@@ -109 +103 @@
- headers_frame[:flags] << [:end_stream]
+ headers_frame[:flags] |= END_HEADERS
@@ -113 +107 @@
- stream << { type: :data, stream: 1, payload: body, flags: [:end_stream] }
+ stream << { type: :data, stream: 1, payload: body, flags: END_STREAM }
@@ -138 +132 @@
- return unless frame[:flags].include?(:ack) && !@origins_sent
+ return unless frame[:flags].anybits?(ACK) && !@origins_sent
@@ -151 +145 @@
- # @param flags [Array[Symbol]]
+ # @param flags Integer
@@ -160 +154 @@
- payload: headers.to_a
+ payload: headers
lib/http/2/stream.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/stream.rb 2026-06-17 02:34:59.307220107 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/stream.rb 2026-06-17 02:34:59.311220188 +0000
@@ -117 +117,2 @@
- case frame[:type]
+ frame_type = frame[:type] #: Symbol
+ case frame_type
@@ -118,0 +120 @@
+ # @type var frame: data_frame
@@ -131,0 +134 @@
+ # @type var frame: headers_frame
@@ -153,0 +157 @@
+ # @type var frame: priority_frame
@@ -155,0 +160 @@
+ # @type var frame: window_update_frame
@@ -157,0 +163 @@
+ # @type var frame: origin_frame
@@ -162,3 +168 @@
- emit(frame[:type], frame) if !frame[:origin] || frame[:origin].empty?
- when :blocked
- emit(frame[:type], frame)
+ emit(frame_type, frame) if !frame[:origin] || frame[:origin].empty?
@@ -201,0 +206 @@
+ # @type var frame: data_frame
@@ -204,0 +210 @@
+ # @type var frame: window_update_frame
@@ -206,0 +213 @@
+ # @type var frame: priority_frame
@@ -222,3 +229,2 @@
- flags = []
- flags << :end_headers if end_headers
- flags << :end_stream if end_stream || @_method == "HEAD"
+ flags = end_headers ? END_HEADERS : 0
+ flags |= END_STREAM if end_stream || @_method == "HEAD"
@@ -232 +238 @@
- flags = end_headers ? [:end_headers] : []
+ flags = end_headers ? END_HEADERS : 0
@@ -257 +263 @@
- send(type: :data, flags: [], payload: chunk)
+ send(type: :data, flags: 0, payload: chunk)
@@ -261,2 +267,2 @@
- flags = []
- flags << :end_stream if end_stream
+ flags = 0
+ flags |= END_STREAM if end_stream
@@ -666 +672,2 @@
- frame[:flags] && frame[:flags].include?(:end_stream)
+ # @type var frame: data_frame | headers_frame | continuation_frame
+ frame[:flags] && frame[:flags].anybits?(END_STREAM)
lib/http/2/version.rb
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/lib/http/2/version.rb 2026-06-17 02:34:59.307220107 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/lib/http/2/version.rb 2026-06-17 02:34:59.311220188 +0000
@@ -4 +4 @@
- VERSION = "1.1.3"
+ VERSION = "1.2.0"
sig/2.rbs
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/sig/2.rbs 2026-06-17 02:34:59.307220107 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/sig/2.rbs 2026-06-17 02:34:59.311220188 +0000
@@ -38,0 +39,8 @@
+ # Frame flags
+ END_STREAM: Integer
+ ACK: Integer
+ RESERVED: Integer
+ END_HEADERS: Integer
+ PADDED: Integer
+ PRIORITY: Integer
+
@@ -42 +50,3 @@
- type frame_control_flags = Array[:end_headers | :end_stream]
+ type frame_control_flags = Integer
+
+ type common_frame = { stream: Integer, flags: frame_control_flags, ?length: Integer, ?ignore: bool }
@@ -44 +54 @@
- type common_frame = { stream: Integer }
+ type connection_frame = settings_frame | ping_frame | goaway_frame | window_update_frame | altsvc_frame | origin_frame
@@ -47,2 +57,2 @@
- type headers_frame = common_frame & {
- type: :headers, flags: frame_control_flags, payload: Enumerable[header_pair] | String,
+ type headers_frame_props = {
+ type: :headers, payload: Enumerable[header_pair] | String,
@@ -50,0 +61,5 @@
+ type headers_frame = common_frame & headers_frame_props
+
+ type continuation_frame_props = headers_frame_props | { type: :continuation }
+
+ type continuation_frame = common_frame & continuation_frame_props
@@ -53 +68,3 @@
- type data_frame = { type: :data, flags: frame_control_flags, ?length: Integer, payload: String, ?padding: Integer }
+ type data_frame_props = { type: :data, ?length: Integer, payload: String, ?padding: Integer }
+
+ type data_frame = common_frame & data_frame_props
@@ -56 +73,3 @@
- type push_promise_frame = { type: :push_promise, promise_stream: Integer, flags: frame_control_flags, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair], ?padding: Integer }
+ type push_promise_frame_props = { promise_stream: Integer, ?length: Integer, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair] | String, ?padding: Integer }
+
+ type push_promise_frame = common_frame & push_promise_frame_props
@@ -59 +78,3 @@
- type settings_frame = { type: :settings, payload: Array[[Symbol | Integer, Integer]] }
+ type settings_frame_props = { type: :settings, payload: (Enumerable[[Symbol | Integer, Integer]] | String) }
+
+ type settings_frame = common_frame & settings_frame_props
@@ -62 +83,3 @@
- type window_update_frame = { type: :window_update, increment: Integer }
+ type window_update_frame_props = { type: :window_update, increment: Integer }
+
+ type window_update_frame = common_frame & window_update_frame_props
@@ -65 +88,5 @@
- type priority_frame = { dependency: Integer, exclusive: bool, weight: Integer }
+ type priority_frame_inner_props = { dependency: Integer, exclusive: bool, weight: Integer }
+
+ type priority_frame_props = { type: :priority } & priority_frame_inner_props
+
+ type priority_frame = common_frame & priority_frame_props
@@ -68 +95,3 @@
- type altsvc_frame = { type: :altsvc, max_age: Integer, port: Integer, proto: "String", host: String }
+ type altsvc_frame_props = { type: :altsvc, max_age: Integer, port: Integer, proto: String, host: String }
+
+ type altsvc_frame = common_frame & altsvc_frame_props
@@ -71 +100,3 @@
- type origin_frame = { type: :origin, origin: Array[String] }
+ type origin_frame_props = { type: :origin, payload: Array[String] }
+
+ type origin_frame = common_frame & origin_frame_props
@@ -74 +105,3 @@
- type ping_frame = { type: :ping, payload: String, length: Integer }
+ type ping_frame_props = { type: :ping, payload: String }
+
+ type ping_frame = common_frame & ping_frame_props
@@ -77 +110,3 @@
- type goaway_frame = { type: :goaway, last_stream: Integer, error: Symbol? }
+ type goaway_frame_props = { type: :goaway, last_stream: Integer, error: (Symbol | Integer)? }
+
+ type goaway_frame = common_frame & goaway_frame_props
@@ -79 +114,6 @@
- # type frame = common_frame & (headers_frame | data_frame | push_promise_frame |
+ # # RST_STREAM
+ type rst_stream_frame_props = { type: :rst_stream, error: (Symbol | Integer)? }
+
+ type rst_stream_frame = common_frame & rst_stream_frame_props
+
+ # type frame = headers_frame | continuation_frame | push_promise_frame | data_frame |
@@ -81 +121,8 @@
- # origin_frame | ping_frame | goaway_frame)
+ # origin_frame | ping_frame | goaway_frame | rst_stream_frame
+
+ # type connection_frame_props = rst_stream_frame_props | ping_frame_props | goaway_frame_props
+ # | window_update_frame_props | settings_frame_props
+
+ # type stream_frame_props = headers_frame_props | continuation_frame_props | push_promise_frame_props
+ # | data_frame_props | rst_stream_frame_props | priority_frame_props
+ # | window_update_frame_props | origin_frame_props | altsvc_frame_props
@@ -111,0 +159,2 @@
+ type connection_frame_props = Hash[frame_key, frame_value]
+ type stream_frame_props = Hash[frame_key, frame_value]
sig/connection.rbs
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/sig/connection.rbs 2026-06-17 02:34:59.307220107 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/sig/connection.rbs 2026-06-17 02:34:59.311220188 +0000
@@ -35,0 +36 @@
+ @oldest_stream_recently_closed: Numeric
@@ -52,0 +54 @@
+ @continuation_size: Integer
@@ -71 +73 @@
- def receive: (string data) -> void
+ def receive: (String data) -> void
@@ -78 +80 @@
- def send: (frame frame) -> void
+ def send: (connection_frame_props | stream_frame_props frame) -> void
@@ -84 +86 @@
- def connection_management: (frame) -> void
+ def connection_management: (connection_frame frame) -> void
@@ -90 +92 @@
- def connection_settings: (frame) -> void
+ def connection_settings: (settings_frame) -> void
@@ -92 +94 @@
- def decode_headers: (frame) -> void
+ def decode_headers: (headers_frame | push_promise_frame) -> void
@@ -94 +96 @@
- def encode_headers: (frame headers_frame) -> void
+ def encode_headers: (headers_frame | push_promise_frame) -> void
@@ -100 +102 @@
- def verify_pseudo_headers: (frame) -> void
+ def verify_pseudo_headers: (headers_frame | push_promise_frame) -> void
@@ -102 +104 @@
- def _verify_pseudo_headers: (frame, Array[String]) -> void
+ def _verify_pseudo_headers: (headers_frame | push_promise_frame, Array[String]) -> void
@@ -106 +108 @@
-end
\ No newline at end of file
+end
sig/flow_buffer.rbs
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/sig/flow_buffer.rbs 2026-06-17 02:34:59.307220107 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/sig/flow_buffer.rbs 2026-06-17 02:34:59.311220188 +0000
@@ -17 +17 @@
- def send_data: (?data_frame? frame, ?bool encode) -> void
+ def send_data: (?data_frame_props? frame, ?bool encode) -> void
@@ -19 +19 @@
- def send_frame: (data_frame frame, bool encode) -> void
+ def send_frame: (data_frame_props frame, bool encode) -> void
sig/frame_buffer.rbs
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/sig/frame_buffer.rbs 2026-06-17 02:34:59.307220107 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/sig/frame_buffer.rbs 2026-06-17 02:34:59.311220188 +0000
@@ -2,0 +3,2 @@
+ include BufferUtils
+
@@ -9 +11 @@
- def <<: (data_frame frame) -> void
+ def <<: (data_frame_props frame) -> void
@@ -13 +15 @@
- def retrieve: (Integer) -> data_frame?
+ def retrieve: (Integer) -> data_frame_props?
sig/framer.rbs
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/sig/framer.rbs 2026-06-17 02:34:59.307220107 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/sig/framer.rbs 2026-06-17 02:34:59.311220188 +0000
@@ -23 +23,3 @@
- DEFINED_ERRORS: Hash[Symbol, Integer]
+ DEFINED_SETTINGS_BY_ID: Hash[Integer, Symbol]
+
+ DEFINED_ERRORS: Array[Symbol]
@@ -31,0 +34,2 @@
+ PRIORITYPACK: String
+ ALTSVCPACK: String
@@ -44 +48 @@
- def read_common_header: (String buf) -> frame
+ def read_common_header: (String buf) -> (common_frame | { length: Integer })
@@ -50 +54 @@
- def parse: (String) -> frame?
+ def parse: (String) -> (frame | { length: Integer })?
@@ -56 +60 @@
- def pack_error: (Integer | Symbol error, buffer: String) -> String
+ def pack_error: (Symbol | Integer error, buffer: String) -> String
sig/header/compressor.rbs
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/sig/header/compressor.rbs 2026-06-17 02:34:59.307220107 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/sig/header/compressor.rbs 2026-06-17 02:34:59.312220208 +0000
@@ -4,0 +5 @@
+ include BufferUtils
sig/header/encoding_context.rbs
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/sig/header/encoding_context.rbs 2026-06-17 02:34:59.307220107 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/sig/header/encoding_context.rbs 2026-06-17 02:34:59.312220208 +0000
@@ -24,0 +25,4 @@
+ @table_by_field: Hash[string, Array[[string, Integer]]]
+
+ @unshifts: Integer
+
sig/header/huffman.rbs
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/sig/header/huffman.rbs 2026-06-17 02:34:59.308220127 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/sig/header/huffman.rbs 2026-06-17 02:34:59.312220208 +0000
@@ -11,0 +12,2 @@
+ EOS_PADDING: Array[String]
+
sig/server.rbs
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/sig/server.rbs 2026-06-17 02:34:59.308220127 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/sig/server.rbs 2026-06-17 02:34:59.312220208 +0000
@@ -10 +10 @@
- def promise: (Stream parent, Enumerable[header_pair] headers, Array[Symbol] flags) { (Stream) -> void } -> void
+ def promise: (Stream parent, Enumerable[header_pair] headers, frame_control_flags flags) { (Stream) -> void } -> void
sig/stream.rbs
--- /tmp/d20260617-505-eixn53/http-2-1.1.3/sig/stream.rbs 2026-06-17 02:34:59.308220127 +0000
+++ /tmp/d20260617-505-eixn53/http-2-1.2.0/sig/stream.rbs 2026-06-17 02:34:59.312220208 +0000
@@ -40 +40 @@
- def send: (frame frame) -> void
+ def send: (stream_frame_props frame) -> void
@@ -73 +73 @@
- def transition: (frame, bool sending) -> void
+ def transition: (stream_frame_props frame, bool sending) -> void
@@ -83 +83 @@
- def process_priority: (priority_frame frame) -> void
+ def process_priority: (priority_frame_inner_props frame) -> void
@@ -85 +85 @@
- def end_stream?: (frame frame) -> boolish
+ def end_stream?: (stream_frame_props frame) -> boolish
@@ -87,2 +87 @@
- def stream_error: (Symbol error, ?msg: String?) -> void
- | () -> void
+ def stream_error: (?Symbol error, ?msg: String?) -> void
@@ -92 +91 @@
- def manage_state: (frame) { () -> void } -> void
+ def manage_state: (stream_frame_props frame) { () -> void } -> void
@@ -94 +93 @@
-end
\ No newline at end of file
+end |
Contributor
gem compare httpx 1.7.8 1.8.0Compared versions: ["1.7.8", "1.8.0"]
DIFFERENT version:
1.7.8: 1.7.8
1.8.0: 1.8.0
DIFFERENT files:
1.7.8->1.8.0:
* Deleted:
lib/httpx/plugins/response_cache/file_store.rb
lib/httpx/plugins/response_cache/store.rb
sig/plugins/response_cache/file_store.rbs
sig/plugins/response_cache/store.rbs
* Added:
doc/release_notes/1_8_0.md +100/-0
lib/httpx/plugins/cache.rb +221/-0
lib/httpx/plugins/cache/file_store.rb +141/-0
lib/httpx/plugins/cache/store.rb +33/-0
lib/httpx/plugins/ntlm_v2_auth.rb +92/-0
lib/httpx/plugins/server_sent_events.rb +158/-0
lib/httpx/resolver/cache/file.rb +56/-0
sig/plugins/cache.rbs +69/-0
sig/plugins/cache/file_store.rbs +21/-0
sig/plugins/cache/store.rbs +13/-0
sig/plugins/ntlm_v2_auth.rbs +36/-0
sig/plugins/server_sent_events.rbs +45/-0
sig/resolver/cache/file.rbs +13/-0
* Changed:
lib/httpx/adapters/datadog.rb +3/-1
lib/httpx/connection.rb +76/-7
lib/httpx/connection/http1.rb +10/-1
lib/httpx/connection/http2.rb +37/-4
lib/httpx/errors.rb +8/-1
lib/httpx/io/tcp.rb +11/-1
lib/httpx/options.rb +16/-4
lib/httpx/parser/http1.rb +8/-2
lib/httpx/plugins/auth.rb +52/-4
lib/httpx/plugins/fiber_concurrency.rb +50/-3
lib/httpx/plugins/oauth.rb +66/-14
lib/httpx/plugins/proxy.rb +5/-0
lib/httpx/plugins/response_cache.rb +26/-105
lib/httpx/plugins/retries.rb +7/-5
lib/httpx/plugins/ssrf_filter.rb +16/-1
lib/httpx/plugins/stream.rb +7/-3
lib/httpx/plugins/tracing.rb +15/-4
lib/httpx/request.rb +18/-1
lib/httpx/resolver/native.rb +14/-3
lib/httpx/response.rb +9/-1
lib/httpx/response/body.rb +4/-2
lib/httpx/selector.rb +7/-1
lib/httpx/version.rb +1/-1
sig/chainable.rbs +3/-0
sig/connection.rbs +11/-8
sig/connection/http1.rbs +1/-1
sig/connection/http2.rbs +1/-1
sig/errors.rbs +9/-3
sig/httpx.rbs +2/-0
sig/io/tcp.rbs +2/-0
sig/loggable.rbs +4/-0
sig/options.rbs +25/-12
sig/parser/http1.rbs +3/-1
sig/plugins/auth/ntlm.rbs +1/-1
sig/plugins/fiber_concurrency.rbs +4/-0
sig/plugins/response_cache.rbs +13/-38
sig/plugins/retries.rbs +5/-5
sig/plugins/ssrf_filter.rbs +5/-1
sig/plugins/stream.rbs +1/-1
sig/plugins/stream_bidi.rbs +0/-2
sig/plugins/webdav.rbs +1/-1
sig/pool.rbs +2/-2
sig/request.rbs +7/-3
sig/resolver.rbs +3/-0
sig/resolver/entry.rbs +1/-1
sig/resolver/https.rbs +3/-3
sig/resolver/multi.rbs +1/-1
sig/resolver/native.rbs +5/-5
sig/resolver/resolver.rbs +1/-3
sig/resolver/system.rbs +2/-2
sig/response.rbs +3/-0
sig/selector.rbs +11/-8
sig/timers.rbs +5/-5
sig/transcoder.rbs +2/-0
sig/transcoder/body.rbs +1/-1
sig/transcoder/gzip.rbs +3/-2
sig/transcoder/multipart.rbs +4/-1
sig/transcoder/utils/deflater.rbs +2/-0
sig/utils.rbs +1/-1
DIFFERENT extra_rdoc_files:
1.7.8->1.8.0:
* Added:
doc/release_notes/1_8_0.md +100/-0
DIFFERENT runtime dependencies:
1.7.8->1.8.0:
* Updated:
http-2 from: [">= 1.1.3"] to: [">= 1.2.0"] |
Contributor
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps httpx from 1.7.8 to 1.8.0.
Commits
c35a340bump version to 1.8.08c220c7proxy: unescape user/password values for proxy options7a6aeb5set minimum version of http-2 to 1.2.087f036cMerge branch 'ping-timeout' into 'master'bd3a58fMerge branch 'issue-383' into 'master'8b03569new option: :ping_timeout54038bbnew options: max_response_body_size, max_response_headers,fa18331Merge branch 'sse' into 'master'56840e1test against incoming http-2 changesfaf50b7fix sig for SSRFFilter.unsafe_ip_address?Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)