1*14675a02SAndroid Build Coastguard Worker /* 2*14675a02SAndroid Build Coastguard Worker * Copyright 2019 Google LLC 3*14675a02SAndroid Build Coastguard Worker * 4*14675a02SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*14675a02SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*14675a02SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*14675a02SAndroid Build Coastguard Worker * 8*14675a02SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*14675a02SAndroid Build Coastguard Worker * 10*14675a02SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*14675a02SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*14675a02SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*14675a02SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*14675a02SAndroid Build Coastguard Worker * limitations under the License. 15*14675a02SAndroid Build Coastguard Worker */ 16*14675a02SAndroid Build Coastguard Worker 17*14675a02SAndroid Build Coastguard Worker #ifndef FCP_CLIENT_GRPC_BIDI_CHANNEL_H_ 18*14675a02SAndroid Build Coastguard Worker #define FCP_CLIENT_GRPC_BIDI_CHANNEL_H_ 19*14675a02SAndroid Build Coastguard Worker 20*14675a02SAndroid Build Coastguard Worker #include <dirent.h> 21*14675a02SAndroid Build Coastguard Worker #include <sys/stat.h> 22*14675a02SAndroid Build Coastguard Worker #include <sys/types.h> 23*14675a02SAndroid Build Coastguard Worker 24*14675a02SAndroid Build Coastguard Worker #include <fstream> 25*14675a02SAndroid Build Coastguard Worker #include <iostream> 26*14675a02SAndroid Build Coastguard Worker #include <memory> 27*14675a02SAndroid Build Coastguard Worker #include <sstream> 28*14675a02SAndroid Build Coastguard Worker #include <string> 29*14675a02SAndroid Build Coastguard Worker 30*14675a02SAndroid Build Coastguard Worker #include "absl/base/attributes.h" 31*14675a02SAndroid Build Coastguard Worker #include "absl/strings/match.h" 32*14675a02SAndroid Build Coastguard Worker #include "absl/strings/str_cat.h" 33*14675a02SAndroid Build Coastguard Worker #include "absl/strings/strip.h" 34*14675a02SAndroid Build Coastguard Worker #include "fcp/base/monitoring.h" 35*14675a02SAndroid Build Coastguard Worker #include "grpcpp/channel.h" 36*14675a02SAndroid Build Coastguard Worker #include "grpcpp/create_channel.h" 37*14675a02SAndroid Build Coastguard Worker #include "grpcpp/security/credentials.h" 38*14675a02SAndroid Build Coastguard Worker 39*14675a02SAndroid Build Coastguard Worker namespace fcp { 40*14675a02SAndroid Build Coastguard Worker namespace client { 41*14675a02SAndroid Build Coastguard Worker 42*14675a02SAndroid Build Coastguard Worker class GrpcBidiChannel { 43*14675a02SAndroid Build Coastguard Worker public: 44*14675a02SAndroid Build Coastguard Worker static constexpr int kChannelMaxMessageSize = 20 * 1000 * 1000; 45*14675a02SAndroid Build Coastguard Worker static constexpr int kKeepAliveTimeSeconds = 60; 46*14675a02SAndroid Build Coastguard Worker static constexpr const absl::string_view kSecurePrefix = "https://"; 47*14675a02SAndroid Build Coastguard Worker static constexpr const absl::string_view kSecureTestPrefix = "https+test://"; 48*14675a02SAndroid Build Coastguard Worker 49*14675a02SAndroid Build Coastguard Worker /** 50*14675a02SAndroid Build Coastguard Worker * Create a channel to the remote endpoint. 51*14675a02SAndroid Build Coastguard Worker * @param target URI of the remote endpoint. 52*14675a02SAndroid Build Coastguard Worker * @param cert_path If the URI is https:// or https+test://, an optional 53*14675a02SAndroid Build Coastguard Worker * path to a certificate root file or directory. 54*14675a02SAndroid Build Coastguard Worker * @return A shared pointer to the channel interface. 55*14675a02SAndroid Build Coastguard Worker */ Create(const std::string & target,std::string cert_path)56*14675a02SAndroid Build Coastguard Worker static std::shared_ptr<grpc::ChannelInterface> Create( 57*14675a02SAndroid Build Coastguard Worker const std::string& target, std::string cert_path) { 58*14675a02SAndroid Build Coastguard Worker bool secure = false; 59*14675a02SAndroid Build Coastguard Worker bool test = false; 60*14675a02SAndroid Build Coastguard Worker // This double check avoids a dependency on re2: 61*14675a02SAndroid Build Coastguard Worker if (absl::StartsWith(target, kSecureTestPrefix)) { 62*14675a02SAndroid Build Coastguard Worker secure = true; 63*14675a02SAndroid Build Coastguard Worker test = true; 64*14675a02SAndroid Build Coastguard Worker } else if (absl::StartsWith(target, kSecurePrefix)) { 65*14675a02SAndroid Build Coastguard Worker secure = true; 66*14675a02SAndroid Build Coastguard Worker } 67*14675a02SAndroid Build Coastguard Worker 68*14675a02SAndroid Build Coastguard Worker grpc::ChannelArguments channel_arguments; 69*14675a02SAndroid Build Coastguard Worker channel_arguments.SetMaxReceiveMessageSize(kChannelMaxMessageSize); 70*14675a02SAndroid Build Coastguard Worker channel_arguments.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, 71*14675a02SAndroid Build Coastguard Worker kKeepAliveTimeSeconds * 1000); 72*14675a02SAndroid Build Coastguard Worker 73*14675a02SAndroid Build Coastguard Worker if (!secure) 74*14675a02SAndroid Build Coastguard Worker return grpc::CreateCustomChannel( 75*14675a02SAndroid Build Coastguard Worker target, grpc::InsecureChannelCredentials(), channel_arguments); 76*14675a02SAndroid Build Coastguard Worker 77*14675a02SAndroid Build Coastguard Worker std::shared_ptr<grpc::ChannelCredentials> channel_creds; 78*14675a02SAndroid Build Coastguard Worker grpc::SslCredentialsOptions ssl_opts{}; 79*14675a02SAndroid Build Coastguard Worker 80*14675a02SAndroid Build Coastguard Worker if (!cert_path.empty()) { 81*14675a02SAndroid Build Coastguard Worker std::ifstream cert_file(cert_path); 82*14675a02SAndroid Build Coastguard Worker FCP_LOG_IF(ERROR, cert_file.fail()) 83*14675a02SAndroid Build Coastguard Worker << "Open for: " << cert_path << " failed: " << strerror(errno); 84*14675a02SAndroid Build Coastguard Worker std::stringstream string_stream; 85*14675a02SAndroid Build Coastguard Worker if (cert_file) { 86*14675a02SAndroid Build Coastguard Worker string_stream << cert_file.rdbuf(); 87*14675a02SAndroid Build Coastguard Worker } 88*14675a02SAndroid Build Coastguard Worker FCP_LOG_IF(WARNING, string_stream.str().empty()) 89*14675a02SAndroid Build Coastguard Worker << "Cert: " << cert_path << " is empty."; 90*14675a02SAndroid Build Coastguard Worker ssl_opts = {string_stream.str(), "", ""}; 91*14675a02SAndroid Build Coastguard Worker } 92*14675a02SAndroid Build Coastguard Worker 93*14675a02SAndroid Build Coastguard Worker channel_creds = grpc::SslCredentials(ssl_opts); 94*14675a02SAndroid Build Coastguard Worker auto target_uri = absl::StrCat( 95*14675a02SAndroid Build Coastguard Worker "dns:///", 96*14675a02SAndroid Build Coastguard Worker absl::StripPrefix(target, test ? kSecureTestPrefix : kSecurePrefix)); 97*14675a02SAndroid Build Coastguard Worker FCP_LOG(INFO) << "Creating channel to: " << target_uri; 98*14675a02SAndroid Build Coastguard Worker return CreateCustomChannel(target_uri, channel_creds, channel_arguments); 99*14675a02SAndroid Build Coastguard Worker } 100*14675a02SAndroid Build Coastguard Worker }; 101*14675a02SAndroid Build Coastguard Worker 102*14675a02SAndroid Build Coastguard Worker } // namespace client 103*14675a02SAndroid Build Coastguard Worker } // namespace fcp 104*14675a02SAndroid Build Coastguard Worker 105*14675a02SAndroid Build Coastguard Worker #endif // FCP_CLIENT_GRPC_BIDI_CHANNEL_H_ 106