diff --git a/src/node/ext/credentials.cc b/src/node/ext/credentials.cc index 4f41c92f6a7926ddaf7a39f0c1ae8ef0adb68e7b..378031a4c1e58b45c34959188e905b21d50b51e5 100644 --- a/src/node/ext/credentials.cc +++ b/src/node/ext/credentials.cc @@ -242,5 +242,34 @@ NAN_METHOD(Credentials::CreateInsecure) { info.GetReturnValue().Set(WrapStruct(NULL)); } +NAN_METHOD(Credentials::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>()); + plugin.get_metadata = plugin_get_metadata; + plugin.destroy = plugin_destroy_state; + plugin.state = reinterpret_cast<void*>(state); + grpc_credentials *creds = grpc_metadata_credentials_create_from_plugin(plugin, + NULL); + if (creds == NULL) { + info.GetReturnValue().SetNull(); + } else { + info.GetReturnValue().Set(WrapStruct(creds())); + } +} + +void plugin_get_metadata(void *state, const char *service_url, + grpc_credentials_plugin_metadata_cb cb, + void *user_data) { + uv_async_t *async = new uv_async_t; + uv_async_init(uv_default_loop(), + async, + PluginCallback); +} + } // namespace node } // namespace grpc diff --git a/src/node/ext/credentials.h b/src/node/ext/credentials.h index d6351a753e722bfee2cf9f9e6056c6f278b58841..553ef81c195a3a15ab4494a5c7fbfc016c268eca 100644 --- a/src/node/ext/credentials.h +++ b/src/node/ext/credentials.h @@ -83,13 +83,37 @@ typedef struct plugin_state { Nan::Callback *callback; } plugin_state; +typedef struct plugin_callback_data { + plugin_state *state; + const char *service_url; + grpc_credentials_plugin_metadata_cb cb; + void *user_data; +} plugin_callback_data; + void plugin_get_metadata(void *state, const char *service_url, - grpc_credentials_plugin_metadata_cb cb, void *user_data); + grpc_credentials_plugin_metadata_cb cb, + void *user_data); void plugin_destroy_state(void *state); static NAN_METHOD(PluginCallback); +NAN_INLINE NAUV_WORK_CB(SendPluginCallback) { + Nan::HandleScope scope; + plugin_callback_data *data = reinterpret_cast<plugin_callback_data>( + async->data); + v8::Local<v8::Function> plugin_callback = Nan::GetFunction( + Nan::New<v8::FunctionTemplate>(PluginCallback).ToLocalChecked()); + // Attach cb and user_data to plugin_callback so that it can access them later + const int argc = 2; + v8::Local<v8::Value> argv = {Nan::New(data->service_url).ToLocalChecked(), + plugin_callback}; + NanCallback *callback = static_cast<NanCallback*>(async->data); + callback->Call(argc, argv); + uv_unref((uv_handle_t *)async); + delete async; +} + } // namespace node } // namespace grpc