1
0
mirror of https://github.com/musix-org/musix-oss synced 2025-06-17 04:26:00 +00:00
This commit is contained in:
MatteZ02
2020-03-03 22:30:50 +02:00
parent edfcc6f474
commit 30022c7634
11800 changed files with 1984416 additions and 1 deletions

79
node_modules/grpc/ext/byte_buffer.cc generated vendored Normal file
View File

@ -0,0 +1,79 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <string.h>
#include <nan.h>
#include <node.h>
#include "grpc/byte_buffer_reader.h"
#include "grpc/grpc.h"
#include "grpc/slice.h"
#include "byte_buffer.h"
#include "slice.h"
namespace grpc {
namespace node {
using Nan::Callback;
using Nan::MaybeLocal;
using v8::Function;
using v8::Local;
using v8::Object;
using v8::Number;
using v8::Value;
grpc_byte_buffer *BufferToByteBuffer(Local<Value> buffer) {
Nan::HandleScope scope;
grpc_slice slice = CreateSliceFromBuffer(buffer);
grpc_byte_buffer *byte_buffer(grpc_raw_byte_buffer_create(&slice, 1));
grpc_slice_unref(slice);
return byte_buffer;
}
namespace {
void delete_buffer(char *data, void *hint) {
grpc_slice *slice = static_cast<grpc_slice *>(hint);
grpc_slice_unref(*slice);
delete slice;
}
}
Local<Value> ByteBufferToBuffer(grpc_byte_buffer *buffer) {
Nan::EscapableHandleScope scope;
if (buffer == NULL) {
return scope.Escape(Nan::Null());
}
grpc_byte_buffer_reader reader;
if (!grpc_byte_buffer_reader_init(&reader, buffer)) {
Nan::ThrowError("Error initializing byte buffer reader.");
return scope.Escape(Nan::Undefined());
}
grpc_slice *slice = new grpc_slice;
*slice = grpc_byte_buffer_reader_readall(&reader);
grpc_byte_buffer_reader_destroy(&reader);
char *result = reinterpret_cast<char *>(GRPC_SLICE_START_PTR(*slice));
size_t length = GRPC_SLICE_LENGTH(*slice);
Local<Value> buf =
Nan::NewBuffer(result, length, delete_buffer, slice).ToLocalChecked();
return scope.Escape(buf);
}
} // namespace node
} // namespace grpc

41
node_modules/grpc/ext/byte_buffer.h generated vendored Normal file
View File

@ -0,0 +1,41 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef NET_GRPC_NODE_BYTE_BUFFER_H_
#define NET_GRPC_NODE_BYTE_BUFFER_H_
#include <string.h>
#include <nan.h>
#include <node.h>
#include "grpc/grpc.h"
namespace grpc {
namespace node {
/* Convert a Node.js Buffer to grpc_byte_buffer. Requires that
::node::Buffer::HasInstance(buffer) */
grpc_byte_buffer *BufferToByteBuffer(v8::Local<v8::Value> buffer);
/* Convert a grpc_byte_buffer to a Node.js Buffer */
v8::Local<v8::Value> ByteBufferToBuffer(grpc_byte_buffer *buffer);
} // namespace node
} // namespace grpc
#endif // NET_GRPC_NODE_BYTE_BUFFER_H_

778
node_modules/grpc/ext/call.cc generated vendored Normal file
View File

@ -0,0 +1,778 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <map>
#include <memory>
#include <vector>
#include <node.h>
#include "byte_buffer.h"
#include "call.h"
#include "call_credentials.h"
#include "channel.h"
#include "completion_queue.h"
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/alloc.h"
#include "grpc/support/log.h"
#include "grpc/support/time.h"
#include "slice.h"
#include "timeval.h"
using std::unique_ptr;
using std::shared_ptr;
using std::vector;
namespace grpc {
namespace node {
using Nan::Callback;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::Maybe;
using Nan::MaybeLocal;
using Nan::ObjectWrap;
using Nan::Persistent;
using Nan::Utf8String;
using v8::Array;
using v8::Boolean;
using v8::Exception;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::ObjectTemplate;
using v8::Uint32;
using v8::String;
using v8::Value;
Callback *Call::constructor;
Persistent<FunctionTemplate> Call::fun_tpl;
/**
* Helper function for throwing errors with a grpc_call_error value.
* Modified from the answer by Gus Goose to
* http://stackoverflow.com/questions/31794200.
*/
Local<Value> nanErrorWithCode(const char *msg, grpc_call_error code) {
EscapableHandleScope scope;
Local<Object> err = Nan::Error(msg).As<Object>();
Nan::Set(err, Nan::New("code").ToLocalChecked(), Nan::New<Uint32>(code));
return scope.Escape(err);
}
bool CreateMetadataArray(Local<Object> metadata_obj, grpc_metadata_array *array) {
HandleScope scope;
Local<Value> metadata_value = (Nan::Get(metadata_obj, Nan::New("metadata").ToLocalChecked())).ToLocalChecked();
if (!metadata_value->IsObject()) {
return false;
}
Local<Object> metadata = Nan::To<Object>(metadata_value).ToLocalChecked();
Local<Array> keys = Nan::GetOwnPropertyNames(metadata).ToLocalChecked();
for (unsigned int i = 0; i < keys->Length(); i++) {
Local<String> current_key =
Nan::To<String>(Nan::Get(keys, i).ToLocalChecked()).ToLocalChecked();
Local<Value> value_array = Nan::Get(metadata, current_key).ToLocalChecked();
if (!value_array->IsArray()) {
return false;
}
array->capacity += Local<Array>::Cast(value_array)->Length();
}
array->metadata = reinterpret_cast<grpc_metadata *>(
gpr_zalloc(array->capacity * sizeof(grpc_metadata)));
for (unsigned int i = 0; i < keys->Length(); i++) {
Local<String> current_key(Nan::To<String>(Nan::Get(keys, i).ToLocalChecked()).ToLocalChecked());
Local<Array> values =
Local<Array>::Cast(Nan::Get(metadata, current_key).ToLocalChecked());
grpc_slice key_slice = CreateSliceFromString(current_key);
grpc_slice key_intern_slice = grpc_slice_intern(key_slice);
grpc_slice_unref(key_slice);
for (unsigned int j = 0; j < values->Length(); j++) {
Local<Value> value = Nan::Get(values, j).ToLocalChecked();
grpc_metadata *current = &array->metadata[array->count];
current->key = key_intern_slice;
// Only allow binary headers for "-bin" keys
if (grpc_is_binary_header(key_intern_slice)) {
if (::node::Buffer::HasInstance(value)) {
current->value = CreateSliceFromBuffer(value);
} else {
return false;
}
} else {
if (value->IsString()) {
Local<String> string_value = Nan::To<String>(value).ToLocalChecked();
current->value = CreateSliceFromString(string_value);
} else {
return false;
}
}
array->count += 1;
}
}
return true;
}
void DestroyMetadataArray(grpc_metadata_array *array) {
for (size_t i = 0; i < array->count; i++) {
// Don't unref keys because they are interned
grpc_slice_unref(array->metadata[i].value);
}
grpc_metadata_array_destroy(array);
}
Local<Value> ParseMetadata(const grpc_metadata_array *metadata_array) {
EscapableHandleScope scope;
grpc_metadata *metadata_elements = metadata_array->metadata;
size_t length = metadata_array->count;
Local<Object> metadata_object = Nan::New<Object>();
for (unsigned int i = 0; i < length; i++) {
grpc_metadata *elem = &metadata_elements[i];
// TODO(murgatroid99): Use zero-copy string construction instead
Local<String> key_string = CopyStringFromSlice(elem->key);
Local<Array> array;
MaybeLocal<Value> maybe_array = Nan::Get(metadata_object, key_string);
if (maybe_array.IsEmpty() || !maybe_array.ToLocalChecked()->IsArray()) {
array = Nan::New<Array>(0);
Nan::Set(metadata_object, key_string, array);
} else {
array = Local<Array>::Cast(maybe_array.ToLocalChecked());
}
if (grpc_is_binary_header(elem->key)) {
Nan::Set(array, array->Length(), CreateBufferFromSlice(elem->value));
} else {
// TODO(murgatroid99): Use zero-copy string construction instead
Nan::Set(array, array->Length(), CopyStringFromSlice(elem->value));
}
}
Local<Object> result = Nan::New<Object>();
Nan::Set(result, Nan::New("metadata").ToLocalChecked(), metadata_object);
Nan::Set(result, Nan::New("flags").ToLocalChecked(), Nan::New<v8::Uint32>(0));
return scope.Escape(result);
}
Local<Value> Op::GetOpType() const {
EscapableHandleScope scope;
return scope.Escape(Nan::New(GetTypeString()).ToLocalChecked());
}
Op::~Op() {}
class SendMetadataOp : public Op {
public:
SendMetadataOp() { grpc_metadata_array_init(&send_metadata); }
~SendMetadataOp() { DestroyMetadataArray(&send_metadata); }
Local<Value> GetNodeValue() const {
EscapableHandleScope scope;
return scope.Escape(Nan::True());
}
bool ParseOp(Local<Value> value, grpc_op *out) {
if (!value->IsObject()) {
return false;
}
MaybeLocal<Object> maybe_metadata = Nan::To<Object>(value);
if (maybe_metadata.IsEmpty()) {
return false;
}
Local<Object> metadata_object = maybe_metadata.ToLocalChecked();
MaybeLocal<Value> maybe_flag_value =
Nan::Get(metadata_object, Nan::New("flags").ToLocalChecked());
if (!maybe_flag_value.IsEmpty()) {
Local<Value> flag_value = maybe_flag_value.ToLocalChecked();
if (flag_value->IsUint32()) {
Maybe<uint32_t> maybe_flag = Nan::To<uint32_t>(flag_value);
out->flags |= maybe_flag.FromMaybe(0) & GRPC_INITIAL_METADATA_USED_MASK;
}
}
if (!CreateMetadataArray(metadata_object, &send_metadata)) {
return false;
}
out->data.send_initial_metadata.count = send_metadata.count;
out->data.send_initial_metadata.metadata = send_metadata.metadata;
return true;
}
bool IsFinalOp() { return false; }
void OnComplete(bool success) {}
protected:
std::string GetTypeString() const { return "send_metadata"; }
private:
grpc_metadata_array send_metadata;
};
class SendMessageOp : public Op {
public:
SendMessageOp() { send_message = NULL; }
~SendMessageOp() {
if (send_message != NULL) {
grpc_byte_buffer_destroy(send_message);
}
}
Local<Value> GetNodeValue() const {
EscapableHandleScope scope;
return scope.Escape(Nan::True());
}
bool ParseOp(Local<Value> value, grpc_op *out) {
if (!::node::Buffer::HasInstance(value)) {
return false;
}
Local<Object> object_value = Nan::To<Object>(value).ToLocalChecked();
MaybeLocal<Value> maybe_flag_value =
Nan::Get(object_value, Nan::New("grpcWriteFlags").ToLocalChecked());
if (!maybe_flag_value.IsEmpty()) {
Local<Value> flag_value = maybe_flag_value.ToLocalChecked();
if (flag_value->IsUint32()) {
Maybe<uint32_t> maybe_flag = Nan::To<uint32_t>(flag_value);
out->flags |= maybe_flag.FromMaybe(0) & GRPC_WRITE_USED_MASK;
}
}
send_message = BufferToByteBuffer(value);
out->data.send_message.send_message = send_message;
return true;
}
bool IsFinalOp() { return false; }
void OnComplete(bool success) {}
protected:
std::string GetTypeString() const { return "send_message"; }
private:
grpc_byte_buffer *send_message;
};
class SendClientCloseOp : public Op {
public:
Local<Value> GetNodeValue() const {
EscapableHandleScope scope;
return scope.Escape(Nan::True());
}
bool ParseOp(Local<Value> value, grpc_op *out) { return true; }
bool IsFinalOp() { return false; }
void OnComplete(bool success) {}
protected:
std::string GetTypeString() const { return "client_close"; }
};
class SendServerStatusOp : public Op {
public:
SendServerStatusOp() {
details = grpc_empty_slice();
grpc_metadata_array_init(&status_metadata);
}
~SendServerStatusOp() {
grpc_slice_unref(details);
DestroyMetadataArray(&status_metadata);
}
Local<Value> GetNodeValue() const {
EscapableHandleScope scope;
return scope.Escape(Nan::True());
}
bool ParseOp(Local<Value> value, grpc_op *out) {
if (!value->IsObject()) {
return false;
}
Local<Object> server_status = Nan::To<Object>(value).ToLocalChecked();
MaybeLocal<Value> maybe_metadata =
Nan::Get(server_status, Nan::New("metadata").ToLocalChecked());
if (maybe_metadata.IsEmpty()) {
return false;
}
if (!maybe_metadata.ToLocalChecked()->IsObject()) {
return false;
}
Local<Object> metadata =
Nan::To<Object>(maybe_metadata.ToLocalChecked()).ToLocalChecked();
MaybeLocal<Value> maybe_code =
Nan::Get(server_status, Nan::New("code").ToLocalChecked());
if (maybe_code.IsEmpty()) {
return false;
}
if (!maybe_code.ToLocalChecked()->IsUint32()) {
return false;
}
uint32_t code = Nan::To<uint32_t>(maybe_code.ToLocalChecked()).FromJust();
MaybeLocal<Value> maybe_details =
Nan::Get(server_status, Nan::New("details").ToLocalChecked());
if (maybe_details.IsEmpty()) {
return false;
}
if (!maybe_details.ToLocalChecked()->IsString()) {
return false;
}
Local<String> details =
Nan::To<String>(maybe_details.ToLocalChecked()).ToLocalChecked();
if (!CreateMetadataArray(metadata, &status_metadata)) {
return false;
}
out->data.send_status_from_server.trailing_metadata_count =
status_metadata.count;
out->data.send_status_from_server.trailing_metadata =
status_metadata.metadata;
out->data.send_status_from_server.status =
static_cast<grpc_status_code>(code);
this->details = CreateSliceFromString(details);
out->data.send_status_from_server.status_details = &this->details;
return true;
}
bool IsFinalOp() { return true; }
void OnComplete(bool success) {}
protected:
std::string GetTypeString() const { return "send_status"; }
private:
grpc_slice details;
grpc_metadata_array status_metadata;
};
class GetMetadataOp : public Op {
public:
GetMetadataOp() { grpc_metadata_array_init(&recv_metadata); }
~GetMetadataOp() { grpc_metadata_array_destroy(&recv_metadata); }
Local<Value> GetNodeValue() const {
EscapableHandleScope scope;
return scope.Escape(ParseMetadata(&recv_metadata));
}
bool ParseOp(Local<Value> value, grpc_op *out) {
out->data.recv_initial_metadata.recv_initial_metadata = &recv_metadata;
return true;
}
bool IsFinalOp() { return false; }
void OnComplete(bool success) {}
protected:
std::string GetTypeString() const { return "metadata"; }
private:
grpc_metadata_array recv_metadata;
};
class ReadMessageOp : public Op {
public:
ReadMessageOp() { recv_message = NULL; }
~ReadMessageOp() {
if (recv_message != NULL) {
grpc_byte_buffer_destroy(recv_message);
}
}
Local<Value> GetNodeValue() const {
EscapableHandleScope scope;
return scope.Escape(ByteBufferToBuffer(recv_message));
}
bool ParseOp(Local<Value> value, grpc_op *out) {
out->data.recv_message.recv_message = &recv_message;
return true;
}
bool IsFinalOp() { return false; }
void OnComplete(bool success) {}
protected:
std::string GetTypeString() const { return "read"; }
private:
grpc_byte_buffer *recv_message;
};
class ClientStatusOp : public Op {
public:
ClientStatusOp() {
grpc_metadata_array_init(&metadata_array);
status_details = grpc_empty_slice();
}
~ClientStatusOp() {
grpc_metadata_array_destroy(&metadata_array);
grpc_slice_unref(status_details);
}
bool ParseOp(Local<Value> value, grpc_op *out) {
out->data.recv_status_on_client.trailing_metadata = &metadata_array;
out->data.recv_status_on_client.status = &status;
out->data.recv_status_on_client.status_details = &status_details;
return true;
}
Local<Value> GetNodeValue() const {
EscapableHandleScope scope;
Local<Object> status_obj = Nan::New<Object>();
Nan::Set(status_obj, Nan::New("code").ToLocalChecked(),
Nan::New<Number>(status));
Nan::Set(status_obj, Nan::New("details").ToLocalChecked(),
CopyStringFromSlice(status_details));
Nan::Set(status_obj, Nan::New("metadata").ToLocalChecked(),
ParseMetadata(&metadata_array));
return scope.Escape(status_obj);
}
bool IsFinalOp() { return true; }
void OnComplete(bool success) {}
protected:
std::string GetTypeString() const { return "status"; }
private:
grpc_metadata_array metadata_array;
grpc_status_code status;
grpc_slice status_details;
};
class ServerCloseResponseOp : public Op {
public:
Local<Value> GetNodeValue() const {
EscapableHandleScope scope;
return scope.Escape(Nan::New<Boolean>(cancelled));
}
bool ParseOp(Local<Value> value, grpc_op *out) {
out->data.recv_close_on_server.cancelled = &cancelled;
return true;
}
bool IsFinalOp() { return false; }
void OnComplete(bool success) {}
protected:
std::string GetTypeString() const { return "cancelled"; }
private:
int cancelled;
};
tag::tag(Callback *callback, OpVec *ops, Call *call, Local<Value> call_value)
: callback(callback),
async_resource(NULL),
ops(ops),
call(call) {
HandleScope scope;
async_resource = new Nan::AsyncResource("grpc:tag"); // Needs handle scope.
call_persist.Reset(call_value);
}
tag::~tag() {
delete callback;
delete async_resource;
delete ops;
}
void CompleteTag(void *tag, const char *error_message) {
HandleScope scope;
struct tag *tag_struct = reinterpret_cast<struct tag *>(tag);
Callback *callback = tag_struct->callback;
if (error_message == NULL) {
Local<Object> tag_obj = Nan::New<Object>();
for (vector<unique_ptr<Op> >::iterator it = tag_struct->ops->begin();
it != tag_struct->ops->end(); ++it) {
Op *op_ptr = it->get();
Nan::Set(tag_obj, op_ptr->GetOpType(), op_ptr->GetNodeValue());
}
Local<Value> argv[] = {Nan::Null(), tag_obj};
callback->Call(2, argv, tag_struct->async_resource);
} else {
Local<Value> argv[] = {Nan::Error(error_message)};
callback->Call(1, argv, tag_struct->async_resource);
}
bool success = (error_message == NULL);
bool is_final_op = false;
for (vector<unique_ptr<Op> >::iterator it = tag_struct->ops->begin();
it != tag_struct->ops->end(); ++it) {
Op *op_ptr = it->get();
op_ptr->OnComplete(success);
if (op_ptr->IsFinalOp()) {
is_final_op = true;
}
}
if (tag_struct->call == NULL) {
return;
}
tag_struct->call->CompleteBatch(is_final_op);
}
void DestroyTag(void *tag) {
struct tag *tag_struct = reinterpret_cast<struct tag *>(tag);
delete tag_struct;
}
void Call::DestroyCall() {
if (this->wrapped_call != NULL) {
grpc_call_unref(this->wrapped_call);
this->wrapped_call = NULL;
}
}
Call::Call(grpc_call *call)
: wrapped_call(call), pending_batches(0), has_final_op_completed(false) {
peer = grpc_call_get_peer(call);
}
Call::~Call() {
DestroyCall();
gpr_free(peer);
}
void Call::Init(Local<Object> exports) {
HandleScope scope;
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("Call").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Nan::SetPrototypeMethod(tpl, "startBatch", StartBatch);
Nan::SetPrototypeMethod(tpl, "cancel", Cancel);
Nan::SetPrototypeMethod(tpl, "cancelWithStatus", CancelWithStatus);
Nan::SetPrototypeMethod(tpl, "getPeer", GetPeer);
Nan::SetPrototypeMethod(tpl, "setCredentials", SetCredentials);
fun_tpl.Reset(tpl);
Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
Nan::Set(exports, Nan::New("Call").ToLocalChecked(), ctr);
constructor = new Callback(ctr);
}
bool Call::HasInstance(Local<Value> val) {
HandleScope scope;
return Nan::New(fun_tpl)->HasInstance(val);
}
grpc_call *Call::GetWrappedCall() { return this->wrapped_call; }
Local<Value> Call::WrapStruct(grpc_call *call) {
EscapableHandleScope scope;
if (call == NULL) {
return scope.Escape(Nan::Null());
}
const int argc = 1;
Local<Value> argv[argc] = {
Nan::New<External>(reinterpret_cast<void *>(call))};
MaybeLocal<Object> maybe_instance =
Nan::NewInstance(constructor->GetFunction(), argc, argv);
if (maybe_instance.IsEmpty()) {
return scope.Escape(Nan::Null());
} else {
return scope.Escape(maybe_instance.ToLocalChecked());
}
}
void Call::CompleteBatch(bool is_final_op) {
if (is_final_op) {
this->has_final_op_completed = true;
}
this->pending_batches--;
if (this->has_final_op_completed && this->pending_batches == 0) {
this->DestroyCall();
}
}
NAN_METHOD(Call::New) {
/* Arguments:
* 0: Channel to make the call on
* 1: Method
* 2: Deadline
* 3: host
* 4: parent Call
* 5: propagation flags
*/
if (info.IsConstructCall()) {
Call *call;
if (!info[0]->IsExternal()) {
return Nan::ThrowTypeError(
"Call can only be created with Channel.createCall");
}
Local<External> ext = info[0].As<External>();
// This option is used for wrapping an existing call
grpc_call *call_value = reinterpret_cast<grpc_call *>(ext->Value());
call = new Call(call_value);
call->Wrap(info.This());
info.GetReturnValue().Set(info.This());
return;
} else {
return Nan::ThrowTypeError(
"Call can only be created with Channel.createCall");
}
}
NAN_METHOD(Call::StartBatch) {
if (!Call::HasInstance(info.This())) {
return Nan::ThrowTypeError("startBatch can only be called on Call objects");
}
if (!info[0]->IsObject()) {
return Nan::ThrowError("startBatch's first argument must be an object");
}
if (!info[1]->IsFunction()) {
return Nan::ThrowError("startBatch's second argument must be a callback");
}
Local<Function> callback_func = info[1].As<Function>();
Call *call = ObjectWrap::Unwrap<Call>(info.This());
if (call->wrapped_call == NULL) {
/* This implies that the call has completed and has been destroyed. To
* emulate
* previous behavior, we should call the callback immediately with an error,
* as though the batch had failed in core */
Local<Value> argv[] = {
Nan::Error("The async function failed because the call has completed")};
Nan::Call(callback_func, Nan::New<Object>(), 1, argv);
return;
}
Local<Object> obj = Nan::To<Object>(info[0]).ToLocalChecked();
Local<Array> keys = Nan::GetOwnPropertyNames(obj).ToLocalChecked();
size_t nops = keys->Length();
vector<grpc_op> ops(nops);
unique_ptr<OpVec> op_vector(new OpVec());
for (unsigned int i = 0; i < nops; i++) {
unique_ptr<Op> op;
MaybeLocal<Value> maybe_key = Nan::Get(keys, i);
if (maybe_key.IsEmpty() || (!maybe_key.ToLocalChecked()->IsUint32())) {
return Nan::ThrowError(
"startBatch's first argument's keys must be integers");
}
uint32_t type = Nan::To<uint32_t>(maybe_key.ToLocalChecked()).FromJust();
ops[i].op = static_cast<grpc_op_type>(type);
ops[i].flags = 0;
ops[i].reserved = NULL;
switch (type) {
case GRPC_OP_SEND_INITIAL_METADATA:
op.reset(new SendMetadataOp());
break;
case GRPC_OP_SEND_MESSAGE:
op.reset(new SendMessageOp());
break;
case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
op.reset(new SendClientCloseOp());
break;
case GRPC_OP_SEND_STATUS_FROM_SERVER:
op.reset(new SendServerStatusOp());
break;
case GRPC_OP_RECV_INITIAL_METADATA:
op.reset(new GetMetadataOp());
break;
case GRPC_OP_RECV_MESSAGE:
op.reset(new ReadMessageOp());
break;
case GRPC_OP_RECV_STATUS_ON_CLIENT:
op.reset(new ClientStatusOp());
break;
case GRPC_OP_RECV_CLOSE_ON_SERVER:
op.reset(new ServerCloseResponseOp());
break;
default:
return Nan::ThrowError("Argument object had an unrecognized key");
}
if (!op->ParseOp(Nan::Get(obj, type).ToLocalChecked(), &ops[i])) {
return Nan::ThrowTypeError("Incorrectly typed arguments to startBatch");
}
op_vector->push_back(std::move(op));
}
Callback *callback = new Callback(callback_func);
grpc_call_error error = grpc_call_start_batch(
call->wrapped_call, &ops[0], nops,
new struct tag(callback, op_vector.release(), call, info.This()), NULL);
if (error != GRPC_CALL_OK) {
return Nan::ThrowError(nanErrorWithCode("startBatch failed", error));
}
call->pending_batches++;
CompletionQueueNext();
}
NAN_METHOD(Call::Cancel) {
if (!Call::HasInstance(info.This())) {
return Nan::ThrowTypeError("cancel can only be called on Call objects");
}
Call *call = ObjectWrap::Unwrap<Call>(info.This());
if (call->wrapped_call == NULL) {
/* Cancel is supposed to be idempotent. If the call has already finished,
* cancel should just complete silently */
return;
}
grpc_call_error error = grpc_call_cancel(call->wrapped_call, NULL);
if (error != GRPC_CALL_OK) {
return Nan::ThrowError(nanErrorWithCode("cancel failed", error));
}
}
NAN_METHOD(Call::CancelWithStatus) {
Nan::HandleScope scope;
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError("cancel can only be called on Call objects");
}
if (!info[0]->IsUint32()) {
return Nan::ThrowTypeError(
"cancelWithStatus's first argument must be a status code");
}
if (!info[1]->IsString()) {
return Nan::ThrowTypeError(
"cancelWithStatus's second argument must be a string");
}
Call *call = ObjectWrap::Unwrap<Call>(info.This());
if (call->wrapped_call == NULL) {
/* Cancel is supposed to be idempotent. If the call has already finished,
* cancel should just complete silently */
return;
}
grpc_status_code code =
static_cast<grpc_status_code>(Nan::To<uint32_t>(info[0]).FromJust());
if (code == GRPC_STATUS_OK) {
return Nan::ThrowRangeError(
"cancelWithStatus cannot be called with OK status");
}
Utf8String details(info[1]);
grpc_call_cancel_with_status(call->wrapped_call, code, *details, NULL);
}
NAN_METHOD(Call::GetPeer) {
Nan::HandleScope scope;
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError("getPeer can only be called on Call objects");
}
Call *call = ObjectWrap::Unwrap<Call>(info.This());
Local<Value> peer_value = Nan::New(call->peer).ToLocalChecked();
info.GetReturnValue().Set(peer_value);
}
NAN_METHOD(Call::SetCredentials) {
Nan::HandleScope scope;
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError(
"setCredentials can only be called on Call objects");
}
if (!CallCredentials::HasInstance(info[0])) {
return Nan::ThrowTypeError(
"setCredentials' first argument must be a CallCredentials");
}
Call *call = ObjectWrap::Unwrap<Call>(info.This());
if (call->wrapped_call == NULL) {
return Nan::ThrowError(
"Cannot set credentials on a call that has already started");
}
CallCredentials *creds_object = ObjectWrap::Unwrap<CallCredentials>(
Nan::To<Object>(info[0]).ToLocalChecked());
grpc_call_credentials *creds = creds_object->GetWrappedCredentials();
grpc_call_error error = GRPC_CALL_ERROR;
if (creds) {
error = grpc_call_set_credentials(call->wrapped_call, creds);
}
info.GetReturnValue().Set(Nan::New<Uint32>(error));
}
} // namespace node
} // namespace grpc

122
node_modules/grpc/ext/call.h generated vendored Normal file
View File

@ -0,0 +1,122 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef NET_GRPC_NODE_CALL_H_
#define NET_GRPC_NODE_CALL_H_
#include <memory>
#include <vector>
#include <nan.h>
#include <node.h>
#include "grpc/grpc.h"
#include "grpc/support/log.h"
#include "channel.h"
namespace grpc {
namespace node {
using std::unique_ptr;
using std::shared_ptr;
v8::Local<v8::Value> nanErrorWithCode(const char *msg, grpc_call_error code);
v8::Local<v8::Value> ParseMetadata(const grpc_metadata_array *metadata_array);
bool CreateMetadataArray(v8::Local<v8::Object> metadata,
grpc_metadata_array *array);
void DestroyMetadataArray(grpc_metadata_array *array);
/* Wrapper class for grpc_call structs. */
class Call : public Nan::ObjectWrap {
public:
static void Init(v8::Local<v8::Object> exports);
static bool HasInstance(v8::Local<v8::Value> val);
/* Wrap a grpc_call struct in a javascript object */
static v8::Local<v8::Value> WrapStruct(grpc_call *call);
grpc_call *GetWrappedCall();
void CompleteBatch(bool is_final_op);
private:
explicit Call(grpc_call *call);
~Call();
// Prevent copying
Call(const Call &);
Call &operator=(const Call &);
void DestroyCall();
static NAN_METHOD(New);
static NAN_METHOD(StartBatch);
static NAN_METHOD(Cancel);
static NAN_METHOD(CancelWithStatus);
static NAN_METHOD(GetPeer);
static NAN_METHOD(SetCredentials);
static Nan::Callback *constructor;
// Used for typechecking instances of this javascript class
static Nan::Persistent<v8::FunctionTemplate> fun_tpl;
grpc_call *wrapped_call;
// The number of ops that were started but not completed on this call
int pending_batches;
/* Indicates whether the "final" op on a call has completed. For a client
call, this is GRPC_OP_RECV_STATUS_ON_CLIENT and for a server call, this
is GRPC_OP_SEND_STATUS_FROM_SERVER */
bool has_final_op_completed;
char *peer;
};
class Op {
public:
virtual v8::Local<v8::Value> GetNodeValue() const = 0;
virtual bool ParseOp(v8::Local<v8::Value> value, grpc_op *out) = 0;
virtual ~Op();
v8::Local<v8::Value> GetOpType() const;
virtual bool IsFinalOp() = 0;
virtual void OnComplete(bool success) = 0;
protected:
virtual std::string GetTypeString() const = 0;
};
typedef std::vector<unique_ptr<Op>> OpVec;
struct tag {
tag(Nan::Callback *callback, OpVec *ops, Call *call,
v8::Local<v8::Value> call_value);
~tag();
Nan::Callback *callback;
Nan::AsyncResource *async_resource;
OpVec *ops;
Call *call;
Nan::Persistent<v8::Value, Nan::CopyablePersistentTraits<v8::Value>>
call_persist;
};
void DestroyTag(void *tag);
void CompleteTag(void *tag, const char *error_message);
} // namespace node
} // namespace grpc
#endif // NET_GRPC_NODE_CALL_H_

276
node_modules/grpc/ext/call_credentials.cc generated vendored Normal file
View File

@ -0,0 +1,276 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <nan.h>
#include <node.h>
#include <uv.h>
#include <queue>
#include "call.h"
#include "call_credentials.h"
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/log.h"
namespace grpc {
namespace node {
using Nan::Callback;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::Maybe;
using Nan::MaybeLocal;
using Nan::ObjectWrap;
using Nan::Persistent;
using Nan::Utf8String;
using v8::Exception;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::Value;
Nan::Callback *CallCredentials::constructor;
Persistent<FunctionTemplate> CallCredentials::fun_tpl;
static Callback *plugin_callback;
CallCredentials::CallCredentials(grpc_call_credentials *credentials)
: wrapped_credentials(credentials) {}
CallCredentials::~CallCredentials() {
grpc_call_credentials_release(wrapped_credentials);
}
void CallCredentials::Init(Local<Object> exports) {
HandleScope scope;
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("CallCredentials").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Nan::SetPrototypeMethod(tpl, "compose", Compose);
fun_tpl.Reset(tpl);
Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
Nan::Set(ctr, Nan::New("createFromPlugin").ToLocalChecked(),
Nan::GetFunction(Nan::New<FunctionTemplate>(CreateFromPlugin))
.ToLocalChecked());
Nan::Set(exports, Nan::New("CallCredentials").ToLocalChecked(), ctr);
constructor = new Nan::Callback(ctr);
Local<FunctionTemplate> callback_tpl =
Nan::New<FunctionTemplate>(PluginCallback);
plugin_callback =
new Callback(Nan::GetFunction(callback_tpl).ToLocalChecked());
}
bool CallCredentials::HasInstance(Local<Value> val) {
HandleScope scope;
return Nan::New(fun_tpl)->HasInstance(val);
}
Local<Value> CallCredentials::WrapStruct(grpc_call_credentials *credentials) {
EscapableHandleScope scope;
const int argc = 1;
if (credentials == NULL) {
return scope.Escape(Nan::Null());
}
Local<Value> argv[argc] = {
Nan::New<External>(reinterpret_cast<void *>(credentials))};
MaybeLocal<Object> maybe_instance =
Nan::NewInstance(constructor->GetFunction(), argc, argv);
if (maybe_instance.IsEmpty()) {
return scope.Escape(Nan::Null());
} else {
return scope.Escape(maybe_instance.ToLocalChecked());
}
}
grpc_call_credentials *CallCredentials::GetWrappedCredentials() {
return wrapped_credentials;
}
NAN_METHOD(CallCredentials::New) {
if (info.IsConstructCall()) {
if (!info[0]->IsExternal()) {
return Nan::ThrowTypeError(
"CallCredentials can only be created with the provided functions");
}
Local<External> ext = info[0].As<External>();
grpc_call_credentials *creds_value =
reinterpret_cast<grpc_call_credentials *>(ext->Value());
CallCredentials *credentials = new CallCredentials(creds_value);
credentials->Wrap(info.This());
info.GetReturnValue().Set(info.This());
return;
} else {
// This should never be called directly
return Nan::ThrowTypeError(
"CallCredentials can only be created with the provided functions");
}
}
NAN_METHOD(CallCredentials::Compose) {
if (!CallCredentials::HasInstance(info.This())) {
return Nan::ThrowTypeError(
"compose can only be called on CallCredentials objects");
}
if (!CallCredentials::HasInstance(info[0])) {
return Nan::ThrowTypeError(
"compose's first argument must be a CallCredentials object");
}
CallCredentials *self = ObjectWrap::Unwrap<CallCredentials>(info.This());
CallCredentials *other = ObjectWrap::Unwrap<CallCredentials>(
Nan::To<Object>(info[0]).ToLocalChecked());
grpc_call_credentials *creds = grpc_composite_call_credentials_create(
self->wrapped_credentials, other->wrapped_credentials, NULL);
info.GetReturnValue().Set(WrapStruct(creds));
}
NAN_METHOD(CallCredentials::CreateFromPlugin) {
if (!info[0]->IsFunction()) {
return Nan::ThrowTypeError(
"createFromPlugin's argument must be a function");
}
grpc_metadata_credentials_plugin plugin;
plugin_state *state = new plugin_state;
state->callback = new Nan::Callback(info[0].As<Function>());
state->pending_callbacks = new std::queue<plugin_callback_data *>();
uv_mutex_init(&state->plugin_mutex);
uv_async_init(uv_default_loop(), &state->plugin_async, SendPluginCallback);
uv_unref((uv_handle_t *)&state->plugin_async);
state->plugin_async.data = state;
plugin.get_metadata = plugin_get_metadata;
plugin.destroy = plugin_destroy_state;
plugin.state = reinterpret_cast<void *>(state);
plugin.type = "";
grpc_call_credentials *creds =
grpc_metadata_credentials_create_from_plugin(plugin, NULL);
info.GetReturnValue().Set(WrapStruct(creds));
}
NAN_METHOD(PluginCallback) {
// Arguments: status code, error details, metadata
if (!info[0]->IsUint32()) {
return Nan::ThrowTypeError(
"The callback's first argument must be a status code");
}
if (!info[1]->IsString()) {
return Nan::ThrowTypeError(
"The callback's second argument must be a string");
}
if (!info[2]->IsObject()) {
return Nan::ThrowTypeError(
"The callback's third argument must be an object");
}
if (!info[3]->IsObject()) {
return Nan::ThrowTypeError(
"The callback's fourth argument must be an object");
}
grpc_status_code code =
static_cast<grpc_status_code>(Nan::To<uint32_t>(info[0]).FromJust());
Utf8String details_utf8_str(info[1]);
char *details = *details_utf8_str;
grpc_metadata_array array;
grpc_metadata_array_init(&array);
Local<Object> callback_data = Nan::To<Object>(info[3]).ToLocalChecked();
if (!CreateMetadataArray(Nan::To<Object>(info[2]).ToLocalChecked(), &array)) {
return Nan::ThrowError("Failed to parse metadata");
}
grpc_credentials_plugin_metadata_cb cb =
reinterpret_cast<grpc_credentials_plugin_metadata_cb>(
Nan::Get(callback_data, Nan::New("cb").ToLocalChecked())
.ToLocalChecked()
.As<External>()
->Value());
void *user_data =
Nan::Get(callback_data, Nan::New("user_data").ToLocalChecked())
.ToLocalChecked()
.As<External>()
->Value();
cb(user_data, array.metadata, array.count, code, details);
DestroyMetadataArray(&array);
}
NAUV_WORK_CB(SendPluginCallback) {
Nan::HandleScope scope;
plugin_state *state = reinterpret_cast<plugin_state *>(async->data);
std::queue<plugin_callback_data *> callbacks;
uv_mutex_lock(&state->plugin_mutex);
state->pending_callbacks->swap(callbacks);
uv_mutex_unlock(&state->plugin_mutex);
while (!callbacks.empty()) {
plugin_callback_data *data = callbacks.front();
callbacks.pop();
Local<Object> callback_data = Nan::New<Object>();
Nan::Set(callback_data, Nan::New("cb").ToLocalChecked(),
Nan::New<v8::External>(reinterpret_cast<void *>(data->cb)));
Nan::Set(callback_data, Nan::New("user_data").ToLocalChecked(),
Nan::New<v8::External>(data->user_data));
const int argc = 3;
v8::Local<v8::Value> argv[argc] = {
Nan::New(data->service_url).ToLocalChecked(), callback_data,
// Get Local<Function> from Nan::Callback*
**plugin_callback};
Nan::Callback *callback = state->callback;
callback->Call(argc, argv, data->async_resource);
delete data;
}
}
int plugin_get_metadata(
void *state, grpc_auth_metadata_context context,
grpc_credentials_plugin_metadata_cb cb,
void *user_data,
grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX],
size_t *num_creds_md, grpc_status_code *status,
const char **error_details) {
HandleScope scope;
plugin_state *p_state = reinterpret_cast<plugin_state *>(state);
plugin_callback_data *data =
new plugin_callback_data(context.service_url, cb, user_data);
uv_mutex_lock(&p_state->plugin_mutex);
p_state->pending_callbacks->push(data);
uv_mutex_unlock(&p_state->plugin_mutex);
uv_async_send(&p_state->plugin_async);
return 0; // Async processing.
}
void plugin_uv_close_cb(uv_handle_t *handle) {
uv_async_t *async = reinterpret_cast<uv_async_t *>(handle);
plugin_state *state = reinterpret_cast<plugin_state *>(async->data);
uv_mutex_destroy(&state->plugin_mutex);
delete state->pending_callbacks;
delete state->callback;
delete state;
}
void plugin_destroy_state(void *ptr) {
plugin_state *state = reinterpret_cast<plugin_state *>(ptr);
uv_close((uv_handle_t *)&state->plugin_async, plugin_uv_close_cb);
}
} // namespace node
} // namespace grpc

110
node_modules/grpc/ext/call_credentials.h generated vendored Normal file
View File

@ -0,0 +1,110 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_NODE_CALL_CREDENTIALS_H_
#define GRPC_NODE_CALL_CREDENTIALS_H_
#include <queue>
#include <nan.h>
#include <node.h>
#include <uv.h>
#include "grpc/grpc_security.h"
namespace grpc {
namespace node {
class CallCredentials : public Nan::ObjectWrap {
public:
static void Init(v8::Local<v8::Object> exports);
static bool HasInstance(v8::Local<v8::Value> val);
/* Wrap a grpc_call_credentials struct in a javascript object */
static v8::Local<v8::Value> WrapStruct(grpc_call_credentials *credentials);
/* Returns the grpc_call_credentials struct that this object wraps */
grpc_call_credentials *GetWrappedCredentials();
private:
explicit CallCredentials(grpc_call_credentials *credentials);
~CallCredentials();
// Prevent copying
CallCredentials(const CallCredentials &);
CallCredentials &operator=(const CallCredentials &);
static NAN_METHOD(New);
static NAN_METHOD(CreateSsl);
static NAN_METHOD(CreateFromPlugin);
static NAN_METHOD(Compose);
static Nan::Callback *constructor;
// Used for typechecking instances of this javascript class
static Nan::Persistent<v8::FunctionTemplate> fun_tpl;
grpc_call_credentials *wrapped_credentials;
};
/* Auth metadata plugin functionality */
typedef struct plugin_callback_data {
plugin_callback_data(const char *service_url_,
grpc_credentials_plugin_metadata_cb cb_,
void *user_data_)
: service_url(service_url_),
cb(cb_),
user_data(user_data_),
async_resource(NULL) {
Nan::HandleScope scope;
async_resource = new Nan::AsyncResource("grpc:plugin_callback_data");
}
~plugin_callback_data() {
delete async_resource;
}
const char *service_url;
grpc_credentials_plugin_metadata_cb cb;
void *user_data;
Nan::AsyncResource *async_resource;
} plugin_callback_data;
typedef struct plugin_state {
Nan::Callback *callback;
std::queue<plugin_callback_data *> *pending_callbacks;
uv_mutex_t plugin_mutex;
// async.data == this
uv_async_t plugin_async;
} plugin_state;
int plugin_get_metadata(
void *state, grpc_auth_metadata_context context,
grpc_credentials_plugin_metadata_cb cb,
void *user_data,
grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX],
size_t *num_creds_md, grpc_status_code *status,
const char **error_details);
void plugin_destroy_state(void *state);
NAN_METHOD(PluginCallback);
NAUV_WORK_CB(SendPluginCallback);
} // namespace node
} // namepsace grpc
#endif // GRPC_NODE_CALL_CREDENTIALS_H_

397
node_modules/grpc/ext/channel.cc generated vendored Normal file
View File

@ -0,0 +1,397 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <vector>
#include "grpc/support/log.h"
#include <nan.h>
#include <node.h>
#include "call.h"
#include "channel.h"
#include "channel_credentials.h"
#include "completion_queue.h"
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "slice.h"
#include "timeval.h"
namespace grpc {
namespace node {
using Nan::Callback;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::Maybe;
using Nan::MaybeLocal;
using Nan::ObjectWrap;
using Nan::Persistent;
using Nan::Utf8String;
using v8::Array;
using v8::Exception;
using v8::Function;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;
Callback *Channel::constructor;
Persistent<FunctionTemplate> Channel::fun_tpl;
static const char grpc_node_user_agent[] = "grpc-node/" GRPC_NODE_VERSION;
void PopulateUserAgentChannelArg(grpc_arg *arg) {
size_t key_len = sizeof(GRPC_ARG_PRIMARY_USER_AGENT_STRING);
size_t val_len = sizeof(grpc_node_user_agent);
arg->key = reinterpret_cast<char *>(calloc(key_len, sizeof(char)));
memcpy(arg->key, GRPC_ARG_PRIMARY_USER_AGENT_STRING, key_len);
arg->type = GRPC_ARG_STRING;
arg->value.string = reinterpret_cast<char *>(calloc(val_len, sizeof(char)));
memcpy(arg->value.string, grpc_node_user_agent, val_len);
}
bool ParseChannelArgs(Local<Value> args_val,
grpc_channel_args **channel_args_ptr) {
if (args_val->IsUndefined() || args_val->IsNull()) {
// Treat null and undefined the same as an empty object
args_val = Nan::New<Object>();
}
if (!args_val->IsObject()) {
*channel_args_ptr = NULL;
return false;
}
grpc_channel_args *channel_args =
reinterpret_cast<grpc_channel_args *>(malloc(sizeof(grpc_channel_args)));
*channel_args_ptr = channel_args;
Local<Object> args_hash = Nan::To<Object>(args_val).ToLocalChecked();
Local<Array> keys = Nan::GetOwnPropertyNames(args_hash).ToLocalChecked();
channel_args->num_args = keys->Length();
/* This is an ugly hack to add in the user agent string argument if it wasn't
* passed by the user */
bool has_user_agent_arg = Nan::HasOwnProperty(
args_hash, Nan::New(GRPC_ARG_PRIMARY_USER_AGENT_STRING).ToLocalChecked()
).FromJust();
if (!has_user_agent_arg) {
channel_args->num_args += 1;
}
channel_args->args = reinterpret_cast<grpc_arg *>(
calloc(channel_args->num_args, sizeof(grpc_arg)));
for (unsigned int i = 0; i < keys->Length(); i++) {
Local<Value> key = Nan::Get(keys, i).ToLocalChecked();
Utf8String key_str(key);
if (*key_str == NULL) {
// Key string conversion failed
return false;
}
Local<Value> value = Nan::Get(args_hash, key).ToLocalChecked();
if (value->IsInt32()) {
channel_args->args[i].type = GRPC_ARG_INTEGER;
channel_args->args[i].value.integer = Nan::To<int32_t>(value).FromJust();
} else if (value->IsString()) {
Utf8String val_str(value);
channel_args->args[i].type = GRPC_ARG_STRING;
/* Append the grpc-node user agent string after the application user agent
* string, and put the combination at the beginning of the user agent string
*/
if (strcmp(*key_str, GRPC_ARG_PRIMARY_USER_AGENT_STRING) == 0) {
/* val_str.length() is the string length and does not include the
* trailing 0 byte. sizeof(grpc_node_user_agent) is the array length,
* so it does include the trailing 0 byte. */
size_t val_str_len = val_str.length();
size_t user_agent_len = sizeof(grpc_node_user_agent);
/* This is the length of the two parts of the string, plus the space in
* between, plus the 0 at the end, which is included in user_agent_len.
*/
channel_args->args[i].value.string =
reinterpret_cast<char *>(calloc(val_str_len + user_agent_len + 1, sizeof(char)));
memcpy(channel_args->args[i].value.string, *val_str,
val_str.length());
channel_args->args[i].value.string[val_str_len] = ' ';
memcpy(channel_args->args[i].value.string + val_str_len + 1,
grpc_node_user_agent, user_agent_len);
} else {
channel_args->args[i].value.string =
reinterpret_cast<char *>(calloc(val_str.length() + 1, sizeof(char)));
memcpy(channel_args->args[i].value.string, *val_str,
val_str.length() + 1);
}
} else {
// The value does not match either of the accepted types
return false;
}
channel_args->args[i].key =
reinterpret_cast<char *>(calloc(key_str.length() + 1, sizeof(char)));
memcpy(channel_args->args[i].key, *key_str, key_str.length() + 1);
}
/* Add a standard user agent string argument if none was provided */
if (!has_user_agent_arg) {
size_t index = channel_args->num_args - 1;
PopulateUserAgentChannelArg(&channel_args->args[index]);
}
return true;
}
void DeallocateChannelArgs(grpc_channel_args *channel_args) {
if (channel_args == NULL) {
return;
}
for (size_t i = 0; i < channel_args->num_args; i++) {
if (channel_args->args[i].key == NULL) {
/* NULL key implies that this argument and all subsequent arguments failed
* to parse */
break;
}
free(channel_args->args[i].key);
if (channel_args->args[i].type == GRPC_ARG_STRING) {
free(channel_args->args[i].value.string);
}
}
free(channel_args->args);
free(channel_args);
}
Channel::Channel(grpc_channel *channel) : wrapped_channel(channel) {}
Channel::~Channel() {
gpr_log(GPR_DEBUG, "Destroying channel");
if (wrapped_channel != NULL) {
grpc_channel_destroy(wrapped_channel);
}
}
void Channel::Init(Local<Object> exports) {
Nan::HandleScope scope;
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("Channel").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Nan::SetPrototypeMethod(tpl, "close", Close);
Nan::SetPrototypeMethod(tpl, "getTarget", GetTarget);
Nan::SetPrototypeMethod(tpl, "getConnectivityState", GetConnectivityState);
Nan::SetPrototypeMethod(tpl, "watchConnectivityState",
WatchConnectivityState);
Nan::SetPrototypeMethod(tpl, "createCall", CreateCall);
fun_tpl.Reset(tpl);
Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
Nan::Set(exports, Nan::New("Channel").ToLocalChecked(), ctr);
constructor = new Callback(ctr);
}
bool Channel::HasInstance(Local<Value> val) {
HandleScope scope;
return Nan::New(fun_tpl)->HasInstance(val);
}
grpc_channel *Channel::GetWrappedChannel() { return this->wrapped_channel; }
NAN_METHOD(Channel::New) {
if (info.IsConstructCall()) {
if (!info[0]->IsString()) {
return Nan::ThrowTypeError(
"Channel's first argument (address) must be a string");
}
grpc_channel *wrapped_channel;
// Owned by the Channel object
Utf8String host(info[0]);
grpc_channel_credentials *creds;
if (!ChannelCredentials::HasInstance(info[1])) {
return Nan::ThrowTypeError(
"Channel's second argument (credentials) must be a ChannelCredentials");
}
ChannelCredentials *creds_object = ObjectWrap::Unwrap<ChannelCredentials>(
Nan::To<Object>(info[1]).ToLocalChecked());
creds = creds_object->GetWrappedCredentials();
grpc_channel_args *channel_args_ptr = NULL;
if (!ParseChannelArgs(info[2], &channel_args_ptr)) {
DeallocateChannelArgs(channel_args_ptr);
return Nan::ThrowTypeError(
"Channel third argument (options) must be an object with "
"string keys and integer or string values");
}
if (creds == NULL) {
wrapped_channel =
grpc_insecure_channel_create(*host, channel_args_ptr, NULL);
} else {
wrapped_channel =
grpc_secure_channel_create(creds, *host, channel_args_ptr, NULL);
}
DeallocateChannelArgs(channel_args_ptr);
Channel *channel = new Channel(wrapped_channel);
channel->Wrap(info.This());
info.GetReturnValue().Set(info.This());
return;
} else {
const int argc = 3;
Local<Value> argv[argc] = {info[0], info[1], info[2]};
MaybeLocal<Object> maybe_instance =
Nan::NewInstance(constructor->GetFunction(), argc, argv);
if (maybe_instance.IsEmpty()) {
// There's probably a pending exception
return;
} else {
info.GetReturnValue().Set(maybe_instance.ToLocalChecked());
}
}
}
NAN_METHOD(Channel::Close) {
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError("close can only be called on Channel objects");
}
Channel *channel = ObjectWrap::Unwrap<Channel>(info.This());
if (channel->wrapped_channel != NULL) {
grpc_channel_destroy(channel->wrapped_channel);
channel->wrapped_channel = NULL;
}
}
NAN_METHOD(Channel::GetTarget) {
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError(
"getTarget can only be called on Channel objects");
}
Channel *channel = ObjectWrap::Unwrap<Channel>(info.This());
if (channel->wrapped_channel == NULL) {
return Nan::ThrowError(
"Cannot call getTarget on a closed Channel");
}
info.GetReturnValue().Set(
Nan::New(grpc_channel_get_target(channel->wrapped_channel))
.ToLocalChecked());
}
NAN_METHOD(Channel::GetConnectivityState) {
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError(
"getConnectivityState can only be called on Channel objects");
}
Channel *channel = ObjectWrap::Unwrap<Channel>(info.This());
if (channel->wrapped_channel == NULL) {
return Nan::ThrowError(
"Cannot call getConnectivityState on a closed Channel");
}
int try_to_connect = (int)info[0]->StrictEquals(Nan::True());
info.GetReturnValue().Set(grpc_channel_check_connectivity_state(
channel->wrapped_channel, try_to_connect));
}
NAN_METHOD(Channel::WatchConnectivityState) {
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError(
"watchConnectivityState can only be called on Channel objects");
}
if (!info[0]->IsUint32()) {
return Nan::ThrowTypeError(
"watchConnectivityState's first argument must be a channel state");
}
if (!(info[1]->IsNumber() || info[1]->IsDate())) {
return Nan::ThrowTypeError(
"watchConnectivityState's second argument must be a date or a number");
}
if (!info[2]->IsFunction()) {
return Nan::ThrowTypeError(
"watchConnectivityState's third argument must be a callback");
}
Channel *channel = ObjectWrap::Unwrap<Channel>(info.This());
if (channel->wrapped_channel == NULL) {
return Nan::ThrowError(
"Cannot call watchConnectivityState on a closed Channel");
}
grpc_connectivity_state last_state = static_cast<grpc_connectivity_state>(
Nan::To<uint32_t>(info[0]).FromJust());
double deadline = Nan::To<double>(info[1]).FromJust();
Local<Function> callback_func = info[2].As<Function>();
Nan::Callback *callback = new Callback(callback_func);
unique_ptr<OpVec> ops(new OpVec());
grpc_channel_watch_connectivity_state(
channel->wrapped_channel, last_state, MillisecondsToTimespec(deadline),
GetCompletionQueue(),
new struct tag(callback, ops.release(), NULL, Nan::Null()));
CompletionQueueNext();
}
NAN_METHOD(Channel::CreateCall) {
/* Arguments:
* 0: Method
* 1: Deadline
* 2: host
* 3: parent Call
* 4: propagation flags
*/
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError(
"createCall can only be called on Channel objects");
}
if (!info[0]->IsString()){
return Nan::ThrowTypeError("createCall's first argument must be a string");
}
if (!(info[1]->IsNumber() || info[1]->IsDate())) {
return Nan::ThrowTypeError(
"createcall's second argument must be a date or a number");
}
// These arguments are at the end because they are optional
grpc_call *parent_call = NULL;
if (Call::HasInstance(info[3])) {
Call *parent_obj =
ObjectWrap::Unwrap<Call>(Nan::To<Object>(info[3]).ToLocalChecked());
parent_call = parent_obj->GetWrappedCall();
} else if (!(info[3]->IsUndefined() || info[3]->IsNull())) {
return Nan::ThrowTypeError(
"createCall's fourth argument must be another call, if provided");
}
uint32_t propagate_flags = GRPC_PROPAGATE_DEFAULTS;
if (info[4]->IsUint32()) {
propagate_flags = Nan::To<uint32_t>(info[4]).FromJust();
} else if (!(info[4]->IsUndefined() || info[4]->IsNull())) {
return Nan::ThrowTypeError(
"createCall's fifth argument must be propagate flags, if provided");
}
Channel *channel = ObjectWrap::Unwrap<Channel>(info.This());
grpc_channel *wrapped_channel = channel->GetWrappedChannel();
if (wrapped_channel == NULL) {
return Nan::ThrowError("Cannot createCall with a closed Channel");
}
grpc_slice method =
CreateSliceFromString(Nan::To<String>(info[0]).ToLocalChecked());
double deadline = Nan::To<double>(info[1]).FromJust();
grpc_call *wrapped_call = NULL;
if (info[2]->IsString()) {
grpc_slice *host = new grpc_slice;
*host =
CreateSliceFromString(Nan::To<String>(info[2]).ToLocalChecked());
wrapped_call = grpc_channel_create_call(
wrapped_channel, parent_call, propagate_flags, GetCompletionQueue(),
method, host, MillisecondsToTimespec(deadline), NULL);
delete host;
} else if (info[2]->IsUndefined() || info[2]->IsNull()) {
wrapped_call = grpc_channel_create_call(
wrapped_channel, parent_call, propagate_flags, GetCompletionQueue(),
method, NULL, MillisecondsToTimespec(deadline), NULL);
} else {
return Nan::ThrowTypeError("createCall's third argument must be a string");
}
grpc_slice_unref(method);
info.GetReturnValue().Set(Call::WrapStruct(wrapped_call));
}
} // namespace node
} // namespace grpc

69
node_modules/grpc/ext/channel.h generated vendored Normal file
View File

@ -0,0 +1,69 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef NET_GRPC_NODE_CHANNEL_H_
#define NET_GRPC_NODE_CHANNEL_H_
#include <nan.h>
#include <node.h>
#include "grpc/grpc.h"
namespace grpc {
namespace node {
bool ParseChannelArgs(v8::Local<v8::Value> args_val,
grpc_channel_args **channel_args_ptr);
void DeallocateChannelArgs(grpc_channel_args *channel_args);
/* Wrapper class for grpc_channel structs */
class Channel : public Nan::ObjectWrap {
public:
static void Init(v8::Local<v8::Object> exports);
static bool HasInstance(v8::Local<v8::Value> val);
/* This is used to typecheck javascript objects before converting them to
this type */
static v8::Persistent<v8::Value> prototype;
/* Returns the grpc_channel struct that this object wraps */
grpc_channel *GetWrappedChannel();
private:
explicit Channel(grpc_channel *channel);
~Channel();
// Prevent copying
Channel(const Channel &);
Channel &operator=(const Channel &);
static NAN_METHOD(New);
static NAN_METHOD(Close);
static NAN_METHOD(GetTarget);
static NAN_METHOD(GetConnectivityState);
static NAN_METHOD(WatchConnectivityState);
static NAN_METHOD(CreateCall);
static Nan::Callback *constructor;
static Nan::Persistent<v8::FunctionTemplate> fun_tpl;
grpc_channel *wrapped_channel;
};
} // namespace node
} // namespace grpc
#endif // NET_GRPC_NODE_CHANNEL_H_

253
node_modules/grpc/ext/channel_credentials.cc generated vendored Normal file
View File

@ -0,0 +1,253 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <node.h>
#include "call.h"
#include "call_credentials.h"
#include "channel_credentials.h"
#include "util.h"
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/log.h"
namespace grpc {
namespace node {
using Nan::Callback;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::Maybe;
using Nan::MaybeLocal;
using Nan::ObjectWrap;
using Nan::Persistent;
using Nan::Utf8String;
using v8::Array;
using v8::Context;
using v8::Exception;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::Value;
Nan::Callback *ChannelCredentials::constructor;
Persistent<FunctionTemplate> ChannelCredentials::fun_tpl;
ChannelCredentials::ChannelCredentials(grpc_channel_credentials *credentials)
: wrapped_credentials(credentials) {}
ChannelCredentials::~ChannelCredentials() {
grpc_channel_credentials_release(wrapped_credentials);
}
static int verify_peer_callback_wrapper(const char* servername, const char* cert, void* userdata) {
Nan::HandleScope scope;
Nan::TryCatch try_catch;
Nan::Callback *callback = (Nan::Callback*)userdata;
const unsigned argc = 2;
Local<Value> argv[argc];
if (servername == NULL) {
argv[0] = Nan::Null();
} else {
argv[0] = Nan::New<v8::String>(servername).ToLocalChecked();
}
if (cert == NULL) {
argv[1] = Nan::Null();
} else {
argv[1] = Nan::New<v8::String>(cert).ToLocalChecked();
}
MaybeLocal<Value> result = Nan::Call(*callback, argc, argv);
// Catch any exception and return with a distinct status code which indicates this
if (try_catch.HasCaught()) {
return 2;
}
// If the result is an error, return a failure
if (result.ToLocalChecked()->IsNativeError()) {
return 1;
}
return 0;
}
static void verify_peer_callback_destruct(void *userdata) {
Nan::Callback *callback = (Nan::Callback*)userdata;
delete callback;
}
void ChannelCredentials::Init(Local<Object> exports) {
HandleScope scope;
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("ChannelCredentials").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Nan::SetPrototypeMethod(tpl, "compose", Compose);
fun_tpl.Reset(tpl);
Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
Nan::Set(
ctr, Nan::New("createSsl").ToLocalChecked(),
Nan::GetFunction(Nan::New<FunctionTemplate>(CreateSsl)).ToLocalChecked());
Nan::Set(ctr, Nan::New("createInsecure").ToLocalChecked(),
Nan::GetFunction(Nan::New<FunctionTemplate>(CreateInsecure))
.ToLocalChecked());
Nan::Set(exports, Nan::New("ChannelCredentials").ToLocalChecked(), ctr);
constructor = new Nan::Callback(ctr);
}
bool ChannelCredentials::HasInstance(Local<Value> val) {
HandleScope scope;
return Nan::New(fun_tpl)->HasInstance(val);
}
Local<Value> ChannelCredentials::WrapStruct(
grpc_channel_credentials *credentials) {
EscapableHandleScope scope;
const int argc = 1;
Local<Value> argv[argc] = {
Nan::New<External>(reinterpret_cast<void *>(credentials))};
MaybeLocal<Object> maybe_instance =
Nan::NewInstance(constructor->GetFunction(), argc, argv);
if (maybe_instance.IsEmpty()) {
return scope.Escape(Nan::Null());
} else {
return scope.Escape(maybe_instance.ToLocalChecked());
}
}
grpc_channel_credentials *ChannelCredentials::GetWrappedCredentials() {
return wrapped_credentials;
}
NAN_METHOD(ChannelCredentials::New) {
if (info.IsConstructCall()) {
if (!info[0]->IsExternal()) {
return Nan::ThrowTypeError(
"ChannelCredentials can only be created with the provided functions");
}
Local<External> ext = info[0].As<External>();
grpc_channel_credentials *creds_value =
reinterpret_cast<grpc_channel_credentials *>(ext->Value());
ChannelCredentials *credentials = new ChannelCredentials(creds_value);
credentials->Wrap(info.This());
info.GetReturnValue().Set(info.This());
return;
} else {
// This should never be called directly
return Nan::ThrowTypeError(
"ChannelCredentials can only be created with the provided functions");
}
}
NAN_METHOD(ChannelCredentials::CreateSsl) {
StringOrNull root_certs;
StringOrNull private_key;
StringOrNull cert_chain;
if (::node::Buffer::HasInstance(info[0])) {
root_certs.assign(info[0]);
} else if (!(info[0]->IsNull() || info[0]->IsUndefined())) {
return Nan::ThrowTypeError("createSsl's first argument must be a Buffer");
}
if (::node::Buffer::HasInstance(info[1])) {
private_key.assign(info[1]);
} else if (!(info[1]->IsNull() || info[1]->IsUndefined())) {
return Nan::ThrowTypeError(
"createSSl's second argument must be a Buffer if provided");
}
if (::node::Buffer::HasInstance(info[2])) {
cert_chain.assign(info[2]);
} else if (!(info[2]->IsNull() || info[2]->IsUndefined())) {
return Nan::ThrowTypeError(
"createSSl's third argument must be a Buffer if provided");
}
grpc_ssl_pem_key_cert_pair key_cert_pair = {private_key.get(),
cert_chain.get()};
if (private_key.isAssigned() != cert_chain.isAssigned()) {
return Nan::ThrowError(
"createSsl's second and third arguments must be"
" provided or omitted together");
}
verify_peer_options verify_options = {NULL, NULL, NULL};
if (!info[3]->IsUndefined()) {
if (!info[3]->IsObject()) {
return Nan::ThrowTypeError("createSsl's fourth argument must be an object");
}
Local<Object> object = Nan::To<Object>(info[3]).ToLocalChecked();
Local<Value> checkServerIdentityValue = Nan::Get(object,
Nan::New("checkServerIdentity").ToLocalChecked()).ToLocalChecked();
if (!checkServerIdentityValue->IsUndefined()) {
if (!checkServerIdentityValue->IsFunction()) {
return Nan::ThrowTypeError("Value of checkServerIdentity must be a function.");
}
Nan::Callback *callback = new Callback(Local<Function>::Cast(
checkServerIdentityValue));
verify_options.verify_peer_callback = verify_peer_callback_wrapper;
verify_options.verify_peer_callback_userdata = (void*)callback;
verify_options.verify_peer_destruct = verify_peer_callback_destruct;
}
}
grpc_channel_credentials *creds = grpc_ssl_credentials_create(
root_certs.get(), private_key.isAssigned() ? &key_cert_pair : NULL,
&verify_options, NULL);
if (creds == NULL) {
info.GetReturnValue().SetNull();
} else {
info.GetReturnValue().Set(WrapStruct(creds));
}
}
NAN_METHOD(ChannelCredentials::Compose) {
if (!ChannelCredentials::HasInstance(info.This())) {
return Nan::ThrowTypeError(
"compose can only be called on ChannelCredentials objects");
}
if (!CallCredentials::HasInstance(info[0])) {
return Nan::ThrowTypeError(
"compose's first argument must be a CallCredentials object");
}
ChannelCredentials *self =
ObjectWrap::Unwrap<ChannelCredentials>(info.This());
if (self->wrapped_credentials == NULL) {
return Nan::ThrowTypeError("Cannot compose insecure credential");
}
CallCredentials *other = ObjectWrap::Unwrap<CallCredentials>(
Nan::To<Object>(info[0]).ToLocalChecked());
grpc_channel_credentials *creds = grpc_composite_channel_credentials_create(
self->wrapped_credentials, other->GetWrappedCredentials(), NULL);
if (creds == NULL) {
info.GetReturnValue().SetNull();
} else {
info.GetReturnValue().Set(WrapStruct(creds));
}
}
NAN_METHOD(ChannelCredentials::CreateInsecure) {
info.GetReturnValue().Set(WrapStruct(NULL));
}
} // namespace node
} // namespace grpc

64
node_modules/grpc/ext/channel_credentials.h generated vendored Normal file
View File

@ -0,0 +1,64 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef NET_GRPC_NODE_CHANNEL_CREDENTIALS_H_
#define NET_GRPC_NODE_CHANNEL_CREDENTIALS_H_
#include <nan.h>
#include <node.h>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
namespace grpc {
namespace node {
/* Wrapper class for grpc_channel_credentials structs */
class ChannelCredentials : public Nan::ObjectWrap {
public:
static void Init(v8::Local<v8::Object> exports);
static bool HasInstance(v8::Local<v8::Value> val);
/* Wrap a grpc_channel_credentials struct in a javascript object */
static v8::Local<v8::Value> WrapStruct(grpc_channel_credentials *credentials);
/* Returns the grpc_channel_credentials struct that this object wraps */
grpc_channel_credentials *GetWrappedCredentials();
private:
explicit ChannelCredentials(grpc_channel_credentials *credentials);
~ChannelCredentials();
// Prevent copying
ChannelCredentials(const ChannelCredentials &);
ChannelCredentials &operator=(const ChannelCredentials &);
static NAN_METHOD(New);
static NAN_METHOD(CreateSsl);
static NAN_METHOD(CreateInsecure);
static NAN_METHOD(Compose);
static Nan::Callback *constructor;
// Used for typechecking instances of this javascript class
static Nan::Persistent<v8::FunctionTemplate> fun_tpl;
grpc_channel_credentials *wrapped_credentials;
};
} // namespace node
} // namespace grpc
#endif // NET_GRPC_NODE_CHANNEL_CREDENTIALS_H_

89
node_modules/grpc/ext/completion_queue.cc generated vendored Normal file
View File

@ -0,0 +1,89 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/grpc.h>
#include <node.h>
#include <uv.h>
#include <v8.h>
#include "call.h"
#include "completion_queue.h"
namespace grpc {
namespace node {
using v8::Local;
using v8::Object;
using v8::Value;
grpc_completion_queue *queue;
uv_prepare_t prepare;
int pending_batches;
static void drain_completion_queue(uv_prepare_t *handle) {
Nan::HandleScope scope;
grpc_event event;
(void)handle;
do {
event = grpc_completion_queue_next(queue, gpr_inf_past(GPR_CLOCK_MONOTONIC),
NULL);
if (event.type == GRPC_OP_COMPLETE) {
const char *error_message;
if (event.success) {
error_message = NULL;
} else {
error_message = "The async function encountered an error";
}
CompleteTag(event.tag, error_message);
grpc::node::DestroyTag(event.tag);
pending_batches--;
}
if (pending_batches == 0) {
uv_prepare_stop(&prepare);
}
} while (event.type != GRPC_QUEUE_TIMEOUT);
}
grpc_completion_queue *GetCompletionQueue() { return queue; }
void CompletionQueueNext() {
if (pending_batches == 0) {
uv_prepare_start(&prepare, drain_completion_queue);
}
pending_batches++;
}
void CompletionQueueInit(Local<Object> exports) {
queue = grpc_completion_queue_create_for_next(NULL);
uv_prepare_init(uv_default_loop(), &prepare);
pending_batches = 0;
}
void CompletionQueueForcePoll() {
/* This sets the prepare object to poll on the completion queue the next time
* Node polls for IO. But it doesn't increment the number of pending batches,
* so it will immediately stop polling after that unless there is an
* intervening CompletionQueueNext call */
if (pending_batches == 0) {
uv_prepare_start(&prepare, drain_completion_queue);
}
}
} // namespace node
} // namespace grpc

34
node_modules/grpc/ext/completion_queue.h generated vendored Normal file
View File

@ -0,0 +1,34 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/grpc.h>
#include <v8.h>
namespace grpc {
namespace node {
grpc_completion_queue *GetCompletionQueue();
void CompletionQueueNext();
void CompletionQueueInit(v8::Local<v8::Object> exports);
void CompletionQueueForcePoll();
} // namespace node
} // namespace grpc

318
node_modules/grpc/ext/node_grpc.cc generated vendored Normal file
View File

@ -0,0 +1,318 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <queue>
#include <nan.h>
#include <node.h>
#include <v8.h>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/alloc.h"
#include "grpc/support/log.h"
#include "grpc/support/time.h"
// TODO(murgatroid99): Remove this when the endpoint API becomes public
#include "src/core/lib/iomgr/pollset_uv.h"
#include "call.h"
#include "call_credentials.h"
#include "channel.h"
#include "channel_credentials.h"
#include "completion_queue.h"
#include "server.h"
#include "server_credentials.h"
#include "slice.h"
#include "timeval.h"
using grpc::node::CreateSliceFromString;
using v8::FunctionTemplate;
using v8::Local;
using v8::Value;
using v8::Number;
using v8::Object;
using v8::Uint32;
using v8::String;
typedef struct log_args {
gpr_log_func_args core_args;
gpr_timespec timestamp;
} log_args;
typedef struct logger_state {
Nan::Callback *callback;
Nan::AsyncResource *async_resource;
std::queue<log_args *> *pending_args;
uv_mutex_t mutex;
uv_async_t async;
// Indicates that a logger has been set
bool logger_set;
} logger_state;
logger_state grpc_logger_state;
static char *pem_root_certs = NULL;
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 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_SHUTDOWN));
Nan::Set(channel_state, Nan::New("FATAL_FAILURE").ToLocalChecked(),
FATAL_FAILURE);
}
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();
grpc_slice slice = CreateSliceFromString(key);
info.GetReturnValue().Set(static_cast<bool>(grpc_header_key_is_legal(slice)));
grpc_slice_unref(slice);
}
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();
grpc_slice slice = CreateSliceFromString(value);
info.GetReturnValue().Set(
static_cast<bool>(grpc_header_nonbin_value_is_legal(slice)));
grpc_slice_unref(slice);
}
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();
grpc_slice slice = CreateSliceFromString(key);
info.GetReturnValue().Set(static_cast<bool>(grpc_is_binary_header(slice)));
grpc_slice_unref(slice);
}
static grpc_ssl_roots_override_result get_ssl_roots_override(
char **pem_root_certs_ptr) {
*pem_root_certs_ptr = pem_root_certs;
if (pem_root_certs == NULL) {
return GRPC_SSL_ROOTS_OVERRIDE_FAIL;
} else {
return GRPC_SSL_ROOTS_OVERRIDE_OK;
}
}
/* This should only be called once, and only before creating any
*ServerCredentials */
NAN_METHOD(SetDefaultRootsPem) {
if (!info[0]->IsString()) {
return Nan::ThrowTypeError(
"setDefaultRootsPem's argument must be a string");
}
Nan::Utf8String utf8_roots(info[0]);
size_t length = static_cast<size_t>(utf8_roots.length());
if (length > 0) {
const char *data = *utf8_roots;
pem_root_certs = (char *)gpr_malloc((length + 1) * sizeof(char));
memcpy(pem_root_certs, data, length + 1);
}
}
NAUV_WORK_CB(LogMessagesCallback) {
Nan::HandleScope scope;
std::queue<log_args *> args;
uv_mutex_lock(&grpc_logger_state.mutex);
grpc_logger_state.pending_args->swap(args);
uv_mutex_unlock(&grpc_logger_state.mutex);
/* Call the callback with each log message */
while (!args.empty()) {
log_args *arg = args.front();
args.pop();
Local<Value> file = Nan::New(arg->core_args.file).ToLocalChecked();
Local<Value> line = Nan::New<Uint32, uint32_t>(arg->core_args.line);
Local<Value> severity =
Nan::New(gpr_log_severity_string(arg->core_args.severity))
.ToLocalChecked();
Local<Value> message = Nan::New(arg->core_args.message).ToLocalChecked();
Local<Value> timestamp =
Nan::New<v8::Date>(grpc::node::TimespecToMilliseconds(arg->timestamp))
.ToLocalChecked();
const int argc = 5;
Local<Value> argv[argc] = {file, line, severity, message, timestamp};
grpc_logger_state.callback->Call(argc, argv, grpc_logger_state.async_resource);
delete[] arg->core_args.message;
delete arg;
}
}
void node_log_func(gpr_log_func_args *args) {
// TODO(mlumish): Use the core's log formatter when it becomes available
log_args *args_copy = new log_args;
size_t message_len = strlen(args->message) + 1;
char *message = new char[message_len];
memcpy(message, args->message, message_len);
memcpy(&args_copy->core_args, args, sizeof(gpr_log_func_args));
args_copy->core_args.message = message;
args_copy->timestamp = gpr_now(GPR_CLOCK_REALTIME);
uv_mutex_lock(&grpc_logger_state.mutex);
grpc_logger_state.pending_args->push(args_copy);
uv_mutex_unlock(&grpc_logger_state.mutex);
uv_async_send(&grpc_logger_state.async);
}
void init_logger() {
memset(&grpc_logger_state, 0, sizeof(logger_state));
grpc_logger_state.pending_args = new std::queue<log_args *>();
uv_mutex_init(&grpc_logger_state.mutex);
uv_async_init(uv_default_loop(), &grpc_logger_state.async,
LogMessagesCallback);
uv_unref((uv_handle_t *)&grpc_logger_state.async);
grpc_logger_state.logger_set = false;
gpr_log_verbosity_init();
}
/* This registers a JavaScript logger for messages from the gRPC core. Because
that handler has to be run in the context of the JavaScript event loop, it
will be run asynchronously. To minimize the problems that could cause for
debugging, we leave core to do its default synchronous logging until a
JavaScript logger is set */
NAN_METHOD(SetDefaultLoggerCallback) {
if (!info[0]->IsFunction()) {
return Nan::ThrowTypeError(
"setDefaultLoggerCallback's argument must be a function");
}
if (!grpc_logger_state.logger_set) {
gpr_set_log_function(node_log_func);
grpc_logger_state.logger_set = true;
}
grpc_logger_state.callback = new Nan::Callback(info[0].As<v8::Function>());
grpc_logger_state.async_resource = new Nan::AsyncResource("grpc:logger");
}
NAN_METHOD(SetLogVerbosity) {
if (!info[0]->IsUint32()) {
return Nan::ThrowTypeError("setLogVerbosity's argument must be a number");
}
gpr_log_severity severity =
static_cast<gpr_log_severity>(Nan::To<uint32_t>(info[0]).FromJust());
gpr_set_log_verbosity(severity);
}
NAN_METHOD(ForcePoll) {
grpc::node::CompletionQueueForcePoll();
}
void init(Local<Object> exports) {
Nan::HandleScope scope;
grpc_init();
grpc_set_ssl_roots_override_callback(get_ssl_roots_override);
init_logger();
InitOpTypeConstants(exports);
InitConnectivityStateConstants(exports);
grpc_pollset_work_run_loop = 0;
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::ServerCredentials::Init(exports);
grpc::node::CompletionQueueInit(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());
Nan::Set(exports, Nan::New("setDefaultRootsPem").ToLocalChecked(),
Nan::GetFunction(Nan::New<FunctionTemplate>(SetDefaultRootsPem))
.ToLocalChecked());
Nan::Set(
exports, Nan::New("setDefaultLoggerCallback").ToLocalChecked(),
Nan::GetFunction(Nan::New<FunctionTemplate>(SetDefaultLoggerCallback))
.ToLocalChecked());
Nan::Set(exports, Nan::New("setLogVerbosity").ToLocalChecked(),
Nan::GetFunction(Nan::New<FunctionTemplate>(SetLogVerbosity))
.ToLocalChecked());
Nan::Set(exports, Nan::New("forcePoll").ToLocalChecked(),
Nan::GetFunction(Nan::New<FunctionTemplate>(ForcePoll))
.ToLocalChecked());
}
NODE_MODULE(grpc_node, init)

313
node_modules/grpc/ext/server.cc generated vendored Normal file
View File

@ -0,0 +1,313 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <memory>
#include "server.h"
#include <nan.h>
#include <node.h>
#include <vector>
#include "call.h"
#include "completion_queue.h"
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/log.h"
#include "server_credentials.h"
#include "slice.h"
#include "timeval.h"
namespace grpc {
namespace node {
using Nan::Callback;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::Maybe;
using Nan::MaybeLocal;
using Nan::ObjectWrap;
using Nan::Persistent;
using Nan::Utf8String;
using std::unique_ptr;
using v8::Array;
using v8::Boolean;
using v8::Date;
using v8::Exception;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;
Nan::Callback *Server::constructor;
Persistent<FunctionTemplate> Server::fun_tpl;
static Persistent<Function> shutdown_cb;
class ServerShutdownOp : public Op {
public:
ServerShutdownOp(Server *server) : server(server) {}
~ServerShutdownOp() {}
Local<Value> GetNodeValue() const {
EscapableHandleScope scope;
return scope.Escape(server->handle());
}
bool ParseOp(Local<Value> value, grpc_op *out) { return true; }
bool IsFinalOp() { return false; }
void OnComplete(bool success) {
if (success) {
server->FinishShutdown();
}
}
Server *server;
protected:
std::string GetTypeString() const { return "try_shutdown"; }
};
class NewCallOp : public Op {
public:
NewCallOp() {
call = NULL;
grpc_call_details_init(&details);
grpc_metadata_array_init(&request_metadata);
}
~NewCallOp() {
grpc_call_details_destroy(&details);
grpc_metadata_array_destroy(&request_metadata);
}
Local<Value> GetNodeValue() const {
Nan::EscapableHandleScope scope;
if (call == NULL) {
return scope.Escape(Nan::Null());
}
Local<Object> obj = Nan::New<Object>();
Nan::Set(obj, Nan::New("call").ToLocalChecked(), Call::WrapStruct(call));
// TODO(murgatroid99): Use zero-copy string construction instead
Nan::Set(obj, Nan::New("method").ToLocalChecked(),
CopyStringFromSlice(details.method));
Nan::Set(obj, Nan::New("host").ToLocalChecked(),
CopyStringFromSlice(details.host));
Nan::Set(obj, Nan::New("deadline").ToLocalChecked(),
Nan::New<Date>(TimespecToMilliseconds(details.deadline))
.ToLocalChecked());
Nan::Set(obj, Nan::New("metadata").ToLocalChecked(),
ParseMetadata(&request_metadata));
return scope.Escape(obj);
}
bool ParseOp(Local<Value> value, grpc_op *out) { return true; }
bool IsFinalOp() { return false; }
void OnComplete(bool success) {}
grpc_call *call;
grpc_call_details details;
grpc_metadata_array request_metadata;
protected:
std::string GetTypeString() const { return "new_call"; }
};
NAN_METHOD(ShutdownCallback) {
HandleScope scope;
if (!info[0]->IsNull()) {
return Nan::ThrowError("forceShutdown failed somehow");
}
}
Server::Server(grpc_server *server) :
wrapped_server(server), is_shutdown(false) {}
Server::~Server() { grpc_server_destroy(this->wrapped_server); }
void Server::Init(Local<Object> exports) {
HandleScope scope;
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("Server").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Nan::SetPrototypeMethod(tpl, "requestCall", RequestCall);
Nan::SetPrototypeMethod(tpl, "addHttp2Port", AddHttp2Port);
Nan::SetPrototypeMethod(tpl, "start", Start);
Nan::SetPrototypeMethod(tpl, "tryShutdown", TryShutdown);
Nan::SetPrototypeMethod(tpl, "forceShutdown", ForceShutdown);
fun_tpl.Reset(tpl);
Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
Nan::Set(exports, Nan::New("Server").ToLocalChecked(), ctr);
constructor = new Callback(ctr);
Local<FunctionTemplate> shutdown_tpl =
Nan::New<FunctionTemplate>(ShutdownCallback);
shutdown_cb.Reset(Nan::GetFunction(shutdown_tpl).ToLocalChecked());
}
bool Server::HasInstance(Local<Value> val) {
HandleScope scope;
return Nan::New(fun_tpl)->HasInstance(val);
}
void Server::FinishShutdown() {
is_shutdown = true;
running_self_ref.Reset();
}
void Server::ShutdownServer() {
Nan::HandleScope scope;
if (!this->is_shutdown) {
Callback *shutdown_callback =
new Callback(Nan::New(shutdown_cb));
ServerShutdownOp *op = new ServerShutdownOp(this);
unique_ptr<OpVec> ops(new OpVec());
ops->push_back(unique_ptr<Op>(op));
grpc_server_shutdown_and_notify(
this->wrapped_server, GetCompletionQueue(),
new struct tag(shutdown_callback, ops.release(), NULL, Nan::Null()));
grpc_server_cancel_all_calls(this->wrapped_server);
CompletionQueueNext();
}
}
NAN_METHOD(Server::New) {
/* If this is not a constructor call, make a constructor call and return
the result */
if (!info.IsConstructCall()) {
const int argc = 1;
Local<Value> argv[argc] = {info[0]};
MaybeLocal<Object> maybe_instance =
Nan::NewInstance(constructor->GetFunction(), argc, argv);
if (maybe_instance.IsEmpty()) {
// There's probably a pending exception
return;
} else {
info.GetReturnValue().Set(maybe_instance.ToLocalChecked());
return;
}
}
grpc_server *wrapped_server;
grpc_completion_queue *queue = GetCompletionQueue();
grpc_channel_args *channel_args;
if (!ParseChannelArgs(info[0], &channel_args)) {
DeallocateChannelArgs(channel_args);
return Nan::ThrowTypeError(
"Server options must be an object with "
"string keys and integer or string values");
}
wrapped_server = grpc_server_create(channel_args, NULL);
DeallocateChannelArgs(channel_args);
grpc_server_register_completion_queue(wrapped_server, queue, NULL);
Server *server = new Server(wrapped_server);
server->Wrap(info.This());
info.GetReturnValue().Set(info.This());
}
NAN_METHOD(Server::RequestCall) {
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError("requestCall can only be called on a Server");
}
Server *server = ObjectWrap::Unwrap<Server>(info.This());
NewCallOp *op = new NewCallOp();
unique_ptr<OpVec> ops(new OpVec());
ops->push_back(unique_ptr<Op>(op));
grpc_call_error error = grpc_server_request_call(
server->wrapped_server, &op->call, &op->details, &op->request_metadata,
GetCompletionQueue(), GetCompletionQueue(),
new struct tag(new Callback(info[0].As<Function>()), ops.release(), NULL,
Nan::Null()));
if (error != GRPC_CALL_OK) {
return Nan::ThrowError(nanErrorWithCode("requestCall failed", error));
}
CompletionQueueNext();
}
NAN_METHOD(Server::AddHttp2Port) {
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError("addHttp2Port can only be called on a Server");
}
if (!info[0]->IsString()) {
return Nan::ThrowTypeError(
"addHttp2Port's first argument must be a String");
}
if (!ServerCredentials::HasInstance(info[1])) {
return Nan::ThrowTypeError(
"addHttp2Port's second argument must be ServerCredentials");
}
Server *server = ObjectWrap::Unwrap<Server>(info.This());
ServerCredentials *creds_object = ObjectWrap::Unwrap<ServerCredentials>(
Nan::To<Object>(info[1]).ToLocalChecked());
grpc_server_credentials *creds = creds_object->GetWrappedServerCredentials();
int port;
if (creds == NULL) {
port = grpc_server_add_insecure_http2_port(server->wrapped_server,
*Utf8String(info[0]));
} else {
port = grpc_server_add_secure_http2_port(server->wrapped_server,
*Utf8String(info[0]), creds);
}
info.GetReturnValue().Set(Nan::New<Number>(port));
}
NAN_METHOD(Server::Start) {
Nan::HandleScope scope;
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError("start can only be called on a Server");
}
Server *server = ObjectWrap::Unwrap<Server>(info.This());
server->running_self_ref.Reset(info.This());
grpc_server_start(server->wrapped_server);
}
NAN_METHOD(Server::TryShutdown) {
Nan::HandleScope scope;
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError("tryShutdown can only be called on a Server");
}
if (!info[0]->IsFunction()) {
return Nan::ThrowError("tryShutdown's argument must be a callback");
}
Server *server = ObjectWrap::Unwrap<Server>(info.This());
ServerShutdownOp *op = new ServerShutdownOp(server);
unique_ptr<OpVec> ops(new OpVec());
ops->push_back(unique_ptr<Op>(op));
grpc_server_shutdown_and_notify(
server->wrapped_server, GetCompletionQueue(),
new struct tag(new Nan::Callback(info[0].As<Function>()), ops.release(),
NULL, Nan::Null()));
CompletionQueueNext();
}
NAN_METHOD(Server::ForceShutdown) {
Nan::HandleScope scope;
if (!HasInstance(info.This())) {
return Nan::ThrowTypeError("forceShutdown can only be called on a Server");
}
Server *server = ObjectWrap::Unwrap<Server>(info.This());
server->ShutdownServer();
}
} // namespace node
} // namespace grpc

70
node_modules/grpc/ext/server.h generated vendored Normal file
View File

@ -0,0 +1,70 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef NET_GRPC_NODE_SERVER_H_
#define NET_GRPC_NODE_SERVER_H_
#include <nan.h>
#include <node.h>
#include "grpc/grpc.h"
namespace grpc {
namespace node {
/* Wraps grpc_server as a JavaScript object. Provides a constructor
and wrapper methods for grpc_server_create, grpc_server_request_call,
grpc_server_add_http2_port, and grpc_server_start. */
class Server : public Nan::ObjectWrap {
public:
/* Initializes the Server class and exposes the constructor and
wrapper methods to JavaScript */
static void Init(v8::Local<v8::Object> exports);
/* Tests whether the given value was constructed by this class's
JavaScript constructor */
static bool HasInstance(v8::Local<v8::Value> val);
void FinishShutdown();
private:
explicit Server(grpc_server *server);
~Server();
// Prevent copying
Server(const Server &);
Server &operator=(const Server &);
void ShutdownServer();
static NAN_METHOD(New);
static NAN_METHOD(RequestCall);
static NAN_METHOD(AddHttp2Port);
static NAN_METHOD(Start);
static NAN_METHOD(TryShutdown);
static NAN_METHOD(ForceShutdown);
static Nan::Callback *constructor;
static Nan::Persistent<v8::FunctionTemplate> fun_tpl;
Nan::Persistent<v8::Value> running_self_ref;
grpc_server *wrapped_server;
bool is_shutdown;
};
} // namespace node
} // namespace grpc
#endif // NET_GRPC_NODE_SERVER_H_

192
node_modules/grpc/ext/server_credentials.cc generated vendored Normal file
View File

@ -0,0 +1,192 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <vector>
#include <nan.h>
#include <node.h>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/log.h"
#include "server_credentials.h"
#include "util.h"
namespace grpc {
namespace node {
using Nan::Callback;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::Maybe;
using Nan::MaybeLocal;
using Nan::ObjectWrap;
using Nan::Persistent;
using Nan::Utf8String;
using v8::Array;
using v8::Exception;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Value;
Nan::Callback *ServerCredentials::constructor;
Persistent<FunctionTemplate> ServerCredentials::fun_tpl;
ServerCredentials::ServerCredentials(grpc_server_credentials *credentials)
: wrapped_credentials(credentials) {}
ServerCredentials::~ServerCredentials() {
grpc_server_credentials_release(wrapped_credentials);
}
void ServerCredentials::Init(Local<Object> exports) {
Nan::HandleScope scope;
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("ServerCredentials").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
Nan::Set(
ctr, Nan::New("createSsl").ToLocalChecked(),
Nan::GetFunction(Nan::New<FunctionTemplate>(CreateSsl)).ToLocalChecked());
Nan::Set(ctr, Nan::New("createInsecure").ToLocalChecked(),
Nan::GetFunction(Nan::New<FunctionTemplate>(CreateInsecure))
.ToLocalChecked());
fun_tpl.Reset(tpl);
constructor = new Nan::Callback(ctr);
Nan::Set(exports, Nan::New("ServerCredentials").ToLocalChecked(), ctr);
}
bool ServerCredentials::HasInstance(Local<Value> val) {
Nan::HandleScope scope;
return Nan::New(fun_tpl)->HasInstance(val);
}
Local<Value> ServerCredentials::WrapStruct(
grpc_server_credentials *credentials) {
Nan::EscapableHandleScope scope;
const int argc = 1;
Local<Value> argv[argc] = {
Nan::New<External>(reinterpret_cast<void *>(credentials))};
MaybeLocal<Object> maybe_instance =
Nan::NewInstance(constructor->GetFunction(), argc, argv);
if (maybe_instance.IsEmpty()) {
return scope.Escape(Nan::Null());
} else {
return scope.Escape(maybe_instance.ToLocalChecked());
}
}
grpc_server_credentials *ServerCredentials::GetWrappedServerCredentials() {
return wrapped_credentials;
}
NAN_METHOD(ServerCredentials::New) {
if (info.IsConstructCall()) {
if (!info[0]->IsExternal()) {
return Nan::ThrowTypeError(
"ServerCredentials can only be created with the provided functions");
}
Local<External> ext = info[0].As<External>();
grpc_server_credentials *creds_value =
reinterpret_cast<grpc_server_credentials *>(ext->Value());
ServerCredentials *credentials = new ServerCredentials(creds_value);
credentials->Wrap(info.This());
info.GetReturnValue().Set(info.This());
} else {
// This should never be called directly
return Nan::ThrowTypeError(
"ServerCredentials can only be created with the provided functions");
}
}
NAN_METHOD(ServerCredentials::CreateSsl) {
Nan::HandleScope scope;
StringOrNull root_certs;
if (::node::Buffer::HasInstance(info[0])) {
root_certs.assign(info[0]);
} else if (!(info[0]->IsNull() || info[0]->IsUndefined())) {
return Nan::ThrowTypeError(
"createSSl's first argument must be a Buffer if provided");
}
if (!info[1]->IsArray()) {
return Nan::ThrowTypeError(
"createSsl's second argument must be a list of objects");
}
// Default to not requesting the client certificate
grpc_ssl_client_certificate_request_type client_certificate_request =
GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE;
if (info[2]->IsBoolean()) {
client_certificate_request =
Nan::To<bool>(info[2]).FromJust()
? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
: GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE;
} else if (!(info[2]->IsUndefined() || info[2]->IsNull())) {
return Nan::ThrowTypeError(
"createSsl's third argument must be a boolean if provided");
}
Local<Array> pair_list = Local<Array>::Cast(info[1]);
uint32_t key_cert_pair_count = pair_list->Length();
std::vector<grpc_ssl_pem_key_cert_pair> key_cert_pairs(key_cert_pair_count);
std::vector<StringOrNull> key_strings(key_cert_pair_count);
std::vector<StringOrNull> cert_strings(key_cert_pair_count);
Local<String> key_key = Nan::New("private_key").ToLocalChecked();
Local<String> cert_key = Nan::New("cert_chain").ToLocalChecked();
for (uint32_t i = 0; i < key_cert_pair_count; i++) {
Local<Value> pair_val = Nan::Get(pair_list, i).ToLocalChecked();
if (!pair_val->IsObject()) {
return Nan::ThrowTypeError("Key/cert pairs must be objects");
}
Local<Object> pair_obj = Nan::To<Object>(pair_val).ToLocalChecked();
Local<Value> maybe_key = Nan::Get(pair_obj, key_key).ToLocalChecked();
Local<Value> maybe_cert = Nan::Get(pair_obj, cert_key).ToLocalChecked();
if (!::node::Buffer::HasInstance(maybe_key)) {
return Nan::ThrowTypeError("private_key must be a Buffer");
}
if (!::node::Buffer::HasInstance(maybe_cert)) {
return Nan::ThrowTypeError("cert_chain must be a Buffer");
}
key_strings[i].assign(maybe_key);
cert_strings[i].assign(maybe_cert);
key_cert_pairs[i].private_key = key_strings[i].get();
key_cert_pairs[i].cert_chain = cert_strings[i].get();
}
grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex(
root_certs.get(), key_cert_pairs.data(), key_cert_pair_count,
client_certificate_request, NULL);
if (creds == NULL) {
info.GetReturnValue().SetNull();
} else {
info.GetReturnValue().Set(WrapStruct(creds));
}
}
NAN_METHOD(ServerCredentials::CreateInsecure) {
info.GetReturnValue().Set(WrapStruct(NULL));
}
} // namespace node
} // namespace grpc

62
node_modules/grpc/ext/server_credentials.h generated vendored Normal file
View File

@ -0,0 +1,62 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef NET_GRPC_NODE_SERVER_CREDENTIALS_H_
#define NET_GRPC_NODE_SERVER_CREDENTIALS_H_
#include <nan.h>
#include <node.h>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
namespace grpc {
namespace node {
/* Wrapper class for grpc_server_credentials structs */
class ServerCredentials : public Nan::ObjectWrap {
public:
static void Init(v8::Local<v8::Object> exports);
static bool HasInstance(v8::Local<v8::Value> val);
/* Wrap a grpc_server_credentials struct in a javascript object */
static v8::Local<v8::Value> WrapStruct(grpc_server_credentials *credentials);
/* Returns the grpc_server_credentials struct that this object wraps */
grpc_server_credentials *GetWrappedServerCredentials();
private:
explicit ServerCredentials(grpc_server_credentials *credentials);
~ServerCredentials();
// Prevent copying
ServerCredentials(const ServerCredentials &);
ServerCredentials &operator=(const ServerCredentials &);
static NAN_METHOD(New);
static NAN_METHOD(CreateSsl);
static NAN_METHOD(CreateInsecure);
static Nan::Callback *constructor;
// Used for typechecking instances of this javascript class
static Nan::Persistent<v8::FunctionTemplate> fun_tpl;
grpc_server_credentials *wrapped_credentials;
};
} // namespace node
} // namespace grpc
#endif // NET_GRPC_NODE_SERVER_CREDENTIALS_H_

90
node_modules/grpc/ext/slice.cc generated vendored Normal file
View File

@ -0,0 +1,90 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/slice.h>
#include <grpc/support/alloc.h>
#include <nan.h>
#include <node.h>
#include "slice.h"
namespace grpc {
namespace node {
using Nan::Persistent;
using v8::Local;
using v8::String;
using v8::Value;
namespace {
void SliceFreeCallback(char *data, void *hint) {
grpc_slice *slice = reinterpret_cast<grpc_slice *>(hint);
grpc_slice_unref(*slice);
delete slice;
}
void string_destroy_func(void *user_data) {
delete reinterpret_cast<Nan::Utf8String *>(user_data);
}
void buffer_destroy_func(void *user_data) {
delete reinterpret_cast<PersistentValue *>(user_data);
}
} // namespace
grpc_slice CreateSliceFromString(const Local<String> source) {
Nan::HandleScope scope;
Nan::Utf8String *utf8_value = new Nan::Utf8String(source);
return grpc_slice_new_with_user_data(**utf8_value, utf8_value->length(),
string_destroy_func, utf8_value);
}
grpc_slice CreateSliceFromBuffer(const Local<Value> source) {
// Prerequisite: ::node::Buffer::HasInstance(source)
Nan::HandleScope scope;
return grpc_slice_new_with_user_data(
::node::Buffer::Data(source), ::node::Buffer::Length(source),
buffer_destroy_func, new PersistentValue(source));
}
Local<String> CopyStringFromSlice(const grpc_slice slice) {
Nan::EscapableHandleScope scope;
if (GRPC_SLICE_LENGTH(slice) == 0) {
return scope.Escape(Nan::EmptyString());
}
return scope.Escape(
Nan::New<String>(const_cast<char *>(reinterpret_cast<const char *>(
GRPC_SLICE_START_PTR(slice))),
GRPC_SLICE_LENGTH(slice))
.ToLocalChecked());
}
Local<Value> CreateBufferFromSlice(const grpc_slice slice) {
Nan::EscapableHandleScope scope;
grpc_slice *slice_ptr = new grpc_slice;
*slice_ptr = grpc_slice_ref(slice);
return scope.Escape(
Nan::NewBuffer(
const_cast<char *>(
reinterpret_cast<const char *>(GRPC_SLICE_START_PTR(*slice_ptr))),
GRPC_SLICE_LENGTH(*slice_ptr), SliceFreeCallback, slice_ptr)
.ToLocalChecked());
}
} // namespace node
} // namespace grpc

38
node_modules/grpc/ext/slice.h generated vendored Normal file
View File

@ -0,0 +1,38 @@
/*
*
* Copyright 2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/slice.h>
#include <nan.h>
#include <node.h>
namespace grpc {
namespace node {
typedef Nan::Persistent<v8::Value, Nan::CopyablePersistentTraits<v8::Value>>
PersistentValue;
grpc_slice CreateSliceFromString(const v8::Local<v8::String> source);
grpc_slice CreateSliceFromBuffer(const v8::Local<v8::Value> source);
v8::Local<v8::String> CopyStringFromSlice(const grpc_slice slice);
v8::Local<v8::Value> CreateBufferFromSlice(const grpc_slice slice);
} // namespace node
} // namespace grpc

53
node_modules/grpc/ext/timeval.cc generated vendored Normal file
View File

@ -0,0 +1,53 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <cstdint>
#include <limits>
#include "grpc/grpc.h"
#include "grpc/support/time.h"
#include "timeval.h"
namespace grpc {
namespace node {
gpr_timespec MillisecondsToTimespec(double millis) {
if (millis == std::numeric_limits<double>::infinity()) {
return gpr_inf_future(GPR_CLOCK_REALTIME);
} else if (millis == -std::numeric_limits<double>::infinity()) {
return gpr_inf_past(GPR_CLOCK_REALTIME);
} else {
return gpr_time_from_micros(static_cast<int64_t>(millis * 1000),
GPR_CLOCK_REALTIME);
}
}
double TimespecToMilliseconds(gpr_timespec timespec) {
timespec = gpr_convert_clock_type(timespec, GPR_CLOCK_REALTIME);
if (gpr_time_cmp(timespec, gpr_inf_future(GPR_CLOCK_REALTIME)) == 0) {
return std::numeric_limits<double>::infinity();
} else if (gpr_time_cmp(timespec, gpr_inf_past(GPR_CLOCK_REALTIME)) == 0) {
return -std::numeric_limits<double>::infinity();
} else {
return (static_cast<double>(timespec.tv_sec) * 1000 +
static_cast<double>(timespec.tv_nsec) / 1000000);
}
}
} // namespace node
} // namespace grpc

33
node_modules/grpc/ext/timeval.h generated vendored Normal file
View File

@ -0,0 +1,33 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef NET_GRPC_NODE_TIMEVAL_H_
#define NET_GRPC_NODE_TIMEVAL_H_
#include "grpc/support/time.h"
namespace grpc {
namespace node {
double TimespecToMilliseconds(gpr_timespec time);
gpr_timespec MillisecondsToTimespec(double millis);
} // namespace node
} // namespace grpc
#endif // NET_GRPC_NODE_TIMEVAL_H_

52
node_modules/grpc/ext/util.h generated vendored Normal file
View File

@ -0,0 +1,52 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef NET_GRPC_NODE_UTIL_H_
#define NET_GRPC_NODE_UTIL_H_
#include <node.h>
#include <nan.h>
#include <string>
namespace grpc {
namespace node {
class StringOrNull {
public:
StringOrNull() : assigned(false) { }
void assign(v8::Local<v8::Value> buffer) {
str_ = std::string(::node::Buffer::Data(buffer),
::node::Buffer::Length(buffer));
assigned = true;
}
const char * get() {
return assigned ? str_.c_str() : NULL;
}
bool isAssigned() {
return assigned;
}
private:
std::string str_;
bool assigned;
};
} // namespace node
} // namespace grpc
#endif // NET_GRPC_NODE_UTIL_H_