From 5bb74ec465f7d4dd12ffb82f67b4e53b0ce94200 Mon Sep 17 00:00:00 2001 From: HoneyryderChuck Date: Sat, 28 Oct 2023 23:32:05 +0100 Subject: [PATCH 1/2] expose the io object via the TCP#socket method, which will be an SSLSocket for SSL case --- lib/httpx/io/tcp.rb | 2 +- test/support/requests/callbacks.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/httpx/io/tcp.rb b/lib/httpx/io/tcp.rb index d4473778..ea990f6d 100644 --- a/lib/httpx/io/tcp.rb +++ b/lib/httpx/io/tcp.rb @@ -41,7 +41,7 @@ module HTTPX end def socket - @io.to_io + @io end def add_addresses(addrs) diff --git a/test/support/requests/callbacks.rb b/test/support/requests/callbacks.rb index 97167d33..9b4baeb4 100644 --- a/test/support/requests/callbacks.rb +++ b/test/support/requests/callbacks.rb @@ -11,7 +11,7 @@ module Requests response = HTTPX.plugin(SessionWithPool).on_connection_opened do |o, sock| origin = o - ip = sock.remote_address.ip_address + ip = sock.to_io.remote_address.ip_address end.get(uri) verify_status(response, 200) From 9465a077b1b4f3b61eeacd3ebddce6e34f415cc3 Mon Sep 17 00:00:00 2001 From: HoneyryderChuck Date: Sat, 28 Oct 2023 23:53:50 +0100 Subject: [PATCH 2/2] Add Response#peer_address and ErrorResponse#peer_address responses can now expose the IP address used to connect to the peer server to fetch the response from. --- lib/httpx/connection.rb | 1 + lib/httpx/request.rb | 4 ++++ lib/httpx/response.rb | 6 ++++++ sig/io/tcp.rbs | 2 +- sig/request.rbs | 2 ++ sig/response.rbs | 9 +++++++++ test/session_test.rb | 9 +++++++++ 7 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/httpx/connection.rb b/lib/httpx/connection.rb index 42e7596e..39058442 100644 --- a/lib/httpx/connection.rb +++ b/lib/httpx/connection.rb @@ -462,6 +462,7 @@ module HTTPX def send_request_to_parser(request) @inflight += 1 + request.peer_address = @io.ip parser.send(request) set_request_timeouts(request) diff --git a/lib/httpx/request.rb b/lib/httpx/request.rb index 8ed68b44..301d3983 100644 --- a/lib/httpx/request.rb +++ b/lib/httpx/request.rb @@ -38,6 +38,9 @@ module HTTPX # Exception raised during enumerable body writes. attr_reader :drain_error + # The IP address from the peer server. + attr_accessor :peer_address + attr_writer :persistent # will be +true+ when request body has been completely flushed. @@ -65,6 +68,7 @@ module HTTPX @body = @options.request_body_class.new(@headers, @options) @state = :idle @response = nil + @peer_address = nil @persistent = @options.persistent end diff --git a/lib/httpx/response.rb b/lib/httpx/response.rb index 024dbb3c..581ff998 100644 --- a/lib/httpx/response.rb +++ b/lib/httpx/response.rb @@ -44,6 +44,9 @@ module HTTPX # the corresponding request uri. def_delegator :@request, :uri + # the IP address of the peer server. + def_delegator :@request, :peer_address + # inits the instance with the corresponding +request+ to this response, an the # response HTTP +status+, +version+ and HTTPX::Headers instance of +headers+. def initialize(request, status, version, headers) @@ -226,6 +229,9 @@ module HTTPX # the request uri def_delegator :@request, :uri + # the IP address of the peer server. + def_delegator :@request, :peer_address + def initialize(request, error, options) @request = request @response = request.response if request.response.is_a?(Response) diff --git a/sig/io/tcp.rbs b/sig/io/tcp.rbs index fc900414..845b301d 100644 --- a/sig/io/tcp.rbs +++ b/sig/io/tcp.rbs @@ -2,7 +2,7 @@ module HTTPX class TCP include Loggable - attr_reader ip: IPAddr? + attr_reader ip: ipaddr? attr_reader port: Integer diff --git a/sig/request.rbs b/sig/request.rbs index 2363d17e..19076c8b 100644 --- a/sig/request.rbs +++ b/sig/request.rbs @@ -15,6 +15,8 @@ module HTTPX attr_reader response: response? attr_reader drain_error: StandardError? + attr_accessor peer_address: ipaddr? + attr_writer persistent: bool @trailers: Headers? diff --git a/sig/response.rbs b/sig/response.rbs index ea94fcef..620adbc0 100644 --- a/sig/response.rbs +++ b/sig/response.rbs @@ -25,12 +25,19 @@ module HTTPX @content_type: ContentType def copy_to: (_ToPath | _Writer destination) -> void + def close: () -> void + def uri: () -> URI::Generic + def peer_address: () -> ipaddr? + def merge_headers: (_Each[[String, headers_value]]) -> void + def bodyless?: () -> bool + def content_type: () -> ContentType + def complete?: () -> bool def json: (?json_options opts) -> untyped @@ -77,6 +84,8 @@ module HTTPX def uri: () -> URI::Generic + def peer_address: () -> ipaddr? + def close: () -> void private diff --git a/test/session_test.rb b/test/session_test.rb index 0099a123..2e8e6bb2 100644 --- a/test/session_test.rb +++ b/test/session_test.rb @@ -128,6 +128,15 @@ class SessionTest < Minitest::Test end end + def test_session_response_peer_address + uri = URI(build_uri("/get")) + response = HTTPX.get(uri) + verify_status(response, 200) + peer_address = response.peer_address + assert peer_address.is_a?(IPAddr) + assert Resolv.getaddresses(uri.host).include?(peer_address.to_s) + end + TestPlugin = Module.new do self::ClassMethods = Module.new do def foo