mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-10-04 00:00:37 -04:00
added request_timeout
This commit is contained in:
parent
c907942c9c
commit
3f9c165d51
@ -432,27 +432,7 @@ module HTTPX
|
|||||||
@inflight += 1
|
@inflight += 1
|
||||||
parser.send(request)
|
parser.send(request)
|
||||||
|
|
||||||
write_timeout = request.write_timeout
|
set_request_timeouts(request)
|
||||||
request.once(:headers) do
|
|
||||||
@timers.after(write_timeout) do
|
|
||||||
if request.state != :done
|
|
||||||
@write_buffer.clear
|
|
||||||
error = WriteTimeoutError.new(request, write_timeout)
|
|
||||||
on_error(error)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end unless write_timeout.nil? || write_timeout.infinite?
|
|
||||||
|
|
||||||
read_timeout = request.read_timeout
|
|
||||||
request.once(:done) do
|
|
||||||
@timers.after(read_timeout) do
|
|
||||||
if request.response.nil? || !request.response.finished?
|
|
||||||
@write_buffer.clear
|
|
||||||
error = ReadTimeoutError.new(request, request.response, read_timeout)
|
|
||||||
on_error(error)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end unless read_timeout.nil? || read_timeout.infinite?
|
|
||||||
|
|
||||||
return unless @state == :inactive
|
return unless @state == :inactive
|
||||||
|
|
||||||
@ -620,5 +600,38 @@ module HTTPX
|
|||||||
request.emit(:response, response)
|
request.emit(:response, response)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_request_timeouts(request)
|
||||||
|
write_timeout = request.write_timeout
|
||||||
|
request.once(:headers) do
|
||||||
|
@timers.after(write_timeout) { write_timeout_callback(request, write_timeout) }
|
||||||
|
end unless write_timeout.nil? || write_timeout.infinite?
|
||||||
|
|
||||||
|
read_timeout = request.read_timeout
|
||||||
|
request.once(:done) do
|
||||||
|
@timers.after(read_timeout) { read_timeout_callback(request, read_timeout) }
|
||||||
|
end unless read_timeout.nil? || read_timeout.infinite?
|
||||||
|
|
||||||
|
request_timeout = request.request_timeout
|
||||||
|
request.once(:headers) do
|
||||||
|
@timers.after(request_timeout) { read_timeout_callback(request, request_timeout, RequestTimeoutError) }
|
||||||
|
end unless request_timeout.nil? || request_timeout.infinite?
|
||||||
|
end
|
||||||
|
|
||||||
|
def write_timeout_callback(request, write_timeout)
|
||||||
|
return if request.state == :done
|
||||||
|
|
||||||
|
@write_buffer.clear
|
||||||
|
error = WriteTimeoutError.new(request, nil, write_timeout)
|
||||||
|
on_error(error)
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_timeout_callback(request, read_timeout, error_type = WriteTimeoutError)
|
||||||
|
return if request.response && request.response.finished?
|
||||||
|
|
||||||
|
@write_buffer.clear
|
||||||
|
error = error_type.new(request, request.response, read_timeout)
|
||||||
|
on_error(error)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -27,8 +27,9 @@ module HTTPX
|
|||||||
class RequestTimeoutError < TimeoutError
|
class RequestTimeoutError < TimeoutError
|
||||||
attr_reader :request
|
attr_reader :request
|
||||||
|
|
||||||
def initialize(request, timeout)
|
def initialize(request, response, timeout)
|
||||||
@request = request
|
@request = request
|
||||||
|
@response = response
|
||||||
super(timeout, "Timed out after #{timeout} seconds")
|
super(timeout, "Timed out after #{timeout} seconds")
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -37,14 +38,7 @@ module HTTPX
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class ReadTimeoutError < RequestTimeoutError
|
class ReadTimeoutError < RequestTimeoutError; end
|
||||||
attr_reader :response
|
|
||||||
|
|
||||||
def initialize(request, response, timeout)
|
|
||||||
@response = response
|
|
||||||
super(request, timeout)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class WriteTimeoutError < RequestTimeoutError; end
|
class WriteTimeoutError < RequestTimeoutError; end
|
||||||
|
|
||||||
|
@ -10,8 +10,7 @@ module HTTPX
|
|||||||
OPERATION_TIMEOUT = 60
|
OPERATION_TIMEOUT = 60
|
||||||
KEEP_ALIVE_TIMEOUT = 20
|
KEEP_ALIVE_TIMEOUT = 20
|
||||||
SETTINGS_TIMEOUT = 10
|
SETTINGS_TIMEOUT = 10
|
||||||
READ_TIMEOUT = Float::INFINITY
|
READ_TIMEOUT = WRITE_TIMEOUT = REQUEST_TIMEOUT = Float::INFINITY
|
||||||
WRITE_TIMEOUT = Float::INFINITY
|
|
||||||
|
|
||||||
# https://github.com/ruby/resolv/blob/095f1c003f6073730500f02acbdbc55f83d70987/lib/resolv.rb#L408
|
# https://github.com/ruby/resolv/blob/095f1c003f6073730500f02acbdbc55f83d70987/lib/resolv.rb#L408
|
||||||
ip_address_families = begin
|
ip_address_families = begin
|
||||||
@ -38,6 +37,7 @@ module HTTPX
|
|||||||
keep_alive_timeout: KEEP_ALIVE_TIMEOUT,
|
keep_alive_timeout: KEEP_ALIVE_TIMEOUT,
|
||||||
read_timeout: READ_TIMEOUT,
|
read_timeout: READ_TIMEOUT,
|
||||||
write_timeout: WRITE_TIMEOUT,
|
write_timeout: WRITE_TIMEOUT,
|
||||||
|
request_timeout: REQUEST_TIMEOUT,
|
||||||
},
|
},
|
||||||
:headers => {},
|
:headers => {},
|
||||||
:window_size => WINDOW_SIZE,
|
:window_size => WINDOW_SIZE,
|
||||||
|
@ -72,6 +72,10 @@ module HTTPX
|
|||||||
@options.timeout[:write_timeout]
|
@options.timeout[:write_timeout]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def request_timeout
|
||||||
|
@options.timeout[:request_timeout]
|
||||||
|
end
|
||||||
|
|
||||||
def trailers?
|
def trailers?
|
||||||
defined?(@trailers)
|
defined?(@trailers)
|
||||||
end
|
end
|
||||||
|
@ -103,5 +103,11 @@ module HTTPX
|
|||||||
def handle_error: (StandardError) -> void
|
def handle_error: (StandardError) -> void
|
||||||
|
|
||||||
def purge_after_closed: () -> void
|
def purge_after_closed: () -> void
|
||||||
|
|
||||||
|
def set_request_timeouts: (Request request) -> void
|
||||||
|
|
||||||
|
def write_timeout_callback: (Request request, Numeric write_timeout)
|
||||||
|
|
||||||
|
def read_timeout_callback: (Request request, Numeric read_timeout, singleton(RequestTimeoutError) error_type)
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -20,7 +20,20 @@ module HTTPX
|
|||||||
class SettingsTimeoutError < TimeoutError
|
class SettingsTimeoutError < TimeoutError
|
||||||
end
|
end
|
||||||
|
|
||||||
class ResolveTimeoutError < TimeoutError
|
class ResolveTimeoutError < RequestTimeoutError
|
||||||
|
end
|
||||||
|
|
||||||
|
class RequestTimeoutError < TimeoutError
|
||||||
|
attr_reader request: Request
|
||||||
|
attr_reader response: response?
|
||||||
|
|
||||||
|
def initialize: (Request request, response? response, Numeric timeout) -> void
|
||||||
|
end
|
||||||
|
|
||||||
|
class ReadTimeoutError < TimeoutError
|
||||||
|
end
|
||||||
|
|
||||||
|
class WriteTimeoutError < RequestTimeoutError
|
||||||
end
|
end
|
||||||
|
|
||||||
class ResolveError < Error
|
class ResolveError < Error
|
||||||
|
@ -10,7 +10,7 @@ module HTTPX
|
|||||||
SETTINGS_TIMEOUT: Integer
|
SETTINGS_TIMEOUT: Integer
|
||||||
DEFAULT_OPTIONS: Hash[Symbol, untyped]
|
DEFAULT_OPTIONS: Hash[Symbol, untyped]
|
||||||
|
|
||||||
type timeout_type = :connect_timeout | :settings_timeout | :operation_timeout | :keep_alive_timeout | :total_timeout | :read_timeout | :write_timeout
|
type timeout_type = :connect_timeout | :settings_timeout | :operation_timeout | :keep_alive_timeout | :total_timeout | :read_timeout | :write_timeout | :request_timeout
|
||||||
type timeout = Hash[timeout_type, Numeric]
|
type timeout = Hash[timeout_type, Numeric]
|
||||||
|
|
||||||
def self.new: (?options) -> instance
|
def self.new: (?options) -> instance
|
||||||
|
@ -50,6 +50,12 @@ module HTTPX
|
|||||||
|
|
||||||
def trailers?: () -> boolish
|
def trailers?: () -> boolish
|
||||||
|
|
||||||
|
def read_timeout: () -> Numeric
|
||||||
|
|
||||||
|
def write_timeout: () -> Numeric
|
||||||
|
|
||||||
|
def request_timeout: () -> Numeric
|
||||||
|
|
||||||
class Body
|
class Body
|
||||||
@headers: Headers
|
@headers: Headers
|
||||||
@body: body_encoder?
|
@body: body_encoder?
|
||||||
|
@ -91,6 +91,17 @@ class SessionTest < Minitest::Test
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_session_timeouts_request_timeout
|
||||||
|
uri = build_uri("/drip?numbytes=10&duration=4&delay=2&code=200")
|
||||||
|
session = HTTPX.with_timeout(request_timeout: 3, operation_timeout: 10)
|
||||||
|
response = session.get(uri)
|
||||||
|
verify_error_response(response, HTTPX::RequestTimeoutError)
|
||||||
|
|
||||||
|
uri = build_uri("/drip?numbytes=10&duration=2&delay=0&code=200")
|
||||||
|
response1 = session.get(uri)
|
||||||
|
verify_status(response1, 200)
|
||||||
|
end
|
||||||
|
|
||||||
# def test_http_timeouts_operation_timeout
|
# def test_http_timeouts_operation_timeout
|
||||||
# uri = build_uri("/delay/2")
|
# uri = build_uri("/delay/2")
|
||||||
# session = HTTPX.with_timeout(operation_timeout: 1)
|
# session = HTTPX.with_timeout(operation_timeout: 1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user