Skip to content

Commit

Permalink
- Fixed missing read of chunked trailer. Closes #101
Browse files Browse the repository at this point in the history
- Added compile-time option to set log-level or disable logging. Closes #67
- Added compile-time option to log to std::clog
- Fixed tests and compiled examples to work without Boost.Log
- Fixed a number of minor bugs that became visible when I worked with the
  Windows build.
  • Loading branch information
jgaa committed Oct 31, 2020
1 parent 081b4bc commit 7bb995e
Show file tree
Hide file tree
Showing 34 changed files with 229 additions and 15 deletions.
31 changes: 30 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ option(RESTC_CPP_WITH_TLS "Enable TLS (Trough OpenSSL)" ON)

option(RESTC_CPP_LOG_WITH_BOOST_LOG "Use boost::log for logging" ON)

option(RESTC_CPP_LOG_WITH_CLOG "Use std::clog for logging" OFF)

set(RESTC_CPP_LOG_LEVEL_STR "info" CACHE STRING "Limit logs to: none, error, warn, info, debug, trace")

option(RESTC_CPP_LOG_JSON_SERIALIZATION "Enable trace logging for json serialization debugging")

option(RESTC_CPP_WITH_ZLIB "Use zlib" ON)
Expand All @@ -54,6 +58,23 @@ if (NOT DEFINED RESTC_CPP_MAX_INPUT_BUFFER_LENGTH)
set (RESTC_CPP_MAX_INPUT_BUFFER_LENGTH 0x7fffffff)
endif()

if (RESTC_CPP_LOG_LEVEL_STR STREQUAL "none")
set (RESTC_CPP_LOG_LEVEL 0)
elseif(RESTC_CPP_LOG_LEVEL_STR STREQUAL "error")
set (RESTC_CPP_LOG_LEVEL 1)
elseif(RESTC_CPP_LOG_LEVEL_STR STREQUAL "warn")
set (RESTC_CPP_LOG_LEVEL 2)
elseif(RESTC_CPP_LOG_LEVEL_STR STREQUAL "info")
set (RESTC_CPP_LOG_LEVEL 3)
elseif(RESTC_CPP_LOG_LEVEL_STR STREQUAL "debug")
set (RESTC_CPP_LOG_LEVEL 4)
elseif(RESTC_CPP_LOG_LEVEL_STR STREQUAL "trace")
set (RESTC_CPP_LOG_LEVEL 5)
else()
message(FATAL_ERROR "Unsupported log level ${RESTC_CPP_LOG_LEVEL_STR}")
endif()


message(STATUS "Using ${CMAKE_CXX_COMPILER}")

macro(SET_CPP_STANDARD target)
Expand Down Expand Up @@ -139,11 +160,19 @@ if (NOT EMBEDDED_RESTC_CPP)
target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_THREAD_LIBS_INIT})
endif()

if (RESTC_CPP_LOG_WITH_BOOST_LOG AND RESTC_CPP_LOG_WITH_CLOG)
message( FATAL_ERROR "You cannot use Boost.Log and std::clog together. Cgoose one (or none)")
endif()

if (RESTC_CPP_LOG_WITH_BOOST_LOG)
set(BOOST_LOG_DEP log)
message(STATUS "Using boost log")
message(STATUS "Using Boost.Log for logging (brace for horrors!)")
endif()

if (RESTC_CPP_LOG_WITH_CLOG)
message(STATUS "Using std::clog for logging")
endif()

#set(Boost_USE_MULTITHREADED ON)
find_package(Boost REQUIRED COMPONENTS
system
Expand Down
2 changes: 2 additions & 0 deletions config.h.template
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
#cmakedefine RESTC_CPP_WITH_UNIT_TESTS 1
#cmakedefine RESTC_CPP_WITH_TLS 1
#cmakedefine RESTC_CPP_LOG_WITH_BOOST_LOG 1
#cmakedefine RESTC_CPP_LOG_WITH_CLOG 1
#cmakedefine RESTC_CPP_WITH_ZLIB 1
#cmakedefine RESTC_CPP_HAVE_BOOST_TYPEINDEX 1
#cmakedefine RESTC_CPP_LOG_JSON_SERIALIZATION 1
#cmakedefine RESTC_CPP_USE_CPP17 1
#cmakedefine RESTC_CPP_THREADED_CTX 1

#define RESTC_CPP_LOG_LEVEL ${RESTC_CPP_LOG_LEVEL}
#define RESTC_CPP_MAX_INPUT_BUFFER_LENGTH ${RESTC_CPP_MAX_INPUT_BUFFER_LENGTH}

#endif // RESTC_CPP_CONFIG_H
5 changes: 4 additions & 1 deletion examples/logip/logip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
#include <ctime>
#include "restc-cpp/logging.h"

#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#endif

#include "restc-cpp/restc-cpp.h"
#include "restc-cpp/RequestBuilder.h"
Expand All @@ -42,12 +44,13 @@ string now() {
}

int main(int argc, char *argv[]) {

#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
namespace logging = boost::log;
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::info
);
#endif

const string url = "https://api.ipify.org";

Expand Down
1 change: 1 addition & 0 deletions include/restc-cpp/DataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class DataReader {

virtual bool IsEof() const = 0;
virtual boost::asio::const_buffers_1 ReadSome() = 0;
virtual void Finish() = 0; // Make sure there are no pending data for the current request

static ptr_t CreateIoReader(const Connection::ptr_t& conn,
Context& ctx, const ReadConfig& cfg);
Expand Down
11 changes: 8 additions & 3 deletions include/restc-cpp/DataReaderStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@ class DataReaderStream : public DataReader {

DataReaderStream(std::unique_ptr<DataReader>&& source);

bool IsEof() const override {
return eof_;
}
bool IsEof() const override {
return eof_;
}

void Finish() override {
if (source_)
source_->Finish();
}

/*! Read whatever we have buffered or can get downstream */
boost::asio::const_buffers_1 ReadSome() override;
Expand Down
42 changes: 42 additions & 0 deletions include/restc-cpp/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*
*/


#include "restc-cpp/config.h"

#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
Expand All @@ -25,6 +26,16 @@
#define RESTC_CPP_LOG_DEBUG_(msg) BOOST_LOG_TRIVIAL(debug) << msg
#define RESTC_CPP_LOG_TRACE_(msg) BOOST_LOG_TRIVIAL(trace) << msg

#elif defined RESTC_CPP_LOG_WITH_CLOG

#include <iostream>

#define RESTC_CPP_LOG_ERROR_(msg) std::clog << "ERROR " << msg << std::endl
#define RESTC_CPP_LOG_WARN_(msg) std::clog << "WARN " << msg << std::endl
#define RESTC_CPP_LOG_INFO_(msg) std::clog << "INFO " << msg << std::endl
#define RESTC_CPP_LOG_DEBUG_(msg) std::clog << "DEBUG " << msg << std::endl
#define RESTC_CPP_LOG_TRACE_(msg) std::clog << "TRACE " << msg << std::endl


#else
// The user of the API framework may provide log macros, or we disable logs
Expand Down Expand Up @@ -63,3 +74,34 @@
# endif

#endif

// Limit the log-level to RESTC_CPP_LOG_LEVEL
// No need to spam production logs.
// By using macros, we also eliminate CPU cycles on irrelevant log statements

#if (RESTC_CPP_LOG_LEVEL < 5)
# undef RESTC_CPP_LOG_TRACE_
# define RESTC_CPP_LOG_TRACE_(msg)
#endif

#if (RESTC_CPP_LOG_LEVEL < 4)
# undef RESTC_CPP_LOG_DEBUG_
# define RESTC_CPP_LOG_DEBUG_(msg)
#endif

#if (RESTC_CPP_LOG_LEVEL < 3)
# undef RESTC_CPP_LOG_INFO_
# define RESTC_CPP_LOG_TRACE_(msg)
#endif

#if (RESTC_CPP_LOG_LEVEL < 2)
# undef RESTC_CPP_LOG_WARN_
# define RESTC_CPP_LOG_WARN_(msg)
#endif

#if (RESTC_CPP_LOG_LEVEL < 1)
# undef RESTC_CPP_LOG_ERROR_
# define RESTC_CPP_LOG_ERROR_(msg)
#endif


2 changes: 1 addition & 1 deletion include/restc-cpp/test_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace {

#define STARTCASE(name) { CASE(#name) { \
RESTC_CPP_LOG_DEBUG_("================================"); \
RESTC_CPP_LOG_INFO_("Test case: " << #name;) \
RESTC_CPP_LOG_INFO_("Test case: " << #name); \
RESTC_CPP_LOG_DEBUG_("================================");

#define ENDCASE \
Expand Down
11 changes: 11 additions & 0 deletions src/ChunkedReaderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ class ChunkedReaderImpl : public DataReader {
return stream_->IsEof();
}

void Finish() override {
ReadSome();
if (!IsEof()) {
throw ProtocolException("Failed to finish chunked payload");
}

if (stream_) {
stream_->Finish();
}
}

string ToPrintable(boost::string_ref buf) const {
ostringstream out;
locale loc;
Expand Down
5 changes: 3 additions & 2 deletions src/DataReaderStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ DataReaderStream::DataReaderStream(std::unique_ptr<DataReader>&& source)
<< RESTC_CPP_TYPENAME(decltype(*source_)));
}


void DataReaderStream::Fetch() {
if (++curr_ >= end_) {
auto buf = source_->ReadSome();
Expand All @@ -24,8 +25,8 @@ void DataReaderStream::Fetch() {

const auto bytes = boost::asio::buffer_size(buf);
if (bytes == 0) {
RESTC_CPP_LOG_TRACE_("DataReaderStream::Fetch: EOF";
throw ProtocolException("Fetch(): EOF"));
RESTC_CPP_LOG_TRACE_("DataReaderStream::Fetch: EOF");
throw ProtocolException("Fetch(): EOF");
}
curr_ = boost::asio::buffer_cast<const char *>(buf);
end_ = curr_ + boost::asio::buffer_size(buf);
Expand Down
4 changes: 4 additions & 0 deletions src/IoReaderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ class IoReaderImpl : public DataReader {
{
}

void Finish() override {
}


boost::asio::const_buffers_1 ReadSome() override {
if (auto conn = connection_.lock()) {
auto timer = IoTimer::Create("IoReaderImpl",
Expand Down
3 changes: 3 additions & 0 deletions src/NoBodyReaderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class NoBodyReaderImpl : public DataReader {
return true;
}

void Finish() override {
}

boost::asio::const_buffers_1 ReadSome() override {
return {nullptr, 0};
}
Expand Down
5 changes: 5 additions & 0 deletions src/PlainReaderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ class PlainReaderImpl : public DataReader {
return remaining_ == 0;
}

void Finish() override {
if (source_)
source_->Finish();
}

boost::asio::const_buffers_1 ReadSome() override {

if (IsEof()) {
Expand Down
1 change: 1 addition & 0 deletions src/ReplyImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ string ReplyImpl::GetBodyAsString(const size_t maxSize) {

void ReplyImpl::CheckIfWeAreDone() {
if (reader_ && reader_->IsEof()) {
reader_->Finish();
ReleaseConnection();
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/ZipReaderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "restc-cpp/restc-cpp.h"
#include "restc-cpp/DataReader.h"
#include "restc-cpp/logging.h"

using namespace std;

Expand Down Expand Up @@ -37,6 +38,11 @@ class ZipReaderImpl : public DataReader {
return done_;
}

void Finish() override {
if (source_)
source_->Finish();
}

bool HaveMoreBufferedInput() const noexcept {
return strm_.avail_in > 0;
}
Expand Down Expand Up @@ -79,6 +85,8 @@ class ZipReaderImpl : public DataReader {
void Decompress(boost::string_ref& src,
boost::string_ref& dst) {

RESTC_CPP_LOG_TRACE_("ZipReaderImpl::Decompress: " << src.size() << " bytes");

if (!HaveMoreBufferedInput()) {
strm_.next_in = const_cast<Bytef *>(
reinterpret_cast<const Bytef *>(src.data()));
Expand Down Expand Up @@ -111,6 +119,7 @@ class ZipReaderImpl : public DataReader {
throw DecompressException(errmsg);
}
case Z_STREAM_END:
RESTC_CPP_LOG_TRACE_("ZipReaderImpl::Decompress(): End Zstream. Done.");
done_ = true;
break;
default: {
Expand All @@ -126,6 +135,7 @@ class ZipReaderImpl : public DataReader {
}

dst = {dst.data(), dst.size() - strm_.avail_out};
RESTC_CPP_LOG_TRACE_("ZipReaderImpl::Decompress: src=" << dec << src.size() << " bytes, dst=" << dst.size() << " bytes");
}

unique_ptr<DataReader> source_;
Expand Down
6 changes: 6 additions & 0 deletions tests/functional/AuthTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
// Include before boost::log headers
#include "restc-cpp/logging.h"

#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#endif

#include <boost/lexical_cast.hpp>
#include <boost/fusion/adapted.hpp>

Expand Down Expand Up @@ -53,10 +56,13 @@ TEST(TestSuccessfulAuth)

int main( int argc, char * argv[] )
{
#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
namespace logging = boost::log;
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::trace
);
#endif

return lest::run( specification, argc, argv );
}
5 changes: 5 additions & 0 deletions tests/functional/BasicTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
// Include before boost::log headers
#include "restc-cpp/logging.h"

#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#endif

#include <boost/lexical_cast.hpp>
#include <boost/fusion/adapted.hpp>

Expand Down Expand Up @@ -121,11 +124,13 @@ void DoSomethingInteresting(Context& ctx) {

int main(int argc, char *argv[]) {

#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
namespace logging = boost::log;
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::trace
);
#endif

try {
auto rest_client = RestClient::Create();
Expand Down
4 changes: 4 additions & 0 deletions tests/functional/CRUD_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
#include "restc-cpp/logging.h"
#include "restc-cpp/RequestBuilder.h"

#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#endif

#include "restc-cpp/test_helper.h"
#include "lest/lest.hpp"
Expand Down Expand Up @@ -128,10 +130,12 @@ STARTCASE(TestHEAD) {

int main( int argc, char * argv[] )
{
#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
namespace logging = boost::log;
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::trace
);
#endif
return lest::run( specification, argc, argv );
}
Loading

0 comments on commit 7bb995e

Please sign in to comment.