grpc 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Rakefile +4 -2
- data/bin/{interop/test/cpp/interop/test.rb → grpc_ruby_interop_client} +4 -14
- data/bin/{interop/test/cpp/interop/empty.rb → grpc_ruby_interop_server} +4 -15
- data/bin/interop/interop_client.rb +9 -335
- data/bin/interop/interop_server.rb +9 -153
- data/bin/math_client.rb +3 -3
- data/bin/math_server.rb +18 -1
- data/bin/noproto_server.rb +2 -1
- data/ext/grpc/rb_call.c +82 -15
- data/ext/grpc/rb_channel.c +141 -11
- data/ext/grpc/rb_channel_args.c +2 -1
- data/ext/grpc/rb_completion_queue.c +8 -7
- data/ext/grpc/rb_credentials.c +7 -6
- data/ext/grpc/rb_grpc.c +23 -8
- data/ext/grpc/rb_server.c +31 -45
- data/ext/grpc/rb_server_credentials.c +91 -34
- data/lib/grpc/generic/active_call.rb +7 -7
- data/lib/grpc/generic/bidi_call.rb +17 -12
- data/lib/grpc/generic/client_stub.rb +88 -22
- data/lib/grpc/generic/rpc_server.rb +19 -18
- data/lib/grpc/generic/service.rb +8 -10
- data/lib/grpc/grpc.so +0 -0
- data/lib/grpc/logconfig.rb +26 -10
- data/lib/grpc/version.rb +1 -1
- data/spec/call_spec.rb +9 -1
- data/spec/channel_spec.rb +2 -2
- data/spec/client_server_spec.rb +28 -11
- data/spec/credentials_spec.rb +7 -7
- data/spec/generic/active_call_spec.rb +43 -18
- data/spec/generic/client_stub_spec.rb +21 -1
- data/spec/generic/rpc_server_spec.rb +20 -9
- data/spec/pb/health/checker_spec.rb +232 -0
- data/spec/server_credentials_spec.rb +32 -7
- data/spec/server_spec.rb +8 -4
- data/spec/spec_helper.rb +13 -1
- metadata +31 -51
- data/.gitignore +0 -15
- data/.rspec +0 -4
- data/.rubocop.yml +0 -10
- data/.rubocop_todo.yml +0 -44
- data/CHANGELOG.md +0 -11
- data/Gemfile +0 -4
- data/README.md +0 -84
- data/bin/interop/README.md +0 -8
- data/bin/interop/test/cpp/interop/messages.rb +0 -89
- data/bin/interop/test/cpp/interop/test_services.rb +0 -60
- data/grpc.gemspec +0 -40
data/ext/grpc/rb_channel_args.c
CHANGED
@@ -41,7 +41,8 @@
|
|
41
41
|
|
42
42
|
static rb_data_type_t grpc_rb_channel_args_data_type = {
|
43
43
|
"grpc_channel_args",
|
44
|
-
{GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE, GRPC_RB_MEMSIZE_UNAVAILABLE
|
44
|
+
{GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE, GRPC_RB_MEMSIZE_UNAVAILABLE,
|
45
|
+
{NULL, NULL}},
|
45
46
|
NULL, NULL,
|
46
47
|
RUBY_TYPED_FREE_IMMEDIATELY
|
47
48
|
};
|
@@ -56,7 +56,7 @@ typedef struct next_call_stack {
|
|
56
56
|
static void *grpc_rb_completion_queue_next_no_gil(void *param) {
|
57
57
|
next_call_stack *const next_call = (next_call_stack*)param;
|
58
58
|
next_call->event =
|
59
|
-
grpc_completion_queue_next(next_call->cq, next_call->timeout);
|
59
|
+
grpc_completion_queue_next(next_call->cq, next_call->timeout, NULL);
|
60
60
|
return NULL;
|
61
61
|
}
|
62
62
|
|
@@ -64,7 +64,7 @@ static void *grpc_rb_completion_queue_next_no_gil(void *param) {
|
|
64
64
|
static void *grpc_rb_completion_queue_pluck_no_gil(void *param) {
|
65
65
|
next_call_stack *const next_call = (next_call_stack*)param;
|
66
66
|
next_call->event = grpc_completion_queue_pluck(next_call->cq, next_call->tag,
|
67
|
-
next_call->timeout);
|
67
|
+
next_call->timeout, NULL);
|
68
68
|
return NULL;
|
69
69
|
}
|
70
70
|
|
@@ -82,7 +82,7 @@ static void grpc_rb_completion_queue_shutdown_drain(grpc_completion_queue *cq) {
|
|
82
82
|
next_call.cq = cq;
|
83
83
|
next_call.event.type = GRPC_QUEUE_TIMEOUT;
|
84
84
|
/* TODO: the timeout should be a module level constant that defaults
|
85
|
-
* to gpr_inf_future.
|
85
|
+
* to gpr_inf_future(GPR_CLOCK_REALTIME).
|
86
86
|
*
|
87
87
|
* - at the moment this does not work, it stalls. Using a small timeout like
|
88
88
|
* this one works, and leads to fast test run times; a longer timeout was
|
@@ -91,7 +91,8 @@ static void grpc_rb_completion_queue_shutdown_drain(grpc_completion_queue *cq) {
|
|
91
91
|
* - investigate further, this is probably another example of C-level cleanup
|
92
92
|
* not working consistently in all cases.
|
93
93
|
*/
|
94
|
-
next_call.timeout = gpr_time_add(gpr_now(),
|
94
|
+
next_call.timeout = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
|
95
|
+
gpr_time_from_micros(5e3, GPR_TIMESPAN));
|
95
96
|
do {
|
96
97
|
rb_thread_call_without_gvl(grpc_rb_completion_queue_next_no_gil,
|
97
98
|
(void *)&next_call, NULL, NULL);
|
@@ -118,7 +119,7 @@ static void grpc_rb_completion_queue_destroy(void *p) {
|
|
118
119
|
static rb_data_type_t grpc_rb_completion_queue_data_type = {
|
119
120
|
"grpc_completion_queue",
|
120
121
|
{GRPC_RB_GC_NOT_MARKED, grpc_rb_completion_queue_destroy,
|
121
|
-
GRPC_RB_MEMSIZE_UNAVAILABLE},
|
122
|
+
GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}},
|
122
123
|
NULL, NULL,
|
123
124
|
/* cannot immediately free because grpc_rb_completion_queue_shutdown_drain
|
124
125
|
* calls rb_thread_call_without_gvl. */
|
@@ -127,7 +128,7 @@ static rb_data_type_t grpc_rb_completion_queue_data_type = {
|
|
127
128
|
|
128
129
|
/* Allocates a completion queue. */
|
129
130
|
static VALUE grpc_rb_completion_queue_alloc(VALUE cls) {
|
130
|
-
grpc_completion_queue *cq = grpc_completion_queue_create();
|
131
|
+
grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
|
131
132
|
if (cq == NULL) {
|
132
133
|
rb_raise(rb_eArgError, "could not create a completion queue: not sure why");
|
133
134
|
}
|
@@ -143,7 +144,7 @@ grpc_event grpc_rb_completion_queue_pluck_event(VALUE self, VALUE tag,
|
|
143
144
|
TypedData_Get_Struct(self, grpc_completion_queue,
|
144
145
|
&grpc_rb_completion_queue_data_type, next_call.cq);
|
145
146
|
if (TYPE(timeout) == T_NIL) {
|
146
|
-
next_call.timeout = gpr_inf_future;
|
147
|
+
next_call.timeout = gpr_inf_future(GPR_CLOCK_REALTIME);
|
147
148
|
} else {
|
148
149
|
next_call.timeout = grpc_rb_time_timeval(timeout, /* absolute time*/ 0);
|
149
150
|
}
|
data/ext/grpc/rb_credentials.c
CHANGED
@@ -89,7 +89,7 @@ static void grpc_rb_credentials_mark(void *p) {
|
|
89
89
|
static rb_data_type_t grpc_rb_credentials_data_type = {
|
90
90
|
"grpc_credentials",
|
91
91
|
{grpc_rb_credentials_mark, grpc_rb_credentials_free,
|
92
|
-
GRPC_RB_MEMSIZE_UNAVAILABLE},
|
92
|
+
GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}},
|
93
93
|
NULL,
|
94
94
|
NULL,
|
95
95
|
RUBY_TYPED_FREE_IMMEDIATELY};
|
@@ -154,7 +154,7 @@ static VALUE grpc_rb_default_credentials_create(VALUE cls) {
|
|
154
154
|
Creates the default credential instances. */
|
155
155
|
static VALUE grpc_rb_compute_engine_credentials_create(VALUE cls) {
|
156
156
|
grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials);
|
157
|
-
wrapper->wrapped =
|
157
|
+
wrapper->wrapped = grpc_google_compute_engine_credentials_create(NULL);
|
158
158
|
if (wrapper->wrapped == NULL) {
|
159
159
|
rb_raise(rb_eRuntimeError,
|
160
160
|
"could not create composite engine credentials, not sure why");
|
@@ -181,8 +181,8 @@ static VALUE grpc_rb_composite_credentials_create(VALUE self, VALUE other) {
|
|
181
181
|
TypedData_Get_Struct(other, grpc_rb_credentials,
|
182
182
|
&grpc_rb_credentials_data_type, other_wrapper);
|
183
183
|
wrapper = ALLOC(grpc_rb_credentials);
|
184
|
-
wrapper->wrapped = grpc_composite_credentials_create(
|
185
|
-
|
184
|
+
wrapper->wrapped = grpc_composite_credentials_create(
|
185
|
+
self_wrapper->wrapped, other_wrapper->wrapped, NULL);
|
186
186
|
if (wrapper->wrapped == NULL) {
|
187
187
|
rb_raise(rb_eRuntimeError,
|
188
188
|
"could not create composite credentials, not sure why");
|
@@ -234,12 +234,13 @@ static VALUE grpc_rb_credentials_init(int argc, VALUE *argv, VALUE self) {
|
|
234
234
|
return Qnil;
|
235
235
|
}
|
236
236
|
if (pem_private_key == Qnil && pem_cert_chain == Qnil) {
|
237
|
-
creds =
|
237
|
+
creds =
|
238
|
+
grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs), NULL, NULL);
|
238
239
|
} else {
|
239
240
|
key_cert_pair.private_key = RSTRING_PTR(pem_private_key);
|
240
241
|
key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain);
|
241
242
|
creds = grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs),
|
242
|
-
&key_cert_pair);
|
243
|
+
&key_cert_pair, NULL);
|
243
244
|
}
|
244
245
|
if (creds == NULL) {
|
245
246
|
rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
|
data/ext/grpc/rb_grpc.c
CHANGED
@@ -51,7 +51,8 @@ static VALUE grpc_rb_cTimeVal = Qnil;
|
|
51
51
|
|
52
52
|
static rb_data_type_t grpc_rb_timespec_data_type = {
|
53
53
|
"gpr_timespec",
|
54
|
-
{GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE, GRPC_RB_MEMSIZE_UNAVAILABLE
|
54
|
+
{GRPC_RB_GC_NOT_MARKED, GRPC_RB_GC_DONT_FREE, GRPC_RB_MEMSIZE_UNAVAILABLE,
|
55
|
+
{NULL, NULL}},
|
55
56
|
NULL,
|
56
57
|
NULL,
|
57
58
|
RUBY_TYPED_FREE_IMMEDIATELY};
|
@@ -75,6 +76,7 @@ VALUE grpc_rb_cannot_init(VALUE self) {
|
|
75
76
|
|
76
77
|
/* Init/Clone func that fails by raising an exception. */
|
77
78
|
VALUE grpc_rb_cannot_init_copy(VALUE copy, VALUE self) {
|
79
|
+
(void)self;
|
78
80
|
rb_raise(rb_eTypeError,
|
79
81
|
"initialization of %s only allowed from the gRPC native layer",
|
80
82
|
rb_obj_classname(copy));
|
@@ -98,6 +100,7 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) {
|
|
98
100
|
const char *tstr = interval ? "time interval" : "time";
|
99
101
|
const char *want = " want <secs from epoch>|<Time>|<GRPC::TimeConst.*>";
|
100
102
|
|
103
|
+
t.clock_type = GPR_CLOCK_REALTIME;
|
101
104
|
switch (TYPE(time)) {
|
102
105
|
case T_DATA:
|
103
106
|
if (CLASS_OF(time) == grpc_rb_cTimeVal) {
|
@@ -136,7 +139,7 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) {
|
|
136
139
|
rb_raise(rb_eRangeError, "%f out of Time range",
|
137
140
|
RFLOAT_VALUE(time));
|
138
141
|
}
|
139
|
-
t.tv_nsec = (
|
142
|
+
t.tv_nsec = (int)(d * 1e9 + 0.5);
|
140
143
|
}
|
141
144
|
break;
|
142
145
|
|
@@ -206,10 +209,12 @@ static ID id_to_s;
|
|
206
209
|
/* Converts a wrapped time constant to a standard time. */
|
207
210
|
static VALUE grpc_rb_time_val_to_time(VALUE self) {
|
208
211
|
gpr_timespec *time_const = NULL;
|
212
|
+
gpr_timespec real_time;
|
209
213
|
TypedData_Get_Struct(self, gpr_timespec, &grpc_rb_timespec_data_type,
|
210
214
|
time_const);
|
211
|
-
|
212
|
-
|
215
|
+
real_time = gpr_convert_clock_type(*time_const, GPR_CLOCK_REALTIME);
|
216
|
+
return rb_funcall(rb_cTime, id_at, 2, INT2NUM(real_time.tv_sec),
|
217
|
+
INT2NUM(real_time.tv_nsec));
|
213
218
|
}
|
214
219
|
|
215
220
|
/* Invokes inspect on the ctime version of the time val. */
|
@@ -222,24 +227,31 @@ static VALUE grpc_rb_time_val_to_s(VALUE self) {
|
|
222
227
|
return rb_funcall(grpc_rb_time_val_to_time(self), id_to_s, 0);
|
223
228
|
}
|
224
229
|
|
230
|
+
static gpr_timespec zero_realtime;
|
231
|
+
static gpr_timespec inf_future_realtime;
|
232
|
+
static gpr_timespec inf_past_realtime;
|
233
|
+
|
225
234
|
/* Adds a module with constants that map to gpr's static timeval structs. */
|
226
235
|
static void Init_grpc_time_consts() {
|
227
236
|
VALUE grpc_rb_mTimeConsts =
|
228
237
|
rb_define_module_under(grpc_rb_mGrpcCore, "TimeConsts");
|
229
238
|
grpc_rb_cTimeVal =
|
230
239
|
rb_define_class_under(grpc_rb_mGrpcCore, "TimeSpec", rb_cObject);
|
240
|
+
zero_realtime = gpr_time_0(GPR_CLOCK_REALTIME);
|
241
|
+
inf_future_realtime = gpr_inf_future(GPR_CLOCK_REALTIME);
|
242
|
+
inf_past_realtime = gpr_inf_past(GPR_CLOCK_REALTIME);
|
231
243
|
rb_define_const(
|
232
244
|
grpc_rb_mTimeConsts, "ZERO",
|
233
245
|
TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
|
234
|
-
(void *)&
|
246
|
+
(void *)&zero_realtime));
|
235
247
|
rb_define_const(
|
236
248
|
grpc_rb_mTimeConsts, "INFINITE_FUTURE",
|
237
249
|
TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
|
238
|
-
(void *)&
|
250
|
+
(void *)&inf_future_realtime));
|
239
251
|
rb_define_const(
|
240
252
|
grpc_rb_mTimeConsts, "INFINITE_PAST",
|
241
253
|
TypedData_Wrap_Struct(grpc_rb_cTimeVal, &grpc_rb_timespec_data_type,
|
242
|
-
(void *)&
|
254
|
+
(void *)&inf_past_realtime));
|
243
255
|
rb_define_method(grpc_rb_cTimeVal, "to_time", grpc_rb_time_val_to_time, 0);
|
244
256
|
rb_define_method(grpc_rb_cTimeVal, "inspect", grpc_rb_time_val_inspect, 0);
|
245
257
|
rb_define_method(grpc_rb_cTimeVal, "to_s", grpc_rb_time_val_to_s, 0);
|
@@ -250,7 +262,10 @@ static void Init_grpc_time_consts() {
|
|
250
262
|
id_tv_nsec = rb_intern("tv_nsec");
|
251
263
|
}
|
252
264
|
|
253
|
-
static void grpc_rb_shutdown(ruby_vm_t *vm) {
|
265
|
+
static void grpc_rb_shutdown(ruby_vm_t *vm) {
|
266
|
+
(void)vm;
|
267
|
+
grpc_shutdown();
|
268
|
+
}
|
254
269
|
|
255
270
|
/* Initialize the GRPC module structs */
|
256
271
|
|
data/ext/grpc/rb_server.c
CHANGED
@@ -49,6 +49,9 @@ static VALUE grpc_rb_cServer = Qnil;
|
|
49
49
|
/* id_at is the constructor method of the ruby standard Time class. */
|
50
50
|
static ID id_at;
|
51
51
|
|
52
|
+
/* id_insecure_server is used to indicate that a server is insecure */
|
53
|
+
static VALUE id_insecure_server;
|
54
|
+
|
52
55
|
/* grpc_rb_server wraps a grpc_server. It provides a peer ruby object,
|
53
56
|
'mark' to minimize copying when a server is created from ruby. */
|
54
57
|
typedef struct grpc_rb_server {
|
@@ -94,7 +97,8 @@ static void grpc_rb_server_mark(void *p) {
|
|
94
97
|
|
95
98
|
static const rb_data_type_t grpc_rb_server_data_type = {
|
96
99
|
"grpc_server",
|
97
|
-
{grpc_rb_server_mark, grpc_rb_server_free, GRPC_RB_MEMSIZE_UNAVAILABLE
|
100
|
+
{grpc_rb_server_mark, grpc_rb_server_free, GRPC_RB_MEMSIZE_UNAVAILABLE,
|
101
|
+
{NULL, NULL}},
|
98
102
|
NULL,
|
99
103
|
NULL,
|
100
104
|
/* It is unsafe to specify RUBY_TYPED_FREE_IMMEDIATELY because the free function would block
|
@@ -127,7 +131,7 @@ static VALUE grpc_rb_server_init(VALUE self, VALUE cqueue, VALUE channel_args) {
|
|
127
131
|
TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type,
|
128
132
|
wrapper);
|
129
133
|
grpc_rb_hash_convert_to_channel_args(channel_args, &args);
|
130
|
-
srv = grpc_server_create(&args);
|
134
|
+
srv = grpc_server_create(&args, NULL);
|
131
135
|
|
132
136
|
if (args.args != NULL) {
|
133
137
|
xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */
|
@@ -135,7 +139,7 @@ static VALUE grpc_rb_server_init(VALUE self, VALUE cqueue, VALUE channel_args) {
|
|
135
139
|
if (srv == NULL) {
|
136
140
|
rb_raise(rb_eRuntimeError, "could not create a gRPC server, not sure why");
|
137
141
|
}
|
138
|
-
grpc_server_register_completion_queue(srv, cq);
|
142
|
+
grpc_server_register_completion_queue(srv, cq, NULL);
|
139
143
|
wrapper->wrapped = srv;
|
140
144
|
|
141
145
|
/* Add the cq as the server's mark object. This ensures the ruby cq can't be
|
@@ -212,6 +216,7 @@ static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue,
|
|
212
216
|
grpc_call_error err;
|
213
217
|
request_call_stack st;
|
214
218
|
VALUE result;
|
219
|
+
gpr_timespec deadline;
|
215
220
|
TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
|
216
221
|
if (s->wrapped == NULL) {
|
217
222
|
rb_raise(rb_eRuntimeError, "destroyed!");
|
@@ -232,6 +237,7 @@ static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue,
|
|
232
237
|
grpc_call_error_detail_of(err), err);
|
233
238
|
return Qnil;
|
234
239
|
}
|
240
|
+
|
235
241
|
ev = grpc_rb_completion_queue_pluck_event(cqueue, tag_new, timeout);
|
236
242
|
if (ev.type == GRPC_QUEUE_TIMEOUT) {
|
237
243
|
grpc_request_call_stack_cleanup(&st);
|
@@ -244,15 +250,13 @@ static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue,
|
|
244
250
|
}
|
245
251
|
|
246
252
|
/* build the NewServerRpc struct result */
|
253
|
+
deadline = gpr_convert_clock_type(st.details.deadline, GPR_CLOCK_REALTIME);
|
247
254
|
result = rb_struct_new(
|
248
|
-
grpc_rb_sNewServerRpc,
|
249
|
-
rb_str_new2(st.details.method),
|
255
|
+
grpc_rb_sNewServerRpc, rb_str_new2(st.details.method),
|
250
256
|
rb_str_new2(st.details.host),
|
251
|
-
rb_funcall(rb_cTime, id_at, 2, INT2NUM(
|
252
|
-
INT2NUM(
|
253
|
-
grpc_rb_md_ary_to_h(&st.md_ary),
|
254
|
-
grpc_rb_wrap_call(call),
|
255
|
-
NULL);
|
257
|
+
rb_funcall(rb_cTime, id_at, 2, INT2NUM(deadline.tv_sec),
|
258
|
+
INT2NUM(deadline.tv_nsec)),
|
259
|
+
grpc_rb_md_ary_to_h(&st.md_ary), grpc_rb_wrap_call(call), NULL);
|
256
260
|
grpc_request_call_stack_cleanup(&st);
|
257
261
|
return result;
|
258
262
|
}
|
@@ -298,43 +302,22 @@ static VALUE grpc_rb_server_destroy(int argc, VALUE *argv, VALUE self) {
|
|
298
302
|
if (s->wrapped != NULL) {
|
299
303
|
grpc_server_shutdown_and_notify(s->wrapped, cq, NULL);
|
300
304
|
ev = grpc_rb_completion_queue_pluck_event(cqueue, Qnil, timeout);
|
301
|
-
|
302
305
|
if (!ev.success) {
|
303
|
-
rb_warn("server shutdown failed,
|
304
|
-
|
305
|
-
|
306
|
-
TODO: renable the rb_raise below.
|
307
|
-
|
308
|
-
At the moment if the timeout is INFINITE_FUTURE as recommended, the
|
309
|
-
pluck blocks forever, even though
|
310
|
-
|
311
|
-
the outstanding server_request_calls correctly fail on the other
|
312
|
-
thread that they are running on.
|
313
|
-
|
314
|
-
it's almost as if calls that fail on the other thread do not get
|
315
|
-
cleaned up by shutdown request, even though it caused htem to
|
316
|
-
terminate.
|
317
|
-
|
318
|
-
rb_raise(rb_eRuntimeError, "grpc server shutdown did not succeed");
|
319
|
-
return Qnil;
|
320
|
-
|
321
|
-
The workaround is just to use a timeout and return without really
|
322
|
-
shutting down the server, and rely on the grpc core garbage collection
|
323
|
-
it down as a 'LEAKED OBJECT'.
|
324
|
-
|
325
|
-
*/
|
306
|
+
rb_warn("server shutdown failed, cancelling the calls, objects may leak");
|
307
|
+
grpc_server_cancel_all_calls(s->wrapped);
|
308
|
+
return Qfalse;
|
326
309
|
}
|
327
310
|
grpc_server_destroy(s->wrapped);
|
328
311
|
s->wrapped = NULL;
|
329
312
|
}
|
330
|
-
return
|
313
|
+
return Qtrue;
|
331
314
|
}
|
332
315
|
|
333
316
|
/*
|
334
317
|
call-seq:
|
335
318
|
// insecure port
|
336
319
|
insecure_server = Server.new(cq, {'arg1': 'value1'})
|
337
|
-
insecure_server.add_http2_port('mydomain:50051')
|
320
|
+
insecure_server.add_http2_port('mydomain:50051', :this_port_is_insecure)
|
338
321
|
|
339
322
|
// secure port
|
340
323
|
server_creds = ...
|
@@ -342,22 +325,24 @@ static VALUE grpc_rb_server_destroy(int argc, VALUE *argv, VALUE self) {
|
|
342
325
|
secure_server.add_http_port('mydomain:50051', server_creds)
|
343
326
|
|
344
327
|
Adds a http2 port to server */
|
345
|
-
static VALUE grpc_rb_server_add_http2_port(
|
346
|
-
|
347
|
-
VALUE rb_creds = Qnil;
|
328
|
+
static VALUE grpc_rb_server_add_http2_port(VALUE self, VALUE port,
|
329
|
+
VALUE rb_creds) {
|
348
330
|
grpc_rb_server *s = NULL;
|
349
331
|
grpc_server_credentials *creds = NULL;
|
350
332
|
int recvd_port = 0;
|
351
333
|
|
352
|
-
/* "11" == 1 mandatory args, 1 (rb_creds) is optional */
|
353
|
-
rb_scan_args(argc, argv, "11", &port, &rb_creds);
|
354
|
-
|
355
334
|
TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
|
356
335
|
if (s->wrapped == NULL) {
|
357
336
|
rb_raise(rb_eRuntimeError, "destroyed!");
|
358
337
|
return Qnil;
|
359
|
-
} else if (rb_creds ==
|
360
|
-
|
338
|
+
} else if (TYPE(rb_creds) == T_SYMBOL) {
|
339
|
+
if (id_insecure_server != SYM2ID(rb_creds)) {
|
340
|
+
rb_raise(rb_eTypeError,
|
341
|
+
"bad creds symbol, want :this_port_is_insecure");
|
342
|
+
return Qnil;
|
343
|
+
}
|
344
|
+
recvd_port =
|
345
|
+
grpc_server_add_insecure_http2_port(s->wrapped, StringValueCStr(port));
|
361
346
|
if (recvd_port == 0) {
|
362
347
|
rb_raise(rb_eRuntimeError,
|
363
348
|
"could not add port %s to server, not sure why",
|
@@ -397,8 +382,9 @@ void Init_grpc_server() {
|
|
397
382
|
rb_define_alias(grpc_rb_cServer, "close", "destroy");
|
398
383
|
rb_define_method(grpc_rb_cServer, "add_http2_port",
|
399
384
|
grpc_rb_server_add_http2_port,
|
400
|
-
|
385
|
+
2);
|
401
386
|
id_at = rb_intern("at");
|
387
|
+
id_insecure_server = rb_intern("this_port_is_insecure");
|
402
388
|
}
|
403
389
|
|
404
390
|
/* Gets the wrapped server from the ruby wrapper */
|
@@ -89,7 +89,7 @@ static void grpc_rb_server_credentials_mark(void *p) {
|
|
89
89
|
static const rb_data_type_t grpc_rb_server_credentials_data_type = {
|
90
90
|
"grpc_server_credentials",
|
91
91
|
{grpc_rb_server_credentials_mark, grpc_rb_server_credentials_free,
|
92
|
-
GRPC_RB_MEMSIZE_UNAVAILABLE},
|
92
|
+
GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}},
|
93
93
|
NULL, NULL,
|
94
94
|
RUBY_TYPED_FREE_IMMEDIATELY
|
95
95
|
};
|
@@ -135,61 +135,117 @@ static VALUE grpc_rb_server_credentials_init_copy(VALUE copy, VALUE orig) {
|
|
135
135
|
return copy;
|
136
136
|
}
|
137
137
|
|
138
|
-
/* The attribute used on the mark object to
|
138
|
+
/* The attribute used on the mark object to preserve the pem_root_certs. */
|
139
139
|
static ID id_pem_root_certs;
|
140
140
|
|
141
|
-
/* The attribute used on the mark object to
|
142
|
-
static ID
|
141
|
+
/* The attribute used on the mark object to preserve the pem_key_certs */
|
142
|
+
static ID id_pem_key_certs;
|
143
143
|
|
144
|
-
/* The
|
145
|
-
static
|
144
|
+
/* The key used to access the pem cert in a key_cert pair hash */
|
145
|
+
static VALUE sym_cert_chain;
|
146
|
+
|
147
|
+
/* The key used to access the pem private key in a key_cert pair hash */
|
148
|
+
static VALUE sym_private_key;
|
146
149
|
|
147
150
|
/*
|
148
151
|
call-seq:
|
149
|
-
creds = ServerCredentials.new(
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
152
|
+
creds = ServerCredentials.new(nil,
|
153
|
+
[{private_key: <pem_private_key1>,
|
154
|
+
{cert_chain: <pem_cert_chain1>}],
|
155
|
+
force_client_auth)
|
156
|
+
creds = ServerCredentials.new(pem_root_certs,
|
157
|
+
[{private_key: <pem_private_key1>,
|
158
|
+
{cert_chain: <pem_cert_chain1>}],
|
159
|
+
force_client_auth)
|
160
|
+
|
161
|
+
pem_root_certs: (optional) PEM encoding of the server root certificate
|
162
|
+
pem_private_key: (required) PEM encoding of the server's private keys
|
163
|
+
force_client_auth: indicatees
|
157
164
|
|
158
165
|
Initializes ServerCredential instances. */
|
159
166
|
static VALUE grpc_rb_server_credentials_init(VALUE self, VALUE pem_root_certs,
|
160
|
-
VALUE
|
161
|
-
VALUE
|
162
|
-
/* TODO support multiple key cert pairs in the ruby API. */
|
167
|
+
VALUE pem_key_certs,
|
168
|
+
VALUE force_client_auth) {
|
163
169
|
grpc_rb_server_credentials *wrapper = NULL;
|
164
170
|
grpc_server_credentials *creds = NULL;
|
165
|
-
grpc_ssl_pem_key_cert_pair
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
+
grpc_ssl_pem_key_cert_pair *key_cert_pairs = NULL;
|
172
|
+
VALUE cert = Qnil;
|
173
|
+
VALUE key = Qnil;
|
174
|
+
VALUE key_cert = Qnil;
|
175
|
+
int auth_client = 0;
|
176
|
+
int num_key_certs = 0;
|
177
|
+
int i;
|
178
|
+
|
179
|
+
if (NIL_P(force_client_auth) ||
|
180
|
+
!(force_client_auth == Qfalse || force_client_auth == Qtrue)) {
|
181
|
+
rb_raise(rb_eTypeError,
|
182
|
+
"bad force_client_auth: got:<%s> want: <True|False|nil>",
|
183
|
+
rb_obj_classname(force_client_auth));
|
171
184
|
return Qnil;
|
172
|
-
}
|
173
|
-
|
174
|
-
|
185
|
+
}
|
186
|
+
if (NIL_P(pem_key_certs) || TYPE(pem_key_certs) != T_ARRAY) {
|
187
|
+
rb_raise(rb_eTypeError, "bad pem_key_certs: got:<%s> want: <Array>",
|
188
|
+
rb_obj_classname(pem_key_certs));
|
189
|
+
return Qnil;
|
190
|
+
}
|
191
|
+
num_key_certs = RARRAY_LEN(pem_key_certs);
|
192
|
+
if (num_key_certs == 0) {
|
193
|
+
rb_raise(rb_eTypeError, "bad pem_key_certs: it had no elements");
|
175
194
|
return Qnil;
|
176
195
|
}
|
177
|
-
|
178
|
-
|
196
|
+
for (i = 0; i < num_key_certs; i++) {
|
197
|
+
key_cert = rb_ary_entry(pem_key_certs, i);
|
198
|
+
if (key_cert == Qnil) {
|
199
|
+
rb_raise(rb_eTypeError,
|
200
|
+
"could not create a server credential: nil key_cert");
|
201
|
+
return Qnil;
|
202
|
+
} else if (TYPE(key_cert) != T_HASH) {
|
203
|
+
rb_raise(rb_eTypeError,
|
204
|
+
"could not create a server credential: want <Hash>, got <%s>",
|
205
|
+
rb_obj_classname(key_cert));
|
206
|
+
return Qnil;
|
207
|
+
} else if (rb_hash_aref(key_cert, sym_private_key) == Qnil) {
|
208
|
+
rb_raise(rb_eTypeError,
|
209
|
+
"could not create a server credential: want nil private key");
|
210
|
+
return Qnil;
|
211
|
+
} else if (rb_hash_aref(key_cert, sym_cert_chain) == Qnil) {
|
212
|
+
rb_raise(rb_eTypeError,
|
213
|
+
"could not create a server credential: want nil cert chain");
|
214
|
+
return Qnil;
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
218
|
+
auth_client = TYPE(force_client_auth) == T_TRUE;
|
219
|
+
key_cert_pairs = ALLOC_N(grpc_ssl_pem_key_cert_pair, num_key_certs);
|
220
|
+
for (i = 0; i < num_key_certs; i++) {
|
221
|
+
key_cert = rb_ary_entry(pem_key_certs, i);
|
222
|
+
key = rb_hash_aref(key_cert, sym_private_key);
|
223
|
+
cert = rb_hash_aref(key_cert, sym_cert_chain);
|
224
|
+
key_cert_pairs[i].private_key = RSTRING_PTR(key);
|
225
|
+
key_cert_pairs[i].cert_chain = RSTRING_PTR(cert);
|
226
|
+
}
|
227
|
+
|
228
|
+
TypedData_Get_Struct(self, grpc_rb_server_credentials,
|
229
|
+
&grpc_rb_server_credentials_data_type, wrapper);
|
230
|
+
|
179
231
|
if (pem_root_certs == Qnil) {
|
180
|
-
creds = grpc_ssl_server_credentials_create(NULL,
|
232
|
+
creds = grpc_ssl_server_credentials_create(NULL, key_cert_pairs,
|
233
|
+
num_key_certs,
|
234
|
+
auth_client, NULL);
|
181
235
|
} else {
|
182
236
|
creds = grpc_ssl_server_credentials_create(RSTRING_PTR(pem_root_certs),
|
183
|
-
|
237
|
+
key_cert_pairs, num_key_certs,
|
238
|
+
auth_client, NULL);
|
184
239
|
}
|
240
|
+
xfree(key_cert_pairs);
|
185
241
|
if (creds == NULL) {
|
186
242
|
rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
|
243
|
+
return Qnil;
|
187
244
|
}
|
188
245
|
wrapper->wrapped = creds;
|
189
246
|
|
190
247
|
/* Add the input objects as hidden fields to preserve them. */
|
191
|
-
rb_ivar_set(self,
|
192
|
-
rb_ivar_set(self, id_pem_private_key, pem_private_key);
|
248
|
+
rb_ivar_set(self, id_pem_key_certs, pem_key_certs);
|
193
249
|
rb_ivar_set(self, id_pem_root_certs, pem_root_certs);
|
194
250
|
|
195
251
|
return self;
|
@@ -209,9 +265,10 @@ void Init_grpc_server_credentials() {
|
|
209
265
|
rb_define_method(grpc_rb_cServerCredentials, "initialize_copy",
|
210
266
|
grpc_rb_server_credentials_init_copy, 1);
|
211
267
|
|
212
|
-
|
213
|
-
id_pem_private_key = rb_intern("__pem_private_key");
|
268
|
+
id_pem_key_certs = rb_intern("__pem_key_certs");
|
214
269
|
id_pem_root_certs = rb_intern("__pem_root_certs");
|
270
|
+
sym_private_key = ID2SYM(rb_intern("private_key"));
|
271
|
+
sym_cert_chain = ID2SYM(rb_intern("cert_chain"));
|
215
272
|
}
|
216
273
|
|
217
274
|
/* Gets the wrapped grpc_server_credentials from the ruby wrapper */
|