grpc 0.5.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.

Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +10 -0
  5. data/.rubocop_todo.yml +52 -0
  6. data/Gemfile +4 -0
  7. data/README.md +82 -0
  8. data/Rakefile +54 -0
  9. data/bin/apis/google/protobuf/empty.rb +44 -0
  10. data/bin/apis/pubsub_demo.rb +267 -0
  11. data/bin/apis/tech/pubsub/proto/pubsub.rb +174 -0
  12. data/bin/apis/tech/pubsub/proto/pubsub_services.rb +103 -0
  13. data/bin/interop/README.md +8 -0
  14. data/bin/interop/interop_client.rb +334 -0
  15. data/bin/interop/interop_server.rb +192 -0
  16. data/bin/interop/test/cpp/interop/empty.rb +44 -0
  17. data/bin/interop/test/cpp/interop/messages.rb +89 -0
  18. data/bin/interop/test/cpp/interop/test.rb +43 -0
  19. data/bin/interop/test/cpp/interop/test_services.rb +60 -0
  20. data/bin/math.proto +80 -0
  21. data/bin/math.rb +61 -0
  22. data/bin/math_client.rb +147 -0
  23. data/bin/math_server.rb +190 -0
  24. data/bin/math_services.rb +56 -0
  25. data/bin/noproto_client.rb +108 -0
  26. data/bin/noproto_server.rb +112 -0
  27. data/ext/grpc/extconf.rb +76 -0
  28. data/ext/grpc/rb_byte_buffer.c +241 -0
  29. data/ext/grpc/rb_byte_buffer.h +54 -0
  30. data/ext/grpc/rb_call.c +569 -0
  31. data/ext/grpc/rb_call.h +59 -0
  32. data/ext/grpc/rb_channel.c +264 -0
  33. data/ext/grpc/rb_channel.h +49 -0
  34. data/ext/grpc/rb_channel_args.c +154 -0
  35. data/ext/grpc/rb_channel_args.h +52 -0
  36. data/ext/grpc/rb_completion_queue.c +185 -0
  37. data/ext/grpc/rb_completion_queue.h +50 -0
  38. data/ext/grpc/rb_credentials.c +281 -0
  39. data/ext/grpc/rb_credentials.h +50 -0
  40. data/ext/grpc/rb_event.c +361 -0
  41. data/ext/grpc/rb_event.h +53 -0
  42. data/ext/grpc/rb_grpc.c +274 -0
  43. data/ext/grpc/rb_grpc.h +74 -0
  44. data/ext/grpc/rb_metadata.c +215 -0
  45. data/ext/grpc/rb_metadata.h +53 -0
  46. data/ext/grpc/rb_server.c +278 -0
  47. data/ext/grpc/rb_server.h +50 -0
  48. data/ext/grpc/rb_server_credentials.c +210 -0
  49. data/ext/grpc/rb_server_credentials.h +50 -0
  50. data/grpc.gemspec +41 -0
  51. data/lib/grpc.rb +39 -0
  52. data/lib/grpc/core/event.rb +44 -0
  53. data/lib/grpc/core/time_consts.rb +71 -0
  54. data/lib/grpc/errors.rb +61 -0
  55. data/lib/grpc/generic/active_call.rb +536 -0
  56. data/lib/grpc/generic/bidi_call.rb +221 -0
  57. data/lib/grpc/generic/client_stub.rb +413 -0
  58. data/lib/grpc/generic/rpc_desc.rb +150 -0
  59. data/lib/grpc/generic/rpc_server.rb +404 -0
  60. data/lib/grpc/generic/service.rb +235 -0
  61. data/lib/grpc/logconfig.rb +40 -0
  62. data/lib/grpc/version.rb +33 -0
  63. data/spec/alloc_spec.rb +44 -0
  64. data/spec/byte_buffer_spec.rb +67 -0
  65. data/spec/call_spec.rb +163 -0
  66. data/spec/channel_spec.rb +181 -0
  67. data/spec/client_server_spec.rb +372 -0
  68. data/spec/completion_queue_spec.rb +74 -0
  69. data/spec/credentials_spec.rb +71 -0
  70. data/spec/event_spec.rb +53 -0
  71. data/spec/generic/active_call_spec.rb +373 -0
  72. data/spec/generic/client_stub_spec.rb +519 -0
  73. data/spec/generic/rpc_desc_spec.rb +357 -0
  74. data/spec/generic/rpc_server_pool_spec.rb +139 -0
  75. data/spec/generic/rpc_server_spec.rb +404 -0
  76. data/spec/generic/service_spec.rb +342 -0
  77. data/spec/metadata_spec.rb +64 -0
  78. data/spec/server_credentials_spec.rb +69 -0
  79. data/spec/server_spec.rb +212 -0
  80. data/spec/spec_helper.rb +51 -0
  81. data/spec/testdata/README +1 -0
  82. data/spec/testdata/ca.pem +15 -0
  83. data/spec/testdata/server1.key +16 -0
  84. data/spec/testdata/server1.pem +16 -0
  85. data/spec/time_consts_spec.rb +89 -0
  86. metadata +353 -0
@@ -0,0 +1,52 @@
1
+ /*
2
+ *
3
+ * Copyright 2015, Google Inc.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are
8
+ * met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above
13
+ * copyright notice, this list of conditions and the following disclaimer
14
+ * in the documentation and/or other materials provided with the
15
+ * distribution.
16
+ * * Neither the name of Google Inc. nor the names of its
17
+ * contributors may be used to endorse or promote products derived from
18
+ * this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ #ifndef GRPC_RB_CHANNEL_ARGS_H_
35
+ #define GRPC_RB_CHANNEL_ARGS_H_
36
+
37
+ #include <ruby.h>
38
+ #include <grpc/grpc.h>
39
+
40
+ /* Converts a hash object containing channel args to a channel args instance.
41
+ *
42
+ * This func ALLOCs args->args. The caller is responsible for freeing it. If
43
+ * a ruby error is raised during processing of the hash values, the func takes
44
+ * care to deallocate any memory allocated so far, and propagate the error.
45
+ *
46
+ * @param src_hash A ruby hash
47
+ * @param dst the grpc_channel_args that the hash entries will be added to.
48
+ */
49
+ void grpc_rb_hash_convert_to_channel_args(VALUE src_hash,
50
+ grpc_channel_args* dst);
51
+
52
+ #endif /* GRPC_RB_CHANNEL_ARGS_H_ */
@@ -0,0 +1,185 @@
1
+ /*
2
+ *
3
+ * Copyright 2015, Google Inc.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are
8
+ * met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above
13
+ * copyright notice, this list of conditions and the following disclaimer
14
+ * in the documentation and/or other materials provided with the
15
+ * distribution.
16
+ * * Neither the name of Google Inc. nor the names of its
17
+ * contributors may be used to endorse or promote products derived from
18
+ * this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ #include "rb_completion_queue.h"
35
+
36
+ #include <ruby.h>
37
+
38
+ #include <grpc/grpc.h>
39
+ #include <grpc/support/time.h>
40
+ #include "rb_grpc.h"
41
+ #include "rb_event.h"
42
+
43
+ /* Used to allow grpc_completion_queue_next call to release the GIL */
44
+ typedef struct next_call_stack {
45
+ grpc_completion_queue *cq;
46
+ grpc_event *event;
47
+ gpr_timespec timeout;
48
+ void *tag;
49
+ } next_call_stack;
50
+
51
+ /* Calls grpc_completion_queue_next without holding the ruby GIL */
52
+ static void *grpc_rb_completion_queue_next_no_gil(next_call_stack *next_call) {
53
+ next_call->event =
54
+ grpc_completion_queue_next(next_call->cq, next_call->timeout);
55
+ return NULL;
56
+ }
57
+
58
+ /* Calls grpc_completion_queue_pluck without holding the ruby GIL */
59
+ static void *grpc_rb_completion_queue_pluck_no_gil(next_call_stack *next_call) {
60
+ next_call->event = grpc_completion_queue_pluck(next_call->cq, next_call->tag,
61
+ next_call->timeout);
62
+ return NULL;
63
+ }
64
+
65
+ /* Shuts down and drains the completion queue if necessary.
66
+ *
67
+ * This is done when the ruby completion queue object is about to be GCed.
68
+ */
69
+ static void grpc_rb_completion_queue_shutdown_drain(grpc_completion_queue *cq) {
70
+ next_call_stack next_call;
71
+ grpc_completion_type type;
72
+ int drained = 0;
73
+ MEMZERO(&next_call, next_call_stack, 1);
74
+
75
+ grpc_completion_queue_shutdown(cq);
76
+ next_call.cq = cq;
77
+ next_call.event = NULL;
78
+ /* TODO: the timeout should be a module level constant that defaults
79
+ * to gpr_inf_future.
80
+ *
81
+ * - at the moment this does not work, it stalls. Using a small timeout like
82
+ * this one works, and leads to fast test run times; a longer timeout was
83
+ * causing unnecessary delays in the test runs.
84
+ *
85
+ * - investigate further, this is probably another example of C-level cleanup
86
+ * not working consistently in all cases.
87
+ */
88
+ next_call.timeout = gpr_time_add(gpr_now(), gpr_time_from_micros(5e3));
89
+ do {
90
+ rb_thread_call_without_gvl(grpc_rb_completion_queue_next_no_gil,
91
+ (void *)&next_call, NULL, NULL);
92
+ if (next_call.event == NULL) {
93
+ break;
94
+ }
95
+ type = next_call.event->type;
96
+ if (type != GRPC_QUEUE_SHUTDOWN) {
97
+ ++drained;
98
+ rb_warning("completion queue shutdown: %d undrained events", drained);
99
+ }
100
+ grpc_event_finish(next_call.event);
101
+ next_call.event = NULL;
102
+ } while (type != GRPC_QUEUE_SHUTDOWN);
103
+ }
104
+
105
+ /* Helper function to free a completion queue. */
106
+ static void grpc_rb_completion_queue_destroy(void *p) {
107
+ grpc_completion_queue *cq = NULL;
108
+ if (p == NULL) {
109
+ return;
110
+ }
111
+ cq = (grpc_completion_queue *)p;
112
+ grpc_rb_completion_queue_shutdown_drain(cq);
113
+ grpc_completion_queue_destroy(cq);
114
+ }
115
+
116
+ /* Allocates a completion queue. */
117
+ static VALUE grpc_rb_completion_queue_alloc(VALUE cls) {
118
+ grpc_completion_queue *cq = grpc_completion_queue_create();
119
+ if (cq == NULL) {
120
+ rb_raise(rb_eArgError, "could not create a completion queue: not sure why");
121
+ }
122
+ return Data_Wrap_Struct(cls, GC_NOT_MARKED, grpc_rb_completion_queue_destroy,
123
+ cq);
124
+ }
125
+
126
+ /* Blocks until the next event is available, and returns the event. */
127
+ static VALUE grpc_rb_completion_queue_next(VALUE self, VALUE timeout) {
128
+ next_call_stack next_call;
129
+ MEMZERO(&next_call, next_call_stack, 1);
130
+ Data_Get_Struct(self, grpc_completion_queue, next_call.cq);
131
+ next_call.timeout = grpc_rb_time_timeval(timeout, /* absolute time*/ 0);
132
+ next_call.event = NULL;
133
+ rb_thread_call_without_gvl(grpc_rb_completion_queue_next_no_gil,
134
+ (void *)&next_call, NULL, NULL);
135
+ if (next_call.event == NULL) {
136
+ return Qnil;
137
+ }
138
+ return grpc_rb_new_event(next_call.event);
139
+ }
140
+
141
+ /* Blocks until the next event for given tag is available, and returns the
142
+ * event. */
143
+ static VALUE grpc_rb_completion_queue_pluck(VALUE self, VALUE tag,
144
+ VALUE timeout) {
145
+ next_call_stack next_call;
146
+ MEMZERO(&next_call, next_call_stack, 1);
147
+ Data_Get_Struct(self, grpc_completion_queue, next_call.cq);
148
+ next_call.timeout = grpc_rb_time_timeval(timeout, /* absolute time*/ 0);
149
+ next_call.tag = ROBJECT(tag);
150
+ next_call.event = NULL;
151
+ rb_thread_call_without_gvl(grpc_rb_completion_queue_pluck_no_gil,
152
+ (void *)&next_call, NULL, NULL);
153
+ if (next_call.event == NULL) {
154
+ return Qnil;
155
+ }
156
+ return grpc_rb_new_event(next_call.event);
157
+ }
158
+
159
+ /* rb_cCompletionQueue is the ruby class that proxies grpc_completion_queue. */
160
+ VALUE rb_cCompletionQueue = Qnil;
161
+
162
+ void Init_grpc_completion_queue() {
163
+ rb_cCompletionQueue =
164
+ rb_define_class_under(rb_mGrpcCore, "CompletionQueue", rb_cObject);
165
+
166
+ /* constructor: uses an alloc func without an initializer. Using a simple
167
+ alloc func works here as the grpc header does not specify any args for
168
+ this func, so no separate initialization step is necessary. */
169
+ rb_define_alloc_func(rb_cCompletionQueue, grpc_rb_completion_queue_alloc);
170
+
171
+ /* Add the next method that waits for the next event. */
172
+ rb_define_method(rb_cCompletionQueue, "next", grpc_rb_completion_queue_next,
173
+ 1);
174
+
175
+ /* Add the pluck method that waits for the next event of given tag */
176
+ rb_define_method(rb_cCompletionQueue, "pluck", grpc_rb_completion_queue_pluck,
177
+ 2);
178
+ }
179
+
180
+ /* Gets the wrapped completion queue from the ruby wrapper */
181
+ grpc_completion_queue *grpc_rb_get_wrapped_completion_queue(VALUE v) {
182
+ grpc_completion_queue *cq = NULL;
183
+ Data_Get_Struct(v, grpc_completion_queue, cq);
184
+ return cq;
185
+ }
@@ -0,0 +1,50 @@
1
+ /*
2
+ *
3
+ * Copyright 2015, Google Inc.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are
8
+ * met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above
13
+ * copyright notice, this list of conditions and the following disclaimer
14
+ * in the documentation and/or other materials provided with the
15
+ * distribution.
16
+ * * Neither the name of Google Inc. nor the names of its
17
+ * contributors may be used to endorse or promote products derived from
18
+ * this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ #ifndef GRPC_RB_COMPLETION_QUEUE_H_
35
+ #define GRPC_RB_COMPLETION_QUEUE_H_
36
+
37
+ #include <grpc/grpc.h>
38
+ #include <ruby.h>
39
+
40
+ /* Gets the wrapped completion queue from the ruby wrapper */
41
+ grpc_completion_queue *grpc_rb_get_wrapped_completion_queue(VALUE v);
42
+
43
+ /* rb_cCompletionQueue is the CompletionQueue class whose instances proxy
44
+ grpc_completion_queue. */
45
+ extern VALUE rb_cCompletionQueue;
46
+
47
+ /* Initializes the CompletionQueue class. */
48
+ void Init_grpc_completion_queue();
49
+
50
+ #endif /* GRPC_RB_COMPLETION_QUEUE_H_ */
@@ -0,0 +1,281 @@
1
+ /*
2
+ *
3
+ * Copyright 2015, Google Inc.
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are
8
+ * met:
9
+ *
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above
13
+ * copyright notice, this list of conditions and the following disclaimer
14
+ * in the documentation and/or other materials provided with the
15
+ * distribution.
16
+ * * Neither the name of Google Inc. nor the names of its
17
+ * contributors may be used to endorse or promote products derived from
18
+ * this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ */
33
+
34
+ #include "rb_credentials.h"
35
+
36
+ #include <ruby.h>
37
+
38
+ #include <grpc/grpc.h>
39
+ #include <grpc/grpc_security.h>
40
+
41
+ #include "rb_grpc.h"
42
+
43
+ /* grpc_rb_credentials wraps a grpc_credentials. It provides a
44
+ * peer ruby object, 'mark' to minimize copying when a credential is
45
+ * created from ruby. */
46
+ typedef struct grpc_rb_credentials {
47
+ /* Holder of ruby objects involved in constructing the credentials */
48
+ VALUE mark;
49
+
50
+ /* The actual credentials */
51
+ grpc_credentials *wrapped;
52
+ } grpc_rb_credentials;
53
+
54
+ /* Destroys the credentials instances. */
55
+ static void grpc_rb_credentials_free(void *p) {
56
+ grpc_rb_credentials *wrapper = NULL;
57
+ if (p == NULL) {
58
+ return;
59
+ };
60
+ wrapper = (grpc_rb_credentials *)p;
61
+
62
+ /* Delete the wrapped object if the mark object is Qnil, which indicates that
63
+ * no other object is the actual owner. */
64
+ if (wrapper->wrapped != NULL && wrapper->mark == Qnil) {
65
+ grpc_credentials_release(wrapper->wrapped);
66
+ wrapper->wrapped = NULL;
67
+ }
68
+
69
+ xfree(p);
70
+ }
71
+
72
+ /* Protects the mark object from GC */
73
+ static void grpc_rb_credentials_mark(void *p) {
74
+ grpc_rb_credentials *wrapper = NULL;
75
+ if (p == NULL) {
76
+ return;
77
+ }
78
+ wrapper = (grpc_rb_credentials *)p;
79
+
80
+ /* If it's not already cleaned up, mark the mark object */
81
+ if (wrapper->mark != Qnil) {
82
+ rb_gc_mark(wrapper->mark);
83
+ }
84
+ }
85
+
86
+ /* Allocates Credential instances.
87
+ Provides safe initial defaults for the instance fields. */
88
+ static VALUE grpc_rb_credentials_alloc(VALUE cls) {
89
+ grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials);
90
+ wrapper->wrapped = NULL;
91
+ wrapper->mark = Qnil;
92
+ return Data_Wrap_Struct(cls, grpc_rb_credentials_mark,
93
+ grpc_rb_credentials_free, wrapper);
94
+ }
95
+
96
+ /* Clones Credentials instances.
97
+ Gives Credentials a consistent implementation of Ruby's object copy/dup
98
+ protocol. */
99
+ static VALUE grpc_rb_credentials_init_copy(VALUE copy, VALUE orig) {
100
+ grpc_rb_credentials *orig_cred = NULL;
101
+ grpc_rb_credentials *copy_cred = NULL;
102
+
103
+ if (copy == orig) {
104
+ return copy;
105
+ }
106
+
107
+ /* Raise an error if orig is not a credentials object or a subclass. */
108
+ if (TYPE(orig) != T_DATA ||
109
+ RDATA(orig)->dfree != (RUBY_DATA_FUNC)grpc_rb_credentials_free) {
110
+ rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(rb_cCredentials));
111
+ }
112
+
113
+ Data_Get_Struct(orig, grpc_rb_credentials, orig_cred);
114
+ Data_Get_Struct(copy, grpc_rb_credentials, copy_cred);
115
+
116
+ /* use ruby's MEMCPY to make a byte-for-byte copy of the credentials
117
+ * wrapper object. */
118
+ MEMCPY(copy_cred, orig_cred, grpc_rb_credentials, 1);
119
+ return copy;
120
+ }
121
+
122
+ /*
123
+ call-seq:
124
+ creds = Credentials.default()
125
+ Creates the default credential instances. */
126
+ static VALUE grpc_rb_default_credentials_create(VALUE cls) {
127
+ grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials);
128
+ wrapper->wrapped = grpc_google_default_credentials_create();
129
+ if (wrapper->wrapped == NULL) {
130
+ rb_raise(rb_eRuntimeError,
131
+ "could not create default credentials, not sure why");
132
+ return Qnil;
133
+ }
134
+
135
+ wrapper->mark = Qnil;
136
+ return Data_Wrap_Struct(cls, grpc_rb_credentials_mark,
137
+ grpc_rb_credentials_free, wrapper);
138
+ }
139
+
140
+ /*
141
+ call-seq:
142
+ creds = Credentials.compute_engine()
143
+ Creates the default credential instances. */
144
+ static VALUE grpc_rb_compute_engine_credentials_create(VALUE cls) {
145
+ grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials);
146
+ wrapper->wrapped = grpc_compute_engine_credentials_create();
147
+ if (wrapper->wrapped == NULL) {
148
+ rb_raise(rb_eRuntimeError,
149
+ "could not create composite engine credentials, not sure why");
150
+ return Qnil;
151
+ }
152
+
153
+ wrapper->mark = Qnil;
154
+ return Data_Wrap_Struct(cls, grpc_rb_credentials_mark,
155
+ grpc_rb_credentials_free, wrapper);
156
+ }
157
+
158
+ /*
159
+ call-seq:
160
+ creds1 = ...
161
+ creds2 = ...
162
+ creds3 = creds1.add(creds2)
163
+ Creates the default credential instances. */
164
+ static VALUE grpc_rb_composite_credentials_create(VALUE self, VALUE other) {
165
+ grpc_rb_credentials *self_wrapper = NULL;
166
+ grpc_rb_credentials *other_wrapper = NULL;
167
+ grpc_rb_credentials *wrapper = NULL;
168
+
169
+ Data_Get_Struct(self, grpc_rb_credentials, self_wrapper);
170
+ Data_Get_Struct(other, grpc_rb_credentials, other_wrapper);
171
+ wrapper = ALLOC(grpc_rb_credentials);
172
+ wrapper->wrapped = grpc_composite_credentials_create(self_wrapper->wrapped,
173
+ other_wrapper->wrapped);
174
+ if (wrapper->wrapped == NULL) {
175
+ rb_raise(rb_eRuntimeError,
176
+ "could not create composite credentials, not sure why");
177
+ return Qnil;
178
+ }
179
+
180
+ wrapper->mark = Qnil;
181
+ return Data_Wrap_Struct(rb_cCredentials, grpc_rb_credentials_mark,
182
+ grpc_rb_credentials_free, wrapper);
183
+ }
184
+
185
+ /* The attribute used on the mark object to hold the pem_root_certs. */
186
+ static ID id_pem_root_certs;
187
+
188
+ /* The attribute used on the mark object to hold the pem_private_key. */
189
+ static ID id_pem_private_key;
190
+
191
+ /* The attribute used on the mark object to hold the pem_private_key. */
192
+ static ID id_pem_cert_chain;
193
+
194
+ /*
195
+ call-seq:
196
+ creds1 = Credentials.new(pem_root_certs)
197
+ ...
198
+ creds2 = Credentials.new(pem_root_certs, pem_private_key,
199
+ pem_cert_chain)
200
+ pem_root_certs: (required) PEM encoding of the server root certificate
201
+ pem_private_key: (optional) PEM encoding of the client's private key
202
+ pem_cert_chain: (optional) PEM encoding of the client's cert chain
203
+ Initializes Credential instances. */
204
+ static VALUE grpc_rb_credentials_init(int argc, VALUE *argv, VALUE self) {
205
+ VALUE pem_root_certs = Qnil;
206
+ VALUE pem_private_key = Qnil;
207
+ VALUE pem_cert_chain = Qnil;
208
+ grpc_rb_credentials *wrapper = NULL;
209
+ grpc_credentials *creds = NULL;
210
+ grpc_ssl_pem_key_cert_pair key_cert_pair;
211
+ MEMZERO(&key_cert_pair, grpc_ssl_pem_key_cert_pair, 1);
212
+ /* TODO: Remove mandatory arg when we support default roots. */
213
+ /* "12" == 1 mandatory arg, 2 (credentials) is optional */
214
+ rb_scan_args(argc, argv, "12", &pem_root_certs, &pem_private_key,
215
+ &pem_cert_chain);
216
+
217
+ Data_Get_Struct(self, grpc_rb_credentials, wrapper);
218
+ if (pem_root_certs == Qnil) {
219
+ rb_raise(rb_eRuntimeError,
220
+ "could not create a credential: nil pem_root_certs");
221
+ return Qnil;
222
+ }
223
+ if (pem_private_key == Qnil && pem_cert_chain == Qnil) {
224
+ creds = grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs), NULL);
225
+ } else {
226
+ key_cert_pair.private_key = RSTRING_PTR(pem_private_key);
227
+ key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain);
228
+ creds = grpc_ssl_credentials_create(
229
+ RSTRING_PTR(pem_root_certs), &key_cert_pair);
230
+ }
231
+ if (creds == NULL) {
232
+ rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
233
+ return Qnil;
234
+ }
235
+ wrapper->wrapped = creds;
236
+
237
+ /* Add the input objects as hidden fields to preserve them. */
238
+ rb_ivar_set(self, id_pem_cert_chain, pem_cert_chain);
239
+ rb_ivar_set(self, id_pem_private_key, pem_private_key);
240
+ rb_ivar_set(self, id_pem_root_certs, pem_root_certs);
241
+
242
+ return self;
243
+ }
244
+
245
+ /* rb_cCredentials is the ruby class that proxies grpc_credentials. */
246
+ VALUE rb_cCredentials = Qnil;
247
+
248
+ void Init_grpc_credentials() {
249
+ rb_cCredentials =
250
+ rb_define_class_under(rb_mGrpcCore, "Credentials", rb_cObject);
251
+
252
+ /* Allocates an object managed by the ruby runtime */
253
+ rb_define_alloc_func(rb_cCredentials, grpc_rb_credentials_alloc);
254
+
255
+ /* Provides a ruby constructor and support for dup/clone. */
256
+ rb_define_method(rb_cCredentials, "initialize", grpc_rb_credentials_init, -1);
257
+ rb_define_method(rb_cCredentials, "initialize_copy",
258
+ grpc_rb_credentials_init_copy, 1);
259
+
260
+ /* Provide static funcs that create new special instances. */
261
+ rb_define_singleton_method(rb_cCredentials, "default",
262
+ grpc_rb_default_credentials_create, 0);
263
+
264
+ rb_define_singleton_method(rb_cCredentials, "compute_engine",
265
+ grpc_rb_compute_engine_credentials_create, 0);
266
+
267
+ /* Provide other methods. */
268
+ rb_define_method(rb_cCredentials, "compose",
269
+ grpc_rb_composite_credentials_create, 1);
270
+
271
+ id_pem_cert_chain = rb_intern("__pem_cert_chain");
272
+ id_pem_private_key = rb_intern("__pem_private_key");
273
+ id_pem_root_certs = rb_intern("__pem_root_certs");
274
+ }
275
+
276
+ /* Gets the wrapped grpc_credentials from the ruby wrapper */
277
+ grpc_credentials *grpc_rb_get_wrapped_credentials(VALUE v) {
278
+ grpc_rb_credentials *wrapper = NULL;
279
+ Data_Get_Struct(v, grpc_rb_credentials, wrapper);
280
+ return wrapper->wrapped;
281
+ }