/* * * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include "grpc/grpc.h" #include "call.h" #include "call_credentials.h" #include "channel.h" #include "channel_credentials.h" #include "server.h" #include "completion_queue_async_worker.h" #include "server_credentials.h" using v8::FunctionTemplate; using v8::Local; using v8::Value; using v8::Object; using v8::Uint32; using v8::String; void InitStatusConstants(Local exports) { Nan::HandleScope scope; Local status = Nan::New(); Nan::Set(exports, Nan::New("status").ToLocalChecked(), status); Local OK(Nan::New(GRPC_STATUS_OK)); Nan::Set(status, Nan::New("OK").ToLocalChecked(), OK); Local CANCELLED(Nan::New(GRPC_STATUS_CANCELLED)); Nan::Set(status, Nan::New("CANCELLED").ToLocalChecked(), CANCELLED); Local UNKNOWN(Nan::New(GRPC_STATUS_UNKNOWN)); Nan::Set(status, Nan::New("UNKNOWN").ToLocalChecked(), UNKNOWN); Local INVALID_ARGUMENT( Nan::New(GRPC_STATUS_INVALID_ARGUMENT)); Nan::Set(status, Nan::New("INVALID_ARGUMENT").ToLocalChecked(), INVALID_ARGUMENT); Local DEADLINE_EXCEEDED( Nan::New(GRPC_STATUS_DEADLINE_EXCEEDED)); Nan::Set(status, Nan::New("DEADLINE_EXCEEDED").ToLocalChecked(), DEADLINE_EXCEEDED); Local NOT_FOUND(Nan::New(GRPC_STATUS_NOT_FOUND)); Nan::Set(status, Nan::New("NOT_FOUND").ToLocalChecked(), NOT_FOUND); Local ALREADY_EXISTS( Nan::New(GRPC_STATUS_ALREADY_EXISTS)); Nan::Set(status, Nan::New("ALREADY_EXISTS").ToLocalChecked(), ALREADY_EXISTS); Local PERMISSION_DENIED( Nan::New(GRPC_STATUS_PERMISSION_DENIED)); Nan::Set(status, Nan::New("PERMISSION_DENIED").ToLocalChecked(), PERMISSION_DENIED); Local UNAUTHENTICATED( Nan::New(GRPC_STATUS_UNAUTHENTICATED)); Nan::Set(status, Nan::New("UNAUTHENTICATED").ToLocalChecked(), UNAUTHENTICATED); Local RESOURCE_EXHAUSTED( Nan::New(GRPC_STATUS_RESOURCE_EXHAUSTED)); Nan::Set(status, Nan::New("RESOURCE_EXHAUSTED").ToLocalChecked(), RESOURCE_EXHAUSTED); Local FAILED_PRECONDITION( Nan::New(GRPC_STATUS_FAILED_PRECONDITION)); Nan::Set(status, Nan::New("FAILED_PRECONDITION").ToLocalChecked(), FAILED_PRECONDITION); Local ABORTED(Nan::New(GRPC_STATUS_ABORTED)); Nan::Set(status, Nan::New("ABORTED").ToLocalChecked(), ABORTED); Local OUT_OF_RANGE( Nan::New(GRPC_STATUS_OUT_OF_RANGE)); Nan::Set(status, Nan::New("OUT_OF_RANGE").ToLocalChecked(), OUT_OF_RANGE); Local UNIMPLEMENTED( Nan::New(GRPC_STATUS_UNIMPLEMENTED)); Nan::Set(status, Nan::New("UNIMPLEMENTED").ToLocalChecked(), UNIMPLEMENTED); Local INTERNAL(Nan::New(GRPC_STATUS_INTERNAL)); Nan::Set(status, Nan::New("INTERNAL").ToLocalChecked(), INTERNAL); Local UNAVAILABLE(Nan::New(GRPC_STATUS_UNAVAILABLE)); Nan::Set(status, Nan::New("UNAVAILABLE").ToLocalChecked(), UNAVAILABLE); Local DATA_LOSS(Nan::New(GRPC_STATUS_DATA_LOSS)); Nan::Set(status, Nan::New("DATA_LOSS").ToLocalChecked(), DATA_LOSS); } void InitCallErrorConstants(Local exports) { Nan::HandleScope scope; Local call_error = Nan::New(); Nan::Set(exports, Nan::New("callError").ToLocalChecked(), call_error); Local OK(Nan::New(GRPC_CALL_OK)); Nan::Set(call_error, Nan::New("OK").ToLocalChecked(), OK); Local CALL_ERROR(Nan::New(GRPC_CALL_ERROR)); Nan::Set(call_error, Nan::New("ERROR").ToLocalChecked(), CALL_ERROR); Local NOT_ON_SERVER( Nan::New(GRPC_CALL_ERROR_NOT_ON_SERVER)); Nan::Set(call_error, Nan::New("NOT_ON_SERVER").ToLocalChecked(), NOT_ON_SERVER); Local NOT_ON_CLIENT( Nan::New(GRPC_CALL_ERROR_NOT_ON_CLIENT)); Nan::Set(call_error, Nan::New("NOT_ON_CLIENT").ToLocalChecked(), NOT_ON_CLIENT); Local ALREADY_INVOKED( Nan::New(GRPC_CALL_ERROR_ALREADY_INVOKED)); Nan::Set(call_error, Nan::New("ALREADY_INVOKED").ToLocalChecked(), ALREADY_INVOKED); Local NOT_INVOKED( Nan::New(GRPC_CALL_ERROR_NOT_INVOKED)); Nan::Set(call_error, Nan::New("NOT_INVOKED").ToLocalChecked(), NOT_INVOKED); Local ALREADY_FINISHED( Nan::New(GRPC_CALL_ERROR_ALREADY_FINISHED)); Nan::Set(call_error, Nan::New("ALREADY_FINISHED").ToLocalChecked(), ALREADY_FINISHED); Local TOO_MANY_OPERATIONS( Nan::New(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS)); Nan::Set(call_error, Nan::New("TOO_MANY_OPERATIONS").ToLocalChecked(), TOO_MANY_OPERATIONS); Local INVALID_FLAGS( Nan::New(GRPC_CALL_ERROR_INVALID_FLAGS)); Nan::Set(call_error, Nan::New("INVALID_FLAGS").ToLocalChecked(), INVALID_FLAGS); } void InitOpTypeConstants(Local exports) { Nan::HandleScope scope; Local op_type = Nan::New(); Nan::Set(exports, Nan::New("opType").ToLocalChecked(), op_type); Local SEND_INITIAL_METADATA( Nan::New(GRPC_OP_SEND_INITIAL_METADATA)); Nan::Set(op_type, Nan::New("SEND_INITIAL_METADATA").ToLocalChecked(), SEND_INITIAL_METADATA); Local SEND_MESSAGE( Nan::New(GRPC_OP_SEND_MESSAGE)); Nan::Set(op_type, Nan::New("SEND_MESSAGE").ToLocalChecked(), SEND_MESSAGE); Local SEND_CLOSE_FROM_CLIENT( Nan::New(GRPC_OP_SEND_CLOSE_FROM_CLIENT)); Nan::Set(op_type, Nan::New("SEND_CLOSE_FROM_CLIENT").ToLocalChecked(), SEND_CLOSE_FROM_CLIENT); Local SEND_STATUS_FROM_SERVER( Nan::New(GRPC_OP_SEND_STATUS_FROM_SERVER)); Nan::Set(op_type, Nan::New("SEND_STATUS_FROM_SERVER").ToLocalChecked(), SEND_STATUS_FROM_SERVER); Local RECV_INITIAL_METADATA( Nan::New(GRPC_OP_RECV_INITIAL_METADATA)); Nan::Set(op_type, Nan::New("RECV_INITIAL_METADATA").ToLocalChecked(), RECV_INITIAL_METADATA); Local RECV_MESSAGE( Nan::New(GRPC_OP_RECV_MESSAGE)); Nan::Set(op_type, Nan::New("RECV_MESSAGE").ToLocalChecked(), RECV_MESSAGE); Local RECV_STATUS_ON_CLIENT( Nan::New(GRPC_OP_RECV_STATUS_ON_CLIENT)); Nan::Set(op_type, Nan::New("RECV_STATUS_ON_CLIENT").ToLocalChecked(), RECV_STATUS_ON_CLIENT); Local RECV_CLOSE_ON_SERVER( Nan::New(GRPC_OP_RECV_CLOSE_ON_SERVER)); Nan::Set(op_type, Nan::New("RECV_CLOSE_ON_SERVER").ToLocalChecked(), RECV_CLOSE_ON_SERVER); } void InitPropagateConstants(Local exports) { Nan::HandleScope scope; Local propagate = Nan::New(); Nan::Set(exports, Nan::New("propagate").ToLocalChecked(), propagate); Local DEADLINE(Nan::New(GRPC_PROPAGATE_DEADLINE)); Nan::Set(propagate, Nan::New("DEADLINE").ToLocalChecked(), DEADLINE); Local CENSUS_STATS_CONTEXT( Nan::New(GRPC_PROPAGATE_CENSUS_STATS_CONTEXT)); Nan::Set(propagate, Nan::New("CENSUS_STATS_CONTEXT").ToLocalChecked(), CENSUS_STATS_CONTEXT); Local CENSUS_TRACING_CONTEXT( Nan::New(GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT)); Nan::Set(propagate, Nan::New("CENSUS_TRACING_CONTEXT").ToLocalChecked(), CENSUS_TRACING_CONTEXT); Local CANCELLATION( Nan::New(GRPC_PROPAGATE_CANCELLATION)); Nan::Set(propagate, Nan::New("CANCELLATION").ToLocalChecked(), CANCELLATION); Local DEFAULTS(Nan::New(GRPC_PROPAGATE_DEFAULTS)); Nan::Set(propagate, Nan::New("DEFAULTS").ToLocalChecked(), DEFAULTS); } void InitConnectivityStateConstants(Local exports) { Nan::HandleScope scope; Local channel_state = Nan::New(); Nan::Set(exports, Nan::New("connectivityState").ToLocalChecked(), channel_state); Local IDLE(Nan::New(GRPC_CHANNEL_IDLE)); Nan::Set(channel_state, Nan::New("IDLE").ToLocalChecked(), IDLE); Local CONNECTING(Nan::New(GRPC_CHANNEL_CONNECTING)); Nan::Set(channel_state, Nan::New("CONNECTING").ToLocalChecked(), CONNECTING); Local READY(Nan::New(GRPC_CHANNEL_READY)); Nan::Set(channel_state, Nan::New("READY").ToLocalChecked(), READY); Local TRANSIENT_FAILURE( Nan::New(GRPC_CHANNEL_TRANSIENT_FAILURE)); Nan::Set(channel_state, Nan::New("TRANSIENT_FAILURE").ToLocalChecked(), TRANSIENT_FAILURE); Local FATAL_FAILURE( Nan::New(GRPC_CHANNEL_FATAL_FAILURE)); Nan::Set(channel_state, Nan::New("FATAL_FAILURE").ToLocalChecked(), FATAL_FAILURE); } void InitWriteFlags(Local exports) { Nan::HandleScope scope; Local write_flags = Nan::New(); Nan::Set(exports, Nan::New("writeFlags").ToLocalChecked(), write_flags); Local BUFFER_HINT(Nan::New(GRPC_WRITE_BUFFER_HINT)); Nan::Set(write_flags, Nan::New("BUFFER_HINT").ToLocalChecked(), BUFFER_HINT); Local NO_COMPRESS(Nan::New(GRPC_WRITE_NO_COMPRESS)); Nan::Set(write_flags, Nan::New("NO_COMPRESS").ToLocalChecked(), NO_COMPRESS); } NAN_METHOD(MetadataKeyIsLegal) { if (!info[0]->IsString()) { return Nan::ThrowTypeError( "headerKeyIsLegal's argument must be a string"); } Local key = Nan::To(info[0]).ToLocalChecked(); char *key_str = *Nan::Utf8String(key); info.GetReturnValue().Set(static_cast( grpc_header_key_is_legal(key_str, static_cast(key->Length())))); } NAN_METHOD(MetadataNonbinValueIsLegal) { if (!info[0]->IsString()) { return Nan::ThrowTypeError( "metadataNonbinValueIsLegal's argument must be a string"); } Local value = Nan::To(info[0]).ToLocalChecked(); char *value_str = *Nan::Utf8String(value); info.GetReturnValue().Set(static_cast( grpc_header_nonbin_value_is_legal( value_str, static_cast(value->Length())))); } NAN_METHOD(MetadataKeyIsBinary) { if (!info[0]->IsString()) { return Nan::ThrowTypeError( "metadataKeyIsLegal's argument must be a string"); } Local key = Nan::To(info[0]).ToLocalChecked(); char *key_str = *Nan::Utf8String(key); info.GetReturnValue().Set(static_cast( grpc_is_binary_header(key_str, static_cast(key->Length())))); } void init(Local exports) { Nan::HandleScope scope; grpc_init(); InitStatusConstants(exports); InitCallErrorConstants(exports); InitOpTypeConstants(exports); InitPropagateConstants(exports); InitConnectivityStateConstants(exports); InitWriteFlags(exports); grpc::node::Call::Init(exports); grpc::node::CallCredentials::Init(exports); grpc::node::Channel::Init(exports); grpc::node::ChannelCredentials::Init(exports); grpc::node::Server::Init(exports); grpc::node::CompletionQueueAsyncWorker::Init(exports); grpc::node::ServerCredentials::Init(exports); // Attach a few utility functions directly to the module Nan::Set(exports, Nan::New("metadataKeyIsLegal").ToLocalChecked(), Nan::GetFunction( Nan::New(MetadataKeyIsLegal)).ToLocalChecked()); Nan::Set(exports, Nan::New("metadataNonbinValueIsLegal").ToLocalChecked(), Nan::GetFunction( Nan::New(MetadataNonbinValueIsLegal) ).ToLocalChecked()); Nan::Set(exports, Nan::New("metadataKeyIsBinary").ToLocalChecked(), Nan::GetFunction( Nan::New(MetadataKeyIsBinary) ).ToLocalChecked()); } NODE_MODULE(grpc_node, init)