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_