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
This commit is contained in:
HoneyryderChuck 2023-11-19 23:58:27 +00:00
parent b82e57c281
commit ee66b7e5cc
5 changed files with 25 additions and 24 deletions

View File

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

View File

@ -36,7 +36,6 @@ module HTTPX
class Inflater
def initialize(response)
@encodings = response.headers.get("grpc-encoding")
@response = response
end
@ -49,7 +48,7 @@ module HTTPX
encoded_data = message.byteslice(5..size + 5 - 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)
encoded_data = decoder.call(encoded_data)
@ -68,6 +67,12 @@ module HTTPX
data
end
private
def grpc_encodings
@grpc_encodings ||= @response.headers.get("grpc-encoding")
end
end
def self.encode(*args, **kwargs)

View File

@ -2,10 +2,9 @@
module HTTPX
class StreamResponse
def initialize(request, session, connections)
def initialize(request, session)
@request = request
@session = session
@connections = connections
end
def each(&block)
@ -16,19 +15,9 @@ module HTTPX
begin
@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.close
ensure
response.close if @response
@on_chunk = nil
end
end
@ -69,9 +58,9 @@ module HTTPX
private
def response
@session.__send__(:receive_requests, [@request], @connections) until @request.response
@request.response
@response ||= begin
@request.response || @session.request(@request)
end
end
def respond_to_missing?(meth, *args)
@ -105,9 +94,7 @@ module HTTPX
request = requests.first
connections = _send_requests(requests)
StreamResponse.new(request, self, connections)
StreamResponse.new(request, self)
end
end

View File

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

View File

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