twirp 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/twirp/client.rb +18 -10
- data/lib/twirp/client_json.rb +2 -2
- data/lib/twirp/version.rb +1 -1
- data/test/client_test.rb +33 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18ad030c26be19ad5b9f8ed10be469b2f5387989
|
4
|
+
data.tar.gz: be7fbfb03aa836b315a100800da5906e3aed3b66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a5f2f6dd28b761a5516c55fc0f0a4d5707d0e5cc01564fd4b0dd7b8e520ff22ed580769e92dc9c65e13a6caaf5c7d2f44a7f1870e0bb1ac07e82dc6e372073a
|
7
|
+
data.tar.gz: f17cf86a2661244cf2833d5d8ddd626046093797cc61eae7a4419eeeb88807d921491a50d2c263120abf7cbb6fa720188cb9b6d141aee9af6a45400e68677782
|
data/lib/twirp/client.rb
CHANGED
@@ -36,11 +36,11 @@ module Twirp
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
# Hook for ServiceDSL#rpc to define a new method client.<ruby_method>(input,
|
39
|
+
# Hook for ServiceDSL#rpc to define a new method client.<ruby_method>(input, req_opts).
|
40
40
|
def rpc_define_method(rpcdef)
|
41
41
|
unless method_defined? rpcdef[:ruby_method] # collision with existing rpc method
|
42
|
-
define_method rpcdef[:ruby_method] do |input|
|
43
|
-
rpc(rpcdef[:rpc_method], input)
|
42
|
+
define_method rpcdef[:ruby_method] do |input, req_opts=nil|
|
43
|
+
rpc(rpcdef[:rpc_method], input, req_opts)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -109,11 +109,17 @@ module Twirp
|
|
109
109
|
status >= 300 && status <= 399
|
110
110
|
end
|
111
111
|
|
112
|
-
def make_http_request(conn, service_full_name, rpc_method, content_type, body)
|
112
|
+
def make_http_request(conn, service_full_name, rpc_method, content_type, req_opts, body)
|
113
113
|
conn.post do |r|
|
114
114
|
r.url "#{service_full_name}/#{rpc_method}"
|
115
115
|
r.headers['Content-Type'] = content_type
|
116
116
|
r.body = body
|
117
|
+
|
118
|
+
if req_opts && req_opts[:headers]
|
119
|
+
req_opts[:headers].each do |k, v|
|
120
|
+
r.headers[k] = v
|
121
|
+
end
|
122
|
+
end
|
117
123
|
end
|
118
124
|
end
|
119
125
|
|
@@ -142,25 +148,27 @@ module Twirp
|
|
142
148
|
# or the attributes (Hash) to instantiate it. Returns a ClientResp instance with an instance of
|
143
149
|
# output_class, or a Twirp::Error. The input and output classes are the ones configued with the rpc DSL.
|
144
150
|
# If rpc_method was not defined with the rpc DSL then a response with a bad_route error is returned instead.
|
145
|
-
def rpc(rpc_method, input)
|
151
|
+
def rpc(rpc_method, input, req_opts=nil)
|
146
152
|
rpcdef = self.class.rpcs[rpc_method.to_s]
|
147
153
|
if !rpcdef
|
148
154
|
return ClientResp.new(nil, Twirp::Error.bad_route("rpc not defined on this client"))
|
149
155
|
end
|
150
156
|
|
157
|
+
content_type = (req_opts && req_opts[:headers] && req_opts[:headers]['Content-Type']) || @content_type
|
158
|
+
|
151
159
|
input = rpcdef[:input_class].new(input) if input.is_a? Hash
|
152
|
-
body = Encoding.encode(input, rpcdef[:input_class],
|
160
|
+
body = Encoding.encode(input, rpcdef[:input_class], content_type)
|
153
161
|
|
154
|
-
resp = self.class.make_http_request(@conn, @service_full_name, rpc_method,
|
162
|
+
resp = self.class.make_http_request(@conn, @service_full_name, rpc_method, content_type, req_opts, body)
|
155
163
|
if resp.status != 200
|
156
164
|
return ClientResp.new(nil, self.class.error_from_response(resp))
|
157
165
|
end
|
158
166
|
|
159
|
-
if resp.headers['Content-Type'] !=
|
160
|
-
return ClientResp.new(nil, Twirp::Error.internal("Expected response Content-Type #{
|
167
|
+
if resp.headers['Content-Type'] != content_type
|
168
|
+
return ClientResp.new(nil, Twirp::Error.internal("Expected response Content-Type #{content_type.inspect} but found #{resp.headers['Content-Type'].inspect}"))
|
161
169
|
end
|
162
170
|
|
163
|
-
data = Encoding.decode(resp.body, rpcdef[:output_class],
|
171
|
+
data = Encoding.decode(resp.body, rpcdef[:output_class], content_type)
|
164
172
|
return ClientResp.new(data, nil)
|
165
173
|
end
|
166
174
|
|
data/lib/twirp/client_json.rb
CHANGED
@@ -30,10 +30,10 @@ module Twirp
|
|
30
30
|
|
31
31
|
# This implementation does not use the defined Protobuf messages to serialize/deserialize data;
|
32
32
|
# the request attrs can be anything and the response data is always a plain Hash of attributes.
|
33
|
-
def rpc(rpc_method, attrs={})
|
33
|
+
def rpc(rpc_method, attrs={}, req_opts=nil)
|
34
34
|
body = Encoding.encode_json(attrs)
|
35
35
|
|
36
|
-
resp = self.class.make_http_request(@conn, @service_full_name, rpc_method, Encoding::JSON, body)
|
36
|
+
resp = self.class.make_http_request(@conn, @service_full_name, rpc_method, Encoding::JSON, req_opts, body)
|
37
37
|
if resp.status != 200
|
38
38
|
return ClientResp.new(nil, self.class.error_from_response(resp))
|
39
39
|
end
|
data/lib/twirp/version.rb
CHANGED
data/test/client_test.rb
CHANGED
@@ -72,6 +72,17 @@ class ClientTest < Minitest::Test
|
|
72
72
|
assert_equal "red", resp.data.color
|
73
73
|
end
|
74
74
|
|
75
|
+
def test_proto_send_headers
|
76
|
+
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
|
77
|
+
assert_equal "Bar", req.request_headers['My-Foo-Header']
|
78
|
+
[200, protoheader, proto(Example::Hat, inches: 99, color: "red")]
|
79
|
+
})
|
80
|
+
resp = c.make_hat({}, headers: {"My-Foo-Header": "Bar"})
|
81
|
+
assert_nil resp.error
|
82
|
+
assert_equal 99, resp.data.inches
|
83
|
+
assert_equal "red", resp.data.color
|
84
|
+
end
|
85
|
+
|
75
86
|
def test_proto_serialized_request_body_attrs
|
76
87
|
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
|
77
88
|
size = Example::Size.decode(req.body) # body is valid protobuf
|
@@ -185,6 +196,17 @@ class ClientTest < Minitest::Test
|
|
185
196
|
assert_equal "red", resp.data.color
|
186
197
|
end
|
187
198
|
|
199
|
+
def test_json_send_headers
|
200
|
+
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
|
201
|
+
assert_equal "Bar", req.request_headers['My-Foo-Header']
|
202
|
+
[200, jsonheader, '{"inches": 99, "color": "red"}']
|
203
|
+
}, content_type: "application/json")
|
204
|
+
resp = c.make_hat({}, headers: {"My-Foo-Header": "Bar"})
|
205
|
+
assert_nil resp.error
|
206
|
+
assert_equal 99, resp.data.inches
|
207
|
+
assert_equal "red", resp.data.color
|
208
|
+
end
|
209
|
+
|
188
210
|
def test_json_serialized_request_body_attrs
|
189
211
|
c = Example::HaberdasherClient.new(conn_stub("/example.Haberdasher/MakeHat") {|req|
|
190
212
|
assert_equal "application/json", req.request_headers['Content-Type']
|
@@ -246,6 +268,17 @@ class ClientTest < Minitest::Test
|
|
246
268
|
assert_equal "out", resp.data.foo
|
247
269
|
end
|
248
270
|
|
271
|
+
def test_rpc_send_headers
|
272
|
+
c = FooClient.new(conn_stub("/Foo/Foo") {|req|
|
273
|
+
assert_equal "Bar", req.request_headers['My-Foo-Header']
|
274
|
+
[200, protoheader, proto(Foo, foo: "out")]
|
275
|
+
})
|
276
|
+
resp = c.rpc :Foo, {foo: "in"}, headers: {"My-Foo-Header": "Bar"}
|
277
|
+
assert_nil resp.error
|
278
|
+
refute_nil resp.data
|
279
|
+
assert_equal "out", resp.data.foo
|
280
|
+
end
|
281
|
+
|
249
282
|
def test_rpc_error
|
250
283
|
c = FooClient.new(conn_stub("/Foo/Foo") {|req|
|
251
284
|
[400, {}, json(code: "invalid_argument", msg: "dont like empty")]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twirp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyrus A. Forbes
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-09-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: google-protobuf
|