Merge pull request #119 from kovyrin/kovyrin/expose-response-headers

Expose response HTTP headers to the caller
This commit is contained in:
Arthur Nogueira Neves 2024-07-12 13:47:45 -04:00 коммит произвёл GitHub
Родитель c9c8b5ea9a c2d2d923e8
Коммит a61951f2df
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
5 изменённых файлов: 23 добавлений и 7 удалений

Просмотреть файл

@ -178,7 +178,7 @@ module Twirp
# natively with twirp-ruby. For normal Faraday, this is a noop.
def rpc_response_thennable(resp)
return yield resp unless resp.respond_to?(:then)
resp.then do |resp|
yield resp
end
@ -186,15 +186,18 @@ module Twirp
def rpc_response_to_clientresp(resp, content_type, rpcdef)
if resp.status != 200
return ClientResp.new(error: self.class.error_from_response(resp))
return ClientResp.new(error: self.class.error_from_response(resp), headers: resp.headers)
end
if resp.headers['Content-Type'] != content_type
return ClientResp.new(error: Twirp::Error.internal("Expected response Content-Type #{content_type.inspect} but found #{resp.headers['Content-Type'].inspect}"))
return ClientResp.new(
error: Twirp::Error.internal("Expected response Content-Type #{content_type.inspect} but found #{resp.headers['Content-Type'].inspect}"),
headers: resp.headers
)
end
data = Encoding.decode(resp.body, rpcdef[:output_class], content_type)
return ClientResp.new(data: data, body: resp.body)
return ClientResp.new(data: data, body: resp.body, headers: resp.headers)
end
end

Просмотреть файл

@ -46,11 +46,11 @@ module Twirp
def rpc_response_to_clientresp(resp)
if resp.status != 200
return ClientResp.new(error: self.class.error_from_response(resp))
return ClientResp.new(error: self.class.error_from_response(resp), headers: resp.headers)
end
data = Encoding.decode_json(resp.body)
return ClientResp.new(data: data, body: resp.body)
return ClientResp.new(data: data, body: resp.body, headers: resp.headers)
end
end

Просмотреть файл

@ -16,11 +16,13 @@ module Twirp
attr_accessor :data
attr_accessor :body
attr_accessor :error
attr_accessor :headers
def initialize(data: nil, body: nil, error: nil)
def initialize(data: nil, body: nil, error: nil, headers: nil)
@data = data
@error = error
@body = body
@headers = headers
end
end
end

Просмотреть файл

@ -27,6 +27,7 @@ class ClientJSONTest < Minitest::Test
assert_nil resp.error
refute_nil resp.data
assert_equal 3, resp.data["blah_resp"]
refute_nil resp.headers
end
def test_client_json_thennable
@ -77,6 +78,7 @@ class ClientJSONTest < Minitest::Test
refute_nil resp.error
assert_equal :invalid_argument, resp.error.code
assert_equal "dont like empty", resp.error.msg
refute_nil resp.headers
end
def test_client_bad_json_route
@ -88,6 +90,7 @@ class ClientJSONTest < Minitest::Test
assert_nil resp.data
refute_nil resp.error
assert_equal :bad_route, resp.error.code
refute_nil resp.headers
end

Просмотреть файл

@ -114,6 +114,7 @@ class ClientTest < Minitest::Test
resp = c.make_hat(inches: 666)
assert_nil resp.error
refute_nil resp.data
refute_nil resp.headers
end
def test_proto_serialized_request_body
@ -128,6 +129,7 @@ class ClientTest < Minitest::Test
resp = c.make_hat(Example::Size.new(inches: 666))
assert_nil resp.error
refute_nil resp.data
refute_nil resp.headers
end
def test_proto_twirp_error
@ -139,6 +141,7 @@ class ClientTest < Minitest::Test
refute_nil resp.error
assert_equal :internal, resp.error.code
assert_equal "something went wrong", resp.error.msg
refute_nil resp.headers
end
def test_proto_intermediary_plain_error
@ -153,6 +156,7 @@ class ClientTest < Minitest::Test
assert_equal "true", resp.error.meta[:http_error_from_intermediary]
assert_equal "Response is not JSON", resp.error.meta[:not_a_twirp_error_because]
assert_equal "plain text error from proxy", resp.error.meta[:body]
refute_nil resp.headers
end
def test_proto_redirect_error
@ -166,6 +170,7 @@ class ClientTest < Minitest::Test
assert_equal "Unexpected HTTP Redirect from location=http://rainbow.com", resp.error.msg
assert_equal "true", resp.error.meta[:http_error_from_intermediary]
assert_equal "Redirects not allowed on Twirp requests", resp.error.meta[:not_a_twirp_error_because]
refute_nil resp.headers
end
def test_proto_missing_response_header
@ -176,6 +181,7 @@ class ClientTest < Minitest::Test
refute_nil resp.error
assert_equal :internal, resp.error.code
assert_equal 'Expected response Content-Type "application/protobuf" but found nil', resp.error.msg
refute_nil resp.headers
end
def test_error_with_invalid_code
@ -187,6 +193,7 @@ class ClientTest < Minitest::Test
refute_nil resp.error
assert_equal :internal, resp.error.code
assert_equal "Invalid Twirp error code: unicorn", resp.error.msg
refute_nil resp.headers
end
def test_error_with_no_code
@ -201,6 +208,7 @@ class ClientTest < Minitest::Test
assert_equal "true", resp.error.meta[:http_error_from_intermediary]
assert_equal 'Response is JSON but it has no "code" attribute', resp.error.meta[:not_a_twirp_error_because]
assert_equal '{"msg":"I have no code of honor"}', resp.error.meta[:body]
refute_nil resp.headers
end
# Call .rpc on JSON client