Skip to content

Commit

Permalink
Stronger types for HttpUrl underlying members
Browse files Browse the repository at this point in the history
  • Loading branch information
abedra committed Jul 4, 2021
1 parent 84261db commit e5c739d
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 26 deletions.
36 changes: 22 additions & 14 deletions simple_http.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ struct Tiny {

SIMPLE_HTTP_TINY_STRING(HttpResponseBody)
SIMPLE_HTTP_TINY_STRING(HttpRequestBody)
SIMPLE_HTTP_TINY_STRING(Protcol)
SIMPLE_HTTP_TINY_STRING(Host)
SIMPLE_HTTP_TINY_STRING(PathSegment)
SIMPLE_HTTP_TINY_STRING(QueryParameterKey)
SIMPLE_HTTP_TINY_STRING(QueryParameterValue)

SIMPLE_HTTP_TINY_LONG(HttpStatusCode)

Expand All @@ -69,6 +74,9 @@ ErrorCallback NoopErrorCallback = [](auto&){};

using Headers = std::unordered_map<std::string, std::string>;

using PathSegments = std::vector<PathSegment>;
using QueryParameters = std::vector<std::pair<QueryParameterKey, QueryParameterValue>>;

static const std::string WHITESPACE = "\n\t\f\v\r ";

static std::string leftTrim(const std::string &candidate) {
Expand Down Expand Up @@ -132,10 +140,10 @@ struct HttpResponse {
struct HttpUrl {
HttpUrl() = default;

HttpUrl(std::string protocol,
std::string host,
std::vector<std::string> path_segments = {},
std::vector<std::pair<std::string, std::string>> query_parameters = {})
HttpUrl(Protcol protocol,
Host host,
PathSegments path_segments = {},
QueryParameters query_parameters = {})
: protocol_(std::move(protocol))
, host_(std::move(host))
, path_segments_(std::move(path_segments))
Expand All @@ -149,7 +157,7 @@ struct HttpUrl {
{}

[[nodiscard]]
const std::string& protocol() {
const Protcol & protocol() {
return protocol_;
}

Expand All @@ -162,34 +170,34 @@ struct HttpUrl {
}

[[nodiscard]]
HttpUrl& with_protocol(std::string protocol) {
HttpUrl& with_protocol(Protcol protocol) {
protocol_ = std::move(protocol);
return *this;
}

[[nodiscard]]
HttpUrl& with_host(std::string host) {
HttpUrl& with_host(Host host) {
host_ = std::move(host);
return *this;
}

[[nodiscard]]
HttpUrl& with_path_segments(std::vector<std::string> path_segments) {
HttpUrl& with_path_segments(PathSegments path_segments) {
path_segments_ = std::move(path_segments);
return *this;
}

[[nodiscard]]
HttpUrl& with_query_parameters(std::vector<std::pair<std::string, std::string>> query_parameters) {
HttpUrl& with_query_parameters(QueryParameters query_parameters) {
query_parameters_ = std::move(query_parameters);
return *this;
}

private:
std::string protocol_;
std::string host_;
std::vector<std::string> path_segments_;
std::vector<std::pair<std::string, std::string>> query_parameters_;
Protcol protocol_;
Host host_;
PathSegments path_segments_;
QueryParameters query_parameters_;
std::string value_;

static std::string detect_protocol(const std::string &url_string) {
Expand Down Expand Up @@ -439,7 +447,7 @@ struct Client {
curl_easy_setopt(curl, CURLOPT_VERBOSE, debug_);
curl_setup_callback(curl);

if (url.protocol() == "https") {
if (url.protocol().value() == "https") {
verify_
? curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L)
: curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
Expand Down
24 changes: 12 additions & 12 deletions test/integration_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ TEST_CASE("Integration Tests")
{
SimpleHttp::Client client;
SimpleHttp::HttpUrl url = SimpleHttp::HttpUrl()
.with_protocol("http")
.with_host("localhost:5000");
.with_protocol(SimpleHttp::Protcol{"http"})
.with_host(SimpleHttp::Host{"localhost:5000"});

SECTION("GET Request")
{
auto maybe_response = client.get(url.with_path_segments({"get"}));
auto maybe_response = client.get(url.with_path_segments({SimpleHttp::PathSegment{"get"}}));

REQUIRE(maybe_response);

Expand All @@ -25,7 +25,7 @@ TEST_CASE("Integration Tests")

SECTION("Post request")
{
auto maybe_response = client.post(url.with_path_segments({"post"}),
auto maybe_response = client.post(url.with_path_segments({SimpleHttp::PathSegment{"post"}}),
SimpleHttp::HttpRequestBody{R"({"name":"test"})"},
{{"Content-Type", "application/json"}});

Expand All @@ -39,7 +39,7 @@ TEST_CASE("Integration Tests")

SECTION("Put request")
{
auto maybe_response = client.put(url.with_path_segments({"put"}),
auto maybe_response = client.put(url.with_path_segments({SimpleHttp::PathSegment{"put"}}),
SimpleHttp::HttpRequestBody{R"({"update":"test"})"},
{{"Content-Type", "application/json"}});

Expand All @@ -53,23 +53,23 @@ TEST_CASE("Integration Tests")

SECTION("Delete request")
{
auto maybe_response = client.del(url.with_path_segments({"delete"}));
auto maybe_response = client.del(url.with_path_segments({SimpleHttp::PathSegment{"delete"}}));

REQUIRE(maybe_response);
CHECK(maybe_response.value().status == SimpleHttp::OK);
}

SECTION("Head request")
{
auto maybe_response = client.head(url.with_path_segments({"get"}));
auto maybe_response = client.head(url.with_path_segments({SimpleHttp::PathSegment{"get"}}));

REQUIRE(maybe_response);
CHECK(maybe_response.value().status == SimpleHttp::OK);
}

SECTION("Options request")
{
auto maybe_response = client.options(url.with_path_segments({"get"}));
auto maybe_response = client.options(url.with_path_segments({SimpleHttp::PathSegment{"get"}}));

REQUIRE(maybe_response);

Expand All @@ -79,7 +79,7 @@ TEST_CASE("Integration Tests")

SECTION("Trace request")
{
auto maybe_response = client.trace(url.with_path_segments({"trace"}));
auto maybe_response = client.trace(url.with_path_segments({SimpleHttp::PathSegment{"trace"}}));

REQUIRE(maybe_response);
CHECK(maybe_response.value().headers.value().at("Content-Type") == "message/http");
Expand All @@ -89,15 +89,15 @@ TEST_CASE("Integration Tests")
{
std::string error;
client = client.with_error_callback([&error](auto &err) { error = "Error: " + err; });
auto maybe_response = client.get(url.with_protocol("zxcv"));
auto maybe_response = client.get(url.with_protocol(SimpleHttp::Protcol{"zxcv"}));

REQUIRE(!maybe_response);
CHECK(error == "Error: Unsupported protocol");
}

SECTION("Post request that expects a 204 NO_CONTENT response")
{
auto maybe_response = client.post(url.with_path_segments({"empty_post_response"}),
auto maybe_response = client.post(url.with_path_segments({SimpleHttp::PathSegment{"empty_post_response"}}),
SimpleHttp::HttpRequestBody{""},
SimpleHttp::eq(SimpleHttp::NO_CONTENT),
{{"Content-Type", "application/json"}});
Expand All @@ -112,7 +112,7 @@ TEST_CASE("Integration Tests")

SECTION("Get request that expects a 405 METHOD_NOT_ALLOWED response")
{
auto maybe_response = client.get(url.with_path_segments({"empty_post_response"}),
auto maybe_response = client.get(url.with_path_segments({SimpleHttp::PathSegment{"empty_post_response"}}),
SimpleHttp::eq(SimpleHttp::METHOD_NOT_ALLOWED));

REQUIRE(maybe_response);
Expand Down

0 comments on commit e5c739d

Please sign in to comment.