适用于C++的REST风格 http请求客户端

4,360 阅读4分钟

适用于C++的REST客户端

关于

这是一个简单的C++的REST客户端。是包装了libcurl的HTTP请求。

用法

restclient-cpp提供了两种与REST端点交互的方式。有一种简单的方式,它不需要你配置一个对象来与API交互。然而,简单的方式也没有提供很多配置选项。因此,如果你需要的不仅仅是一个简单的HTTP调用,你可能会想看看高级用法。

简单用法

一些最常见的HTTP的静态方法

#include "restclient-cpp/restclient.h"

RestClient::Response r = RestClient::get("http://url.com")
RestClient::Response r = RestClient::post("http://url.com/post", "text/json", "{"foo": "bla"}")
RestClient::Response r = RestClient::put("http://url.com/put", "text/json", "{"foo": "bla"}")
RestClient::Response r = RestClient::del("http://url.com/delete")
RestClient::Response r = RestClient::head("http://url.com")

响应是RestClient::Response的类型,有三个属性。

RestClient::Response.code // HTTP response code
RestClient::Response.body // HTTP response body
RestClient::Response.headers // HTTP response headers

高级用法

然而,如果你想要更复杂的功能,如连接重用、超时或认证,也有一个不同的、更可配置的方法。

#include "restclient-cpp/connection.h"
#include "restclient-cpp/restclient.h"

// initialize RestClient
RestClient::init();

// get a connection object
RestClient::Connection* conn = new RestClient::Connection("http://url.com");

// configure basic auth
conn->SetBasicAuth("WarMachine68", "WARMACHINEROX");

// set connection timeout to 5s
conn->SetTimeout(5);

// set custom user agent
// (this will result in the UA "foo/cool restclient-cpp/VERSION")
conn->SetUserAgent("foo/cool");

// enable following of redirects (default is off)
conn->FollowRedirects(true);

// set headers
RestClient::HeaderFields headers;
headers["Accept"] = "application/json";
conn->SetHeaders(headers)

// append additional headers
conn->AppendHeader("X-MY-HEADER", "foo")

// if using a non-standard Certificate Authority (CA) trust file
conn->SetCAInfoFilePath("/etc/custom-ca.crt")

RestClient::Response r = conn->get("/get")
RestClient::Response r = conn->head("/get")
RestClient::Response r = conn->del("/delete")

// set different content header for POST and PUT
conn->AppendHeader("Content-Type", "text/json")
RestClient::Response r = conn->post("/post", "{"foo": "bla"}")
RestClient::Response r = conn->put("/put", "text/json", "{"foo": "bla"}")

// deinit RestClient. After calling this you have to call RestClient::init()
// again before you can use it
RestClient::disable();

响应也是RestClient::Response的类型,有三个属性。

RestClient::Response.code // HTTP response code
RestClient::Response.body // HTTP response body
RestClient::Response.headers // HTTP response headers

连接对象还提供了一个简单的方法,通过conn->GetInfo()获得一些诊断和度量信息。其结果是一个RestClient::Connection::Info结构,看起来像这样。

typedef struct {
  std::string base_url;
  RestClients::HeaderFields headers;
  int timeout;
  struct {
    std::string username;
    std::string password;
  } basicAuth;

  std::string certPath;
  std::string certType;
  std::string keyPath;
  std::string customUserAgent;
  struct {
    // total time of the last request in seconds Total time of previous
    // transfer. See CURLINFO_TOTAL_TIME
    int totalTime;
    // time spent in DNS lookup in seconds Time from start until name
    // resolving completed. See CURLINFO_NAMELOOKUP_TIME
    int nameLookupTime;
    // time it took until Time from start until remote host or proxy
    // completed. See CURLINFO_CONNECT_TIME
    int connectTime;
    // Time from start until SSL/SSH handshake completed. See
    // CURLINFO_APPCONNECT_TIME
    int appConnectTime;
    // Time from start until just before the transfer begins. See
    // CURLINFO_PRETRANSFER_TIME
    int preTransferTime;
    // Time from start until just when the first byte is received. See
    // CURLINFO_STARTTRANSFER_TIME
    int startTransferTime;
    // Time taken for all redirect steps before the final transfer. See
    // CURLINFO_REDIRECT_TIME
    int redirectTime;
    // number of redirects followed. See CURLINFO_REDIRECT_COUNT
    int redirectCount;
  } lastRequest;
} Info;

持久连接/Keep-Alive

连接对象在一个实例变量中存储curl的简单句柄,并在对象的生命周期内使用该句柄。这意味着curl会自动重复使用该句柄的连接

线程安全

restclient-cpp在很大程度上依赖于libcurl,因为它的目的是为它提供一个薄的包装。这意味着它遵守了由libcurl提供的的基本线程安全水平。RestClient::init()RestClient::disable()方法基本上对应于curl_global_initcurl_global_cleanup,因此需要分别在程序开始和关机前调用。这些设置了环境,并且不是线程安全的。之后,你可以在你的线程中创建连接对象。不要跨线程共享连接对象,因为这意味着同时从多个线程访问curl句柄,这是不允许的。

为了提供一个易于使用的API,通过静态方法的简单使用隐含地调用了curl全局函数,因此也是不是线程安全的

HTTPS用户证书

提供了简单的封装函数,允许客户端使用证书进行认证。在引擎盖下,这些包装器使用curl_easy_setopt设置cURL选项,例如CURLOPT_SSLCERT。注意:目前用gnutls编译的libcurl(例如ubuntu上的libcurl4-gnutls-dev)有问题,当这些选项被设置为无效值时,它会返回一个错误的代码。

//设置CURLOPT_SSLCERT
conn->SetCertPath(certPath)。
// 设置 CURLOPT_SSLCERTTYPE
conn->SetCertType(type);
// 设置 CURLOPT_SSLKEY
conn->SetKeyPath(keyPath)。

依赖性

安装

packagecloud上有一些用于Linux的软件包。对于OSX,你可以从mrtazz/oss的自制软件中获得它。

brew tap mrtazz/oss
brew install restclient-cpp

否则,你可以用常规的自动工具来做。

./autogen.sh
./configure
进行安装

贡献

所有的贡献都受到高度赞赏。这包括提交问题、更新文档和编写代码。请先看一下贡献指南,以便你的贡献能尽快被合并。