httpx/test/support/servlets/keep_alive.rb
HoneyryderChuck cb78091e03 don't bookkeep retry attempts when errors happen on just-checked-out open connections
in case of multiple connections to the same server, where the server may have closed all of them at the same time, a request will fail after checkout multiple times, before starting a new one where the request may succeed. this patch allows the prior attempts not to exhaust the number of possible retries on the request

it does so by marking the request as ping when the connection it's being sent to is marked as inactive; this leverages the logic of gating retries bookkeeping in such a case

Closes https://github.com/HoneyryderChuck/httpx/issues/92
2025-05-28 15:25:50 +01:00

90 lines
1.8 KiB
Ruby

# frozen_string_literal: true
require_relative "test"
class KeepAliveServer < TestServer
class KeepAliveApp < WEBrick::HTTPServlet::AbstractServlet
def do_GET(_req, res) # rubocop:disable Naming/MethodName
res.status = 200
res["Connection"] = "Keep-Alive"
res["Content-Type"] = "application/json"
res.body = "{\"counter\": infinity}"
end
end
class KeepAliveMax2App < WEBrick::HTTPServlet::AbstractServlet
def do_GET(_req, res) # rubocop:disable Naming/MethodName
res.status = 200
res["Connection"] = "Keep-Alive"
res["Keep-Alive"] = "max=2"
res["Content-Type"] = "application/json"
res.body = "{\"counter\": 2}"
end
end
def initialize(options = {})
super
mount("/", KeepAliveApp)
mount("/2", KeepAliveMax2App)
end
end
class KeepAlivePongThenGoawayServer < TestHTTP2Server
attr_reader :pings, :pongs
def initialize(**)
@sent = Hash.new(false)
super()
end
private
def handle_stream(conn, stream)
# responds once, then closes the connection
if @sent[conn]
conn.goaway
@sent[conn] = false
else
super
@sent[conn] = true
end
end
end
class KeepAlivePongThenCloseSocketServer < TestHTTP2Server
def initialize
@sent = false
super
end
private
def handle_connection(conn, sock)
super
conn.on(:stream) do |stream|
stream.on(:close) do
@sent = true
close_socket(sock)
end
end
end
end
class KeepAlivePongThenTimeoutSocketServer < TestHTTP2Server
def initialize(interval: 10, **args)
@interval = interval
super(**args)
end
private
def handle_connection(conn, sock)
super
conn.on(:stream) do |stream|
stream.on(:close) do
sleep(@interval)
end
end
end
end