Skip to content

Commit 2221570

Browse files
committed
feat: add curl / cpr (c++ curl wrapper) http backend
1 parent ebb834c commit 2221570

File tree

4 files changed

+203
-3
lines changed

4 files changed

+203
-3
lines changed

src/lobby/client.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@
55

66
#if defined(_OOPETRIS_ONLINE_USE_CURL)
77
#include "./curl_client.hpp"
8-
#error "TODO"
8+
9+
10+
std::string oopetris::http::status_message([[maybe_unused]] int status) {
11+
return "Not Available";
12+
}
13+
14+
915
#else
1016

1117
#include "./httplib_client.hpp"

src/lobby/curl_client.cpp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,132 @@
11

22
#include "./curl_client.hpp"
3+
4+
5+
#define TRANSFORM_RESULT(result) std::make_unique<ActualResult>((result))
6+
7+
8+
oopetris::http::implementation::ActualResult::ActualResult(cpr::Response&& result) : m_result{ std::move(result) } { }
9+
10+
oopetris::http::implementation::ActualResult::~ActualResult() = default;
11+
12+
[[nodiscard]] std::optional<std::string> oopetris::http::implementation::ActualResult::get_header(const std::string& key
13+
) const {
14+
15+
if (not m_result.header.contains(key)) {
16+
return std::nullopt;
17+
}
18+
19+
return m_result.header.at(key);
20+
}
21+
22+
[[nodiscard]] std::string oopetris::http::implementation::ActualResult::body() const {
23+
return m_result.text;
24+
}
25+
26+
[[nodiscard]] int oopetris::http::implementation::ActualResult::status() const {
27+
return m_result.status_code;
28+
}
29+
30+
[[nodiscard]] std::optional<std::string> oopetris::http::implementation::ActualResult::get_error() const {
31+
32+
if (static_cast<bool>(m_result.error) || m_result.status_code == 0) {
33+
return m_result.error.message;
34+
}
35+
36+
return std::nullopt;
37+
}
38+
39+
40+
namespace {
41+
std::string normalize_url(const std::string& value) {
42+
if (value.ends_with("/")) {
43+
value.substr(0, value.size() - 1);
44+
}
45+
46+
return value;
47+
}
48+
} // namespace
49+
50+
oopetris::http::implementation::ActualClient::ActualClient(ActualClient&& other) noexcept
51+
: m_session{ std::move(other.m_session) } { }
52+
53+
oopetris::http::implementation::ActualClient::~ActualClient() = default;
54+
55+
oopetris::http::implementation::ActualClient::ActualClient(const std::string& api_url)
56+
: m_session{},
57+
m_base_url{ normalize_url(api_url) } {
58+
59+
m_session.SetUrl(cpr::Url{ api_url });
60+
m_session.SetAcceptEncoding(cpr::AcceptEncoding{
61+
{ cpr::AcceptEncodingMethods::deflate, cpr::AcceptEncodingMethods::gzip,
62+
cpr::AcceptEncodingMethods::zlib }
63+
});
64+
m_session.SetHeader(cpr::Header{
65+
{ "Accept", ::http::constants::json_content_type }
66+
});
67+
}
68+
69+
70+
void oopetris::http::implementation::ActualClient::set_url(const std::string& url) {
71+
m_session.SetUrl(cpr::Url{ m_base_url, url });
72+
}
73+
74+
75+
[[nodiscard]] std::unique_ptr<oopetris::http::Result> oopetris::http::implementation::ActualClient::Get(
76+
const std::string& url
77+
) {
78+
set_url(url);
79+
return TRANSFORM_RESULT(m_session.Get());
80+
}
81+
82+
[[nodiscard]] std::unique_ptr<oopetris::http::Result> oopetris::http::implementation::ActualClient::Delete(
83+
const std::string& url
84+
) {
85+
set_url(url);
86+
return TRANSFORM_RESULT(m_session.Delete());
87+
}
88+
89+
[[nodiscard]] std::unique_ptr<oopetris::http::Result> oopetris::http::implementation::ActualClient::Post(
90+
const std::string& url,
91+
const std::optional<std::pair<std::string, std::string>>& payload
92+
) {
93+
94+
set_url(url);
95+
96+
if (not payload.has_value()) {
97+
return TRANSFORM_RESULT(m_session.Post());
98+
}
99+
100+
auto [content, content_type] = payload.value();
101+
102+
m_session.SetBody(cpr::Body{ content });
103+
104+
return TRANSFORM_RESULT(m_session.Post());
105+
}
106+
107+
[[nodiscard]] std::unique_ptr<oopetris::http::Result> oopetris::http::implementation::ActualClient::Put(
108+
const std::string& url,
109+
const std::optional<std::pair<std::string, std::string>>& payload
110+
) {
111+
set_url(url);
112+
113+
if (not payload.has_value()) {
114+
return TRANSFORM_RESULT(m_session.Put());
115+
}
116+
117+
auto [content, content_type] = payload.value();
118+
119+
m_session.SetBody(cpr::Body{ content });
120+
121+
return TRANSFORM_RESULT(m_session.Put());
122+
}
123+
124+
void oopetris::http::implementation::ActualClient::SetBearerAuth(const std::string& token) {
125+
126+
127+
#if CPR_LIBCURL_VERSION_NUM >= 0x073D00
128+
m_session.SetBearer(token);
129+
#else
130+
m_session.SetHeader(cpr::Header{ "Authorization", fmt::format("Bearer {}", token) });
131+
#endif
132+
}

src/lobby/curl_client.hpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,68 @@
11

22
#pragma once
3+
4+
5+
#include "./client.hpp"
6+
7+
#include <cpr/cpr.h>
8+
9+
namespace oopetris::http::implementation {
10+
11+
struct ActualResult : ::oopetris::http::Result {
12+
private:
13+
cpr::Response m_result;
14+
15+
16+
public:
17+
OOPETRIS_GRAPHICS_EXPORTED ActualResult(cpr::Response&& result);
18+
19+
OOPETRIS_GRAPHICS_EXPORTED ~ActualResult() override;
20+
21+
OOPETRIS_GRAPHICS_EXPORTED [[nodiscard]] std::optional<std::string> get_header(const std::string& key
22+
) const override;
23+
24+
OOPETRIS_GRAPHICS_EXPORTED [[nodiscard]] std::string body() const override;
25+
26+
OOPETRIS_GRAPHICS_EXPORTED [[nodiscard]] int status() const override;
27+
28+
OOPETRIS_GRAPHICS_EXPORTED [[nodiscard]] std::optional<std::string> get_error() const override;
29+
};
30+
31+
32+
struct ActualClient : ::oopetris::http::Client {
33+
private:
34+
cpr::Session m_session;
35+
std::string m_base_url;
36+
37+
void set_url(const std::string& url);
38+
39+
public:
40+
OOPETRIS_GRAPHICS_EXPORTED ActualClient(ActualClient&& other) noexcept;
41+
OOPETRIS_GRAPHICS_EXPORTED ActualClient& operator=(ActualClient&& other) noexcept = delete;
42+
43+
OOPETRIS_GRAPHICS_EXPORTED ActualClient(const ActualClient& other) = delete;
44+
OOPETRIS_GRAPHICS_EXPORTED ActualClient& operator=(const ActualClient& other) = delete;
45+
46+
OOPETRIS_GRAPHICS_EXPORTED ~ActualClient() override;
47+
48+
OOPETRIS_GRAPHICS_EXPORTED explicit ActualClient(const std::string& api_url);
49+
50+
OOPETRIS_GRAPHICS_EXPORTED [[nodiscard]] std::unique_ptr<Result> Get(const std::string& url) override;
51+
52+
OOPETRIS_GRAPHICS_EXPORTED [[nodiscard]] std::unique_ptr<Result> Delete(const std::string& url) override;
53+
54+
OOPETRIS_GRAPHICS_EXPORTED [[nodiscard]] std::unique_ptr<Result> Post(
55+
const std::string& url,
56+
const std::optional<std::pair<std::string, std::string>>& payload = std::nullopt
57+
) override;
58+
59+
OOPETRIS_GRAPHICS_EXPORTED [[nodiscard]] std::unique_ptr<Result> Put(
60+
const std::string& url,
61+
const std::optional<std::pair<std::string, std::string>>& payload = std::nullopt
62+
) override;
63+
64+
OOPETRIS_GRAPHICS_EXPORTED void SetBearerAuth(const std::string& token) override;
65+
};
66+
67+
68+
} // namespace oopetris::http::implementation

src/lobby/httplib_client.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@
2020
#pragma warning(default : 4100)
2121
#endif
2222

23-
2423
#include "./client.hpp"
2524

26-
2725
namespace oopetris::http::implementation {
2826

2927
struct ActualResult : ::oopetris::http::Result {

0 commit comments

Comments
 (0)