blob: 95e273f8ac9fc31d173116f19fa50442af77beb6 [file] [log] [blame]
murgatroid99749666e2015-01-12 18:25:58 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
murgatroid99749666e2015-01-12 18:25:58 -08004 * 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
murgatroid99c6bbc472016-12-06 11:00:39 -080034#include <queue>
murgatroid999b9708a2016-06-01 11:42:20 -070035
murgatroid99e5061512015-01-12 18:14:35 -080036#include <node.h>
37#include <nan.h>
38#include <v8.h>
39#include "grpc/grpc.h"
murgatroid996f607662016-04-27 16:38:33 -070040#include "grpc/grpc_security.h"
41#include "grpc/support/alloc.h"
murgatroid999b9708a2016-06-01 11:42:20 -070042#include "grpc/support/log.h"
murgatroid991d2f2892016-06-02 14:33:22 -070043#include "grpc/support/time.h"
murgatroid99e5061512015-01-12 18:14:35 -080044
Michael Lumish197d87e2016-10-07 14:49:05 -070045// TODO(murgatroid99): Remove this when the endpoint API becomes public
murgatroid992c287ca2016-10-07 09:55:35 -070046#ifdef GRPC_UV
Michael Lumish197d87e2016-10-07 14:49:05 -070047extern "C" {
murgatroid992c287ca2016-10-07 09:55:35 -070048#include "src/core/lib/iomgr/pollset_uv.h"
Michael Lumish197d87e2016-10-07 14:49:05 -070049}
murgatroid992c287ca2016-10-07 09:55:35 -070050#endif
51
murgatroid99e5061512015-01-12 18:14:35 -080052#include "call.h"
murgatroid995f709ca2015-09-30 14:22:54 -070053#include "call_credentials.h"
murgatroid99e5061512015-01-12 18:14:35 -080054#include "channel.h"
murgatroid995f709ca2015-09-30 14:22:54 -070055#include "channel_credentials.h"
murgatroid99e5061512015-01-12 18:14:35 -080056#include "server.h"
57#include "completion_queue_async_worker.h"
murgatroid99e5061512015-01-12 18:14:35 -080058#include "server_credentials.h"
Craig Tiller7c70b6c2017-01-23 07:48:42 -080059#include "slice.h"
murgatroid991d2f2892016-06-02 14:33:22 -070060#include "timeval.h"
murgatroid999030c812016-09-16 13:25:08 -070061#include "completion_queue.h"
murgatroid99e5061512015-01-12 18:14:35 -080062
Craig Tiller7c70b6c2017-01-23 07:48:42 -080063using grpc::node::CreateSliceFromString;
64
murgatroid99f776f902016-01-07 10:03:18 -080065using v8::FunctionTemplate;
murgatroid992b097832015-09-17 13:56:25 -070066using v8::Local;
murgatroid99e5061512015-01-12 18:14:35 -080067using v8::Value;
murgatroid999b9708a2016-06-01 11:42:20 -070068using v8::Number;
murgatroid99e5061512015-01-12 18:14:35 -080069using v8::Object;
70using v8::Uint32;
71using v8::String;
72
murgatroid991d2f2892016-06-02 14:33:22 -070073typedef struct log_args {
74 gpr_log_func_args core_args;
75 gpr_timespec timestamp;
76} log_args;
77
murgatroid999b9708a2016-06-01 11:42:20 -070078typedef struct logger_state {
79 Nan::Callback *callback;
murgatroid99c6bbc472016-12-06 11:00:39 -080080 std::queue<log_args *> *pending_args;
murgatroid999b9708a2016-06-01 11:42:20 -070081 uv_mutex_t mutex;
82 uv_async_t async;
83 // Indicates that a logger has been set
84 bool logger_set;
85} logger_state;
86
87logger_state grpc_logger_state;
88
murgatroid996f607662016-04-27 16:38:33 -070089static char *pem_root_certs = NULL;
90
murgatroid992b097832015-09-17 13:56:25 -070091void InitStatusConstants(Local<Object> exports) {
92 Nan::HandleScope scope;
93 Local<Object> status = Nan::New<Object>();
94 Nan::Set(exports, Nan::New("status").ToLocalChecked(), status);
95 Local<Value> OK(Nan::New<Uint32, uint32_t>(GRPC_STATUS_OK));
96 Nan::Set(status, Nan::New("OK").ToLocalChecked(), OK);
97 Local<Value> CANCELLED(Nan::New<Uint32, uint32_t>(GRPC_STATUS_CANCELLED));
98 Nan::Set(status, Nan::New("CANCELLED").ToLocalChecked(), CANCELLED);
99 Local<Value> UNKNOWN(Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNKNOWN));
100 Nan::Set(status, Nan::New("UNKNOWN").ToLocalChecked(), UNKNOWN);
101 Local<Value> INVALID_ARGUMENT(
102 Nan::New<Uint32, uint32_t>(GRPC_STATUS_INVALID_ARGUMENT));
103 Nan::Set(status, Nan::New("INVALID_ARGUMENT").ToLocalChecked(),
104 INVALID_ARGUMENT);
105 Local<Value> DEADLINE_EXCEEDED(
106 Nan::New<Uint32, uint32_t>(GRPC_STATUS_DEADLINE_EXCEEDED));
107 Nan::Set(status, Nan::New("DEADLINE_EXCEEDED").ToLocalChecked(),
108 DEADLINE_EXCEEDED);
109 Local<Value> NOT_FOUND(Nan::New<Uint32, uint32_t>(GRPC_STATUS_NOT_FOUND));
110 Nan::Set(status, Nan::New("NOT_FOUND").ToLocalChecked(), NOT_FOUND);
111 Local<Value> ALREADY_EXISTS(
112 Nan::New<Uint32, uint32_t>(GRPC_STATUS_ALREADY_EXISTS));
113 Nan::Set(status, Nan::New("ALREADY_EXISTS").ToLocalChecked(), ALREADY_EXISTS);
114 Local<Value> PERMISSION_DENIED(
115 Nan::New<Uint32, uint32_t>(GRPC_STATUS_PERMISSION_DENIED));
116 Nan::Set(status, Nan::New("PERMISSION_DENIED").ToLocalChecked(),
117 PERMISSION_DENIED);
118 Local<Value> UNAUTHENTICATED(
119 Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNAUTHENTICATED));
120 Nan::Set(status, Nan::New("UNAUTHENTICATED").ToLocalChecked(),
121 UNAUTHENTICATED);
122 Local<Value> RESOURCE_EXHAUSTED(
123 Nan::New<Uint32, uint32_t>(GRPC_STATUS_RESOURCE_EXHAUSTED));
124 Nan::Set(status, Nan::New("RESOURCE_EXHAUSTED").ToLocalChecked(),
125 RESOURCE_EXHAUSTED);
126 Local<Value> FAILED_PRECONDITION(
127 Nan::New<Uint32, uint32_t>(GRPC_STATUS_FAILED_PRECONDITION));
128 Nan::Set(status, Nan::New("FAILED_PRECONDITION").ToLocalChecked(),
129 FAILED_PRECONDITION);
130 Local<Value> ABORTED(Nan::New<Uint32, uint32_t>(GRPC_STATUS_ABORTED));
131 Nan::Set(status, Nan::New("ABORTED").ToLocalChecked(), ABORTED);
132 Local<Value> OUT_OF_RANGE(
133 Nan::New<Uint32, uint32_t>(GRPC_STATUS_OUT_OF_RANGE));
134 Nan::Set(status, Nan::New("OUT_OF_RANGE").ToLocalChecked(), OUT_OF_RANGE);
135 Local<Value> UNIMPLEMENTED(
136 Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNIMPLEMENTED));
137 Nan::Set(status, Nan::New("UNIMPLEMENTED").ToLocalChecked(), UNIMPLEMENTED);
138 Local<Value> INTERNAL(Nan::New<Uint32, uint32_t>(GRPC_STATUS_INTERNAL));
139 Nan::Set(status, Nan::New("INTERNAL").ToLocalChecked(), INTERNAL);
140 Local<Value> UNAVAILABLE(Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNAVAILABLE));
141 Nan::Set(status, Nan::New("UNAVAILABLE").ToLocalChecked(), UNAVAILABLE);
142 Local<Value> DATA_LOSS(Nan::New<Uint32, uint32_t>(GRPC_STATUS_DATA_LOSS));
143 Nan::Set(status, Nan::New("DATA_LOSS").ToLocalChecked(), DATA_LOSS);
murgatroid99e5061512015-01-12 18:14:35 -0800144}
145
murgatroid992b097832015-09-17 13:56:25 -0700146void InitCallErrorConstants(Local<Object> exports) {
147 Nan::HandleScope scope;
148 Local<Object> call_error = Nan::New<Object>();
149 Nan::Set(exports, Nan::New("callError").ToLocalChecked(), call_error);
150 Local<Value> OK(Nan::New<Uint32, uint32_t>(GRPC_CALL_OK));
151 Nan::Set(call_error, Nan::New("OK").ToLocalChecked(), OK);
Michael Lumishe2f34652016-01-27 16:41:54 -0800152 Local<Value> CALL_ERROR(Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR));
153 Nan::Set(call_error, Nan::New("ERROR").ToLocalChecked(), CALL_ERROR);
murgatroid992b097832015-09-17 13:56:25 -0700154 Local<Value> NOT_ON_SERVER(
155 Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_ON_SERVER));
156 Nan::Set(call_error, Nan::New("NOT_ON_SERVER").ToLocalChecked(),
157 NOT_ON_SERVER);
158 Local<Value> NOT_ON_CLIENT(
159 Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_ON_CLIENT));
160 Nan::Set(call_error, Nan::New("NOT_ON_CLIENT").ToLocalChecked(),
161 NOT_ON_CLIENT);
162 Local<Value> ALREADY_INVOKED(
163 Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_ALREADY_INVOKED));
164 Nan::Set(call_error, Nan::New("ALREADY_INVOKED").ToLocalChecked(),
165 ALREADY_INVOKED);
166 Local<Value> NOT_INVOKED(
167 Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_INVOKED));
168 Nan::Set(call_error, Nan::New("NOT_INVOKED").ToLocalChecked(), NOT_INVOKED);
169 Local<Value> ALREADY_FINISHED(
170 Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_ALREADY_FINISHED));
171 Nan::Set(call_error, Nan::New("ALREADY_FINISHED").ToLocalChecked(),
172 ALREADY_FINISHED);
173 Local<Value> TOO_MANY_OPERATIONS(
174 Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS));
175 Nan::Set(call_error, Nan::New("TOO_MANY_OPERATIONS").ToLocalChecked(),
176 TOO_MANY_OPERATIONS);
177 Local<Value> INVALID_FLAGS(
178 Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_INVALID_FLAGS));
179 Nan::Set(call_error, Nan::New("INVALID_FLAGS").ToLocalChecked(),
180 INVALID_FLAGS);
murgatroid99e5061512015-01-12 18:14:35 -0800181}
182
murgatroid992b097832015-09-17 13:56:25 -0700183void InitOpTypeConstants(Local<Object> exports) {
184 Nan::HandleScope scope;
185 Local<Object> op_type = Nan::New<Object>();
186 Nan::Set(exports, Nan::New("opType").ToLocalChecked(), op_type);
187 Local<Value> SEND_INITIAL_METADATA(
188 Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_INITIAL_METADATA));
189 Nan::Set(op_type, Nan::New("SEND_INITIAL_METADATA").ToLocalChecked(),
190 SEND_INITIAL_METADATA);
191 Local<Value> SEND_MESSAGE(
192 Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_MESSAGE));
193 Nan::Set(op_type, Nan::New("SEND_MESSAGE").ToLocalChecked(), SEND_MESSAGE);
194 Local<Value> SEND_CLOSE_FROM_CLIENT(
195 Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_CLOSE_FROM_CLIENT));
196 Nan::Set(op_type, Nan::New("SEND_CLOSE_FROM_CLIENT").ToLocalChecked(),
197 SEND_CLOSE_FROM_CLIENT);
198 Local<Value> SEND_STATUS_FROM_SERVER(
199 Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_STATUS_FROM_SERVER));
200 Nan::Set(op_type, Nan::New("SEND_STATUS_FROM_SERVER").ToLocalChecked(),
201 SEND_STATUS_FROM_SERVER);
202 Local<Value> RECV_INITIAL_METADATA(
203 Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_INITIAL_METADATA));
204 Nan::Set(op_type, Nan::New("RECV_INITIAL_METADATA").ToLocalChecked(),
205 RECV_INITIAL_METADATA);
206 Local<Value> RECV_MESSAGE(
207 Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_MESSAGE));
208 Nan::Set(op_type, Nan::New("RECV_MESSAGE").ToLocalChecked(), RECV_MESSAGE);
209 Local<Value> RECV_STATUS_ON_CLIENT(
210 Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_STATUS_ON_CLIENT));
211 Nan::Set(op_type, Nan::New("RECV_STATUS_ON_CLIENT").ToLocalChecked(),
212 RECV_STATUS_ON_CLIENT);
213 Local<Value> RECV_CLOSE_ON_SERVER(
214 Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_CLOSE_ON_SERVER));
215 Nan::Set(op_type, Nan::New("RECV_CLOSE_ON_SERVER").ToLocalChecked(),
216 RECV_CLOSE_ON_SERVER);
murgatroid99a9b99c92015-02-05 17:42:01 -0800217}
218
murgatroid992b097832015-09-17 13:56:25 -0700219void InitPropagateConstants(Local<Object> exports) {
220 Nan::HandleScope scope;
221 Local<Object> propagate = Nan::New<Object>();
222 Nan::Set(exports, Nan::New("propagate").ToLocalChecked(), propagate);
223 Local<Value> DEADLINE(Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_DEADLINE));
224 Nan::Set(propagate, Nan::New("DEADLINE").ToLocalChecked(), DEADLINE);
225 Local<Value> CENSUS_STATS_CONTEXT(
226 Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CENSUS_STATS_CONTEXT));
227 Nan::Set(propagate, Nan::New("CENSUS_STATS_CONTEXT").ToLocalChecked(),
228 CENSUS_STATS_CONTEXT);
229 Local<Value> CENSUS_TRACING_CONTEXT(
230 Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT));
231 Nan::Set(propagate, Nan::New("CENSUS_TRACING_CONTEXT").ToLocalChecked(),
232 CENSUS_TRACING_CONTEXT);
233 Local<Value> CANCELLATION(
234 Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CANCELLATION));
235 Nan::Set(propagate, Nan::New("CANCELLATION").ToLocalChecked(), CANCELLATION);
236 Local<Value> DEFAULTS(Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_DEFAULTS));
237 Nan::Set(propagate, Nan::New("DEFAULTS").ToLocalChecked(), DEFAULTS);
murgatroid9999e21042015-08-14 10:35:43 -0700238}
239
murgatroid992b097832015-09-17 13:56:25 -0700240void InitConnectivityStateConstants(Local<Object> exports) {
241 Nan::HandleScope scope;
242 Local<Object> channel_state = Nan::New<Object>();
243 Nan::Set(exports, Nan::New("connectivityState").ToLocalChecked(),
244 channel_state);
245 Local<Value> IDLE(Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_IDLE));
246 Nan::Set(channel_state, Nan::New("IDLE").ToLocalChecked(), IDLE);
247 Local<Value> CONNECTING(Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_CONNECTING));
248 Nan::Set(channel_state, Nan::New("CONNECTING").ToLocalChecked(), CONNECTING);
249 Local<Value> READY(Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_READY));
250 Nan::Set(channel_state, Nan::New("READY").ToLocalChecked(), READY);
251 Local<Value> TRANSIENT_FAILURE(
252 Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_TRANSIENT_FAILURE));
253 Nan::Set(channel_state, Nan::New("TRANSIENT_FAILURE").ToLocalChecked(),
254 TRANSIENT_FAILURE);
255 Local<Value> FATAL_FAILURE(
Craig Tiller48ed92e2016-06-02 11:07:12 -0700256 Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_SHUTDOWN));
murgatroid992b097832015-09-17 13:56:25 -0700257 Nan::Set(channel_state, Nan::New("FATAL_FAILURE").ToLocalChecked(),
258 FATAL_FAILURE);
murgatroid99c7f4d4f2015-07-28 15:18:57 -0700259}
260
murgatroid992b097832015-09-17 13:56:25 -0700261void InitWriteFlags(Local<Object> exports) {
262 Nan::HandleScope scope;
263 Local<Object> write_flags = Nan::New<Object>();
264 Nan::Set(exports, Nan::New("writeFlags").ToLocalChecked(), write_flags);
265 Local<Value> BUFFER_HINT(Nan::New<Uint32, uint32_t>(GRPC_WRITE_BUFFER_HINT));
266 Nan::Set(write_flags, Nan::New("BUFFER_HINT").ToLocalChecked(), BUFFER_HINT);
267 Local<Value> NO_COMPRESS(Nan::New<Uint32, uint32_t>(GRPC_WRITE_NO_COMPRESS));
268 Nan::Set(write_flags, Nan::New("NO_COMPRESS").ToLocalChecked(), NO_COMPRESS);
murgatroid994a1474f2015-08-17 14:00:31 -0700269}
270
murgatroid999b9708a2016-06-01 11:42:20 -0700271void InitLogConstants(Local<Object> exports) {
272 Nan::HandleScope scope;
273 Local<Object> log_verbosity = Nan::New<Object>();
274 Nan::Set(exports, Nan::New("logVerbosity").ToLocalChecked(), log_verbosity);
Tim Ryan7e642e32016-09-26 19:11:06 -0400275 Local<Value> LOG_DEBUG(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_DEBUG));
276 Nan::Set(log_verbosity, Nan::New("DEBUG").ToLocalChecked(), LOG_DEBUG);
277 Local<Value> LOG_INFO(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_INFO));
278 Nan::Set(log_verbosity, Nan::New("INFO").ToLocalChecked(), LOG_INFO);
murgatroid992dfcf142016-06-24 11:06:28 -0700279 Local<Value> LOG_ERROR(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_ERROR));
280 Nan::Set(log_verbosity, Nan::New("ERROR").ToLocalChecked(), LOG_ERROR);
murgatroid999b9708a2016-06-01 11:42:20 -0700281}
282
murgatroid99f776f902016-01-07 10:03:18 -0800283NAN_METHOD(MetadataKeyIsLegal) {
284 if (!info[0]->IsString()) {
285 return Nan::ThrowTypeError(
286 "headerKeyIsLegal's argument must be a string");
287 }
288 Local<String> key = Nan::To<String>(info[0]).ToLocalChecked();
murgatroid99f776f902016-01-07 10:03:18 -0800289 info.GetReturnValue().Set(static_cast<bool>(
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800290 grpc_header_key_is_legal(CreateSliceFromString(key))));
murgatroid99f776f902016-01-07 10:03:18 -0800291}
292
293NAN_METHOD(MetadataNonbinValueIsLegal) {
294 if (!info[0]->IsString()) {
295 return Nan::ThrowTypeError(
296 "metadataNonbinValueIsLegal's argument must be a string");
297 }
298 Local<String> value = Nan::To<String>(info[0]).ToLocalChecked();
murgatroid99f776f902016-01-07 10:03:18 -0800299 info.GetReturnValue().Set(static_cast<bool>(
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800300 grpc_header_nonbin_value_is_legal(CreateSliceFromString(value))));
murgatroid99f776f902016-01-07 10:03:18 -0800301}
302
303NAN_METHOD(MetadataKeyIsBinary) {
304 if (!info[0]->IsString()) {
305 return Nan::ThrowTypeError(
306 "metadataKeyIsLegal's argument must be a string");
307 }
308 Local<String> key = Nan::To<String>(info[0]).ToLocalChecked();
murgatroid99f776f902016-01-07 10:03:18 -0800309 info.GetReturnValue().Set(static_cast<bool>(
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800310 grpc_is_binary_header(CreateSliceFromString(key))));
murgatroid99f776f902016-01-07 10:03:18 -0800311}
312
murgatroid996f607662016-04-27 16:38:33 -0700313static grpc_ssl_roots_override_result get_ssl_roots_override(
314 char **pem_root_certs_ptr) {
315 *pem_root_certs_ptr = pem_root_certs;
316 if (pem_root_certs == NULL) {
317 return GRPC_SSL_ROOTS_OVERRIDE_FAIL;
318 } else {
319 return GRPC_SSL_ROOTS_OVERRIDE_OK;
320 }
321}
322
323/* This should only be called once, and only before creating any
324 *ServerCredentials */
325NAN_METHOD(SetDefaultRootsPem) {
326 if (!info[0]->IsString()) {
327 return Nan::ThrowTypeError(
328 "setDefaultRootsPem's argument must be a string");
329 }
330 Nan::Utf8String utf8_roots(info[0]);
331 size_t length = static_cast<size_t>(utf8_roots.length());
332 if (length > 0) {
333 const char *data = *utf8_roots;
334 pem_root_certs = (char *)gpr_malloc((length + 1) * sizeof(char));
335 memcpy(pem_root_certs, data, length + 1);
336 }
337}
338
murgatroid999b9708a2016-06-01 11:42:20 -0700339NAUV_WORK_CB(LogMessagesCallback) {
340 Nan::HandleScope scope;
murgatroid99c6bbc472016-12-06 11:00:39 -0800341 std::queue<log_args *> args;
murgatroid999b9708a2016-06-01 11:42:20 -0700342 uv_mutex_lock(&grpc_logger_state.mutex);
murgatroid99c6bbc472016-12-06 11:00:39 -0800343 grpc_logger_state.pending_args->swap(args);
murgatroid999b9708a2016-06-01 11:42:20 -0700344 uv_mutex_unlock(&grpc_logger_state.mutex);
345 /* Call the callback with each log message */
346 while (!args.empty()) {
murgatroid991d2f2892016-06-02 14:33:22 -0700347 log_args *arg = args.front();
murgatroid99c6bbc472016-12-06 11:00:39 -0800348 args.pop();
murgatroid991d2f2892016-06-02 14:33:22 -0700349 Local<Value> file = Nan::New(arg->core_args.file).ToLocalChecked();
350 Local<Value> line = Nan::New<Uint32, uint32_t>(arg->core_args.line);
murgatroid999b9708a2016-06-01 11:42:20 -0700351 Local<Value> severity = Nan::New(
murgatroid991d2f2892016-06-02 14:33:22 -0700352 gpr_log_severity_string(arg->core_args.severity)).ToLocalChecked();
353 Local<Value> message = Nan::New(arg->core_args.message).ToLocalChecked();
354 Local<Value> timestamp = Nan::New<v8::Date>(
355 grpc::node::TimespecToMilliseconds(arg->timestamp)).ToLocalChecked();
356 const int argc = 5;
357 Local<Value> argv[argc] = {file, line, severity, message, timestamp};
murgatroid999b9708a2016-06-01 11:42:20 -0700358 grpc_logger_state.callback->Call(argc, argv);
murgatroid991d2f2892016-06-02 14:33:22 -0700359 delete[] arg->core_args.message;
murgatroid999b9708a2016-06-01 11:42:20 -0700360 delete arg;
361 }
362}
363
364void node_log_func(gpr_log_func_args *args) {
365 // TODO(mlumish): Use the core's log formatter when it becomes available
murgatroid991d2f2892016-06-02 14:33:22 -0700366 log_args *args_copy = new log_args;
murgatroid999b9708a2016-06-01 11:42:20 -0700367 size_t message_len = strlen(args->message) + 1;
368 char *message = new char[message_len];
369 memcpy(message, args->message, message_len);
murgatroid991d2f2892016-06-02 14:33:22 -0700370 memcpy(&args_copy->core_args, args, sizeof(gpr_log_func_args));
371 args_copy->core_args.message = message;
372 args_copy->timestamp = gpr_now(GPR_CLOCK_REALTIME);
murgatroid999b9708a2016-06-01 11:42:20 -0700373
374 uv_mutex_lock(&grpc_logger_state.mutex);
murgatroid99c6bbc472016-12-06 11:00:39 -0800375 grpc_logger_state.pending_args->push(args_copy);
murgatroid999b9708a2016-06-01 11:42:20 -0700376 uv_mutex_unlock(&grpc_logger_state.mutex);
377
378 uv_async_send(&grpc_logger_state.async);
379}
380
381void init_logger() {
382 memset(&grpc_logger_state, 0, sizeof(logger_state));
murgatroid99c6bbc472016-12-06 11:00:39 -0800383 grpc_logger_state.pending_args = new std::queue<log_args *>();
murgatroid999b9708a2016-06-01 11:42:20 -0700384 uv_mutex_init(&grpc_logger_state.mutex);
385 uv_async_init(uv_default_loop(),
386 &grpc_logger_state.async,
387 LogMessagesCallback);
388 uv_unref((uv_handle_t*)&grpc_logger_state.async);
389 grpc_logger_state.logger_set = false;
390
391 gpr_log_verbosity_init();
392}
393
394/* This registers a JavaScript logger for messages from the gRPC core. Because
395 that handler has to be run in the context of the JavaScript event loop, it
396 will be run asynchronously. To minimize the problems that could cause for
397 debugging, we leave core to do its default synchronous logging until a
398 JavaScript logger is set */
399NAN_METHOD(SetDefaultLoggerCallback) {
400 if (!info[0]->IsFunction()) {
401 return Nan::ThrowTypeError(
402 "setDefaultLoggerCallback's argument must be a function");
403 }
404 if (!grpc_logger_state.logger_set) {
405 gpr_set_log_function(node_log_func);
406 grpc_logger_state.logger_set = true;
407 }
408 grpc_logger_state.callback = new Nan::Callback(info[0].As<v8::Function>());
409}
410
411NAN_METHOD(SetLogVerbosity) {
412 if (!info[0]->IsUint32()) {
413 return Nan::ThrowTypeError(
414 "setLogVerbosity's argument must be a number");
415 }
416 gpr_log_severity severity = static_cast<gpr_log_severity>(
417 Nan::To<uint32_t>(info[0]).FromJust());
418 gpr_set_log_verbosity(severity);
419}
420
murgatroid992b097832015-09-17 13:56:25 -0700421void init(Local<Object> exports) {
422 Nan::HandleScope scope;
murgatroid99e5061512015-01-12 18:14:35 -0800423 grpc_init();
murgatroid996f607662016-04-27 16:38:33 -0700424 grpc_set_ssl_roots_override_callback(get_ssl_roots_override);
murgatroid999b9708a2016-06-01 11:42:20 -0700425 init_logger();
426
murgatroid99e5061512015-01-12 18:14:35 -0800427 InitStatusConstants(exports);
428 InitCallErrorConstants(exports);
murgatroid99a9b99c92015-02-05 17:42:01 -0800429 InitOpTypeConstants(exports);
murgatroid9999e21042015-08-14 10:35:43 -0700430 InitPropagateConstants(exports);
murgatroid99c7f4d4f2015-07-28 15:18:57 -0700431 InitConnectivityStateConstants(exports);
murgatroid994a1474f2015-08-17 14:00:31 -0700432 InitWriteFlags(exports);
murgatroid999b9708a2016-06-01 11:42:20 -0700433 InitLogConstants(exports);
murgatroid99e5061512015-01-12 18:14:35 -0800434
murgatroid992c287ca2016-10-07 09:55:35 -0700435#ifdef GRPC_UV
436 grpc_pollset_work_run_loop = 0;
437#endif
murgatroid999030c812016-09-16 13:25:08 -0700438
murgatroid99e5061512015-01-12 18:14:35 -0800439 grpc::node::Call::Init(exports);
murgatroid995f709ca2015-09-30 14:22:54 -0700440 grpc::node::CallCredentials::Init(exports);
murgatroid99e5061512015-01-12 18:14:35 -0800441 grpc::node::Channel::Init(exports);
murgatroid995f709ca2015-09-30 14:22:54 -0700442 grpc::node::ChannelCredentials::Init(exports);
murgatroid99e5061512015-01-12 18:14:35 -0800443 grpc::node::Server::Init(exports);
murgatroid99e5061512015-01-12 18:14:35 -0800444 grpc::node::ServerCredentials::Init(exports);
murgatroid99f776f902016-01-07 10:03:18 -0800445
murgatroid999030c812016-09-16 13:25:08 -0700446 grpc::node::CompletionQueueInit(exports);
447
murgatroid99f776f902016-01-07 10:03:18 -0800448 // Attach a few utility functions directly to the module
449 Nan::Set(exports, Nan::New("metadataKeyIsLegal").ToLocalChecked(),
450 Nan::GetFunction(
451 Nan::New<FunctionTemplate>(MetadataKeyIsLegal)).ToLocalChecked());
452 Nan::Set(exports, Nan::New("metadataNonbinValueIsLegal").ToLocalChecked(),
453 Nan::GetFunction(
454 Nan::New<FunctionTemplate>(MetadataNonbinValueIsLegal)
455 ).ToLocalChecked());
456 Nan::Set(exports, Nan::New("metadataKeyIsBinary").ToLocalChecked(),
457 Nan::GetFunction(
458 Nan::New<FunctionTemplate>(MetadataKeyIsBinary)
459 ).ToLocalChecked());
murgatroid996f607662016-04-27 16:38:33 -0700460 Nan::Set(exports, Nan::New("setDefaultRootsPem").ToLocalChecked(),
461 Nan::GetFunction(
462 Nan::New<FunctionTemplate>(SetDefaultRootsPem)
463 ).ToLocalChecked());
murgatroid999b9708a2016-06-01 11:42:20 -0700464 Nan::Set(exports, Nan::New("setDefaultLoggerCallback").ToLocalChecked(),
465 Nan::GetFunction(
466 Nan::New<FunctionTemplate>(SetDefaultLoggerCallback)
467 ).ToLocalChecked());
468 Nan::Set(exports, Nan::New("setLogVerbosity").ToLocalChecked(),
469 Nan::GetFunction(
470 Nan::New<FunctionTemplate>(SetLogVerbosity)
471 ).ToLocalChecked());
murgatroid99e5061512015-01-12 18:14:35 -0800472}
473
murgatroid99196188f2015-10-02 12:49:03 -0700474NODE_MODULE(grpc_node, init)