Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use CPR (Curl for People) library for HTTP clients #37

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
timeout-minutes: 10
- name: Install dependencies
run: |
sudo apt-get update && sudo apt-get install pbuilder debhelper -y
sudo apt-get update && sudo apt-get install git pbuilder debhelper -y
- name: Setup pdebuilderrc for cross-compiling
env:
PBUILDER_RC: |
Expand Down
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
your system's [jsmn](https://github.com/zserge/jsmn) lib, instead of
downloading it automatically.

### Changed
### Changes

#### voucher
#### Build

**The voucher ABI has breaking changes**.
* C++17 is now required to build the `brski` CLI tool.

## [0.2.0] - 2023-03-27
### Added
Expand Down
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ add_compile_options(
$<$<COMPILE_LANGUAGE:C>:-Wextra>
)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# use -std=c++11 rather than -std=gnu++11
# use -std=c++17 rather than -std=gnu++17
set(CMAKE_CXX_EXTENSIONS OFF)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)
Expand All @@ -166,6 +166,7 @@ set(CMAKE_LIBRARY_PATH "${CMAKE_LIBRARY_PATH};${CMAKE_CURRENT_BINARY_DIR}/lib")

# Include the libraries
include(cmocka)
include(cpr) # need to call `FetchContent_MakeAvailable(cpr)` later
include(openssl3)
include(httplib)
include(minIni)
Expand Down
4 changes: 2 additions & 2 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Maintainer: Alexandru Mereacre <[email protected]>
Build-Depends: debhelper-compat (= 12),
ca-certificates, cmake (>=3.15.0),
libssl-dev (>=3.0.0),
libminini-dev (>=1.2),
libjsmn-dev (>=1.1.0)
libminini-dev (>=1.2), zlib1g-dev,
libjsmn-dev (>=1.1.0), git (>=2.30.0)
Standards-Version: 4.5.0
Homepage: https://github.com/nqminds/brski
Vcs-Browser: https://github.com/nqminds/brski
Expand Down
11 changes: 11 additions & 0 deletions lib/cpr.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
if (BUILD_ONLY_DOCS)
else()
include(FetchContent)
SET(CURL_ZLIB OFF CACHE STRING "" FORCE)
FetchContent_Declare(cpr
URL https://github.com/libcpr/cpr/archive/refs/tags/1.9.5.tar.gz
URL_HASH SHA3_256=bea98952db1fe1f45f8d7cf88af98ac67178072722fef33c677f6956690fb489
DOWNLOAD_NAME "cpr-1.9.5.tar.gz"
DOWNLOAD_DIR "${EP_DOWNLOAD_DIR}" # if empty string, uses default dir
)
endif()
17 changes: 14 additions & 3 deletions src/brski/http/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
set(CMAKE_C_EXTENSIONS ON) # needed to compile cpr
set(BRSKI_BUILD_TESTING "${BUILD_TESTING}")

FetchContent_GetProperties(cpr)
if(NOT cpr_POPULATED)
FetchContent_Populate(cpr)
# zlib-ng causes issues with `make install`, at least until v2.1.2
add_subdirectory(${cpr_SOURCE_DIR} ${cpr_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
# cpr overwrites the BUILD_TESTING var, so we need to reset it
set(BUILD_TESTING "${BRSKI_BUILD_TESTING}" CACHE BOOL "Build the testing tree." FORCE)

add_library(https_server https_server.cpp)
add_library(https_client https_client.cpp)
target_link_libraries(https_client PRIVATE os log cpr::cpr)

if (USE_CPPHTTPLIB_LIB)
add_library(httplib_wrapper httplib_wrapper.cpp)
target_link_libraries(httplib_wrapper PRIVATE os log httplib::httplib OpenSSL3::Crypto)

target_compile_definitions(https_server PUBLIC WITH_CPPHTTPLIB_LIB)
target_link_libraries(https_server PRIVATE os log httplib_wrapper)

target_compile_definitions(https_client PUBLIC WITH_CPPHTTPLIB_LIB)
target_link_libraries(https_client PRIVATE os log httplib_wrapper)
endif()
24 changes: 0 additions & 24 deletions src/brski/http/httplib_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,27 +231,3 @@ int httplib_start(struct http_config *config,

return 0;
}

int httplib_post_request(const std::string &client_key_path,
const std::string &client_cert_path,
const std::string &host, int port,
const std::string &path, bool verify,
const std::string &body,
const std::string &content_type,
std::string &response) {

httplib::SSLClient cli(host, port, client_cert_path, client_key_path);

cli.enable_server_certificate_verification(verify);

log_info("Post request to %s:%d%s", host.c_str(), port, path.c_str());
if (httplib::Result res = cli.Post(path, body, content_type)) {
response = res->body;
return res->status;
} else {
std::string err = to_string(res.error());
log_error("httplib::Client fail with \"%s\"", err.c_str());

return -1;
}
}
21 changes: 0 additions & 21 deletions src/brski/http/httplib_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,4 @@ int httplib_start(struct http_config *config,
*/
void httplib_stop(void *srv_ctx);

/**
* @brief Sends a POST request to an endpoint
*
* @param[in] client_key_path The https client key path
* @param[in] client_cert_path The https client cert path
* @param[in] host The https server host name
* @param[in] port The https server port name
* @param[in] path The endpoint route path string
* @param[in] verify Enable server certificate verification
* @param[in] body The request body string
* @param[in] content_type The content typ string
* @param[out] response The output response string
* @return int the status code on success, -1 on failure
*/
int httplib_post_request(const std::string &client_key_path,
const std::string &client_cert_path,
const std::string &host, int port,
const std::string &path, bool verify,
const std::string &body,
const std::string &content_type,
std::string &response);
#endif
39 changes: 28 additions & 11 deletions src/brski/http/https_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,47 @@
* @brief File containing the implementation of the https client functions.
*/

#include <cpr/cpr.h>
#include <string>

#include "./https_client.hpp"

extern "C" {
#include "../../utils/log.h"
#include "../../utils/os.h"
}

#ifdef WITH_CPPHTTPLIB_LIB
#include "httplib_wrapper.hpp"
#endif

int https_post_request(const std::string &client_key_path,
const std::string &client_cert_path,
const std::string &host, int port,
const std::string &path, bool verify,
const std::string &body, const std::string &content_type,
std::string &response) {
#ifdef WITH_CPPHTTPLIB_LIB
return httplib_post_request(client_key_path, client_cert_path, host, port,
path, verify, body, content_type, response);
#else
log_error("No https client defined");
return -1;
#endif
auto key = cpr::ssl::PemKey(std::string{client_key_path});
auto cert = cpr::ssl::PemCert(std::string{client_cert_path});

cpr::SslOptions sslOpts = cpr::Ssl(cert, key, cpr::ssl::VerifyHost{verify},
cpr::ssl::VerifyPeer{verify});
auto url = cpr::Url{get_https_address(host.c_str(), port) + path};
log_info("Post request to %s", url.c_str());
cpr::Response res = cpr::Post(
cpr::Url{get_https_address(host.c_str(), port) + path}, sslOpts,
cpr::Body{body}, cpr::Header{{"Content-Type", content_type}},
cpr::DebugCallback([&](cpr::DebugCallback::InfoType type,
std::string data, intptr_t userdata) -> void {
if (type == cpr::DebugCallback::InfoType::TEXT) {
log_trace("%s", data.c_str());
}
}));

if (res.status_code == 0) {
log_error("Post request to %s returned error %s", url.c_str(),
res.error.message.c_str());
return -1;
}

response = res.text;
return res.status_code;
}

std::string get_https_address(const char *bind_address, int port) {
Expand Down
Loading