separated data structure of body

This commit is contained in:
2019-06-26 03:19:23 +07:00
parent 54932af2c1
commit 0bcdf6636a
3 changed files with 354 additions and 247 deletions

View File

@@ -27,8 +27,10 @@ namespace curly_hpp
explicit exception(const std::string& what); explicit exception(const std::string& what);
}; };
struct case_insensitive_compare { struct icase_compare {
bool operator()(const std::string& l, const std::string& r) const noexcept; bool operator()(
const std::string& l,
const std::string& r) const noexcept;
}; };
enum class methods { enum class methods {
@@ -38,15 +40,12 @@ namespace curly_hpp
post post
}; };
using headers_t = std::map<
std::string, std::string,
case_insensitive_compare>;
using body_t = std::vector<char>;
using response_code_t = std::uint16_t; using response_code_t = std::uint16_t;
using headers_t = std::map<std::string, std::string, icase_compare>;
using sec_t = std::chrono::seconds; using time_sec_t = std::chrono::seconds;
using ms_t = std::chrono::milliseconds; using time_ms_t = std::chrono::milliseconds;
using time_point_t = std::chrono::steady_clock::time_point;
class upload_handler { class upload_handler {
public: public:
@@ -63,84 +62,67 @@ namespace curly_hpp
using uploader_uptr = std::unique_ptr<upload_handler>; using uploader_uptr = std::unique_ptr<upload_handler>;
using downloader_uptr = std::unique_ptr<download_handler>; using downloader_uptr = std::unique_ptr<download_handler>;
}
class request_builder { namespace curly_hpp
{
class content_t {
public: public:
request_builder() = default; content_t() = default;
request_builder(request_builder&&) = default; content_t(content_t&&) = default;
request_builder& operator=(request_builder&&) = default; content_t& operator=(content_t&&) = default;
request_builder(const request_builder&) = delete; content_t(const content_t&) = default;
request_builder& operator=(const request_builder&) = delete; content_t& operator=(const content_t&) = default;
explicit request_builder(methods m) noexcept; content_t(std::string_view data);
explicit request_builder(std::string u) noexcept; content_t(std::vector<char> data) noexcept;
explicit request_builder(methods m, std::string u) noexcept;
request_builder& url(std::string u) noexcept; std::size_t size() const noexcept;
request_builder& method(methods m) noexcept; std::vector<char>& data() noexcept;
request_builder& header(std::string key, std::string value); const std::vector<char>& data() const noexcept;
request_builder& verbose(bool v) noexcept; std::string as_string_copy() const;
request_builder& verification(bool v) noexcept; std::string_view as_string_view() const noexcept;
request_builder& response_timeout(sec_t t) noexcept;
request_builder& connection_timeout(sec_t t) noexcept;
request_builder& redirections(std::uint32_t r) noexcept;
request_builder& body(body_t b) noexcept;
request_builder& body(std::string_view b);
request_builder& uploader(uploader_uptr u) noexcept;
request_builder& downloader(downloader_uptr d) noexcept;
[[nodiscard]] const std::string& url() const noexcept;
[[nodiscard]] methods method() const noexcept;
[[nodiscard]] const headers_t& headers() const noexcept;
[[nodiscard]] bool verbose() const noexcept;
[[nodiscard]] bool verification() const noexcept;
[[nodiscard]] sec_t response_timeout() const noexcept;
[[nodiscard]] sec_t connection_timeout() const noexcept;
[[nodiscard]] std::uint32_t redirections() const noexcept;
[[nodiscard]] body_t& body() noexcept;
[[nodiscard]] const body_t& body() const noexcept;
[[nodiscard]] uploader_uptr& uploader() noexcept;
[[nodiscard]] const uploader_uptr& uploader() const noexcept;
[[nodiscard]] downloader_uptr& downloader() noexcept;
[[nodiscard]] const downloader_uptr& downloader() const noexcept;
private: private:
std::string url_; std::vector<char> data_;
methods method_{methods::get};
headers_t headers_;
bool verbose_{false};
bool verification_{true};
sec_t response_timeout_{60u};
sec_t connection_timeout_{20u};
std::uint32_t redirections_{~0u};
private:
body_t body_;
uploader_uptr uploader_;
downloader_uptr downloader_;
}; };
}
namespace curly_hpp
{
class response { class response {
public: public:
response() = default; response() = default;
response(response_code_t c, body_t b, headers_t h);
response(response&&) = default;
response& operator=(response&&) = default;
response(const response&) = default;
response& operator=(const response&) = default;
explicit response(response_code_t rc) noexcept;
response(response_code_t rc, headers_t h) noexcept;
response(response_code_t rc, content_t c) noexcept;
response(response_code_t rc, headers_t h, content_t c) noexcept;
response_code_t code() const noexcept; response_code_t code() const noexcept;
const body_t& body() const noexcept;
content_t& content() noexcept;
const content_t& content() const noexcept;
headers_t& headers() noexcept;
const headers_t& headers() const noexcept; const headers_t& headers() const noexcept;
std::string_view body_as_string() const noexcept;
private: private:
response_code_t code_{0u}; response_code_t code_{0u};
body_t body_; content_t content_;
headers_t headers_; headers_t headers_;
}; };
}
namespace curly_hpp
{
class request { class request {
public: public:
enum class statuses { enum class statuses {
@@ -165,22 +147,93 @@ namespace curly_hpp
private: private:
internal_state_ptr state_; internal_state_ptr state_;
}; };
}
namespace curly_hpp
{
class request_builder {
public:
request_builder() = default;
request_builder(request_builder&&) = default;
request_builder& operator=(request_builder&&) = default;
request_builder(const request_builder&) = delete;
request_builder& operator=(const request_builder&) = delete;
explicit request_builder(methods m) noexcept;
explicit request_builder(std::string u) noexcept;
explicit request_builder(methods m, std::string u) noexcept;
request_builder& url(std::string u) noexcept;
request_builder& method(methods m) noexcept;
request_builder& header(std::string key, std::string value);
request_builder& verbose(bool v) noexcept;
request_builder& verification(bool v) noexcept;
request_builder& redirections(std::uint32_t r) noexcept;
request_builder& response_timeout(time_sec_t t) noexcept;
request_builder& connection_timeout(time_sec_t t) noexcept;
request_builder& content(std::string_view b);
request_builder& content(content_t b) noexcept;
request_builder& uploader(uploader_uptr u) noexcept;
request_builder& downloader(downloader_uptr d) noexcept;
[[nodiscard]] const std::string& url() const noexcept;
[[nodiscard]] methods method() const noexcept;
[[nodiscard]] const headers_t& headers() const noexcept;
[[nodiscard]] bool verbose() const noexcept;
[[nodiscard]] bool verification() const noexcept;
[[nodiscard]] std::uint32_t redirections() const noexcept;
[[nodiscard]] time_sec_t response_timeout() const noexcept;
[[nodiscard]] time_sec_t connection_timeout() const noexcept;
[[nodiscard]] content_t& content() noexcept;
[[nodiscard]] const content_t& content() const noexcept;
[[nodiscard]] uploader_uptr& uploader() noexcept;
[[nodiscard]] const uploader_uptr& uploader() const noexcept;
[[nodiscard]] downloader_uptr& downloader() noexcept;
[[nodiscard]] const downloader_uptr& downloader() const noexcept;
private:
std::string url_;
methods method_{methods::get};
headers_t headers_;
bool verbose_{false};
bool verification_{true};
std::uint32_t redirections_{~0u};
time_sec_t response_timeout_{60u};
time_sec_t connection_timeout_{20u};
private:
content_t content_;
uploader_uptr uploader_;
downloader_uptr downloader_;
};
}
namespace curly_hpp
{
class auto_updater { class auto_updater {
public: public:
auto_updater(); auto_updater();
~auto_updater() noexcept; ~auto_updater() noexcept;
ms_t wait_activity() const noexcept; time_ms_t wait_activity() const noexcept;
void wait_activity(ms_t ms) noexcept; void wait_activity(time_ms_t ms) noexcept;
private: private:
std::thread thread_; std::thread thread_;
ms_t wait_activity_{100}; time_ms_t wait_activity_{100};
std::atomic<bool> done_{false}; std::atomic<bool> done_{false};
}; };
}
namespace curly_hpp
{
void update(); void update();
void wait_activity(ms_t ms); void wait_activity(time_ms_t ms);
request perform(request_builder& rb); request perform(request_builder& rb);
request perform(request_builder&& rb); request perform(request_builder&& rb);

View File

@@ -33,7 +33,6 @@ namespace
CURL, CURL,
void(*)(CURL*)>; void(*)(CURL*)>;
using time_point_t = std::chrono::steady_clock::time_point;
using req_state_t = std::shared_ptr<request::internal_state>; using req_state_t = std::shared_ptr<request::internal_state>;
std::map<CURL*, req_state_t> handles; std::map<CURL*, req_state_t> handles;
@@ -130,13 +129,13 @@ namespace curly_hpp
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// //
// case_insensitive_compare // icase_compare
// //
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
namespace curly_hpp namespace curly_hpp
{ {
bool case_insensitive_compare::operator()( bool icase_compare::operator()(
const std::string& l, const std::string& l,
const std::string& r) const noexcept const std::string& r) const noexcept
{ {
@@ -150,136 +149,36 @@ namespace curly_hpp
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// //
// request_builder // content_t
// //
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
namespace curly_hpp namespace curly_hpp
{ {
request_builder::request_builder(methods m) noexcept content_t::content_t(std::string_view data)
: method_(m) {} : data_(data.cbegin(), data.cend() ) {}
request_builder::request_builder(std::string u) noexcept content_t::content_t(std::vector<char> data) noexcept
: url_(std::move(u)) {} : data_(std::move(data)) {}
request_builder::request_builder(methods m, std::string u) noexcept std::size_t content_t::size() const noexcept {
: url_(std::move(u)) return data_.size();
, method_(m) {}
request_builder& request_builder::url(std::string u) noexcept {
url_ = std::move(u);
return *this;
} }
request_builder& request_builder::method(methods m) noexcept { std::vector<char>& content_t::data() noexcept {
method_ = m; return data_;
return *this;
} }
request_builder& request_builder::header(std::string key, std::string value) { const std::vector<char>& content_t::data() const noexcept {
headers_.insert_or_assign(std::move(key), std::move(value)); return data_;
return *this;
} }
request_builder& request_builder::verbose(bool v) noexcept { std::string content_t::as_string_copy() const {
verbose_ = v; return {data_.data(), data_.size()};
return *this;
} }
request_builder& request_builder::verification(bool v) noexcept { std::string_view content_t::as_string_view() const noexcept {
verification_ = v; return {data_.data(), data_.size()};
return *this;
}
request_builder& request_builder::response_timeout(sec_t t) noexcept {
response_timeout_ = t;
return *this;
}
request_builder& request_builder::connection_timeout(sec_t t) noexcept {
connection_timeout_ = t;
return *this;
}
request_builder& request_builder::redirections(std::uint32_t r) noexcept {
redirections_ = r;
return *this;
}
request_builder& request_builder::body(body_t b) noexcept {
body_ = std::move(b);
return *this;
}
request_builder& request_builder::body(std::string_view b) {
body_.assign(b.begin(), b.end());
return *this;
}
request_builder& request_builder::uploader(uploader_uptr u) noexcept {
uploader_ = std::move(u);
return *this;
}
request_builder& request_builder::downloader(downloader_uptr d) noexcept {
downloader_ = std::move(d);
return *this;
}
const std::string& request_builder::url() const noexcept {
return url_;
}
methods request_builder::method() const noexcept {
return method_;
}
const headers_t& request_builder::headers() const noexcept {
return headers_;
}
bool request_builder::verbose() const noexcept {
return verbose_;
}
bool request_builder::verification() const noexcept {
return verification_;
}
sec_t request_builder::response_timeout() const noexcept {
return response_timeout_;
}
sec_t request_builder::connection_timeout() const noexcept {
return connection_timeout_;
}
std::uint32_t request_builder::redirections() const noexcept {
return redirections_;
}
body_t& request_builder::body() noexcept {
return body_;
}
const body_t& request_builder::body() const noexcept {
return body_;
}
uploader_uptr& request_builder::uploader() noexcept {
return uploader_;
}
const uploader_uptr& request_builder::uploader() const noexcept {
return uploader_;
}
downloader_uptr& request_builder::downloader() noexcept {
return downloader_;
}
const downloader_uptr& request_builder::downloader() const noexcept {
return downloader_;
} }
} }
@@ -289,25 +188,43 @@ namespace curly_hpp
// //
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
response::response(response_code_t c, body_t b, headers_t h) namespace curly_hpp
: code_(c) {
, body_(std::move(b)) response::response(response_code_t rc) noexcept
, headers_(std::move(h)) {} : code_(rc) {}
response_code_t response::code() const noexcept { response::response(response_code_t rc, headers_t h) noexcept
return code_; : code_(rc)
} , headers_(std::move(h)) {}
const body_t& response::body() const noexcept { response::response(response_code_t rc, content_t c) noexcept
return body_; : code_(rc)
} , content_(std::move(c)) {}
const headers_t& response::headers() const noexcept { response::response(response_code_t rc, headers_t h, content_t c) noexcept
return headers_; : code_(rc)
} , headers_(std::move(h))
, content_(std::move(c)) {}
std::string_view response::body_as_string() const noexcept { response_code_t response::code() const noexcept {
return {body_.data(), body_.size()}; return code_;
}
content_t& response::content() noexcept {
return content_;
}
const content_t& response::content() const noexcept {
return content_;
}
headers_t& response::headers() noexcept {
return headers_;
}
const headers_t& response::headers() const noexcept {
return headers_;
}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@@ -323,7 +240,7 @@ namespace curly_hpp
internal_state(handle_t handle, request_builder&& rb) internal_state(handle_t handle, request_builder&& rb)
: hlist_(make_header_slist(rb.headers())) : hlist_(make_header_slist(rb.headers()))
, handle_(std::move(handle)) , handle_(std::move(handle))
, body_(std::move(rb.body())) , content_(std::move(rb.content()))
, uploader_(std::move(rb.uploader())) , uploader_(std::move(rb.uploader()))
, downloader_(std::move(rb.downloader())) , downloader_(std::move(rb.downloader()))
{ {
@@ -356,7 +273,7 @@ namespace curly_hpp
curl_easy_setopt(handle_.get(), CURLOPT_UPLOAD, 1L); curl_easy_setopt(handle_.get(), CURLOPT_UPLOAD, 1L);
curl_easy_setopt(handle_.get(), CURLOPT_INFILESIZE_LARGE, uploader_ curl_easy_setopt(handle_.get(), CURLOPT_INFILESIZE_LARGE, uploader_
? static_cast<curl_off_t>(uploader_->size()) ? static_cast<curl_off_t>(uploader_->size())
: static_cast<curl_off_t>(body_.size())); : static_cast<curl_off_t>(content_.size()));
break; break;
case methods::get: case methods::get:
curl_easy_setopt(handle_.get(), CURLOPT_HTTPGET, 1L); curl_easy_setopt(handle_.get(), CURLOPT_HTTPGET, 1L);
@@ -368,7 +285,7 @@ namespace curly_hpp
curl_easy_setopt(handle_.get(), CURLOPT_POST, 1L); curl_easy_setopt(handle_.get(), CURLOPT_POST, 1L);
curl_easy_setopt(handle_.get(), CURLOPT_POSTFIELDSIZE_LARGE, uploader_ curl_easy_setopt(handle_.get(), CURLOPT_POSTFIELDSIZE_LARGE, uploader_
? static_cast<curl_off_t>(uploader_->size()) ? static_cast<curl_off_t>(uploader_->size())
: static_cast<curl_off_t>(body_.size())); : static_cast<curl_off_t>(content_.size()));
break; break;
default: default:
throw exception("curly_hpp: unexpected request method"); throw exception("curly_hpp: unexpected request method");
@@ -390,10 +307,10 @@ namespace curly_hpp
} }
curl_easy_setopt(handle_.get(), CURLOPT_CONNECTTIMEOUT, curl_easy_setopt(handle_.get(), CURLOPT_CONNECTTIMEOUT,
std::max(sec_t(1), rb.connection_timeout()).count()); std::max(time_sec_t(1), rb.connection_timeout()).count());
last_response_ = time_point_t::clock::now(); last_response_ = time_point_t::clock::now();
response_timeout_ = std::max(sec_t(1), rb.response_timeout()); response_timeout_ = std::max(time_sec_t(1), rb.response_timeout());
} }
bool done() noexcept { bool done() noexcept {
@@ -410,8 +327,8 @@ namespace curly_hpp
response_ = response( response_ = response(
static_cast<response_code_t>(response_code), static_cast<response_code_t>(response_code),
std::move(response_body_), std::move(response_headers_),
std::move(response_headers_)); std::move(response_content_));
status_ = statuses::done; status_ = statuses::done;
error_.clear(); error_.clear();
@@ -528,8 +445,8 @@ namespace curly_hpp
return bytes; return bytes;
} }
std::lock_guard<std::mutex> guard(mutex_); std::lock_guard<std::mutex> guard(mutex_);
size = std::min(size, body_.size() - uploaded_.load()); size = std::min(size, content_.size() - uploaded_.load());
std::memcpy(dst, body_.data() + uploaded_.load(), size); std::memcpy(dst, content_.data().data() + uploaded_.load(), size);
uploaded_.fetch_add(size); uploaded_.fetch_add(size);
return size; return size;
} catch (...) { } catch (...) {
@@ -544,7 +461,7 @@ namespace curly_hpp
downloaded_.fetch_add(bytes); downloaded_.fetch_add(bytes);
return bytes; return bytes;
} }
response_body_.insert(response_body_.end(), src, src + size); response_content_.insert(response_content_.end(), src, src + size);
downloaded_.fetch_add(size); downloaded_.fetch_add(size);
return size; return size;
} catch (...) { } catch (...) {
@@ -578,22 +495,24 @@ namespace curly_hpp
private: private:
slist_t hlist_; slist_t hlist_;
handle_t handle_; handle_t handle_;
body_t body_; content_t content_;
uploader_uptr uploader_; uploader_uptr uploader_;
downloader_uptr downloader_; downloader_uptr downloader_;
private: private:
time_point_t last_response_; time_point_t last_response_;
time_point_t::duration response_timeout_; time_point_t::duration response_timeout_;
private: private:
mutable std::mutex mutex_;
mutable std::condition_variable cond_var_;
response response_; response response_;
body_t response_body_;
headers_t response_headers_; headers_t response_headers_;
std::vector<char> response_content_;
private:
std::atomic_size_t uploaded_{0u}; std::atomic_size_t uploaded_{0u};
std::atomic_size_t downloaded_{0u}; std::atomic_size_t downloaded_{0u};
statuses status_{statuses::pending}; statuses status_{statuses::pending};
std::string error_{"Unknown error"}; std::string error_{"Unknown error"};
private:
mutable std::mutex mutex_;
mutable std::condition_variable cond_var_;
}; };
} }
@@ -623,6 +542,141 @@ namespace curly_hpp
} }
} }
// -----------------------------------------------------------------------------
//
// request_builder
//
// -----------------------------------------------------------------------------
namespace curly_hpp
{
request_builder::request_builder(methods m) noexcept
: method_(m) {}
request_builder::request_builder(std::string u) noexcept
: url_(std::move(u)) {}
request_builder::request_builder(methods m, std::string u) noexcept
: url_(std::move(u))
, method_(m) {}
request_builder& request_builder::url(std::string u) noexcept {
url_ = std::move(u);
return *this;
}
request_builder& request_builder::method(methods m) noexcept {
method_ = m;
return *this;
}
request_builder& request_builder::header(std::string key, std::string value) {
headers_.insert_or_assign(std::move(key), std::move(value));
return *this;
}
request_builder& request_builder::verbose(bool v) noexcept {
verbose_ = v;
return *this;
}
request_builder& request_builder::verification(bool v) noexcept {
verification_ = v;
return *this;
}
request_builder& request_builder::redirections(std::uint32_t r) noexcept {
redirections_ = r;
return *this;
}
request_builder& request_builder::response_timeout(time_sec_t t) noexcept {
response_timeout_ = t;
return *this;
}
request_builder& request_builder::connection_timeout(time_sec_t t) noexcept {
connection_timeout_ = t;
return *this;
}
request_builder& request_builder::content(std::string_view c) {
content_ = content_t(c);
return *this;
}
request_builder& request_builder::content(content_t c) noexcept {
content_ = std::move(c);
return *this;
}
request_builder& request_builder::uploader(uploader_uptr u) noexcept {
uploader_ = std::move(u);
return *this;
}
request_builder& request_builder::downloader(downloader_uptr d) noexcept {
downloader_ = std::move(d);
return *this;
}
const std::string& request_builder::url() const noexcept {
return url_;
}
methods request_builder::method() const noexcept {
return method_;
}
const headers_t& request_builder::headers() const noexcept {
return headers_;
}
bool request_builder::verbose() const noexcept {
return verbose_;
}
bool request_builder::verification() const noexcept {
return verification_;
}
std::uint32_t request_builder::redirections() const noexcept {
return redirections_;
}
time_sec_t request_builder::response_timeout() const noexcept {
return response_timeout_;
}
time_sec_t request_builder::connection_timeout() const noexcept {
return connection_timeout_;
}
content_t& request_builder::content() noexcept {
return content_;
}
const content_t& request_builder::content() const noexcept {
return content_;
}
uploader_uptr& request_builder::uploader() noexcept {
return uploader_;
}
const uploader_uptr& request_builder::uploader() const noexcept {
return uploader_;
}
downloader_uptr& request_builder::downloader() noexcept {
return downloader_;
}
const downloader_uptr& request_builder::downloader() const noexcept {
return downloader_;
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// //
// auto_updater // auto_updater
@@ -647,11 +701,11 @@ namespace curly_hpp
} }
} }
ms_t auto_updater::wait_activity() const noexcept { time_ms_t auto_updater::wait_activity() const noexcept {
return wait_activity_; return wait_activity_;
} }
void auto_updater::wait_activity(ms_t ms) noexcept { void auto_updater::wait_activity(time_ms_t ms) noexcept {
wait_activity_ = ms; wait_activity_ = ms;
} }
} }
@@ -704,7 +758,7 @@ namespace curly_hpp
}); });
} }
void wait_activity(ms_t ms) { void wait_activity(time_ms_t ms) {
curl_state::with([ms](CURLM* curlm){ curl_state::with([ms](CURLM* curlm){
curl_multi_wait(curlm, nullptr, 0, static_cast<int>(ms.count()), nullptr); curl_multi_wait(curlm, nullptr, 0, static_cast<int>(ms.count()), nullptr);
}); });

View File

@@ -100,7 +100,7 @@ TEST_CASE("curly"){
{ {
auto req = net::perform(net::request_builder() auto req = net::perform(net::request_builder()
.url("https://httpbin.org/delay/2") .url("https://httpbin.org/delay/2")
.response_timeout(net::sec_t(0))); .response_timeout(net::time_sec_t(0)));
REQUIRE(req.wait() == net::request::statuses::timeout); REQUIRE(req.wait() == net::request::statuses::timeout);
REQUIRE_THROWS_AS(req.get(), net::exception); REQUIRE_THROWS_AS(req.get(), net::exception);
} }
@@ -205,9 +205,9 @@ TEST_CASE("curly"){
.header("Custom-Header-1", "custom_header_value_1") .header("Custom-Header-1", "custom_header_value_1")
.header("Custom-Header-2", "custom header value 2")); .header("Custom-Header-2", "custom header value 2"));
const auto resp = req.get(); const auto resp = req.get();
const auto body_j = json::parse(resp.body_as_string()); const auto content_j = json::parse(resp.content().as_string_view());
REQUIRE(body_j["headers"]["Custom-Header-1"] == "custom_header_value_1"); REQUIRE(content_j["headers"]["Custom-Header-1"] == "custom_header_value_1");
REQUIRE(body_j["headers"]["Custom-Header-2"] == "custom header value 2"); REQUIRE(content_j["headers"]["Custom-Header-2"] == "custom header value 2");
} }
SECTION("response_inspection") { SECTION("response_inspection") {
@@ -215,18 +215,18 @@ TEST_CASE("curly"){
auto req = net::perform(net::request_builder() auto req = net::perform(net::request_builder()
.url("https://httpbin.org/response-headers?hello=world&world=hello")); .url("https://httpbin.org/response-headers?hello=world&world=hello"));
const auto resp = req.get(); const auto resp = req.get();
const auto body_j = json::parse(resp.body_as_string()); const auto content_j = json::parse(resp.content().as_string_view());
REQUIRE(body_j["hello"] == "world"); REQUIRE(content_j["hello"] == "world");
REQUIRE(body_j["world"] == "hello"); REQUIRE(content_j["world"] == "hello");
} }
{ {
auto req = net::perform(net::request_builder() auto req = net::perform(net::request_builder()
.url("https://httpbin.org/response-headers?hello=world&world=hello") .url("https://httpbin.org/response-headers?hello=world&world=hello")
.method(net::methods::post)); .method(net::methods::post));
const auto resp = req.get(); const auto resp = req.get();
const auto body_j = json::parse(resp.body_as_string()); const auto content_j = json::parse(resp.content().as_string_view());
REQUIRE(body_j["hello"] == "world"); REQUIRE(content_j["hello"] == "world");
REQUIRE(body_j["world"] == "hello"); REQUIRE(content_j["world"] == "hello");
} }
} }
@@ -235,20 +235,20 @@ TEST_CASE("curly"){
auto req = net::perform(net::request_builder() auto req = net::perform(net::request_builder()
.url("https://httpbin.org/base64/SFRUUEJJTiBpcyBhd2Vzb21l")); .url("https://httpbin.org/base64/SFRUUEJJTiBpcyBhd2Vzb21l"));
const auto resp = req.get(); const auto resp = req.get();
REQUIRE(resp.body_as_string() == "HTTPBIN is awesome"); REQUIRE(resp.content().as_string_view() == "HTTPBIN is awesome");
REQUIRE(req.error().empty()); REQUIRE(req.error().empty());
} }
{ {
auto req = net::perform(net::request_builder() auto req = net::perform(net::request_builder()
.url("https://httpbin.org/delay/10") .url("https://httpbin.org/delay/10")
.response_timeout(net::sec_t(0))); .response_timeout(net::time_sec_t(0)));
REQUIRE(req.wait() == net::request::statuses::timeout); REQUIRE(req.wait() == net::request::statuses::timeout);
REQUIRE_FALSE(req.error().empty()); REQUIRE_FALSE(req.error().empty());
} }
{ {
auto req = net::perform(net::request_builder() auto req = net::perform(net::request_builder()
.url("https://httpbin.org/delay/10") .url("https://httpbin.org/delay/10")
.response_timeout(net::sec_t(1))); .response_timeout(net::time_sec_t(1)));
REQUIRE(req.wait() == net::request::statuses::timeout); REQUIRE(req.wait() == net::request::statuses::timeout);
REQUIRE_FALSE(req.error().empty()); REQUIRE_FALSE(req.error().empty());
} }
@@ -263,9 +263,9 @@ TEST_CASE("curly"){
REQUIRE(resp.code() == 200u); REQUIRE(resp.code() == 200u);
REQUIRE(resp.headers().count("Content-Type")); REQUIRE(resp.headers().count("Content-Type"));
REQUIRE(resp.headers().at("Content-Type") == "image/png"); REQUIRE(resp.headers().at("Content-Type") == "image/png");
REQUIRE(untests::png_data_length == resp.body().size()); REQUIRE(untests::png_data_length == resp.content().size());
REQUIRE(!std::memcmp( REQUIRE(!std::memcmp(
resp.body().data(), resp.content().data().data(),
untests::png_data, untests::png_data,
untests::png_data_length)); untests::png_data_length));
} }
@@ -277,9 +277,9 @@ TEST_CASE("curly"){
REQUIRE(resp.code() == 200u); REQUIRE(resp.code() == 200u);
REQUIRE(resp.headers().count("Content-Type")); REQUIRE(resp.headers().count("Content-Type"));
REQUIRE(resp.headers().at("Content-Type") == "image/jpeg"); REQUIRE(resp.headers().at("Content-Type") == "image/jpeg");
REQUIRE(untests::jpeg_data_length == resp.body().size()); REQUIRE(untests::jpeg_data_length == resp.content().size());
REQUIRE(!std::memcmp( REQUIRE(!std::memcmp(
resp.body().data(), resp.content().data().data(),
untests::jpeg_data, untests::jpeg_data,
untests::jpeg_data_length)); untests::jpeg_data_length));
} }
@@ -312,31 +312,31 @@ TEST_CASE("curly"){
.url("https://httpbin.org/anything") .url("https://httpbin.org/anything")
.method(net::methods::put) .method(net::methods::put)
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.body(R"({"hello":"world"})")); .content(R"({"hello":"world"})"));
const auto resp = req.get(); const auto resp = req.get();
const auto body_j = json::parse(resp.body_as_string()); const auto content_j = json::parse(resp.content().as_string_view());
REQUIRE(body_j["data"] == R"({"hello":"world"})"); REQUIRE(content_j["data"] == R"({"hello":"world"})");
} }
{ {
auto req = net::perform(net::request_builder() auto req = net::perform(net::request_builder()
.url("https://httpbin.org/anything") .url("https://httpbin.org/anything")
.method(net::methods::post) .method(net::methods::post)
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.body(R"({"hello":"world"})")); .content(R"({"hello":"world"})"));
const auto resp = req.get(); const auto resp = req.get();
const auto body_j = json::parse(resp.body_as_string()); const auto content_j = json::parse(resp.content().as_string_view());
REQUIRE(body_j["data"] == R"({"hello":"world"})"); REQUIRE(content_j["data"] == R"({"hello":"world"})");
} }
{ {
auto req = net::perform(net::request_builder() auto req = net::perform(net::request_builder()
.url("https://httpbin.org/anything") .url("https://httpbin.org/anything")
.method(net::methods::post) .method(net::methods::post)
.header("Content-Type", "application/x-www-form-urlencoded") .header("Content-Type", "application/x-www-form-urlencoded")
.body("hello=world&world=hello")); .content("hello=world&world=hello"));
const auto resp = req.get(); const auto resp = req.get();
const auto body_j = json::parse(resp.body_as_string()); const auto content_j = json::parse(resp.content().as_string_view());
REQUIRE(body_j["form"]["hello"] == "world"); REQUIRE(content_j["form"]["hello"] == "world");
REQUIRE(body_j["form"]["world"] == "hello"); REQUIRE(content_j["form"]["world"] == "hello");
} }
} }
} }