Skip to content

Commit 7bb995e

Browse files
committed
- Fixed missing read of chunked trailer. Closes jgaa#101
- Added compile-time option to set log-level or disable logging. Closes jgaa#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.
1 parent 081b4bc commit 7bb995e

34 files changed

+229
-15
lines changed

CMakeLists.txt

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ option(RESTC_CPP_WITH_TLS "Enable TLS (Trough OpenSSL)" ON)
4242

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

45+
option(RESTC_CPP_LOG_WITH_CLOG "Use std::clog for logging" OFF)
46+
47+
set(RESTC_CPP_LOG_LEVEL_STR "info" CACHE STRING "Limit logs to: none, error, warn, info, debug, trace")
48+
4549
option(RESTC_CPP_LOG_JSON_SERIALIZATION "Enable trace logging for json serialization debugging")
4650

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

61+
if (RESTC_CPP_LOG_LEVEL_STR STREQUAL "none")
62+
set (RESTC_CPP_LOG_LEVEL 0)
63+
elseif(RESTC_CPP_LOG_LEVEL_STR STREQUAL "error")
64+
set (RESTC_CPP_LOG_LEVEL 1)
65+
elseif(RESTC_CPP_LOG_LEVEL_STR STREQUAL "warn")
66+
set (RESTC_CPP_LOG_LEVEL 2)
67+
elseif(RESTC_CPP_LOG_LEVEL_STR STREQUAL "info")
68+
set (RESTC_CPP_LOG_LEVEL 3)
69+
elseif(RESTC_CPP_LOG_LEVEL_STR STREQUAL "debug")
70+
set (RESTC_CPP_LOG_LEVEL 4)
71+
elseif(RESTC_CPP_LOG_LEVEL_STR STREQUAL "trace")
72+
set (RESTC_CPP_LOG_LEVEL 5)
73+
else()
74+
message(FATAL_ERROR "Unsupported log level ${RESTC_CPP_LOG_LEVEL_STR}")
75+
endif()
76+
77+
5778
message(STATUS "Using ${CMAKE_CXX_COMPILER}")
5879

5980
macro(SET_CPP_STANDARD target)
@@ -139,11 +160,19 @@ if (NOT EMBEDDED_RESTC_CPP)
139160
target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_THREAD_LIBS_INIT})
140161
endif()
141162

163+
if (RESTC_CPP_LOG_WITH_BOOST_LOG AND RESTC_CPP_LOG_WITH_CLOG)
164+
message( FATAL_ERROR "You cannot use Boost.Log and std::clog together. Cgoose one (or none)")
165+
endif()
166+
142167
if (RESTC_CPP_LOG_WITH_BOOST_LOG)
143168
set(BOOST_LOG_DEP log)
144-
message(STATUS "Using boost log")
169+
message(STATUS "Using Boost.Log for logging (brace for horrors!)")
145170
endif()
146171

172+
if (RESTC_CPP_LOG_WITH_CLOG)
173+
message(STATUS "Using std::clog for logging")
174+
endif()
175+
147176
#set(Boost_USE_MULTITHREADED ON)
148177
find_package(Boost REQUIRED COMPONENTS
149178
system

config.h.template

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
#cmakedefine RESTC_CPP_WITH_UNIT_TESTS 1
1414
#cmakedefine RESTC_CPP_WITH_TLS 1
1515
#cmakedefine RESTC_CPP_LOG_WITH_BOOST_LOG 1
16+
#cmakedefine RESTC_CPP_LOG_WITH_CLOG 1
1617
#cmakedefine RESTC_CPP_WITH_ZLIB 1
1718
#cmakedefine RESTC_CPP_HAVE_BOOST_TYPEINDEX 1
1819
#cmakedefine RESTC_CPP_LOG_JSON_SERIALIZATION 1
1920
#cmakedefine RESTC_CPP_USE_CPP17 1
2021
#cmakedefine RESTC_CPP_THREADED_CTX 1
2122

23+
#define RESTC_CPP_LOG_LEVEL ${RESTC_CPP_LOG_LEVEL}
2224
#define RESTC_CPP_MAX_INPUT_BUFFER_LENGTH ${RESTC_CPP_MAX_INPUT_BUFFER_LENGTH}
2325

2426
#endif // RESTC_CPP_CONFIG_H

examples/logip/logip.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
#include <ctime>
1414
#include "restc-cpp/logging.h"
1515

16+
#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
1617
#include <boost/log/core.hpp>
1718
#include <boost/log/trivial.hpp>
1819
#include <boost/log/expressions.hpp>
20+
#endif
1921

2022
#include "restc-cpp/restc-cpp.h"
2123
#include "restc-cpp/RequestBuilder.h"
@@ -42,12 +44,13 @@ string now() {
4244
}
4345

4446
int main(int argc, char *argv[]) {
45-
47+
#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
4648
namespace logging = boost::log;
4749
logging::core::get()->set_filter
4850
(
4951
logging::trivial::severity >= logging::trivial::info
5052
);
53+
#endif
5154

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

include/restc-cpp/DataReader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class DataReader {
4545

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

4950
static ptr_t CreateIoReader(const Connection::ptr_t& conn,
5051
Context& ctx, const ReadConfig& cfg);

include/restc-cpp/DataReaderStream.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,14 @@ class DataReaderStream : public DataReader {
2424

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

27-
bool IsEof() const override {
28-
return eof_;
29-
}
27+
bool IsEof() const override {
28+
return eof_;
29+
}
30+
31+
void Finish() override {
32+
if (source_)
33+
source_->Finish();
34+
}
3035

3136
/*! Read whatever we have buffered or can get downstream */
3237
boost::asio::const_buffers_1 ReadSome() override;

include/restc-cpp/logging.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*
1010
*/
1111

12+
1213
#include "restc-cpp/config.h"
1314

1415
#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
@@ -25,6 +26,16 @@
2526
#define RESTC_CPP_LOG_DEBUG_(msg) BOOST_LOG_TRIVIAL(debug) << msg
2627
#define RESTC_CPP_LOG_TRACE_(msg) BOOST_LOG_TRIVIAL(trace) << msg
2728

29+
#elif defined RESTC_CPP_LOG_WITH_CLOG
30+
31+
#include <iostream>
32+
33+
#define RESTC_CPP_LOG_ERROR_(msg) std::clog << "ERROR " << msg << std::endl
34+
#define RESTC_CPP_LOG_WARN_(msg) std::clog << "WARN " << msg << std::endl
35+
#define RESTC_CPP_LOG_INFO_(msg) std::clog << "INFO " << msg << std::endl
36+
#define RESTC_CPP_LOG_DEBUG_(msg) std::clog << "DEBUG " << msg << std::endl
37+
#define RESTC_CPP_LOG_TRACE_(msg) std::clog << "TRACE " << msg << std::endl
38+
2839

2940
#else
3041
// The user of the API framework may provide log macros, or we disable logs
@@ -63,3 +74,34 @@
6374
# endif
6475

6576
#endif
77+
78+
// Limit the log-level to RESTC_CPP_LOG_LEVEL
79+
// No need to spam production logs.
80+
// By using macros, we also eliminate CPU cycles on irrelevant log statements
81+
82+
#if (RESTC_CPP_LOG_LEVEL < 5)
83+
# undef RESTC_CPP_LOG_TRACE_
84+
# define RESTC_CPP_LOG_TRACE_(msg)
85+
#endif
86+
87+
#if (RESTC_CPP_LOG_LEVEL < 4)
88+
# undef RESTC_CPP_LOG_DEBUG_
89+
# define RESTC_CPP_LOG_DEBUG_(msg)
90+
#endif
91+
92+
#if (RESTC_CPP_LOG_LEVEL < 3)
93+
# undef RESTC_CPP_LOG_INFO_
94+
# define RESTC_CPP_LOG_TRACE_(msg)
95+
#endif
96+
97+
#if (RESTC_CPP_LOG_LEVEL < 2)
98+
# undef RESTC_CPP_LOG_WARN_
99+
# define RESTC_CPP_LOG_WARN_(msg)
100+
#endif
101+
102+
#if (RESTC_CPP_LOG_LEVEL < 1)
103+
# undef RESTC_CPP_LOG_ERROR_
104+
# define RESTC_CPP_LOG_ERROR_(msg)
105+
#endif
106+
107+

include/restc-cpp/test_helper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace {
1111

1212
#define STARTCASE(name) { CASE(#name) { \
1313
RESTC_CPP_LOG_DEBUG_("================================"); \
14-
RESTC_CPP_LOG_INFO_("Test case: " << #name;) \
14+
RESTC_CPP_LOG_INFO_("Test case: " << #name); \
1515
RESTC_CPP_LOG_DEBUG_("================================");
1616

1717
#define ENDCASE \

src/ChunkedReaderImpl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ class ChunkedReaderImpl : public DataReader {
2525
return stream_->IsEof();
2626
}
2727

28+
void Finish() override {
29+
ReadSome();
30+
if (!IsEof()) {
31+
throw ProtocolException("Failed to finish chunked payload");
32+
}
33+
34+
if (stream_) {
35+
stream_->Finish();
36+
}
37+
}
38+
2839
string ToPrintable(boost::string_ref buf) const {
2940
ostringstream out;
3041
locale loc;

src/DataReaderStream.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ DataReaderStream::DataReaderStream(std::unique_ptr<DataReader>&& source)
1515
<< RESTC_CPP_TYPENAME(decltype(*source_)));
1616
}
1717

18+
1819
void DataReaderStream::Fetch() {
1920
if (++curr_ >= end_) {
2021
auto buf = source_->ReadSome();
@@ -24,8 +25,8 @@ void DataReaderStream::Fetch() {
2425

2526
const auto bytes = boost::asio::buffer_size(buf);
2627
if (bytes == 0) {
27-
RESTC_CPP_LOG_TRACE_("DataReaderStream::Fetch: EOF";
28-
throw ProtocolException("Fetch(): EOF"));
28+
RESTC_CPP_LOG_TRACE_("DataReaderStream::Fetch: EOF");
29+
throw ProtocolException("Fetch(): EOF");
2930
}
3031
curr_ = boost::asio::buffer_cast<const char *>(buf);
3132
end_ = curr_ + boost::asio::buffer_size(buf);

src/IoReaderImpl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ class IoReaderImpl : public DataReader {
2020
{
2121
}
2222

23+
void Finish() override {
24+
}
25+
26+
2327
boost::asio::const_buffers_1 ReadSome() override {
2428
if (auto conn = connection_.lock()) {
2529
auto timer = IoTimer::Create("IoReaderImpl",

src/NoBodyReaderImpl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ class NoBodyReaderImpl : public DataReader {
1414
return true;
1515
}
1616

17+
void Finish() override {
18+
}
19+
1720
boost::asio::const_buffers_1 ReadSome() override {
1821
return {nullptr, 0};
1922
}

src/PlainReaderImpl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ class PlainReaderImpl : public DataReader {
1919
return remaining_ == 0;
2020
}
2121

22+
void Finish() override {
23+
if (source_)
24+
source_->Finish();
25+
}
26+
2227
boost::asio::const_buffers_1 ReadSome() override {
2328

2429
if (IsEof()) {

src/ReplyImpl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ string ReplyImpl::GetBodyAsString(const size_t maxSize) {
207207

208208
void ReplyImpl::CheckIfWeAreDone() {
209209
if (reader_ && reader_->IsEof()) {
210+
reader_->Finish();
210211
ReleaseConnection();
211212
}
212213
}

src/ZipReaderImpl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "restc-cpp/restc-cpp.h"
44
#include "restc-cpp/DataReader.h"
5+
#include "restc-cpp/logging.h"
56

67
using namespace std;
78

@@ -37,6 +38,11 @@ class ZipReaderImpl : public DataReader {
3738
return done_;
3839
}
3940

41+
void Finish() override {
42+
if (source_)
43+
source_->Finish();
44+
}
45+
4046
bool HaveMoreBufferedInput() const noexcept {
4147
return strm_.avail_in > 0;
4248
}
@@ -79,6 +85,8 @@ class ZipReaderImpl : public DataReader {
7985
void Decompress(boost::string_ref& src,
8086
boost::string_ref& dst) {
8187

88+
RESTC_CPP_LOG_TRACE_("ZipReaderImpl::Decompress: " << src.size() << " bytes");
89+
8290
if (!HaveMoreBufferedInput()) {
8391
strm_.next_in = const_cast<Bytef *>(
8492
reinterpret_cast<const Bytef *>(src.data()));
@@ -111,6 +119,7 @@ class ZipReaderImpl : public DataReader {
111119
throw DecompressException(errmsg);
112120
}
113121
case Z_STREAM_END:
122+
RESTC_CPP_LOG_TRACE_("ZipReaderImpl::Decompress(): End Zstream. Done.");
114123
done_ = true;
115124
break;
116125
default: {
@@ -126,6 +135,7 @@ class ZipReaderImpl : public DataReader {
126135
}
127136

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

131141
unique_ptr<DataReader> source_;

tests/functional/AuthTest.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
// Include before boost::log headers
55
#include "restc-cpp/logging.h"
66

7+
#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
78
#include <boost/log/core.hpp>
89
#include <boost/log/trivial.hpp>
910
#include <boost/log/expressions.hpp>
11+
#endif
12+
1013
#include <boost/lexical_cast.hpp>
1114
#include <boost/fusion/adapted.hpp>
1215

@@ -53,10 +56,13 @@ TEST(TestSuccessfulAuth)
5356

5457
int main( int argc, char * argv[] )
5558
{
59+
#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
5660
namespace logging = boost::log;
5761
logging::core::get()->set_filter
5862
(
5963
logging::trivial::severity >= logging::trivial::trace
6064
);
65+
#endif
66+
6167
return lest::run( specification, argc, argv );
6268
}

tests/functional/BasicTests.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
// Include before boost::log headers
55
#include "restc-cpp/logging.h"
66

7+
#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
78
#include <boost/log/core.hpp>
89
#include <boost/log/trivial.hpp>
910
#include <boost/log/expressions.hpp>
11+
#endif
12+
1013
#include <boost/lexical_cast.hpp>
1114
#include <boost/fusion/adapted.hpp>
1215

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

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

127+
#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
124128
namespace logging = boost::log;
125129
logging::core::get()->set_filter
126130
(
127131
logging::trivial::severity >= logging::trivial::trace
128132
);
133+
#endif
129134

130135
try {
131136
auto rest_client = RestClient::Create();

tests/functional/CRUD_test.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
#include "restc-cpp/logging.h"
66
#include "restc-cpp/RequestBuilder.h"
77

8+
#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
89
#include <boost/log/core.hpp>
910
#include <boost/log/trivial.hpp>
1011
#include <boost/log/expressions.hpp>
12+
#endif
1113

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

129131
int main( int argc, char * argv[] )
130132
{
133+
#ifdef RESTC_CPP_LOG_WITH_BOOST_LOG
131134
namespace logging = boost::log;
132135
logging::core::get()->set_filter
133136
(
134137
logging::trivial::severity >= logging::trivial::trace
135138
);
139+
#endif
136140
return lest::run( specification, argc, argv );
137141
}

0 commit comments

Comments
 (0)