kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/cxx/common/net_client.h (about) 1 /* 2 * Copyright 2015 The Kythe Authors. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef KYTHE_CXX_COMMON_NET_CLIENT_H_ 18 #define KYTHE_CXX_COMMON_NET_CLIENT_H_ 19 20 #include <curl/curl.h> 21 22 #include <memory> 23 #include <string> 24 25 #include "kythe/proto/graph.pb.h" 26 #include "kythe/proto/storage.pb.h" 27 #include "kythe/proto/xref.pb.h" 28 #include "rapidjson/document.h" 29 30 namespace kythe { 31 32 /// \brief Issues JSON-formatted RPCs. 33 /// 34 /// JsonClient is not thread-safe. 35 class JsonClient { 36 public: 37 JsonClient(); 38 ~JsonClient(); 39 40 /// \brief Call once to initialize the underlying network library. 41 static void InitNetwork(); 42 43 /// \brief Issue a request. 44 /// \param uri The URI to request. 45 /// \param post Issue this request as a post? 46 /// \param request The document to issue as the request. 47 /// \param response The document to fill with the response. 48 /// \return true on success and false on failure 49 bool Request(const std::string& uri, bool post, 50 const rapidjson::Document& request, 51 rapidjson::Document* response); 52 53 /// \brief Issue a request. 54 /// \param uri The URI to request. 55 /// \param post Issue this request as a post? 56 /// \param request The string to issue as the request. 57 /// \param response The document to fill with the response. 58 /// \return true on success and false on failure 59 bool Request(const std::string& uri, bool post, const std::string& request, 60 rapidjson::Document* response); 61 62 /// \brief Issue a request. 63 /// \param uri The URI to request. 64 /// \param post Issue this request as a post? 65 /// \param request The string to issue as the request. 66 /// \param response The raw string to fill with the response. 67 /// \return true on success and false on failure 68 bool Request(const std::string& uri, bool post, const std::string& request, 69 std::string* response); 70 71 private: 72 static size_t CurlWriteCallback(void* data, size_t size, size_t nmemb, 73 void* user); 74 static size_t CurlReadCallback(void* data, size_t size, size_t nmemb, 75 void* user); 76 77 /// The network context. 78 CURL* curl_; 79 /// A buffer used for communications. 80 std::string to_send_; 81 /// Where we are in the buffer. 82 size_t send_head_; 83 /// A buffer used for communications. 84 std::string received_; 85 }; 86 87 /// \brief A client for a Kythe xrefs service. 88 class XrefsClient { 89 public: 90 virtual ~XrefsClient() {} 91 92 /// \brief Issues a Nodes call. 93 /// \param request The request to send. 94 /// \param reply On success, will be merged with the reply. 95 /// \param error_text On failure, will be set to an error description. 96 /// \return true on success, false on failure. 97 virtual bool Nodes(const proto::NodesRequest& request, 98 proto::NodesReply* reply, std::string* error_text) { 99 if (error_text) { 100 *error_text = "Unimplemented."; 101 } 102 return false; 103 } 104 105 /// \brief Issues an Edges call. 106 /// \param request The request to send. 107 /// \param reply On success, will be merged with the reply. 108 /// \param error_text On failure, will be set to an error description. 109 /// \return true on success, false on failure. 110 virtual bool Edges(const proto::EdgesRequest& request, 111 proto::EdgesReply* reply, std::string* error_text) { 112 if (error_text) { 113 *error_text = "Unimplemented."; 114 } 115 return false; 116 } 117 118 /// \brief Issues a Decorations call. 119 /// \param request The request to send. 120 /// \param reply On success, will be merged with the reply. 121 /// \param error_text On failure, will be set to an error description. 122 /// \return true on success, false on failure. 123 virtual bool Decorations(const proto::DecorationsRequest& request, 124 proto::DecorationsReply* reply, 125 std::string* error_text) { 126 if (error_text) { 127 *error_text = "Unimplemented."; 128 } 129 return false; 130 } 131 132 /// \brief Issues a Documentation call. 133 /// \param request The request to send. 134 /// \param reply On success, will be merged with the reply. 135 /// \param error_text On failure, will be set to an error description. 136 /// \return true on success, false on failure. 137 virtual bool Documentation(const proto::DocumentationRequest& request, 138 proto::DocumentationReply* reply, 139 std::string* error_text) { 140 if (error_text) { 141 *error_text = "Unimplemented."; 142 } 143 return false; 144 } 145 }; 146 147 /// \brief A client for a Kythe xrefs service that talks JSON. 148 class XrefsJsonClient : public XrefsClient { 149 public: 150 /// \param client The JsonClient to use. 151 /// \param base_uri The base URI of the service ("http://localhost:8080") 152 XrefsJsonClient(std::unique_ptr<JsonClient> client, 153 const std::string& base_uri) 154 : client_(std::move(client)), 155 nodes_uri_(base_uri + "/nodes?proto=1"), 156 edges_uri_(base_uri + "/edges?proto=1"), 157 decorations_uri_(base_uri + "/decorations?proto=1"), 158 documentation_uri_(base_uri + "/documentation?proto=1") {} 159 bool Nodes(const proto::NodesRequest& request, proto::NodesReply* reply, 160 std::string* error_text) override { 161 return Roundtrip(nodes_uri_, request, reply, error_text); 162 } 163 bool Edges(const proto::EdgesRequest& request, proto::EdgesReply* reply, 164 std::string* error_text) override { 165 return Roundtrip(edges_uri_, request, reply, error_text); 166 } 167 bool Decorations(const proto::DecorationsRequest& request, 168 proto::DecorationsReply* reply, 169 std::string* error_text) override { 170 return Roundtrip(decorations_uri_, request, reply, error_text); 171 } 172 bool Documentation(const proto::DocumentationRequest& request, 173 proto::DocumentationReply* reply, 174 std::string* error_text) override { 175 return Roundtrip(documentation_uri_, request, reply, error_text); 176 } 177 178 private: 179 bool Roundtrip(const std::string& endpoint, 180 const google::protobuf::Message& request, 181 google::protobuf::Message* response, std::string* error_text); 182 183 std::unique_ptr<JsonClient> client_; 184 std::string nodes_uri_; 185 std::string edges_uri_; 186 std::string decorations_uri_; 187 std::string documentation_uri_; 188 }; 189 } // namespace kythe 190 191 #endif // KYTHE_CXX_COMMON_NET_CLIENT_H_