lib/httpx/connection.rb in httpx-1.0.2 vs lib/httpx/connection.rb in httpx-1.1.0

- old
+ new

@@ -68,10 +68,12 @@ end @inflight = 0 @keep_alive_timeout = @options.timeout[:keep_alive_timeout] + @intervals = [] + self.addresses = @options.addresses if @options.addresses end # this is a semi-private method, to be used by the resolver # to initiate the io object. @@ -211,10 +213,13 @@ @io.to_io end def call case @state + when :idle + connect + consume when :closed return when :closing consume transition(:closed) @@ -292,11 +297,19 @@ def open? @state == :open || @state == :inactive end - def raise_timeout_error(interval) + def handle_socket_timeout(interval) + @intervals.delete_if(&:elapsed?) + + unless @intervals.empty? + # remove the intervals which will elapse + + return + end + error = HTTPX::TimeoutError.new(interval, "timed out while waiting on select") error.set_backtrace(caller) on_error(error) end @@ -447,10 +460,11 @@ @parser ||= build_parser end def send_request_to_parser(request) @inflight += 1 + request.peer_address = @io.ip parser.send(request) set_request_timeouts(request) return unless @state == :inactive @@ -653,23 +667,30 @@ 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? + + unless write_timeout.nil? || write_timeout.infinite? + set_request_timeout(request, write_timeout, :headers, %i[done response]) do + write_timeout_callback(request, write_timeout) + end + end + + unless read_timeout.nil? || read_timeout.infinite? + set_request_timeout(request, read_timeout, :done, :response) do + read_timeout_callback(request, read_timeout) + end + end + + return if request_timeout.nil? || request_timeout.infinite? + + set_request_timeout(request, request_timeout, :headers, :response) do + read_timeout_callback(request, request_timeout, RequestTimeoutError) + end end def write_timeout_callback(request, write_timeout) return if request.state == :done @@ -684,9 +705,27 @@ return if response && response.finished? @write_buffer.clear error = error_type.new(request, request.response, read_timeout) on_error(error) + end + + def set_request_timeout(request, timeout, start_event, finish_events, &callback) + request.once(start_event) do + interval = @timers.after(timeout, callback) + + Array(finish_events).each do |event| + # clean up reques timeouts if the connection errors out + request.once(event) do + if @intervals.include?(interval) + interval.delete(callback) + @intervals.delete(interval) if interval.no_callbacks? + end + end + end + + @intervals << interval + end end class << self def parser_type(protocol) case protocol