diff options
-rw-r--r-- | include/grpc++/auth_metadata_processor.h | 4 | ||||
-rw-r--r-- | include/grpc/grpc_security.h | 5 | ||||
-rw-r--r-- | src/core/security/server_auth_filter.c | 8 | ||||
-rw-r--r-- | src/cpp/server/secure_server_credentials.cc | 37 | ||||
-rw-r--r-- | src/cpp/server/secure_server_credentials.h | 5 |
5 files changed, 37 insertions, 22 deletions
diff --git a/include/grpc++/auth_metadata_processor.h b/include/grpc++/auth_metadata_processor.h index e077ec0c60..45030a6a45 100644 --- a/include/grpc++/auth_metadata_processor.h +++ b/include/grpc++/auth_metadata_processor.h @@ -45,6 +45,10 @@ class AuthMetadataProcessor { public: virtual ~AuthMetadataProcessor() {} + // If this method returns true, the Process function will be scheduled in + // a different thread as the one processing the call. + virtual bool IsBlocking() const { return true; } + // context is read/write: it contains the properties of the channel peer and // it is the job of the Process method to augment it with properties derived // from the passed-in auth_metadata. diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 640c1fda98..c1e5afd3a4 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -286,9 +286,10 @@ typedef void (*grpc_process_auth_metadata_done_cb)( typedef struct { /* The context object is read/write: it contains the properties of the channel peer and it is the job of the process function to augment it with - properties derived from the passed-in metadata. */ + properties derived from the passed-in metadata. + The lifetime of these objects is guaranteed until cb is invoked. */ void (*process)(void *state, grpc_auth_context *context, - const grpc_metadata *md, size_t md_count, + const grpc_metadata *md, size_t num_md, grpc_process_auth_metadata_done_cb cb, void *user_data); void *state; } grpc_auth_metadata_processor; diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c index 2fc689caec..98d7788c83 100644 --- a/src/core/security/server_auth_filter.c +++ b/src/core/security/server_auth_filter.c @@ -50,6 +50,7 @@ typedef struct call_data { handling it. */ grpc_iomgr_closure auth_on_recv; grpc_transport_stream_op transport_op; + grpc_metadata_array md; const grpc_metadata *consumed_md; size_t num_consumed_md; grpc_stream_op *md_op; @@ -124,6 +125,7 @@ static void on_md_processing_done(void *user_data, GRPC_STATUS_UNAUTHENTICATED, &message); grpc_call_next_op(elem, &calld->transport_op); } + grpc_metadata_array_destroy(&calld->md); } static void auth_on_recv(void *user_data, int success) { @@ -135,17 +137,15 @@ static void auth_on_recv(void *user_data, int success) { size_t nops = calld->recv_ops->nops; grpc_stream_op *ops = calld->recv_ops->ops; for (i = 0; i < nops; i++) { - grpc_metadata_array md_array; grpc_stream_op *op = &ops[i]; if (op->type != GRPC_OP_METADATA || calld->got_client_metadata) continue; calld->got_client_metadata = 1; if (chand->processor.process == NULL) continue; calld->md_op = op; - md_array = metadata_batch_to_md_array(&op->data.metadata); + calld->md = metadata_batch_to_md_array(&op->data.metadata); chand->processor.process(chand->processor.state, calld->auth_context, - md_array.metadata, md_array.count, + calld->md.metadata, calld->md.count, on_md_processing_done, elem); - grpc_metadata_array_destroy(&md_array); return; } } diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index e5f5c3041c..fab538f1c4 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -44,27 +44,36 @@ namespace grpc { void AuthMetadataProcessorAyncWrapper::Process( - void* self, grpc_auth_context* context, const grpc_metadata* md, - size_t md_count, grpc_process_auth_metadata_done_cb cb, void* user_data) { - auto* instance = reinterpret_cast<AuthMetadataProcessorAyncWrapper*>(self); - auto* metadata(new Metadata); - for (size_t i = 0; i < md_count; i++) { - metadata->insert(std::make_pair( - md[i].key, grpc::string(md[i].value, md[i].value_length))); + void* wrapper, grpc_auth_context* context, const grpc_metadata* md, + size_t num_md, grpc_process_auth_metadata_done_cb cb, void* user_data) { + auto* w = reinterpret_cast<AuthMetadataProcessorAyncWrapper*>(wrapper); + if (w->processor_ == nullptr) { + // Early exit. + cb(user_data, NULL, 0, 1); + return; + } + if (w->processor_->IsBlocking()) { + w->thread_pool_->Add( + std::bind(&AuthMetadataProcessorAyncWrapper::InvokeProcessor, w, + context, md, num_md, cb, user_data)); + } else { + // invoke directly. + w->InvokeProcessor(context, md, num_md, cb, user_data); } - instance->thread_pool_->Add( - std::bind(&AuthMetadataProcessorAyncWrapper::ProcessAsync, instance, - context, metadata, cb, user_data)); } -void AuthMetadataProcessorAyncWrapper::ProcessAsync( +void AuthMetadataProcessorAyncWrapper::InvokeProcessor( grpc_auth_context* ctx, - Metadata* metadata, + const grpc_metadata* md, size_t num_md, grpc_process_auth_metadata_done_cb cb, void* user_data) { - std::unique_ptr<Metadata> metadata_deleter(metadata); + Metadata metadata; + for (size_t i = 0; i < num_md; i++) { + metadata.insert(std::make_pair( + md[i].key, grpc::string(md[i].value, md[i].value_length))); + } SecureAuthContext context(ctx); Metadata consumed_metadata; - bool ok = processor_->Process(*metadata, &context, &consumed_metadata); + bool ok = processor_->Process(metadata, &context, &consumed_metadata); if (ok) { std::vector<grpc_metadata> consumed_md(consumed_metadata.size()); for (const auto& entry : consumed_metadata) { diff --git a/src/cpp/server/secure_server_credentials.h b/src/cpp/server/secure_server_credentials.h index 22fd9e2cae..f2709637b1 100644 --- a/src/cpp/server/secure_server_credentials.h +++ b/src/cpp/server/secure_server_credentials.h @@ -55,8 +55,9 @@ class AuthMetadataProcessorAyncWrapper GRPC_FINAL { private: typedef std::multimap<grpc::string, grpc::string> Metadata; - void ProcessAsync(grpc_auth_context* context, Metadata* auth_metadata, - grpc_process_auth_metadata_done_cb cb, void* user_data); + void InvokeProcessor(grpc_auth_context* context, const grpc_metadata* md, + size_t md_count, grpc_process_auth_metadata_done_cb cb, + void* user_data); std::unique_ptr<ThreadPoolInterface> thread_pool_; std::shared_ptr<AuthMetadataProcessor> processor_; }; |