Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby: [2.7 ,'3.0', 3.1, 3.2, 3.3, 3.4, 4.0, jruby, truffleruby]
ruby: [2.7 ,'3.0', 3.1, 3.2, 3.3, 3.4, 4.0, head, jruby, truffleruby]

steps:
- uses: actions/checkout@v4
Expand All @@ -35,7 +35,7 @@ jobs:
RUBY_VERSION=`ruby -e 'puts RUBY_VERSION'`
RUBY_PLATFORM=`ruby -e 'puts RUBY_PLATFORM'`
RUBY_ENGINE=`ruby -e 'puts RUBY_ENGINE'`
if [[ "$RUBY_ENGINE" = "ruby" ]] && [[ ${RUBY_VERSION:0:1} = "3" ]] && [[ ! $RUBYOPT =~ "jit" ]]; then
if [[ "$RUBY_ENGINE" = "ruby" ]] && [[ ${RUBY_VERSION:0:1} = "4" ]] && [[ ! $RUBYOPT =~ "jit" ]]; then
echo "running runtime type checking..."
bundle exec rbs collection install
export RUBYOPT="-rbundler/setup -rrbs/test/setup"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea/
Gemfile.lock
*.gem
spec/hpack-test-case
23 changes: 12 additions & 11 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ require_relative "tasks/generate_huffman_table"

RUBY_MAJOR_MINOR = RUBY_VERSION.split(".").first(2).join(".")

begin
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new(:spec) do |t|
t.exclude_pattern = "./spec/hpack_test_spec.rb"
end
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new(:spec) do |t|
t.exclude_pattern = "./spec/hpack_test_spec.rb"
end

RSpec::Core::RakeTask.new(:hpack) do |t|
t.pattern = "./spec/hpack_test_spec.rb"
end
rescue LoadError
RSpec::Core::RakeTask.new(:hpack) do |t|
t.pattern = "./spec/hpack_test_spec.rb"
end

task :prepare_hpack do
system("git clone --depth 1 https://github.com/http2jp/hpack-test-case.git spec/hpack-test-case")
end

begin
Expand Down Expand Up @@ -103,6 +104,6 @@ end

default_tasks = %i[spec]
default_tasks << :rubocop if defined?(RuboCop) && RUBY_ENGINE == "ruby"
default_tasks += %i[h2spec_install h2spec] if ENV.key?("CI")
default_tasks += %i[prepare_hpack hpack h2spec_install h2spec] if ENV.key?("CI")
task default: default_tasks
task all: %i[default hpack]
task all: default_tasks
7 changes: 5 additions & 2 deletions lib/http/2/header/decompressor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Decompressor

# @param options [Hash] decoding options. Only :table_size is effective.
def initialize(options = {})
@accept_invalid_headers = options.fetch(:accept_invalid_headers, false)
@cc = EncodingContext.new(options)
end

Expand Down Expand Up @@ -123,12 +124,14 @@ def decode(buf, frame = nil)
next if field.nil?

is_pseudo_header = field.start_with?(":")
if !decoding_pseudo_headers && is_pseudo_header
if !decoding_pseudo_headers && is_pseudo_header && !@accept_invalid_headers
raise ProtocolError, "one or more pseudo headers encountered after regular headers"
end

decoding_pseudo_headers = is_pseudo_header
raise ProtocolError, "invalid header received: #{field}" if FORBIDDEN_HEADERS.include?(field)
if !@accept_invalid_headers && FORBIDDEN_HEADERS.include?(field)
raise ProtocolError, "invalid header received: #{field}"
end

if frame
case field
Expand Down
12 changes: 6 additions & 6 deletions spec/hpack_test_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@
story = JSON.parse(File.read("#{path}/#{file}"))
cases = story["cases"]
table_size = cases[0]["header_table_size"] || 4096
@dc = Decompressor.new(table_size: table_size)
@dc = Decompressor.new(table_size: table_size, accept_invalid_headers: true)
cases.each do |c|
wire = [c["wire"]].pack("H*").force_encoding(Encoding::BINARY)
@emitted = @dc.decode(HTTP2::Buffer.new(wire))
@emitted = @dc.decode(wire)
headers = c["headers"].flat_map(&:to_a)
expect(@emitted).to eq headers
expect(@emitted).to match_array(headers)
end
end
end
Expand Down Expand Up @@ -74,12 +74,12 @@
story = JSON.parse(File.read("#{path}/#{file}"))
cases = story["cases"]
@cc = Compressor.new(options)
@dc = Decompressor.new(options)
@dc = Decompressor.new(options.merge(accept_invalid_headers: true))
cases.each do |c|
headers = c["headers"].flat_map(&:to_a)
wire = @cc.encode(headers)
decoded = @dc.decode(HTTP2::Buffer.new(wire))
expect(decoded).to eq headers
decoded = @dc.decode(wire)
expect(decoded).to match_array(headers)
end
end
end
Expand Down
Loading