diff --git a/lib/twirp/client.rb b/lib/twirp/client.rb index e153f55..69229ff 100644 --- a/lib/twirp/client.rb +++ b/lib/twirp/client.rb @@ -178,7 +178,7 @@ def rpc(rpc_method, input, req_opts=nil) # 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 @@ def rpc_response_thennable(resp) 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 diff --git a/lib/twirp/client_json.rb b/lib/twirp/client_json.rb index 5966805..df8e4ce 100644 --- a/lib/twirp/client_json.rb +++ b/lib/twirp/client_json.rb @@ -46,11 +46,11 @@ def rpc(rpc_method, attrs={}, req_opts=nil) 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 diff --git a/lib/twirp/client_resp.rb b/lib/twirp/client_resp.rb index 814f3f9..86620bb 100644 --- a/lib/twirp/client_resp.rb +++ b/lib/twirp/client_resp.rb @@ -16,11 +16,13 @@ class ClientResp 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 diff --git a/test/client_json_test.rb b/test/client_json_test.rb index 166cd81..a0cc845 100644 --- a/test/client_json_test.rb +++ b/test/client_json_test.rb @@ -27,6 +27,7 @@ def test_client_json_success 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 @@ def test_client_json_error 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 @@ def test_client_bad_json_route assert_nil resp.data refute_nil resp.error assert_equal :bad_route, resp.error.code + refute_nil resp.headers end diff --git a/test/client_test.rb b/test/client_test.rb index a017f13..73e5f37 100644 --- a/test/client_test.rb +++ b/test/client_test.rb @@ -114,6 +114,7 @@ def test_proto_serialized_request_body_attrs 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 @@ def test_proto_serialized_request_body 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 @@ def test_proto_twirp_error 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 @@ def test_proto_intermediary_plain_error 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 @@ def test_proto_redirect_error 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 @@ def test_proto_missing_response_header 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 @@ def test_error_with_invalid_code 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 @@ def test_error_with_no_code 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