immprove h2c to not misuse max_concurrrent_requests

the h2c was relying heavily on rewriting connection options to only allow the first request to upgrade; this changes by instead changing the parser on first incoming request, so that if it's upgrade and contains the header, blocks the remainder until the upgrade is successful or not, and if it's not reverts the max concurrent requests anyway
This commit is contained in:
HoneyryderChuck 2023-12-06 14:16:09 +00:00
parent 7842d075ad
commit 874bb6f1cf
3 changed files with 22 additions and 5 deletions

View File

@ -12,6 +12,8 @@ module HTTPX
attr_reader :pending, :requests
attr_accessor :max_concurrent_requests
def initialize(buffer, options)
@options = Options.new(options)
@max_concurrent_requests = @options.max_concurrent_requests || MAX_REQUESTS

View File

@ -73,20 +73,34 @@ module HTTPX
@inflight -= prev_parser.requests.size
end
parser_options = @options.merge(max_concurrent_requests: request.options.max_concurrent_requests)
@parser = H2CParser.new(@write_buffer, parser_options)
@parser = H2CParser.new(@write_buffer, @options)
set_parser_callbacks(@parser)
@inflight += 1
@parser.upgrade(request, response)
@upgrade_protocol = "h2c"
@options = @options.merge(max_concurrent_requests: nil)
prev_parser.requests.each do |req|
req.transition(:idle)
send(req)
end
end
private
def send_request_to_parser(request)
super
return unless request.headers["upgrade"] == "h2c" && parser.is_a?(Connection::HTTP1)
max_concurrent_requests = parser.max_concurrent_requests
return if max_concurrent_requests == 1
parser.max_concurrent_requests = 1
request.once(:response) do
parser.max_concurrent_requests = max_concurrent_requests
end
end
end
end
register_plugin(:h2c, H2C)

View File

@ -10,8 +10,9 @@ module HTTPX
attr_reader pending: Array[Request]
attr_reader requests: Array[Request]
attr_accessor max_concurrent_requests: Integer
@options: Options
@max_concurrent_requests: Integer
@max_requests: Integer
@parser: Parser::HTTP1
@buffer: Buffer