Rename Request() to Send().

master
Chunting Gu 6 years ago
parent 1a21989b2e
commit ad1016734e

@ -4,7 +4,7 @@
Lightweight C++ HTTP client and server library based on [Boost Asio](https://www.boost.org/doc/libs/release/libs/asio/).
Please turn to our [Wiki](https://github.com/sprinfall/webcc/wiki) (under construction) for more tutorials and guides.
Please turn to our [Wiki](https://github.com/sprinfall/webcc/wiki) for more tutorials and guides.
Wondering how to build Webcc? Check [Build Instructions](https://github.com/sprinfall/webcc/wiki/Build-Instructions).
@ -12,7 +12,7 @@ Git repo: https://github.com/sprinfall/webcc. Please check this one instead of t
**Features**
- Cross-platform: Linux, Windows and Mac
- Cross-platform: Windows, Linux and MacOS
- Easy-to-use client API inspired by Python [requests](https://2.python-requests.org//en/master/)
- SSL/HTTPS support with OpenSSL (optional)
- GZip compression support with Zlib (optional)
@ -25,7 +25,6 @@ Git repo: https://github.com/sprinfall/webcc. Please check this one instead of t
- Source code follows [Google C++ Style](https://google.github.io/styleguide/cppguide.html)
- Automation tests and unit tests included
- No memory leak detected by [VLD](https://kinddragon.github.io/vld/)
- etc.
## Client API
@ -48,7 +47,9 @@ int main() {
// Catch exceptions for error handling.
try {
// Send a HTTP GET request.
auto r = session.Get("http://httpbin.org/get");
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/get")
());
// Print the response data.
std::cout << r->data() << std::endl;
@ -61,46 +62,30 @@ int main() {
}
```
The `Get()` method is nothing but a shortcut of `Request()`. Using `Request()` directly is more complicated:
```cpp
auto r = session.Request(webcc::RequestBuilder{}.Get("http://httpbin.org/get")());
```
As you can see, a helper class named `RequestBuilder` is used to chain the parameters and finally build a request object. Please pay attention to the `()` operator.
Both the shortcut and `Request()` accept URL query parameters:
URL query parameters can be easily added through `Query()` method:
```cpp
// Query parameters are passed using a std::vector.
session.Get("http://httpbin.org/get", { "key1", "value1", "key2", "value2" });
session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Query("key1", "value1").
Query("key2", "value2")
());
session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Query("key1", "value1").Query("key2", "value2")
());
```
Adding additional headers is also easy:
```cpp
session.Get("http://httpbin.org/get",
{"key1", "value1", "key2", "value2"},
{"Accept", "application/json"}); // Also a std::vector
session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Query("key1", "value1").
Query("key2", "value2").
Header("Accept", "application/json")
());
session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Header("Accept", "application/json")
());
```
Accessing HTTPS has no difference from HTTP:
```cpp
session.Get("https://httpbin.org/get");
session.Send(webcc::RequestBuilder{}.Get("https://httpbin.org/get")());
```
*NOTE: The HTTPS/SSL support requires the build option `WEBCC_ENABLE_SSL` to be enabled.*
@ -108,38 +93,40 @@ session.Get("https://httpbin.org/get");
Listing GitHub public events is not a big deal:
```cpp
auto r = session.Get("https://api.github.com/events");
auto r = session.Send(webcc::RequestBuilder{}.
Get("https://api.github.com/events")
());
```
You can then parse `r->data()` to JSON object with your favorite JSON library. My choice for the examples is [jsoncpp](https://github.com/open-source-parsers/jsoncpp). But Webcc itself doesn't understand JSON nor require one. It's up to you to choose the most appropriate JSON library.
The shortcuts (`Get()`, `Post()`, etc.) are easier to use but `RequestBuilder` is more powerful. It provides a lot of functions for you to customize the request. Let's see more examples.
`RequestBuilder` provides a lot of functions for you to customize the request. Let's see more examples.
In order to list the followers of an authorized GitHub user, you need either **Basic Authorization**:
```cpp
session.Request(webcc::RequestBuilder{}.
Get("https://api.github.com/user/followers").
AuthBasic(login, password) // Should be replaced by real login and password
());
session.Send(webcc::RequestBuilder{}.
Get("https://api.github.com/user/followers").
AuthBasic(login, password) // Should be replaced by valid login and passwords
());
```
Or **Token Authorization**:
```cpp
session.Request(webcc::RequestBuilder{}.
Get("https://api.github.com/user/followers").
AuthToken(token) // Should be replaced by a valid token
());
session.Send(webcc::RequestBuilder{}.
Get("https://api.github.com/user/followers").
AuthToken(token) // Should be replaced by a valid token
());
```
Though **Keep-Alive** (i.e., persistent connection) is a good feature and enabled by default, you can turn it off:
```cpp
auto r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
KeepAlive(false) // No Keep-Alive
());
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
KeepAlive(false) // No Keep-Alive
());
```
The API for other HTTP requests is no different from GET.
@ -147,24 +134,36 @@ The API for other HTTP requests is no different from GET.
POST request needs a body which is normally a JSON string for REST API. Let's post a small UTF-8 encoded JSON string:
```cpp
session.Request(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
Body("{'name'='Adam', 'age'=20}").
Json().Utf8()
());
session.Send(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
Body("{'name'='Adam', 'age'=20}").Json().Utf8()
());
```
Webcc has the ability to stream large response data to a file. This is especially useful when downloading files.
```cpp
auto r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/image/jpeg")(),
true); // !!!
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/image/jpeg")
(), true); // stream = true
// Move the streamed file to your destination.
r->file_body()->Move("./wolf.jpeg");
```
Streaming is also available for uploading:
```cpp
auto r = session.Send(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
File(path) // Should be replaced by a valid file path
());
```
The file will not be loaded into the memory all at once, instead, it will be read and sent piece by piece.
Please note that `Content-Length` header will still be set to the true size of the file, this is different from the handling of chunked data (`Transfer-Encoding: chunked`).
Please check the [examples](https://github.com/sprinfall/webcc/tree/master/examples/) for more information.
## Server API

@ -41,7 +41,9 @@ int main() {
try {
// 发起一个 HTTP GET 请求
auto r = session.Get("http://httpbin.org/get");
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/get")
());
// 输出响应数据
std::cout << r->data() << std::endl;
@ -55,47 +57,30 @@ int main() {
}
```
因为 `Get()` 不过是 `Request()` 的一种快捷方式,直接调用 `Request()` 会更复杂一些:
如你所见,这里通过一个辅助类 `RequestBuilder`,串联起各种参数,最后再生成一个请求对象。注意不要漏了最后的 `()` 操作符。
```cpp
auto r = session.Request(webcc::RequestBuilder{}.Get("http://httpbin.org/get")());
```
这里多了个辅助类 `RequestBuilder`,用来串联起各种参数,最后再生成一个请求对象。注意不要漏了 `()` 操作符。
不管是 `Get` 还是 `Request()`,都接受 URL 查询参数:
通过 `Query()` 可以方便地指定 URL 查询参数:
```cpp
// 查询参数由 std::vector 一起指定,键值成对出现
session.Get("http://httpbin.org/get", { "key1", "value1", "key2", "value2" });
// 查询参数由 Query() 挨个指定
session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Query("key1", "value1").
Query("key2", "value2")
());
session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Query("key1", "value1").Query("key2", "value2")
());
```
要添加额外的头部也很简单:
```cpp
session.Get("http://httpbin.org/get",
{"key1", "value1", "key2", "value2"},
{"Accept", "application/json"}); // 也是 std::vector
session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Query("key1", "value1").
Query("key2", "value2").
Header("Accept", "application/json")
());
session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Header("Accept", "application/json")
());
```
访问 HTTPS 和访问 HTTP 没有差别,对用户是透明的:
```cpp
session.Get("https://httpbin.org/get");
session.Send(webcc::RequestBuilder{}.Get("https://httpbin.org/get")());
```
*注意:对 HTTPS/SSL 的支持,需要启用编译选项 `WEBCC_ENABLE_SSL`,也会依赖 OpenSSL。*
@ -103,40 +88,42 @@ session.Get("https://httpbin.org/get");
列出 GitHub 公开事件 (public events) 也不是什么难题:
```cpp
auto r = session.Get("https://api.github.com/events");
auto r = session.Send(webcc::RequestBuilder{}.
Get("https://api.github.com/events")
());
```
然后,你可以把 `r->data()` 解析成 JSON 对象,随便用个什么 JSON 程序库。
我在示例程序里用的是 [jsoncpp](https://github.com/open-source-parsers/jsoncpp),但是 Webcc 本身并不理解 JSON用什么 JSON 程序库,完全是你自己的选择。
快捷函数(`Get()``Post()`,等)用起来方便,但是参数有限,限制比较多。`RequestBuilder` 更灵活更强大,它提供了很多函数供你定制请求的样子。
`RequestBuilder` 本质上是为了解决 C++ 没有“键值参数”的问题,它提供了很多函数供你定制请求的样子。
为了列出一个授权的 (authorized) GitHub 用户的“粉丝” (followers),要么使用 **Basic 认证**
为了列出一个授权的 (authorized) GitHub 用户的“粉丝” (followers),要么使用 **Basic 认证**
```cpp
session.Request(webcc::RequestBuilder{}.
Get("https://api.github.com/user/followers").
AuthBasic(login, password) // 应该替换成具体的账号、密码
());
session.Send(webcc::RequestBuilder{}.
Get("https://api.github.com/user/followers").
AuthBasic(login, password) // 应该替换成具体的账号、密码
());
```
要么使用 **Token 认证**
```cpp
session.Request(webcc::RequestBuilder{}.
Get("https://api.github.com/user/followers").
AuthToken(token) // 应该替换成具体合法的 token
());
session.Send(webcc::RequestBuilder{}.
Get("https://api.github.com/user/followers").
AuthToken(token) // 应该替换成具体合法的 token
());
```
尽管**持久连接** (Keep-Alive) 这个功能不错,你也可以手动关掉它:
尽管 **持久连接** (Keep-Alive) 这个功能不错,你也可以手动关掉它:
```cpp
auto r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
KeepAlive(false) // 不要 Keep-Alive
());
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
KeepAlive(false) // 不要 Keep-Alive
());
```
其他 HTTP 请求的 API 跟 GET 并无太多差别。
@ -144,19 +131,18 @@ auto r = session.Request(webcc::RequestBuilder{}.
POST 请求需要一个“体” (body),就 REST API 来说通常是一个 JSON 字符串。让我们 POST 一个 UTF-8 编码的 JSON 字符串:
```cpp
session.Request(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
Body("{'name'='Adam', 'age'=20}").
Json().Utf8()
());
session.Send(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
Body("{'name'='Adam', 'age'=20}").Json().Utf8()
());
```
Webcc 可以把大型的响应数据串流到临时文件,串流在下载文件时特别有用。
```cpp
auto r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/image/jpeg")(),
true); // stream = true
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/image/jpeg")
(), true); // stream = true
// 把串流的文件移到目标位置
r->file_body()->Move("./wolf.jpeg");
@ -165,13 +151,13 @@ r->file_body()->Move("./wolf.jpeg");
不光下载,上传也可以串流:
```cpp
auto r = session.Request(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
File(path) // 应该替换成具体的文件路径
());
auto r = session.Send(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
File(path) // 应该替换成具体的文件路径
());
```
这个文件在 POST 时,不会一次加载到内存,读一块数据发一块数据,直到发送完。
这个文件在 POST 时,不会一次加载到内存,而是读一块数据发一块数据,直到发送完。
注意,`Content-Length` 头部还是会设置为文件的真实大小,不同于 `Transfer-Encoding: chunked` 的分块数据形式。

@ -37,9 +37,9 @@ TEST(ClientTest, Head) {
webcc::ClientSession session;
try {
auto r = session.Request(webcc::RequestBuilder{}.
Head("http://httpbin.org/get")
());
auto r = session.Send(webcc::RequestBuilder{}.
Head("http://httpbin.org/get")
());
EXPECT_EQ(webcc::Status::kOK, r->status());
EXPECT_EQ("OK", r->reason());
@ -59,10 +59,10 @@ TEST(ClientTest, Head_AcceptEncodingIdentity) {
webcc::ClientSession session;
try {
auto r = session.Request(webcc::RequestBuilder{}.
Head("http://httpbin.org/get").
Header("Accept-Encoding", "identity")
());
auto r = session.Send(webcc::RequestBuilder{}.
Head("http://httpbin.org/get").
Header("Accept-Encoding", "identity")
());
EXPECT_EQ(webcc::Status::kOK, r->status());
EXPECT_EQ("OK", r->reason());
@ -106,12 +106,11 @@ TEST(ClientTest, Get) {
webcc::ClientSession session;
try {
auto r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Query("key1", "value1").
Query("key2", "value2").
Header("Accept", "application/json")
());
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Query("key1", "value1").Query("key2", "value2").
Header("Accept", "application/json")
());
AssertGet(r);
@ -125,10 +124,9 @@ TEST(ClientTest, Get_QueryEncode) {
webcc::ClientSession session;
try {
auto r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Query("name", "Chunting Gu", true)
());
auto r = session.Send(webcc::RequestBuilder{}.Get("http://httpbin.org/get").
Query("name", "Chunting Gu", true)
());
EXPECT_EQ(webcc::Status::kOK, r->status());
EXPECT_EQ("OK", r->reason());
@ -151,12 +149,11 @@ TEST(ClientTest, Get_SSL) {
try {
// HTTPS is auto-detected from the URL scheme.
auto r = session.Request(webcc::RequestBuilder{}.
Get("https://httpbin.org/get").
Query("key1", "value1").
Query("key2", "value2").
Header("Accept", "application/json")
());
auto r = session.Send(webcc::RequestBuilder{}.
Get("https://httpbin.org/get").
Query("key1", "value1").Query("key2", "value2").
Header("Accept", "application/json")
());
AssertGet(r);
@ -171,9 +168,9 @@ TEST(ClientTest, Get_Jpeg_NoStream) {
webcc::ClientSession session;
try {
auto r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/image/jpeg")
());
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/image/jpeg")
());
// TODO: Verify the response is a valid JPEG image.
//std::ofstream ofs(<path>, std::ios::binary);
@ -188,10 +185,9 @@ TEST(ClientTest, Get_Jpeg_Stream) {
webcc::ClientSession session;
try {
auto r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/image/jpeg")
(),
true);
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/image/jpeg")
(), true);
auto file_body = r->file_body();
@ -227,10 +223,9 @@ TEST(ClientTest, Get_Jpeg_Stream_NoMove) {
webcc::Path ori_path;
{
auto r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/image/jpeg")
(),
true);
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/image/jpeg")
(), true);
auto file_body = r->file_body();
@ -258,9 +253,9 @@ TEST(ClientTest, Get_Gzip) {
webcc::ClientSession session;
try {
auto r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/gzip")
());
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/gzip")
());
Json::Value json = StringToJson(r->data());
@ -278,9 +273,9 @@ TEST(ClientTest, Get_Deflate) {
webcc::ClientSession session;
try {
auto r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/deflate")
());
auto r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/deflate")
());
Json::Value json = StringToJson(r->data());
@ -300,10 +295,9 @@ TEST(ClientTest, Post) {
try {
const std::string data = "{'name'='Adam', 'age'=20}";
auto r = session.Request(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
Body(data).Json()
());
auto r = session.Send(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").Body(data).Json()
());
EXPECT_EQ(webcc::Status::kOK, r->status());
EXPECT_EQ("OK", r->reason());
@ -347,10 +341,9 @@ TEST(ClientTest, Post_FileBody) {
}
try {
auto r = session.Request(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
File(path) // Use the file as body
());
auto r = session.Send(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").File(path)
());
EXPECT_EQ(webcc::Status::kOK, r->status());
EXPECT_EQ("OK", r->reason());
@ -377,11 +370,10 @@ TEST(ClientTest, Post_Gzip_SmallData) {
const std::string data = "{'name'='Adam', 'age'=20}";
// This doesn't really compress the body!
auto r = session.Request(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
Body(data).Json().
Gzip()
());
auto r = session.Send(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").Body(data).Json().
Gzip()
());
//Json::Value json = StringToJson(r->data());
@ -398,16 +390,15 @@ TEST(ClientTest, Post_Gzip) {
try {
// Use Boost.org home page as the POST data.
auto r1 = session.Request(webcc::RequestBuilder{}.
Get("https://www.boost.org/")
());
auto r1 = session.Send(webcc::RequestBuilder{}.
Get("https://www.boost.org/")
());
const std::string& data = r1->data();
auto r2 = session.Request(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
Body(data).Gzip()
());
auto r2 = session.Send(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").Body(data).Gzip()
());
EXPECT_EQ(webcc::Status::kOK, r2->status());
EXPECT_EQ("OK", r2->reason());
@ -440,33 +431,26 @@ TEST(ClientTest, KeepAlive) {
try {
// Keep-Alive by default.
auto r = session.Request(webcc::RequestBuilder{}.Get(url)());
auto r = session.Send(webcc::RequestBuilder{}.Get(url)());
using boost::iequals;
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Keep-alive"));
// Close by setting Connection header directly.
r = session.Request(webcc::RequestBuilder{}.
Get(url).
Header("Connection", "Close")
());
r = session.Send(webcc::RequestBuilder{}.Get(url).
Header("Connection", "Close")
());
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Close"));
// Close by using request builder.
r = session.Request(webcc::RequestBuilder{}.
Get(url).
KeepAlive(false)
());
r = session.Send(webcc::RequestBuilder{}.Get(url).KeepAlive(false)());
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Close"));
// Keep-Alive explicitly by using request builder.
r = session.Request(webcc::RequestBuilder{}.
Get(url).
KeepAlive(true)
());
r = session.Send(webcc::RequestBuilder{}.Get(url).KeepAlive(true)());
EXPECT_TRUE(iequals(r->GetHeader("Connection"), "Keep-alive"));

@ -12,30 +12,28 @@ int main() {
webcc::ResponsePtr r;
try {
r = session.Request(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Query("name", "Adam Gu", /*encode*/true).
Header("Accept", "application/json").
Date()
());
r = session.Send(webcc::RequestBuilder{}.
Get("http://httpbin.org/get").
Query("name", "Adam Gu", /*encode*/true).
Header("Accept", "application/json").Date()
());
assert(r->status() == webcc::Status::kOK);
assert(!r->data().empty());
r = session.Request(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
Body("{'name'='Adam', 'age'=20}").
Json().Utf8()
());
r = session.Send(webcc::RequestBuilder{}.
Post("http://httpbin.org/post").
Body("{'name'='Adam', 'age'=20}").Json().Utf8()
());
assert(r->status() == webcc::Status::kOK);
assert(!r->data().empty());
#if WEBCC_ENABLE_SSL
r = session.Request(webcc::RequestBuilder{}.
Get("https://httpbin.org/get")
());
r = session.Send(webcc::RequestBuilder{}.
Get("https://httpbin.org/get")
());
assert(r->status() == webcc::Status::kOK);
assert(!r->data().empty());

@ -26,8 +26,7 @@ int main(int argc, char* argv[]) {
webcc::ClientSession session;
try {
auto r = session.Request(webcc::RequestBuilder{}.Get(url)(),
true); // Stream the response data to file.
auto r = session.Send(webcc::RequestBuilder{}.Get(url)(), true);
if (auto file_body = r->file_body()) {
file_body->Move(path);

@ -41,11 +41,10 @@ int main(int argc, char* argv[]) {
webcc::ClientSession session;
try {
auto r = session.Request(webcc::RequestBuilder{}.
Post(url).
FormFile("file", upload_dir / "remember.txt").
FormData("json", "{}", "application/json")
());
auto r = session.Send(webcc::RequestBuilder{}.Post(url).
FormFile("file", upload_dir / "remember.txt").
FormData("json", "{}", "application/json")
());
std::cout << r->status() << std::endl;

@ -55,9 +55,8 @@ void PrettyPrintJsonString(const std::string& str) {
// List public events.
void ListEvents(webcc::ClientSession& session) {
try {
auto r = session.Request(webcc::RequestBuilder{}.
Get(kUrlRoot).Path("events")
());
auto r = session.Send(webcc::RequestBuilder{}.Get(kUrlRoot).Path("events")
());
PRINT_JSON_STRING(r->data());
@ -71,10 +70,9 @@ void ListEvents(webcc::ClientSession& session) {
// ListUserFollowers(session, "<user>")
void ListUserFollowers(webcc::ClientSession& session, const std::string& user) {
try {
auto r = session.Request(webcc::RequestBuilder{}.
Get(kUrlRoot).Path("users").Path(user).
Path("followers")
());
auto r = session.Send(webcc::RequestBuilder{}.Get(kUrlRoot).
Path("users").Path(user).Path("followers")
());
PRINT_JSON_STRING(r->data());
@ -90,10 +88,9 @@ void ListAuthUserFollowers(webcc::ClientSession& session,
const std::string& login,
const std::string& password) {
try {
auto r = session.Request(webcc::RequestBuilder{}.
Get(kUrlRoot).Path("user/followers").
AuthBasic(login, password)
());
auto r = session.Send(webcc::RequestBuilder{}.Get(kUrlRoot).
Path("user/followers").AuthBasic(login, password)
());
PRINT_JSON_STRING(r->data());
@ -112,12 +109,10 @@ void CreateAuthorization(webcc::ClientSession& session,
" 'scopes': ['public_repo', 'repo', 'repo:status', 'user']\n"
"}";
auto r = session.Request(webcc::RequestBuilder{}.
Post(kUrlRoot).Path("authorizations").
Body(std::move(data)).
Json().Utf8().
AuthBasic(login, password)
());
auto r = session.Send(webcc::RequestBuilder{}.Post(kUrlRoot).
Path("authorizations").AuthBasic(login, password).
Body(std::move(data)).Json().Utf8()
());
std::cout << r->data() << std::endl;

@ -57,7 +57,7 @@ BookClient::BookClient(const std::string& url, int timeout)
bool BookClient::ListBooks(std::list<Book>* books) {
try {
auto r = session_.Request(WEBCC_GET(url_).Path("books")());
auto r = session_.Send(WEBCC_GET(url_).Path("books")());
if (!CheckStatus(r, webcc::Status::kOK)) {
// Response HTTP status error.
@ -89,9 +89,9 @@ bool BookClient::CreateBook(const std::string& title, double price,
req_json["price"] = price;
try {
auto r = session_.Request(WEBCC_POST(url_).Path("books").
Body(JsonToString(req_json))
());
auto r = session_.Send(WEBCC_POST(url_).Path("books").
Body(JsonToString(req_json))
());
if (!CheckStatus(r, webcc::Status::kCreated)) {
return false;
@ -110,7 +110,7 @@ bool BookClient::CreateBook(const std::string& title, double price,
bool BookClient::GetBook(const std::string& id, Book* book) {
try {
auto r = session_.Request(WEBCC_GET(url_).Path("books").Path(id)());
auto r = session_.Send(WEBCC_GET(url_).Path("books").Path(id)());
if (!CheckStatus(r, webcc::Status::kOK)) {
return false;
@ -131,9 +131,9 @@ bool BookClient::UpdateBook(const std::string& id, const std::string& title,
json["price"] = price;
try {
auto r = session_.Request(WEBCC_PUT(url_).Path("books").Path(id).
Body(JsonToString(json))
());
auto r = session_.Send(WEBCC_PUT(url_).Path("books").Path(id).
Body(JsonToString(json))
());
if (!CheckStatus(r, webcc::Status::kOK)) {
return false;
@ -149,7 +149,7 @@ bool BookClient::UpdateBook(const std::string& id, const std::string& title,
bool BookClient::DeleteBook(const std::string& id) {
try {
auto r = session_.Request(WEBCC_DELETE(url_).Path("books").Path(id)());
auto r = session_.Send(WEBCC_DELETE(url_).Path("books").Path(id)());
if (!CheckStatus(r, webcc::Status::kOK)) {
return false;

@ -28,7 +28,7 @@ void ClientSession::AuthToken(const std::string& token) {
return Auth("Token", token);
}
ResponsePtr ClientSession::Request(RequestPtr request, bool stream) {
ResponsePtr ClientSession::Send(RequestPtr request, bool stream) {
assert(request);
for (auto& h : headers_.data()) {
@ -44,7 +44,7 @@ ResponsePtr ClientSession::Request(RequestPtr request, bool stream) {
request->Prepare();
return Send(request, stream);
return DoSend(request, stream);
}
void ClientSession::InitHeaders() {
@ -85,7 +85,7 @@ void ClientSession::InitHeaders() {
headers_.Set(kConnection, "Keep-Alive");
}
ResponsePtr ClientSession::Send(RequestPtr request, bool stream) {
ResponsePtr ClientSession::DoSend(RequestPtr request, bool stream) {
const ClientPool::Key key{ request->url() };
// Reuse a pooled connection.

@ -61,12 +61,12 @@ public:
// the response body will be FileBody, and you can easily move the temp file
// to another path with FileBody::Move(). So, |stream| is really useful for
// downloading files (JPEG, etc.) or saving memory for huge data responses.
ResponsePtr Request(RequestPtr request, bool stream = false);
ResponsePtr Send(RequestPtr request, bool stream = false);
private:
void InitHeaders();
ResponsePtr Send(RequestPtr request, bool stream);
ResponsePtr DoSend(RequestPtr request, bool stream);
private:
// Default media type for `Content-Type` header.

Loading…
Cancel
Save