mirror of
https://github.com/musix-org/musix-oss
synced 2025-06-17 04:26:00 +00:00
Modules
This commit is contained in:
79
node_modules/grpc/ext/byte_buffer.cc
generated
vendored
Normal file
79
node_modules/grpc/ext/byte_buffer.cc
generated
vendored
Normal 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
41
node_modules/grpc/ext/byte_buffer.h
generated
vendored
Normal 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
778
node_modules/grpc/ext/call.cc
generated
vendored
Normal 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
122
node_modules/grpc/ext/call.h
generated
vendored
Normal 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
276
node_modules/grpc/ext/call_credentials.cc
generated
vendored
Normal 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
110
node_modules/grpc/ext/call_credentials.h
generated
vendored
Normal 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
397
node_modules/grpc/ext/channel.cc
generated
vendored
Normal 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
69
node_modules/grpc/ext/channel.h
generated
vendored
Normal 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
253
node_modules/grpc/ext/channel_credentials.cc
generated
vendored
Normal 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
64
node_modules/grpc/ext/channel_credentials.h
generated
vendored
Normal 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
89
node_modules/grpc/ext/completion_queue.cc
generated
vendored
Normal 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
34
node_modules/grpc/ext/completion_queue.h
generated
vendored
Normal 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
318
node_modules/grpc/ext/node_grpc.cc
generated
vendored
Normal 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
313
node_modules/grpc/ext/server.cc
generated
vendored
Normal 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
70
node_modules/grpc/ext/server.h
generated
vendored
Normal 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
192
node_modules/grpc/ext/server_credentials.cc
generated
vendored
Normal 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
62
node_modules/grpc/ext/server_credentials.h
generated
vendored
Normal 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
90
node_modules/grpc/ext/slice.cc
generated
vendored
Normal 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
38
node_modules/grpc/ext/slice.h
generated
vendored
Normal 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
53
node_modules/grpc/ext/timeval.cc
generated
vendored
Normal 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
33
node_modules/grpc/ext/timeval.h
generated
vendored
Normal 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
52
node_modules/grpc/ext/util.h
generated
vendored
Normal 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_
|
Reference in New Issue
Block a user