diff --git a/binding.gyp b/binding.gyp index a6440309..36147a55 100644 --- a/binding.gyp +++ b/binding.gyp @@ -72,9 +72,10 @@ "sources": [ "ext/byte_buffer.cc", "ext/call.cc", + "ext/call_credentials.cc", "ext/channel.cc", + "ext/channel_credentials.cc", "ext/completion_queue_async_worker.cc", - "ext/credentials.cc", "ext/node_grpc.cc", "ext/server.cc", "ext/server_credentials.cc", diff --git a/ext/call.cc b/ext/call.cc index fccb30f5..11626355 100644 --- a/ext/call.cc +++ b/ext/call.cc @@ -46,7 +46,7 @@ #include "call.h" #include "channel.h" #include "completion_queue_async_worker.h" -#include "credentials.h" +#include "call_credentials.h" #include "timeval.h" using std::unique_ptr; @@ -733,12 +733,12 @@ NAN_METHOD(Call::SetCredentials) { return Nan::ThrowTypeError( "setCredentials can only be called on Call objects"); } - if (!Credentials::HasInstance(info[0])) { + if (!CallCredentials::HasInstance(info[0])) { return Nan::ThrowTypeError( - "setCredentials' first argument must be a credential"); + "setCredentials' first argument must be a CallCredentials"); } Call *call = ObjectWrap::Unwrap(info.This()); - Credentials *creds_object = ObjectWrap::Unwrap( + CallCredentials *creds_object = ObjectWrap::Unwrap( Nan::To(info[0]).ToLocalChecked()); grpc_credentials *creds = creds_object->GetWrappedCredentials(); grpc_call_error error = GRPC_CALL_ERROR; diff --git a/ext/credentials.cc b/ext/call_credentials.cc similarity index 68% rename from ext/credentials.cc rename to ext/call_credentials.cc index 182c99d0..839bb567 100644 --- a/ext/credentials.cc +++ b/ext/call_credentials.cc @@ -36,7 +36,7 @@ #include "grpc/grpc.h" #include "grpc/grpc_security.h" #include "grpc/support/log.h" -#include "credentials.h" +#include "call_credentials.h" #include "call.h" namespace grpc { @@ -61,47 +61,42 @@ using v8::Object; using v8::ObjectTemplate; using v8::Value; -Nan::Callback *Credentials::constructor; -Persistent Credentials::fun_tpl; +Nan::Callback *CallCredentials::constructor; +Persistent CallCredentials::fun_tpl; -Credentials::Credentials(grpc_credentials *credentials) +CallCredentials::CallCredentials(grpc_credentials *credentials) : wrapped_credentials(credentials) {} -Credentials::~Credentials() { +CallCredentials::~CallCredentials() { grpc_credentials_release(wrapped_credentials); } -void Credentials::Init(Local exports) { +void CallCredentials::Init(Local exports) { HandleScope scope; Local tpl = Nan::New(New); - tpl->SetClassName(Nan::New("Credentials").ToLocalChecked()); + tpl->SetClassName(Nan::New("CallCredentials").ToLocalChecked()); tpl->InstanceTemplate()->SetInternalFieldCount(1); + Nan::SetPrototypeMethod(tpl, "compose", Compose); fun_tpl.Reset(tpl); Local ctr = Nan::GetFunction(tpl).ToLocalChecked(); - Nan::Set(ctr, Nan::New("createSsl").ToLocalChecked(), - Nan::GetFunction( - Nan::New(CreateSsl)).ToLocalChecked()); - Nan::Set(ctr, Nan::New("createComposite").ToLocalChecked(), - Nan::GetFunction( - Nan::New(CreateComposite)).ToLocalChecked()); - Nan::Set(ctr, Nan::New("createInsecure").ToLocalChecked(), - Nan::GetFunction( - Nan::New(CreateInsecure)).ToLocalChecked()); Nan::Set(ctr, Nan::New("createFromPlugin").ToLocalChecked(), Nan::GetFunction( Nan::New(CreateFromPlugin)).ToLocalChecked()); - Nan::Set(exports, Nan::New("Credentials").ToLocalChecked(), ctr); + Nan::Set(exports, Nan::New("CallCredentials").ToLocalChecked(), ctr); constructor = new Nan::Callback(ctr); } -bool Credentials::HasInstance(Local val) { +bool CallCredentials::HasInstance(Local val) { HandleScope scope; return Nan::New(fun_tpl)->HasInstance(val); } -Local Credentials::WrapStruct(grpc_credentials *credentials) { +Local CallCredentials::WrapStruct(grpc_credentials *credentials) { EscapableHandleScope scope; const int argc = 1; + if (credentials == NULL) { + return scope.Escape(Nan::Null()); + } Local argv[argc] = { Nan::New(reinterpret_cast(credentials))}; MaybeLocal maybe_instance = Nan::NewInstance( @@ -113,20 +108,20 @@ Local Credentials::WrapStruct(grpc_credentials *credentials) { } } -grpc_credentials *Credentials::GetWrappedCredentials() { +grpc_credentials *CallCredentials::GetWrappedCredentials() { return wrapped_credentials; } -NAN_METHOD(Credentials::New) { +NAN_METHOD(CallCredentials::New) { if (info.IsConstructCall()) { if (!info[0]->IsExternal()) { return Nan::ThrowTypeError( - "Credentials can only be created with the provided functions"); + "CallCredentials can only be created with the provided functions"); } Local ext = info[0].As(); grpc_credentials *creds_value = reinterpret_cast(ext->Value()); - Credentials *credentials = new Credentials(creds_value); + CallCredentials *credentials = new CallCredentials(creds_value); credentials->Wrap(info.This()); info.GetReturnValue().Set(info.This()); return; @@ -144,71 +139,26 @@ NAN_METHOD(Credentials::New) { } } -NAN_METHOD(Credentials::CreateSsl) { - char *root_certs = NULL; - grpc_ssl_pem_key_cert_pair key_cert_pair = {NULL, NULL}; - if (::node::Buffer::HasInstance(info[0])) { - root_certs = ::node::Buffer::Data(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])) { - key_cert_pair.private_key = ::node::Buffer::Data(info[1]); - } else if (!(info[1]->IsNull() || info[1]->IsUndefined())) { +NAN_METHOD(CallCredentials::Compose) { + if (!CallCredentials::HasInstance(info.This())) { return Nan::ThrowTypeError( - "createSSl's second argument must be a Buffer if provided"); + "compose can only be called on CallCredentials objects"); } - if (::node::Buffer::HasInstance(info[2])) { - key_cert_pair.cert_chain = ::node::Buffer::Data(info[2]); - } else if (!(info[2]->IsNull() || info[2]->IsUndefined())) { + if (!CallCredentials::HasInstance(info[0])) { return Nan::ThrowTypeError( - "createSSl's third argument must be a Buffer if provided"); + "compose's first argument must be a CallCredentials object"); } - grpc_credentials *creds = grpc_ssl_credentials_create( - root_certs, key_cert_pair.private_key == NULL ? NULL : &key_cert_pair, - NULL); - if (creds == NULL) { - info.GetReturnValue().SetNull(); - } else { - info.GetReturnValue().Set(WrapStruct(creds)); - } -} - -NAN_METHOD(Credentials::CreateComposite) { - if (!HasInstance(info[0])) { - return Nan::ThrowTypeError( - "createComposite's first argument must be a Credentials object"); - } - if (!HasInstance(info[1])) { - return Nan::ThrowTypeError( - "createComposite's second argument must be a Credentials object"); - } - Credentials *creds0 = ObjectWrap::Unwrap( + CallCredentials *self = ObjectWrap::Unwrap(info.This()); + CallCredentials *other = ObjectWrap::Unwrap( Nan::To(info[0]).ToLocalChecked()); - Credentials *creds1 = ObjectWrap::Unwrap( - Nan::To(info[1]).ToLocalChecked()); - if (creds0->wrapped_credentials == NULL) { - info.GetReturnValue().Set(info[1]); - return; - } - if (creds1->wrapped_credentials == NULL) { - info.GetReturnValue().Set(info[0]); - return; - } grpc_credentials *creds = grpc_composite_credentials_create( - creds0->wrapped_credentials, creds1->wrapped_credentials, NULL); - if (creds == NULL) { - info.GetReturnValue().SetNull(); - } else { - info.GetReturnValue().Set(WrapStruct(creds)); - } + self->wrapped_credentials, other->wrapped_credentials, NULL); + info.GetReturnValue().Set(WrapStruct(creds)); } -NAN_METHOD(Credentials::CreateInsecure) { - info.GetReturnValue().Set(WrapStruct(NULL)); -} -NAN_METHOD(Credentials::CreateFromPlugin) { + +NAN_METHOD(CallCredentials::CreateFromPlugin) { if (!info[0]->IsFunction()) { return Nan::ThrowTypeError( "createFromPlugin's argument must be a function"); @@ -221,11 +171,7 @@ NAN_METHOD(Credentials::CreateFromPlugin) { plugin.state = reinterpret_cast(state); grpc_credentials *creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL); - if (creds == NULL) { - info.GetReturnValue().SetNull(); - } else { - info.GetReturnValue().Set(WrapStruct(creds)); - } + info.GetReturnValue().Set(WrapStruct(creds)); } NAN_METHOD(PluginCallback) { @@ -245,9 +191,6 @@ NAN_METHOD(PluginCallback) { shared_ptr resources(new Resources); grpc_status_code code = static_cast( Nan::To(info[0]).FromJust()); - //Utf8String details_str(info[1]); - //char *details = static_cast(calloc(details_str.length(), sizeof(char))); - //memcpy(details, *details_str, details_str.length()); char *details = *Utf8String(info[1]); grpc_metadata_array array; if (!CreateMetadataArray(Nan::To(info[2]).ToLocalChecked(), diff --git a/ext/credentials.h b/ext/call_credentials.h similarity index 85% rename from ext/credentials.h rename to ext/call_credentials.h index fd0360ed..618292d1 100644 --- a/ext/credentials.h +++ b/ext/call_credentials.h @@ -31,19 +31,17 @@ * */ -#ifndef NET_GRPC_NODE_CREDENTIALS_H_ -#define NET_GRPC_NODE_CREDENTIALS_H_ +#ifndef GRPC_NODE_CALL_CREDENTIALS_H_ +#define GRPC_NODE_CALL_CREDENTIALS_H_ #include #include -#include "grpc/grpc.h" #include "grpc/grpc_security.h" namespace grpc { namespace node { -/* Wrapper class for grpc_credentials structs */ -class Credentials : public Nan::ObjectWrap { +class CallCredentials : public Nan::ObjectWrap { public: static void Init(v8::Local exports); static bool HasInstance(v8::Local val); @@ -54,18 +52,18 @@ class Credentials : public Nan::ObjectWrap { grpc_credentials *GetWrappedCredentials(); private: - explicit Credentials(grpc_credentials *credentials); - ~Credentials(); + explicit CallCredentials(grpc_credentials *credentials); + ~CallCredentials(); // Prevent copying - Credentials(const Credentials &); - Credentials &operator=(const Credentials &); + CallCredentials(const CallCredentials &); + CallCredentials &operator=(const CallCredentials &); static NAN_METHOD(New); static NAN_METHOD(CreateSsl); - static NAN_METHOD(CreateComposite); - static NAN_METHOD(CreateInsecure); static NAN_METHOD(CreateFromPlugin); + + static NAN_METHOD(Compose); static Nan::Callback *constructor; // Used for typechecking instances of this javascript class static Nan::Persistent fun_tpl; @@ -97,6 +95,6 @@ NAN_METHOD(PluginCallback); NAUV_WORK_CB(SendPluginCallback); } // namespace node -} // namespace grpc +} // namepsace grpc -#endif // NET_GRPC_NODE_CREDENTIALS_H_ +#endif // GRPC_NODE_CALL_CREDENTIALS_H_ diff --git a/ext/channel.cc b/ext/channel.cc index 6eb1e776..a328c017 100644 --- a/ext/channel.cc +++ b/ext/channel.cc @@ -42,7 +42,7 @@ #include "call.h" #include "channel.h" #include "completion_queue_async_worker.h" -#include "credentials.h" +#include "channel_credentials.h" #include "timeval.h" namespace grpc { @@ -112,11 +112,11 @@ NAN_METHOD(Channel::New) { // Owned by the Channel object Utf8String host(info[0]); grpc_credentials *creds; - if (!Credentials::HasInstance(info[1])) { + if (!ChannelCredentials::HasInstance(info[1])) { return Nan::ThrowTypeError( - "Channel's second argument must be a credential"); + "Channel's second argument must be a ChannelCredentials"); } - Credentials *creds_object = ObjectWrap::Unwrap( + ChannelCredentials *creds_object = ObjectWrap::Unwrap( Nan::To(info[1]).ToLocalChecked()); creds = creds_object->GetWrappedCredentials(); grpc_channel_args *channel_args_ptr; diff --git a/ext/channel_credentials.cc b/ext/channel_credentials.cc new file mode 100644 index 00000000..07763bd3 --- /dev/null +++ b/ext/channel_credentials.cc @@ -0,0 +1,200 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include "grpc/grpc.h" +#include "grpc/grpc_security.h" +#include "grpc/support/log.h" +#include "channel_credentials.h" +#include "call_credentials.h" +#include "call.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 *ChannelCredentials::constructor; +Persistent ChannelCredentials::fun_tpl; + +ChannelCredentials::ChannelCredentials(grpc_credentials *credentials) + : wrapped_credentials(credentials) {} + +ChannelCredentials::~ChannelCredentials() { + grpc_credentials_release(wrapped_credentials); +} + +void ChannelCredentials::Init(Local exports) { + HandleScope scope; + Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("ChannelCredentials").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + Nan::SetPrototypeMethod(tpl, "compose", Compose); + fun_tpl.Reset(tpl); + Local ctr = Nan::GetFunction(tpl).ToLocalChecked(); + Nan::Set(ctr, Nan::New("createSsl").ToLocalChecked(), + Nan::GetFunction( + Nan::New(CreateSsl)).ToLocalChecked()); + Nan::Set(ctr, Nan::New("createInsecure").ToLocalChecked(), + Nan::GetFunction( + Nan::New(CreateInsecure)).ToLocalChecked()); + Nan::Set(exports, Nan::New("ChannelCredentials").ToLocalChecked(), ctr); + constructor = new Nan::Callback(ctr); +} + +bool ChannelCredentials::HasInstance(Local val) { + HandleScope scope; + return Nan::New(fun_tpl)->HasInstance(val); +} + +Local ChannelCredentials::WrapStruct(grpc_credentials *credentials) { + EscapableHandleScope scope; + const int argc = 1; + Local argv[argc] = { + Nan::New(reinterpret_cast(credentials))}; + MaybeLocal 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_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 ext = info[0].As(); + grpc_credentials *creds_value = + reinterpret_cast(ext->Value()); + ChannelCredentials *credentials = new ChannelCredentials(creds_value); + credentials->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); + return; + } else { + const int argc = 1; + Local argv[argc] = {info[0]}; + MaybeLocal maybe_instance = constructor->GetFunction()->NewInstance( + argc, argv); + if (maybe_instance.IsEmpty()) { + // There's probably a pending exception + return; + } else { + info.GetReturnValue().Set(maybe_instance.ToLocalChecked()); + } + } +} + +NAN_METHOD(ChannelCredentials::CreateSsl) { + char *root_certs = NULL; + grpc_ssl_pem_key_cert_pair key_cert_pair = {NULL, NULL}; + if (::node::Buffer::HasInstance(info[0])) { + root_certs = ::node::Buffer::Data(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])) { + key_cert_pair.private_key = ::node::Buffer::Data(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])) { + key_cert_pair.cert_chain = ::node::Buffer::Data(info[2]); + } else if (!(info[2]->IsNull() || info[2]->IsUndefined())) { + return Nan::ThrowTypeError( + "createSSl's third argument must be a Buffer if provided"); + } + grpc_credentials *creds = grpc_ssl_credentials_create( + root_certs, key_cert_pair.private_key == NULL ? NULL : &key_cert_pair, + 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( + info.This()); + CallCredentials *other = ObjectWrap::Unwrap( + Nan::To(info[0]).ToLocalChecked()); + grpc_credentials *creds = grpc_composite_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 diff --git a/ext/channel_credentials.h b/ext/channel_credentials.h new file mode 100644 index 00000000..31ea0987 --- /dev/null +++ b/ext/channel_credentials.h @@ -0,0 +1,79 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef NET_GRPC_NODE_CHANNEL_CREDENTIALS_H_ +#define NET_GRPC_NODE_CHANNEL_CREDENTIALS_H_ + +#include +#include +#include "grpc/grpc.h" +#include "grpc/grpc_security.h" + +namespace grpc { +namespace node { + +/* Wrapper class for grpc_credentials structs */ +class ChannelCredentials : public Nan::ObjectWrap { + public: + static void Init(v8::Local exports); + static bool HasInstance(v8::Local val); + /* Wrap a grpc_credentials struct in a javascript object */ + static v8::Local WrapStruct(grpc_credentials *credentials); + + /* Returns the grpc_credentials struct that this object wraps */ + grpc_credentials *GetWrappedCredentials(); + + private: + explicit ChannelCredentials(grpc_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 fun_tpl; + + grpc_credentials *wrapped_credentials; +}; + +} // namespace node +} // namespace grpc + +#endif // NET_GRPC_NODE_CHANNEL_CREDENTIALS_H_ diff --git a/ext/node_grpc.cc b/ext/node_grpc.cc index caca0fc4..6fdd398f 100644 --- a/ext/node_grpc.cc +++ b/ext/node_grpc.cc @@ -37,10 +37,11 @@ #include "grpc/grpc.h" #include "call.h" +#include "call_credentials.h" #include "channel.h" +#include "channel_credentials.h" #include "server.h" #include "completion_queue_async_worker.h" -#include "credentials.h" #include "server_credentials.h" using v8::Local; @@ -240,10 +241,11 @@ void init(Local exports) { InitWriteFlags(exports); grpc::node::Call::Init(exports); + grpc::node::CallCredentials::Init(exports); grpc::node::Channel::Init(exports); + grpc::node::ChannelCredentials::Init(exports); grpc::node::Server::Init(exports); grpc::node::CompletionQueueAsyncWorker::Init(exports); - grpc::node::Credentials::Init(exports); grpc::node::ServerCredentials::Init(exports); } diff --git a/interop/interop_client.js b/interop/interop_client.js index 84cd7aff..ba87d422 100644 --- a/interop/interop_client.js +++ b/interop/interop_client.js @@ -460,7 +460,8 @@ function runTest(address, host_override, test_case, tls, test_ca, done) { if (test.getCreds) { test.getCreds(function(err, new_creds) { - execute(err, grpc.credentials.combineCredentials(creds, new_creds)); + execute(err, grpc.credentials.combineChannelCredentials( + creds, new_creds)); }); } else { execute(null, creds); diff --git a/src/credentials.js b/src/credentials.js index f233ba76..b7a3ea5b 100644 --- a/src/credentials.js +++ b/src/credentials.js @@ -40,7 +40,9 @@ var grpc = require('bindings')('grpc.node'); -var Credentials = grpc.Credentials; +var CallCredentials = grpc.CallCredentials; + +var ChannelCredentials = grpc.ChannelCredentials; var Metadata = require('./metadata.js'); @@ -51,8 +53,9 @@ var Metadata = require('./metadata.js'); * @param {Buffer=} private_key The client certificate private key, if * applicable * @param {Buffer=} cert_chain The client certificate cert chain, if applicable + * @return {ChannelCredentials} The SSL Credentials object */ -exports.createSsl = Credentials.createSsl; +exports.createSsl = ChannelCredentials.createSsl; /** * Create a gRPC credentials object from a metadata generation function. This @@ -61,10 +64,10 @@ exports.createSsl = Credentials.createSsl; * which corresponds to a status code that this library uses. * @param {function(String, function(Error, Metadata))} metadata_generator The * function that generates metadata - * @return {Credentials} The credentials object + * @return {CallCredentials} The credentials object */ exports.createFromMetadataGenerator = function(metadata_generator) { - return Credentials.createFromPlugin(function(service_url, callback) { + return CallCredentials.createFromPlugin(function(service_url, callback) { metadata_generator(service_url, function(error, metadata) { var code = grpc.status.OK; var message = ''; @@ -82,7 +85,7 @@ exports.createFromMetadataGenerator = function(metadata_generator) { /** * Create a gRPC credential from a Google credential object. * @param {Object} google_credential The Google credential object to use - * @return {Credentials} The resulting credentials object + * @return {CallCredentials} The resulting credentials object */ exports.createFromGoogleCredential = function(google_credential) { return exports.createFromMetadataGenerator(function(service_url, callback) { @@ -99,22 +102,39 @@ exports.createFromGoogleCredential = function(google_credential) { }; /** - * Combine any number of Credentials into a single credentials object - * @param(...Credentials) credentials The Credentials to combine - * @return Credentials A credentials object that combines all of the input - * credentials + * Combine a ChannelCredentials with any number of CallCredentials into a single + * ChannelCredentials object. + * @param {ChannelCredentials} channel_credential The ChannelCredentials to + * start with + * @param {...CallCredentials} credentials The CallCredentials to compose + * @return ChannelCredentials A credentials object that combines all of the + * input credentials */ -exports.combineCredentials = function() { - var current = arguments[0]; +exports.combineChannelCredentials = function(channel_credential) { + var current = channel_credential; for (var i = 1; i < arguments.length; i++) { - current = Credentials.createComposite(current, arguments[i]); + current = current.compose(arguments[i]); } return current; }; +/** + * Combine any number of CallCredentials into a single CallCredentials object + * @param {...CallCredentials} credentials the CallCredentials to compose + * @return CallCredentials A credentials object that combines all of the input + * credentials + */ +exports.combineCallCredentials = function() { + var current = arguments[0]; + for (var i = 1; i < arguments.length; i++) { + current = current.compose(arguments[i]); + } + return current; +} + /** * Create an insecure credentials object. This is used to create a channel that * does not use SSL. - * @return Credentials The insecure credentials object + * @return {ChannelCredentials} The insecure credentials object */ -exports.createInsecure = Credentials.createInsecure; +exports.createInsecure = ChannelCredentials.createInsecure; diff --git a/test/call_test.js b/test/call_test.js index e7f071bc..bb292cb2 100644 --- a/test/call_test.js +++ b/test/call_test.js @@ -48,7 +48,7 @@ function getDeadline(timeout_secs) { return deadline; } -var insecureCreds = grpc.Credentials.createInsecure(); +var insecureCreds = grpc.ChannelCredentials.createInsecure(); describe('call', function() { var channel; diff --git a/test/channel_test.js b/test/channel_test.js index 2e436222..da7aa8d7 100644 --- a/test/channel_test.js +++ b/test/channel_test.js @@ -56,7 +56,7 @@ function multiDone(done, count) { } }; } -var insecureCreds = grpc.Credentials.createInsecure(); +var insecureCreds = grpc.ChannelCredentials.createInsecure(); describe('channel', function() { describe('constructor', function() { diff --git a/test/credentials_test.js b/test/credentials_test.js index e84ade68..8eb91ee6 100644 --- a/test/credentials_test.js +++ b/test/credentials_test.js @@ -219,5 +219,25 @@ describe('client credentials', function() { }); call.end(); }); + it('should be able to use multiple plugin credentials', function(done) { + var altMetadataUpdater = function(service_url, callback) { + var metadata = new grpc.Metadata(); + metadata.set('other_plugin_key', 'other_plugin_value'); + callback(null, metadata); + }; + var alt_updater_creds = grpc.credentials.createFromMetadataGenerator( + altMetadataUpdater); + var combined_updater = grpc.credentials.combineCallCredentials( + updater_creds, alt_updater_creds); + var call = client.unary({}, function(err, data) { + assert.ifError(err); + }, null, {credentials: updater_creds}); + call.on('metadata', function(metadata) { + assert.deepEqual(metadata.get('plugin_key'), ['plugin_value']); + assert.deepEqual(metadata.get('other_plugin_key'), + ['other_plugin_value']); + done(); + }); + }); }); }); diff --git a/test/end_to_end_test.js b/test/end_to_end_test.js index 4b8da3bf..78a99fba 100644 --- a/test/end_to_end_test.js +++ b/test/end_to_end_test.js @@ -57,7 +57,7 @@ function multiDone(done, count) { }; } -var insecureCreds = grpc.Credentials.createInsecure(); +var insecureCreds = grpc.ChannelCredentials.createInsecure(); describe('end-to-end', function() { var server;