From 8cde3d7c20445289f7072f29029e44870beecc37 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 24 Sep 2015 16:11:19 -0700 Subject: [PATCH] Implemented credentials plugin interface --- src/node/ext/call.h | 3 +++ src/node/ext/credentials.cc | 34 ++++++++++++++++++++++++++++++++++ src/node/ext/credentials.h | 6 +++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/node/ext/call.h b/src/node/ext/call.h index 2f8e1f17aae..d965f339fc9 100644 --- a/src/node/ext/call.h +++ b/src/node/ext/call.h @@ -66,6 +66,9 @@ inline v8::Local nanErrorWithCode(const char *msg, return scope.Escape(err); } +bool CreateMetadataArray(Local metadata, grpc_metadata_array *array, + shared_ptr resources); + v8::Local ParseMetadata(const grpc_metadata_array *metadata_array); struct Resources { diff --git a/src/node/ext/credentials.cc b/src/node/ext/credentials.cc index 378031a4c1e..34603650567 100644 --- a/src/node/ext/credentials.cc +++ b/src/node/ext/credentials.cc @@ -37,6 +37,7 @@ #include "grpc/grpc_security.h" #include "grpc/support/log.h" #include "credentials.h" +#include "call.h" namespace grpc { namespace node { @@ -262,6 +263,39 @@ NAN_METHOD(Credentials::CreateFromPlugin) { } } +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"); + } + grpc_status_code code = static_cast( + Nan::To(info[0]).FromJust()); + char *details = *Nan::Utf8String(info[1]); + grpc_metadata_array array; + if (!CreateMetadataArray(Nan::To(info[2]).ToLocalChecked(), + &array, shared_ptr(new Resources))){ + return Nan::ThrowError("Failed to parse metadata"); + } + grpc_credentials_plugin_metadata_cb cb = + reinterpret_cast( + Nan::To( + Nan::Get(info.Callee, "cb").ToLocalChecked() + ).ToLocalChecked()->Value()); + void *user_data = Nan::To( + Nan::Get(info.Callee, "user_data").ToLocalChecked() + ).ToLocalChecked()->Value(); + cb(user_data, array.metadata, array.count, code, details); +} + void plugin_get_metadata(void *state, const char *service_url, grpc_credentials_plugin_metadata_cb cb, void *user_data) { diff --git a/src/node/ext/credentials.h b/src/node/ext/credentials.h index 553ef81c195..94ed884228e 100644 --- a/src/node/ext/credentials.h +++ b/src/node/ext/credentials.h @@ -102,9 +102,13 @@ NAN_INLINE NAUV_WORK_CB(SendPluginCallback) { Nan::HandleScope scope; plugin_callback_data *data = reinterpret_cast( async->data); + // Attach cb and user_data to plugin_callback so that it can access them later v8::Local plugin_callback = Nan::GetFunction( Nan::New(PluginCallback).ToLocalChecked()); - // Attach cb and user_data to plugin_callback so that it can access them later + Nan::Set(plugin_callback, Nan::New("cb").ToLocalChecked(), + Nan::New(reinterpret_cast(data->cb))); + Nan::Set(plugin_callback, Nan::New("user_data").ToLocalChecked(), + Nan::New(data->user_data)); const int argc = 2; v8::Local argv = {Nan::New(data->service_url).ToLocalChecked(), plugin_callback};