blob: 654c5aed09bcd75b4cfaf8bf7186cc73352a2cec [file] [log] [blame]
/*
*
* 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 <node.h>
#include <nan.h>
#include <v8.h>
#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<Object> exports) {
Nan::HandleScope scope;
Local<Object> status = Nan::New<Object>();
Nan::Set(exports, Nan::New("status").ToLocalChecked(), status);
Local<Value> OK(Nan::New<Uint32, uint32_t>(GRPC_STATUS_OK));
Nan::Set(status, Nan::New("OK").ToLocalChecked(), OK);
Local<Value> CANCELLED(Nan::New<Uint32, uint32_t>(GRPC_STATUS_CANCELLED));
Nan::Set(status, Nan::New("CANCELLED").ToLocalChecked(), CANCELLED);
Local<Value> UNKNOWN(Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNKNOWN));
Nan::Set(status, Nan::New("UNKNOWN").ToLocalChecked(), UNKNOWN);
Local<Value> INVALID_ARGUMENT(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_INVALID_ARGUMENT));
Nan::Set(status, Nan::New("INVALID_ARGUMENT").ToLocalChecked(),
INVALID_ARGUMENT);
Local<Value> DEADLINE_EXCEEDED(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_DEADLINE_EXCEEDED));
Nan::Set(status, Nan::New("DEADLINE_EXCEEDED").ToLocalChecked(),
DEADLINE_EXCEEDED);
Local<Value> NOT_FOUND(Nan::New<Uint32, uint32_t>(GRPC_STATUS_NOT_FOUND));
Nan::Set(status, Nan::New("NOT_FOUND").ToLocalChecked(), NOT_FOUND);
Local<Value> ALREADY_EXISTS(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_ALREADY_EXISTS));
Nan::Set(status, Nan::New("ALREADY_EXISTS").ToLocalChecked(), ALREADY_EXISTS);
Local<Value> PERMISSION_DENIED(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_PERMISSION_DENIED));
Nan::Set(status, Nan::New("PERMISSION_DENIED").ToLocalChecked(),
PERMISSION_DENIED);
Local<Value> UNAUTHENTICATED(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNAUTHENTICATED));
Nan::Set(status, Nan::New("UNAUTHENTICATED").ToLocalChecked(),
UNAUTHENTICATED);
Local<Value> RESOURCE_EXHAUSTED(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_RESOURCE_EXHAUSTED));
Nan::Set(status, Nan::New("RESOURCE_EXHAUSTED").ToLocalChecked(),
RESOURCE_EXHAUSTED);
Local<Value> FAILED_PRECONDITION(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_FAILED_PRECONDITION));
Nan::Set(status, Nan::New("FAILED_PRECONDITION").ToLocalChecked(),
FAILED_PRECONDITION);
Local<Value> ABORTED(Nan::New<Uint32, uint32_t>(GRPC_STATUS_ABORTED));
Nan::Set(status, Nan::New("ABORTED").ToLocalChecked(), ABORTED);
Local<Value> OUT_OF_RANGE(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_OUT_OF_RANGE));
Nan::Set(status, Nan::New("OUT_OF_RANGE").ToLocalChecked(), OUT_OF_RANGE);
Local<Value> UNIMPLEMENTED(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNIMPLEMENTED));
Nan::Set(status, Nan::New("UNIMPLEMENTED").ToLocalChecked(), UNIMPLEMENTED);
Local<Value> INTERNAL(Nan::New<Uint32, uint32_t>(GRPC_STATUS_INTERNAL));
Nan::Set(status, Nan::New("INTERNAL").ToLocalChecked(), INTERNAL);
Local<Value> UNAVAILABLE(Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNAVAILABLE));
Nan::Set(status, Nan::New("UNAVAILABLE").ToLocalChecked(), UNAVAILABLE);
Local<Value> DATA_LOSS(Nan::New<Uint32, uint32_t>(GRPC_STATUS_DATA_LOSS));
Nan::Set(status, Nan::New("DATA_LOSS").ToLocalChecked(), DATA_LOSS);
}
void InitCallErrorConstants(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> call_error = Nan::New<Object>();
Nan::Set(exports, Nan::New("callError").ToLocalChecked(), call_error);
Local<Value> OK(Nan::New<Uint32, uint32_t>(GRPC_CALL_OK));
Nan::Set(call_error, Nan::New("OK").ToLocalChecked(), OK);
Local<Value> CALL_ERROR(Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR));
Nan::Set(call_error, Nan::New("ERROR").ToLocalChecked(), CALL_ERROR);
Local<Value> NOT_ON_SERVER(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_ON_SERVER));
Nan::Set(call_error, Nan::New("NOT_ON_SERVER").ToLocalChecked(),
NOT_ON_SERVER);
Local<Value> NOT_ON_CLIENT(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_ON_CLIENT));
Nan::Set(call_error, Nan::New("NOT_ON_CLIENT").ToLocalChecked(),
NOT_ON_CLIENT);
Local<Value> ALREADY_INVOKED(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_ALREADY_INVOKED));
Nan::Set(call_error, Nan::New("ALREADY_INVOKED").ToLocalChecked(),
ALREADY_INVOKED);
Local<Value> NOT_INVOKED(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_INVOKED));
Nan::Set(call_error, Nan::New("NOT_INVOKED").ToLocalChecked(), NOT_INVOKED);
Local<Value> ALREADY_FINISHED(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_ALREADY_FINISHED));
Nan::Set(call_error, Nan::New("ALREADY_FINISHED").ToLocalChecked(),
ALREADY_FINISHED);
Local<Value> TOO_MANY_OPERATIONS(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS));
Nan::Set(call_error, Nan::New("TOO_MANY_OPERATIONS").ToLocalChecked(),
TOO_MANY_OPERATIONS);
Local<Value> INVALID_FLAGS(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_INVALID_FLAGS));
Nan::Set(call_error, Nan::New("INVALID_FLAGS").ToLocalChecked(),
INVALID_FLAGS);
}
void InitOpTypeConstants(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> op_type = Nan::New<Object>();
Nan::Set(exports, Nan::New("opType").ToLocalChecked(), op_type);
Local<Value> SEND_INITIAL_METADATA(
Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_INITIAL_METADATA));
Nan::Set(op_type, Nan::New("SEND_INITIAL_METADATA").ToLocalChecked(),
SEND_INITIAL_METADATA);
Local<Value> SEND_MESSAGE(
Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_MESSAGE));
Nan::Set(op_type, Nan::New("SEND_MESSAGE").ToLocalChecked(), SEND_MESSAGE);
Local<Value> SEND_CLOSE_FROM_CLIENT(
Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_CLOSE_FROM_CLIENT));
Nan::Set(op_type, Nan::New("SEND_CLOSE_FROM_CLIENT").ToLocalChecked(),
SEND_CLOSE_FROM_CLIENT);
Local<Value> SEND_STATUS_FROM_SERVER(
Nan::New<Uint32, uint32_t>(GRPC_OP_SEND_STATUS_FROM_SERVER));
Nan::Set(op_type, Nan::New("SEND_STATUS_FROM_SERVER").ToLocalChecked(),
SEND_STATUS_FROM_SERVER);
Local<Value> RECV_INITIAL_METADATA(
Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_INITIAL_METADATA));
Nan::Set(op_type, Nan::New("RECV_INITIAL_METADATA").ToLocalChecked(),
RECV_INITIAL_METADATA);
Local<Value> RECV_MESSAGE(
Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_MESSAGE));
Nan::Set(op_type, Nan::New("RECV_MESSAGE").ToLocalChecked(), RECV_MESSAGE);
Local<Value> RECV_STATUS_ON_CLIENT(
Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_STATUS_ON_CLIENT));
Nan::Set(op_type, Nan::New("RECV_STATUS_ON_CLIENT").ToLocalChecked(),
RECV_STATUS_ON_CLIENT);
Local<Value> RECV_CLOSE_ON_SERVER(
Nan::New<Uint32, uint32_t>(GRPC_OP_RECV_CLOSE_ON_SERVER));
Nan::Set(op_type, Nan::New("RECV_CLOSE_ON_SERVER").ToLocalChecked(),
RECV_CLOSE_ON_SERVER);
}
void InitPropagateConstants(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> propagate = Nan::New<Object>();
Nan::Set(exports, Nan::New("propagate").ToLocalChecked(), propagate);
Local<Value> DEADLINE(Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_DEADLINE));
Nan::Set(propagate, Nan::New("DEADLINE").ToLocalChecked(), DEADLINE);
Local<Value> CENSUS_STATS_CONTEXT(
Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CENSUS_STATS_CONTEXT));
Nan::Set(propagate, Nan::New("CENSUS_STATS_CONTEXT").ToLocalChecked(),
CENSUS_STATS_CONTEXT);
Local<Value> CENSUS_TRACING_CONTEXT(
Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT));
Nan::Set(propagate, Nan::New("CENSUS_TRACING_CONTEXT").ToLocalChecked(),
CENSUS_TRACING_CONTEXT);
Local<Value> CANCELLATION(
Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CANCELLATION));
Nan::Set(propagate, Nan::New("CANCELLATION").ToLocalChecked(), CANCELLATION);
Local<Value> DEFAULTS(Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_DEFAULTS));
Nan::Set(propagate, Nan::New("DEFAULTS").ToLocalChecked(), DEFAULTS);
}
void InitConnectivityStateConstants(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> channel_state = Nan::New<Object>();
Nan::Set(exports, Nan::New("connectivityState").ToLocalChecked(),
channel_state);
Local<Value> IDLE(Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_IDLE));
Nan::Set(channel_state, Nan::New("IDLE").ToLocalChecked(), IDLE);
Local<Value> CONNECTING(Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_CONNECTING));
Nan::Set(channel_state, Nan::New("CONNECTING").ToLocalChecked(), CONNECTING);
Local<Value> READY(Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_READY));
Nan::Set(channel_state, Nan::New("READY").ToLocalChecked(), READY);
Local<Value> TRANSIENT_FAILURE(
Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_TRANSIENT_FAILURE));
Nan::Set(channel_state, Nan::New("TRANSIENT_FAILURE").ToLocalChecked(),
TRANSIENT_FAILURE);
Local<Value> FATAL_FAILURE(
Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_FATAL_FAILURE));
Nan::Set(channel_state, Nan::New("FATAL_FAILURE").ToLocalChecked(),
FATAL_FAILURE);
}
void InitWriteFlags(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> write_flags = Nan::New<Object>();
Nan::Set(exports, Nan::New("writeFlags").ToLocalChecked(), write_flags);
Local<Value> BUFFER_HINT(Nan::New<Uint32, uint32_t>(GRPC_WRITE_BUFFER_HINT));
Nan::Set(write_flags, Nan::New("BUFFER_HINT").ToLocalChecked(), BUFFER_HINT);
Local<Value> NO_COMPRESS(Nan::New<Uint32, uint32_t>(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<String> key = Nan::To<String>(info[0]).ToLocalChecked();
char *key_str = *Nan::Utf8String(key);
info.GetReturnValue().Set(static_cast<bool>(
grpc_header_key_is_legal(key_str, static_cast<size_t>(key->Length()))));
}
NAN_METHOD(MetadataNonbinValueIsLegal) {
if (!info[0]->IsString()) {
return Nan::ThrowTypeError(
"metadataNonbinValueIsLegal's argument must be a string");
}
Local<String> value = Nan::To<String>(info[0]).ToLocalChecked();
char *value_str = *Nan::Utf8String(value);
info.GetReturnValue().Set(static_cast<bool>(
grpc_header_nonbin_value_is_legal(
value_str, static_cast<size_t>(value->Length()))));
}
NAN_METHOD(MetadataKeyIsBinary) {
if (!info[0]->IsString()) {
return Nan::ThrowTypeError(
"metadataKeyIsLegal's argument must be a string");
}
Local<String> key = Nan::To<String>(info[0]).ToLocalChecked();
char *key_str = *Nan::Utf8String(key);
info.GetReturnValue().Set(static_cast<bool>(
grpc_is_binary_header(key_str, static_cast<size_t>(key->Length()))));
}
void init(Local<Object> 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<FunctionTemplate>(MetadataKeyIsLegal)).ToLocalChecked());
Nan::Set(exports, Nan::New("metadataNonbinValueIsLegal").ToLocalChecked(),
Nan::GetFunction(
Nan::New<FunctionTemplate>(MetadataNonbinValueIsLegal)
).ToLocalChecked());
Nan::Set(exports, Nan::New("metadataKeyIsBinary").ToLocalChecked(),
Nan::GetFunction(
Nan::New<FunctionTemplate>(MetadataKeyIsBinary)
).ToLocalChecked());
}
NODE_MODULE(grpc_node, init)