Compare commits

...

6 Commits

Author SHA1 Message Date
HoneyryderChuck
6437b4b5fb bump version to 1.1.4 2023-11-20 10:16:04 +00:00
HoneyryderChuck
ce5c2c2f21 Merge branch 'master' of gitlab.com:os85/httpx 2023-11-20 10:09:53 +00:00
HoneyryderChuck
4eb1ccb532 Merge branch 'issue-278' into 'master'
stream plugin fix: do not preempt request

Closes #278

See merge request os85/httpx!304
2023-11-20 10:03:48 +00:00
HoneyryderChuck
b0e1e2e837 datadog: use Gem::Version for comparisons 2023-11-20 10:02:43 +00:00
HoneyryderChuck
ee66b7e5cc stream plugin fix: do not preempt request
while stream requests are lazy, they were being nonetheless enqueued, before any function would be called. this was not great behaviour, as they could perhaps never been called, it also interfered with how other plugins inferred finished responses, such as the webmock adapter and follow_redirects. Another flaw in the grpc plugin was fixed as a result, given that bidirectional streams were actually being buffered
2023-11-19 23:58:27 +00:00
HoneyryderChuck
b82e57c281 ad test for integration of webmock with follow_redirects and stream plugins 2023-11-19 22:43:30 +00:00
10 changed files with 47 additions and 29 deletions

View File

@ -1,4 +1,4 @@
# 1.1.2 # 1.1.3
## improvements ## improvements

View File

@ -0,0 +1,6 @@
# 1.1.4
## bug reports
* datadog adapter: use `Gem::Version` to invoke the correct configuration API.
* stream plugin: do not preempt request enqueuing (this was making integration with the `:follow_redirects` plugin fail when set up with `webmock`).

View File

@ -214,6 +214,17 @@ class WebmockTest < Minitest::Test
assert_not_requested(:get, "http://#{httpbin}") assert_not_requested(:get, "http://#{httpbin}")
end end
def test_webmock_follow_redirects_with_stream_plugin
session = HTTPX.plugin(:follow_redirects).plugin(:stream)
redirect_url = "#{MOCK_URL_HTTP}/redirect"
initial_request = stub_request(:get, MOCK_URL_HTTP).to_return(status: 302, headers: { location: redirect_url })
redirect_request = stub_request(:get, redirect_url)
session.get(MOCK_URL_HTTP, stream: true).each.to_a.join
assert_requested(initial_request)
assert_requested(redirect_request)
end
private private
def assert_raise_with_message(e, message, &block) def assert_raise_with_message(e, message, &block)

View File

@ -126,7 +126,7 @@ module Datadog::Tracing
option :distributed_tracing, default: true option :distributed_tracing, default: true
option :split_by_domain, default: false option :split_by_domain, default: false
if DDTrace::VERSION::STRING >= "1.13.0" if Gem::Version.new(DDTrace::VERSION::STRING) >= Gem::Version.new("1.13.0")
option :enabled do |o| option :enabled do |o|
o.type :bool o.type :bool
o.env "DD_TRACE_HTTPX_ENABLED" o.env "DD_TRACE_HTTPX_ENABLED"
@ -182,12 +182,12 @@ module Datadog::Tracing
option :distributed_tracing, default: true option :distributed_tracing, default: true
if DDTrace::VERSION::STRING >= "1.15.0" if Gem::Version.new(DDTrace::VERSION::STRING) >= Gem::Version.new("1.15.0")
option :error_handler do |o| option :error_handler do |o|
o.type :proc o.type :proc
o.default_proc(&DEFAULT_ERROR_HANDLER) o.default_proc(&DEFAULT_ERROR_HANDLER)
end end
elsif DDTrace::VERSION::STRING >= "1.13.0" elsif Gem::Version.new(DDTrace::VERSION::STRING) >= Gem::Version.new("1.13.0")
option :error_handler do |o| option :error_handler do |o|
o.type :proc o.type :proc
o.experimental_default_proc(&DEFAULT_ERROR_HANDLER) o.experimental_default_proc(&DEFAULT_ERROR_HANDLER)

View File

@ -215,7 +215,7 @@ module HTTPX
**opts) **opts)
grpc_request = build_grpc_request(rpc_method, input, deadline: deadline, metadata: metadata, **opts) grpc_request = build_grpc_request(rpc_method, input, deadline: deadline, metadata: metadata, **opts)
response = request(grpc_request, **opts) response = request(grpc_request, **opts)
response.raise_for_status response.raise_for_status unless opts[:stream]
GRPC::Call.new(response) GRPC::Call.new(response)
end end

View File

@ -36,7 +36,6 @@ module HTTPX
class Inflater class Inflater
def initialize(response) def initialize(response)
@encodings = response.headers.get("grpc-encoding")
@response = response @response = response
end end
@ -49,7 +48,7 @@ module HTTPX
encoded_data = message.byteslice(5..size + 5 - 1) encoded_data = message.byteslice(5..size + 5 - 1)
if compressed == 1 if compressed == 1
@encodings.reverse_each do |encoding| grpc_encodings.reverse_each do |encoding|
decoder = @response.body.class.initialize_inflater_by_encoding(encoding, @response, bytesize: encoded_data.bytesize) decoder = @response.body.class.initialize_inflater_by_encoding(encoding, @response, bytesize: encoded_data.bytesize)
encoded_data = decoder.call(encoded_data) encoded_data = decoder.call(encoded_data)
@ -68,6 +67,12 @@ module HTTPX
data data
end end
private
def grpc_encodings
@grpc_encodings ||= @response.headers.get("grpc-encoding")
end
end end
def self.encode(*args, **kwargs) def self.encode(*args, **kwargs)

View File

@ -2,10 +2,9 @@
module HTTPX module HTTPX
class StreamResponse class StreamResponse
def initialize(request, session, connections) def initialize(request, session)
@request = request @request = request
@session = session @session = session
@connections = connections
end end
def each(&block) def each(&block)
@ -16,19 +15,9 @@ module HTTPX
begin begin
@on_chunk = block @on_chunk = block
if @request.response
# if we've already started collecting the payload, yield it first
# before proceeding
body = @request.response.body
body.each do |chunk|
on_chunk(chunk)
end
end
response.raise_for_status response.raise_for_status
response.close
ensure ensure
response.close if @response
@on_chunk = nil @on_chunk = nil
end end
end end
@ -69,9 +58,9 @@ module HTTPX
private private
def response def response
@session.__send__(:receive_requests, [@request], @connections) until @request.response @response ||= begin
@request.response || @session.request(@request)
@request.response end
end end
def respond_to_missing?(meth, *args) def respond_to_missing?(meth, *args)
@ -105,9 +94,7 @@ module HTTPX
request = requests.first request = requests.first
connections = _send_requests(requests) StreamResponse.new(request, self)
StreamResponse.new(request, self, connections)
end end
end end

View File

@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
module HTTPX module HTTPX
VERSION = "1.1.3" VERSION = "1.1.4"
end end

View File

@ -21,11 +21,15 @@ module HTTPX
class Inflater class Inflater
@response: Response @response: Response
@encodings: Array[String] @grpc_encodings: Array[String]
def initialize: (Response | StreamResponse response) -> void def initialize: (Response | StreamResponse response) -> void
def call: (String message) ?{ (String) -> void } -> String def call: (String message) ?{ (String) -> void } -> String
private
def grpc_encodings: () -> Array[String]
end end
end end

View File

@ -2,6 +2,10 @@ module HTTPX
class StreamResponse class StreamResponse
include _ToS include _ToS
@request: Request & RequestMethods
@session: sessionStream
@on_chunk: ^(String) -> void | nil
def each: () { (String) -> void } -> void def each: () { (String) -> void } -> void
| () -> Enumerable[String] | () -> Enumerable[String]
@ -10,10 +14,11 @@ module HTTPX
def on_chunk: (string) -> void def on_chunk: (string) -> void
def initialize: (Request, Session) -> void
private private
def response: () -> response def response: () -> response
def initialize: (Request, Session, Array[Connection]) -> untyped
end end
module Plugins module Plugins