diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h index 6ab00612f6e660b82d56039650f6fc80af2a84de..1d5117925709bf762182113cf3c74262b4eb7925 100644 --- a/include/grpc++/impl/codegen/call.h +++ b/include/grpc++/impl/codegen/call.h @@ -45,6 +45,7 @@ #include <grpc++/impl/codegen/config.h> #include <grpc++/impl/codegen/core_codegen_interface.h> #include <grpc++/impl/codegen/serialization_traits.h> +#include <grpc++/impl/codegen/slice.h> #include <grpc++/impl/codegen/status.h> #include <grpc++/impl/codegen/status_helper.h> #include <grpc++/impl/codegen/string_ref.h> @@ -68,8 +69,8 @@ inline void FillMetadataMap( for (size_t i = 0; i < arr->count; i++) { // TODO(yangg) handle duplicates? metadata->insert(std::pair<grpc::string_ref, grpc::string_ref>( - arr->metadata[i].key, grpc::string_ref(arr->metadata[i].value, - arr->metadata[i].value_length))); + StringRefFromSlice(arr->metadata[i].key), + StringRefFromSlice(arr->metadata[i].value))); } g_core_codegen_interface->grpc_metadata_array_destroy(arr); g_core_codegen_interface->grpc_metadata_array_init(arr); @@ -87,9 +88,8 @@ inline grpc_metadata* FillMetadataArray( metadata.size() * sizeof(grpc_metadata))); size_t i = 0; for (auto iter = metadata.cbegin(); iter != metadata.cend(); ++iter, ++i) { - metadata_array[i].key = iter->first.c_str(); - metadata_array[i].value = iter->second.c_str(); - metadata_array[i].value_length = iter->second.size(); + metadata_array[i].key = SliceReferencingString(iter->first); + metadata_array[i].value = SliceReferencingString(iter->second); } return metadata_array; } @@ -451,8 +451,9 @@ class CallOpServerSendStatus { trailing_metadata_count_; op->data.send_status_from_server.trailing_metadata = trailing_metadata_; op->data.send_status_from_server.status = send_status_code_; + grpc_slice status_details = SliceReferencingString(send_status_details_); op->data.send_status_from_server.status_details = - send_status_details_.empty() ? nullptr : send_status_details_.c_str(); + send_status_details_.empty() ? nullptr : &status_details; op->flags = 0; op->reserved = NULL; } @@ -515,16 +516,12 @@ class CallOpClientRecvStatus { if (recv_status_ == nullptr) return; memset(&recv_trailing_metadata_arr_, 0, sizeof(recv_trailing_metadata_arr_)); - status_details_ = nullptr; - status_details_capacity_ = 0; grpc_op* op = &ops[(*nops)++]; op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; op->data.recv_status_on_client.trailing_metadata = &recv_trailing_metadata_arr_; op->data.recv_status_on_client.status = &status_code_; op->data.recv_status_on_client.status_details = &status_details_; - op->data.recv_status_on_client.status_details_capacity = - &status_details_capacity_; op->flags = 0; op->reserved = NULL; } @@ -532,10 +529,10 @@ class CallOpClientRecvStatus { void FinishOp(bool* status, int max_receive_message_size) { if (recv_status_ == nullptr) return; FillMetadataMap(&recv_trailing_metadata_arr_, recv_trailing_metadata_); - *recv_status_ = Status( - static_cast<StatusCode>(status_code_), - status_details_ ? grpc::string(status_details_) : grpc::string()); - g_core_codegen_interface->gpr_free(status_details_); + *recv_status_ = Status(static_cast<StatusCode>(status_code_), + grpc::string(GRPC_SLICE_START_PTR(status_details_), + GRPC_SLICE_END_PTR(status_details_))); + g_core_codegen_interface->grpc_slice_unref(status_details_); recv_status_ = nullptr; } @@ -544,8 +541,7 @@ class CallOpClientRecvStatus { Status* recv_status_; grpc_metadata_array recv_trailing_metadata_arr_; grpc_status_code status_code_; - char* status_details_; - size_t status_details_capacity_; + grpc_slice status_details_; }; /// An abstract collection of CallOpSet's, to be used whenever diff --git a/include/grpc++/impl/codegen/core_codegen.h b/include/grpc++/impl/codegen/core_codegen.h index 6b5e637e4e2ce7bd7ba6d2689483fac36908ce73..b5ab26154e2f7af684539a3b941391ce081125ea 100644 --- a/include/grpc++/impl/codegen/core_codegen.h +++ b/include/grpc++/impl/codegen/core_codegen.h @@ -81,7 +81,10 @@ class CoreCodegen : public CoreCodegenInterface { grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split) override; void grpc_slice_buffer_add(grpc_slice_buffer* sb, grpc_slice slice) override; void grpc_slice_buffer_pop(grpc_slice_buffer* sb) override; - + grpc_slice grpc_slice_from_static_buffer(const void* buffer, + size_t length) override; + grpc_slice grpc_slice_from_copied_buffer(const void* buffer, + size_t length) override; void grpc_metadata_array_init(grpc_metadata_array* array) override; void grpc_metadata_array_destroy(grpc_metadata_array* array) override; diff --git a/include/grpc++/impl/codegen/core_codegen_interface.h b/include/grpc++/impl/codegen/core_codegen_interface.h index 4783a43454fe64f1ce84f87e795e2aa70d6c88e4..9c1af972b3c399922154747edfd618dca2f8f58f 100644 --- a/include/grpc++/impl/codegen/core_codegen_interface.h +++ b/include/grpc++/impl/codegen/core_codegen_interface.h @@ -99,6 +99,10 @@ class CoreCodegenInterface { virtual void grpc_slice_buffer_add(grpc_slice_buffer* sb, grpc_slice slice) = 0; virtual void grpc_slice_buffer_pop(grpc_slice_buffer* sb) = 0; + virtual grpc_slice grpc_slice_from_static_buffer(const void* buffer, + size_t length) = 0; + virtual grpc_slice grpc_slice_from_copied_buffer(const void* buffer, + size_t length) = 0; virtual void grpc_metadata_array_init(grpc_metadata_array* array) = 0; virtual void grpc_metadata_array_destroy(grpc_metadata_array* array) = 0; diff --git a/include/grpc++/impl/codegen/slice.h b/include/grpc++/impl/codegen/slice.h new file mode 100644 index 0000000000000000000000000000000000000000..7280698978898560b03fcb9a74da4819f30fe9a5 --- /dev/null +++ b/include/grpc++/impl/codegen/slice.h @@ -0,0 +1,59 @@ +/* + * + * 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 GRPCXX_IMPL_CODEGEN_SLICE_H +#define GRPCXX_IMPL_CODEGEN_SLICE_H + +#include <grpc++/impl/codegen/core_codegen_interface.h> +#include <grpc++/impl/codegen/string_ref.h> + +namespace grpc { + +inline grpc::string_ref StringRefFromSlice(grpc_slice slice) { + return grpc::string_ref(reinterpret_cast<char*>(GRPC_SLICE_START_PTR(slice)), + GRPC_SLICE_LENGTH(slice)); +} + +inline grpc_slice SliceReferencingString(const grpc::string& str) { + return g_core_codegen_interface->grpc_slice_from_static_buffer(str.data(), + str.length()); +} + +inline grpc_slice SliceFromCopiedString(const grpc::string& str) { + return g_core_codegen_interface->grpc_slice_from_copied_buffer(str.data(), + str.length()); +} + +} // namespace grpc + +#endif diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 357d8317adfc8eed1744d7e9221396f918778c9f..c985183ae7600022d36bef593547202772ff76d8 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -107,10 +107,20 @@ Call Channel::CreateCall(const RpcMethod& method, ClientContext* context, } else if (!host_.empty()) { host_str = host_.c_str(); } - c_call = grpc_channel_create_call(c_channel_, context->propagate_from_call_, - context->propagation_options_.c_bitmask(), - cq->cq(), method.name(), host_str, - context->raw_deadline(), nullptr); + grpc_slice method_slice = SliceFromCopiedString(method.name()); + grpc_slice host_slice; + if (host_str != nullptr) { + host_slice = SliceFromCopiedString(host_str); + } + c_call = grpc_channel_create_call( + c_channel_, context->propagate_from_call_, + context->propagation_options_.c_bitmask(), cq->cq(), method_slice, + host_str == nullptr ? nullptr : &host_slice, context->raw_deadline(), + nullptr); + grpc_slice_unref(method_slice); + if (host_str != nullptr) { + grpc_slice_unref(host_slice); + } } grpc_census_call_set_context(c_call, context->census_context()); context->set_call(c_call, shared_from_this()); diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 269c523bba12304ae20c82b1a790eec2cf3846b2..21445c91fd86348a629f2aeab155e6548050b477 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -206,9 +206,8 @@ void MetadataCredentialsPluginWrapper::InvokePlugin( std::vector<grpc_metadata> md; for (auto it = metadata.begin(); it != metadata.end(); ++it) { grpc_metadata md_entry; - md_entry.key = it->first.c_str(); - md_entry.value = it->second.data(); - md_entry.value_length = it->second.size(); + md_entry.key = SliceReferencingString(it->first); + md_entry.value = SliceReferencingString(it->second); md_entry.flags = 0; md.push_back(md_entry); } diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc index a07ad54376956573a64cff0048cbb566989ae337..36c8938c95bff912c2134391a623cf039b6b299a 100644 --- a/src/cpp/common/core_codegen.cc +++ b/src/cpp/common/core_codegen.cc @@ -123,6 +123,16 @@ grpc_slice CoreCodegen::grpc_slice_split_tail(grpc_slice* s, size_t split) { return ::grpc_slice_split_tail(s, split); } +grpc_slice CoreCodegen::grpc_slice_from_static_buffer(const void* buffer, + size_t length) { + return ::grpc_slice_from_static_buffer(buffer, length); +} + +grpc_slice CoreCodegen::grpc_slice_from_copied_buffer(const void* buffer, + size_t length) { + return ::grpc_slice_from_copied_buffer(buffer, length); +} + void CoreCodegen::grpc_slice_buffer_add(grpc_slice_buffer* sb, grpc_slice slice) { ::grpc_slice_buffer_add(sb, slice); diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index 33bdc2a1f4f1ca6f8a74e803c43cbecb55b8b14a..3c90986cd055b4eb7ec1b85751089a278ac50474 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -35,11 +35,12 @@ #include <map> #include <memory> +#include <grpc++/impl/codegen/slice.h> +#include <grpc++/security/auth_metadata_processor.h> + #include "src/cpp/common/secure_auth_context.h" #include "src/cpp/server/secure_server_credentials.h" -#include <grpc++/security/auth_metadata_processor.h> - namespace grpc { void AuthMetadataProcessorAyncWrapper::Destroy(void* wrapper) { @@ -71,8 +72,8 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor( grpc_process_auth_metadata_done_cb cb, void* user_data) { AuthMetadataProcessor::InputMetadata metadata; for (size_t i = 0; i < num_md; i++) { - metadata.insert(std::make_pair( - md[i].key, grpc::string_ref(md[i].value, md[i].value_length))); + metadata.insert(std::make_pair(StringRefFromSlice(md[i].key), + StringRefFromSlice(md[i].value))); } SecureAuthContext context(ctx, false); AuthMetadataProcessor::OutputMetadata consumed_metadata; @@ -85,9 +86,8 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor( for (auto it = consumed_metadata.begin(); it != consumed_metadata.end(); ++it) { grpc_metadata md_entry; - md_entry.key = it->first.c_str(); - md_entry.value = it->second.data(); - md_entry.value_length = it->second.size(); + md_entry.key = SliceReferencingString(it->first); + md_entry.value = SliceReferencingString(it->second); md_entry.flags = 0; consumed_md.push_back(md_entry); } @@ -95,9 +95,8 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor( for (auto it = response_metadata.begin(); it != response_metadata.end(); ++it) { grpc_metadata md_entry; - md_entry.key = it->first.c_str(); - md_entry.value = it->second.data(); - md_entry.value_length = it->second.size(); + md_entry.key = SliceReferencingString(it->first); + md_entry.value = SliceReferencingString(it->second); md_entry.flags = 0; response_md.push_back(md_entry); }