Skip to content

Commit

Permalink
Using std::variant for cpr::Session content
Browse files Browse the repository at this point in the history
  • Loading branch information
COM8 committed Oct 27, 2023
1 parent d9a1baf commit c177aa3
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 59 deletions.
73 changes: 20 additions & 53 deletions cpr/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
#include <string>

#include <curl/curl.h>
#include <variant>

#include "cpr/async.h"
#include "cpr/cprtypes.h"
#include "cpr/interceptor.h"
#include "cpr/multipart.h"
#include "cpr/util.h"

#if SUPPORT_CURLOPT_SSL_CTX_FUNCTION
Expand Down Expand Up @@ -353,19 +355,11 @@ void Session::SetUserAgent(const UserAgent& ua) {
}

void Session::SetPayload(const Payload& payload) {
payload_ = payload;

// Either a body, multipart or a payload is allowed.
body_ = std::nullopt;
multipart_ = std::nullopt;
content_ = payload;
}

void Session::SetPayload(Payload&& payload) {
payload_ = std::move(payload);

// Either a body, multipart or a payload is allowed.
body_ = std::nullopt;
multipart_ = std::nullopt;
content_ = std::move(payload);
}

void Session::SetProxies(const Proxies& proxies) {
Expand All @@ -385,19 +379,11 @@ void Session::SetProxyAuth(const ProxyAuthentication& proxy_auth) {
}

void Session::SetMultipart(const Multipart& multipart) {
multipart_ = multipart;

// Either a body, multipart or a payload is allowed.
body_ = std::nullopt;
payload_ = std::nullopt;
content_ = multipart;
}

void Session::SetMultipart(Multipart&& multipart) {
multipart_ = std::move(multipart);

// Either a body, multipart or a payload is allowed.
body_ = std::nullopt;
payload_ = std::nullopt;
content_ = std::move(multipart);
}

void Session::SetRedirect(const Redirect& redirect) {
Expand Down Expand Up @@ -425,19 +411,11 @@ void Session::SetCookies(const Cookies& cookies) {
}

void Session::SetBody(const Body& body) {
body_ = body;

// Either a body, multipart or a payload is allowed.
payload_ = std::nullopt;
multipart_ = std::nullopt;
content_ = body;
}

void Session::SetBody(Body&& body) {
body_ = std::move(body);

// Either a body, multipart or a payload is allowed.
payload_ = std::nullopt;
multipart_ = std::nullopt;
content_ = std::move(body);
}

void Session::SetLowSpeed(const LowSpeed& low_speed) {
Expand Down Expand Up @@ -888,35 +866,24 @@ Response Session::intercept() {
void Session::prepareBodyPayloadOrMultipart() const {
// Either a body, multipart or a payload is allowed.

if (payload_) {
assert(!body_);
assert(!multipart_);

const std::string content = payload_->GetContent(*curl_);
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(content.length()));
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, content.c_str());
}

if (body_) {
assert(!payload_);
assert(!multipart_);

curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(body_->str().length()));
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, body_->c_str());
}

if (multipart_) {
assert(!payload_);
assert(!body_);

if (std::holds_alternative<cpr::Payload>(content_)) {
const std::string payload = std::get<cpr::Payload>(content_).GetContent(*curl_);
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(payload.length()));
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, payload.c_str());
} else if (std::holds_alternative<cpr::Body>(content_)) {
const std::string& body = std::get<cpr::Body>(content_).str();
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(body.length()));
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, body.c_str());
} else if (std::holds_alternative<cpr::Multipart>(content_)) {
// Make sure, we have a empty multipart to start with:
if (curl_->multipart) {
curl_mime_free(curl_->multipart);
}
curl_->multipart = curl_mime_init(curl_->handle);

// Add all multipart pieces:
for (const Part& part : multipart_->parts) {
const cpr::Multipart& multipart = std::get<cpr::Multipart>(content_);
for (const Part& part : multipart.parts) {
if (part.is_file) {
for (const File& file : part.files) {
curl_mimepart* mimePart = curl_mime_addpart(curl_->multipart);
Expand Down Expand Up @@ -953,7 +920,7 @@ void Session::prepareBodyPayloadOrMultipart() const {
}

[[nodiscard]] bool Session::hasBodyOrPayload() const {
return payload_ || body_;
return std::holds_alternative<cpr::Body>(content_) || std::holds_alternative<cpr::Payload>(content_);
}

// clang-format off
Expand Down
6 changes: 3 additions & 3 deletions include/cpr/cprtypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ class StringHolder {
const std::string& str() {
return str_;
}
const std::string& str() const {
[[nodiscard]] const std::string& str() const {
return str_;
}
const char* c_str() const {
[[nodiscard]] const char* c_str() const {
return str_.c_str();
}
const char* data() const {
[[nodiscard]] const char* data() const {
return str_.data();
}

Expand Down
8 changes: 5 additions & 3 deletions include/cpr/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <memory>
#include <optional>
#include <queue>
#include <variant>

#include "cpr/accept_encoding.h"
#include "cpr/async_wrapper.h"
Expand Down Expand Up @@ -232,9 +233,7 @@ class Session : public std::enable_shared_from_this<Session> {


bool chunkedTransferEncoding_{false};
std::optional<cpr::Payload> payload_;
std::optional<cpr::Body> body_;
std::optional<cpr::Multipart> multipart_;
std::variant<std::monostate, cpr::Payload, cpr::Body, cpr::Multipart> content_{std::monostate{}};
std::shared_ptr<CurlHolder> curl_;
Url url_;
Parameters parameters_;
Expand Down Expand Up @@ -276,6 +275,9 @@ class Session : public std::enable_shared_from_this<Session> {
std::shared_ptr<Session> GetSharedPtrFromThis();
CURLcode DoEasyPerform();
void prepareBodyPayloadOrMultipart() const;
/**
* Returns true in case content_ is of type cpr::Body or cpr::Payload.
**/
[[nodiscard]] bool hasBodyOrPayload() const;
};

Expand Down

0 comments on commit c177aa3

Please sign in to comment.