Moved Stream concrete classes into detail namespace
This commit is contained in:
parent
dfebfd9033
commit
a15d16a9de
139
httplib.h
139
httplib.h
@ -354,42 +354,6 @@ public:
|
|||||||
int write_format(const char *fmt, const Args &... args);
|
int write_format(const char *fmt, const Args &... args);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SocketStream : public Stream {
|
|
||||||
public:
|
|
||||||
SocketStream(socket_t sock, time_t read_timeout_sec,
|
|
||||||
time_t read_timeout_usec);
|
|
||||||
~SocketStream() override;
|
|
||||||
|
|
||||||
int read(char *ptr, size_t size) override;
|
|
||||||
int write(const char *ptr, size_t size) override;
|
|
||||||
int write(const char *ptr) override;
|
|
||||||
int write(const std::string &s) override;
|
|
||||||
std::string get_remote_addr() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
socket_t sock_;
|
|
||||||
time_t read_timeout_sec_;
|
|
||||||
time_t read_timeout_usec_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BufferStream : public Stream {
|
|
||||||
public:
|
|
||||||
BufferStream() = default;
|
|
||||||
~BufferStream() override = default;
|
|
||||||
|
|
||||||
int read(char *ptr, size_t size) override;
|
|
||||||
int write(const char *ptr, size_t size) override;
|
|
||||||
int write(const char *ptr) override;
|
|
||||||
int write(const std::string &s) override;
|
|
||||||
std::string get_remote_addr() const override;
|
|
||||||
|
|
||||||
const std::string &get_buffer() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string buffer;
|
|
||||||
int position = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TaskQueue {
|
class TaskQueue {
|
||||||
public:
|
public:
|
||||||
TaskQueue() = default;
|
TaskQueue() = default;
|
||||||
@ -856,26 +820,6 @@ inline void Post(std::vector<Request> &requests, const char *path,
|
|||||||
Post(requests, path, Headers(), body, content_type);
|
Post(requests, path, Headers(), body, content_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
||||||
class SSLSocketStream : public Stream {
|
|
||||||
public:
|
|
||||||
SSLSocketStream(socket_t sock, SSL *ssl, time_t read_timeout_sec,
|
|
||||||
time_t read_timeout_usec);
|
|
||||||
virtual ~SSLSocketStream();
|
|
||||||
|
|
||||||
virtual int read(char *ptr, size_t size);
|
|
||||||
virtual int write(const char *ptr, size_t size);
|
|
||||||
virtual int write(const char *ptr);
|
|
||||||
virtual int write(const std::string &s);
|
|
||||||
virtual std::string get_remote_addr() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
socket_t sock_;
|
|
||||||
SSL *ssl_;
|
|
||||||
time_t read_timeout_sec_;
|
|
||||||
time_t read_timeout_usec_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SSLServer : public Server {
|
class SSLServer : public Server {
|
||||||
public:
|
public:
|
||||||
SSLServer(const char *cert_path, const char *private_key_path,
|
SSLServer(const char *cert_path, const char *private_key_path,
|
||||||
@ -1272,6 +1216,62 @@ inline bool wait_until_socket_is_ready(socket_t sock, time_t sec, time_t usec) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SocketStream : public Stream {
|
||||||
|
public:
|
||||||
|
SocketStream(socket_t sock, time_t read_timeout_sec,
|
||||||
|
time_t read_timeout_usec);
|
||||||
|
~SocketStream() override;
|
||||||
|
|
||||||
|
int read(char *ptr, size_t size) override;
|
||||||
|
int write(const char *ptr, size_t size) override;
|
||||||
|
int write(const char *ptr) override;
|
||||||
|
int write(const std::string &s) override;
|
||||||
|
std::string get_remote_addr() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
socket_t sock_;
|
||||||
|
time_t read_timeout_sec_;
|
||||||
|
time_t read_timeout_usec_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
|
class SSLSocketStream : public Stream {
|
||||||
|
public:
|
||||||
|
SSLSocketStream(socket_t sock, SSL *ssl, time_t read_timeout_sec,
|
||||||
|
time_t read_timeout_usec);
|
||||||
|
virtual ~SSLSocketStream();
|
||||||
|
|
||||||
|
virtual int read(char *ptr, size_t size);
|
||||||
|
virtual int write(const char *ptr, size_t size);
|
||||||
|
virtual int write(const char *ptr);
|
||||||
|
virtual int write(const std::string &s);
|
||||||
|
virtual std::string get_remote_addr() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
socket_t sock_;
|
||||||
|
SSL *ssl_;
|
||||||
|
time_t read_timeout_sec_;
|
||||||
|
time_t read_timeout_usec_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BufferStream : public Stream {
|
||||||
|
public:
|
||||||
|
BufferStream() = default;
|
||||||
|
~BufferStream() override = default;
|
||||||
|
|
||||||
|
int read(char *ptr, size_t size) override;
|
||||||
|
int write(const char *ptr, size_t size) override;
|
||||||
|
int write(const char *ptr) override;
|
||||||
|
int write(const std::string &s) override;
|
||||||
|
std::string get_remote_addr() const override;
|
||||||
|
|
||||||
|
const std::string &get_buffer() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string buffer;
|
||||||
|
int position = 0;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool process_socket(bool is_client_request, socket_t sock,
|
inline bool process_socket(bool is_client_request, socket_t sock,
|
||||||
size_t keep_alive_max_count, time_t read_timeout_sec,
|
size_t keep_alive_max_count, time_t read_timeout_sec,
|
||||||
@ -1284,7 +1284,7 @@ inline bool process_socket(bool is_client_request, socket_t sock,
|
|||||||
auto count = keep_alive_max_count;
|
auto count = keep_alive_max_count;
|
||||||
while (count > 0 &&
|
while (count > 0 &&
|
||||||
(is_client_request ||
|
(is_client_request ||
|
||||||
detail::select_read(sock, CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND,
|
select_read(sock, CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND,
|
||||||
CPPHTTPLIB_KEEPALIVE_TIMEOUT_USECOND) > 0)) {
|
CPPHTTPLIB_KEEPALIVE_TIMEOUT_USECOND) > 0)) {
|
||||||
SocketStream strm(sock, read_timeout_sec, read_timeout_usec);
|
SocketStream strm(sock, read_timeout_sec, read_timeout_usec);
|
||||||
auto last_connection = count == 1;
|
auto last_connection = count == 1;
|
||||||
@ -1823,7 +1823,7 @@ bool read_content(Stream &strm, T &x, size_t payload_max_length, int &status,
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CPPHTTPLIB_ZLIB_SUPPORT
|
#ifdef CPPHTTPLIB_ZLIB_SUPPORT
|
||||||
detail::decompressor decompressor;
|
decompressor decompressor;
|
||||||
|
|
||||||
if (!decompressor.is_valid()) {
|
if (!decompressor.is_valid()) {
|
||||||
status = 500;
|
status = 500;
|
||||||
@ -2051,7 +2051,7 @@ inline bool parse_range_header(const std::string &s, Ranges &ranges) {
|
|||||||
auto pos = m.position(1);
|
auto pos = m.position(1);
|
||||||
auto len = m.length(1);
|
auto len = m.length(1);
|
||||||
bool all_valid_ranges = true;
|
bool all_valid_ranges = true;
|
||||||
detail::split(
|
split(
|
||||||
&s[pos], &s[pos + len], ',', [&](const char *b, const char *e) {
|
&s[pos], &s[pos + len], ',', [&](const char *b, const char *e) {
|
||||||
if (!all_valid_ranges) return;
|
if (!all_valid_ranges) return;
|
||||||
static auto re_another_range = std::regex(R"(\s*(\d*)-(\d*))");
|
static auto re_another_range = std::regex(R"(\s*(\d*)-(\d*))");
|
||||||
@ -2317,7 +2317,7 @@ bool process_multipart_ranges_data(const Request &req, Response &res,
|
|||||||
ctoken("\r\n");
|
ctoken("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto offsets = detail::get_range_offset_and_length(req, res.body.size(), i);
|
auto offsets = get_range_offset_and_length(req, res.body.size(), i);
|
||||||
auto offset = offsets.first;
|
auto offset = offsets.first;
|
||||||
auto length = offsets.second;
|
auto length = offsets.second;
|
||||||
|
|
||||||
@ -2380,7 +2380,7 @@ inline bool write_multipart_ranges_data(Stream &strm, const Request &req,
|
|||||||
[&](const std::string &token) { strm.write(token); },
|
[&](const std::string &token) { strm.write(token); },
|
||||||
[&](const char *token) { strm.write(token); },
|
[&](const char *token) { strm.write(token); },
|
||||||
[&](size_t offset, size_t length) {
|
[&](size_t offset, size_t length) {
|
||||||
return detail::write_content(strm, res.content_provider, offset,
|
return write_content(strm, res.content_provider, offset,
|
||||||
length) >= 0;
|
length) >= 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -2425,7 +2425,6 @@ inline std::string message_digest(const std::string &s, Init init,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline std::string MD5(const std::string &s) {
|
inline std::string MD5(const std::string &s) {
|
||||||
using namespace detail;
|
|
||||||
return message_digest<MD5_CTX>(s, MD5_Init, MD5_Update, MD5_Final,
|
return message_digest<MD5_CTX>(s, MD5_Init, MD5_Update, MD5_Final,
|
||||||
MD5_DIGEST_LENGTH);
|
MD5_DIGEST_LENGTH);
|
||||||
}
|
}
|
||||||
@ -2717,6 +2716,8 @@ inline int Stream::write_format(const char *fmt, const Args &... args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
// Socket stream implementation
|
// Socket stream implementation
|
||||||
inline SocketStream::SocketStream(socket_t sock, time_t read_timeout_sec,
|
inline SocketStream::SocketStream(socket_t sock, time_t read_timeout_sec,
|
||||||
time_t read_timeout_usec)
|
time_t read_timeout_usec)
|
||||||
@ -2776,6 +2777,8 @@ inline std::string BufferStream::get_remote_addr() const { return ""; }
|
|||||||
|
|
||||||
inline const std::string &BufferStream::get_buffer() const { return buffer; }
|
inline const std::string &BufferStream::get_buffer() const { return buffer; }
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
// HTTP server implementation
|
// HTTP server implementation
|
||||||
inline Server::Server()
|
inline Server::Server()
|
||||||
: keep_alive_max_count_(CPPHTTPLIB_KEEPALIVE_MAX_COUNT),
|
: keep_alive_max_count_(CPPHTTPLIB_KEEPALIVE_MAX_COUNT),
|
||||||
@ -3678,7 +3681,7 @@ inline bool Client::redirect(const Request &req, Response &res) {
|
|||||||
|
|
||||||
inline bool Client::write_request(Stream &strm, const Request &req,
|
inline bool Client::write_request(Stream &strm, const Request &req,
|
||||||
bool last_connection) {
|
bool last_connection) {
|
||||||
BufferStream bstrm;
|
detail::BufferStream bstrm;
|
||||||
|
|
||||||
// Request line
|
// Request line
|
||||||
const auto &path = detail::encode_url(req.path);
|
const auto &path = detail::encode_url(req.path);
|
||||||
@ -4333,10 +4336,6 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static SSLInit sslinit_;
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
// SSL socket stream implementation
|
// SSL socket stream implementation
|
||||||
inline SSLSocketStream::SSLSocketStream(socket_t sock, SSL *ssl,
|
inline SSLSocketStream::SSLSocketStream(socket_t sock, SSL *ssl,
|
||||||
time_t read_timeout_sec,
|
time_t read_timeout_sec,
|
||||||
@ -4348,7 +4347,7 @@ inline SSLSocketStream::~SSLSocketStream() {}
|
|||||||
|
|
||||||
inline int SSLSocketStream::read(char *ptr, size_t size) {
|
inline int SSLSocketStream::read(char *ptr, size_t size) {
|
||||||
if (SSL_pending(ssl_) > 0 ||
|
if (SSL_pending(ssl_) > 0 ||
|
||||||
detail::select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0) {
|
select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0) {
|
||||||
return SSL_read(ssl_, ptr, static_cast<int>(size));
|
return SSL_read(ssl_, ptr, static_cast<int>(size));
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -4370,6 +4369,10 @@ inline std::string SSLSocketStream::get_remote_addr() const {
|
|||||||
return detail::get_remote_addr(sock_);
|
return detail::get_remote_addr(sock_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SSLInit sslinit_;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
// SSL HTTP server implementation
|
// SSL HTTP server implementation
|
||||||
inline SSLServer::SSLServer(const char *cert_path, const char *private_key_path,
|
inline SSLServer::SSLServer(const char *cert_path, const char *private_key_path,
|
||||||
const char *client_ca_cert_file_path,
|
const char *client_ca_cert_file_path,
|
||||||
|
28
test/test.cc
28
test/test.cc
@ -199,6 +199,26 @@ TEST(ParseHeaderValueTest, Range) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(BufferStreamTest, read) {
|
||||||
|
detail::BufferStream strm;
|
||||||
|
|
||||||
|
EXPECT_EQ(5, strm.write("hello"));
|
||||||
|
|
||||||
|
char buf[512];
|
||||||
|
EXPECT_EQ(2, strm.read(buf, 2));
|
||||||
|
EXPECT_EQ('h', buf[0]);
|
||||||
|
EXPECT_EQ('e', buf[1]);
|
||||||
|
|
||||||
|
EXPECT_EQ(2, strm.read(buf, 2));
|
||||||
|
EXPECT_EQ('l', buf[0]);
|
||||||
|
EXPECT_EQ('l', buf[1]);
|
||||||
|
|
||||||
|
EXPECT_EQ(1, strm.read(buf, 1));
|
||||||
|
EXPECT_EQ('o', buf[0]);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, strm.read(buf, 1));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ChunkedEncodingTest, FromHTTPWatch) {
|
TEST(ChunkedEncodingTest, FromHTTPWatch) {
|
||||||
auto host = "www.httpwatch.com";
|
auto host = "www.httpwatch.com";
|
||||||
|
|
||||||
@ -1967,7 +1987,7 @@ TEST(ServerRequestParsingTest, ReadHeadersRegexComplexity) {
|
|||||||
TEST(ServerStopTest, StopServerWithChunkedTransmission) {
|
TEST(ServerStopTest, StopServerWithChunkedTransmission) {
|
||||||
Server svr;
|
Server svr;
|
||||||
|
|
||||||
svr.Get("/events", [](const Request &req, Response &res) {
|
svr.Get("/events", [](const Request & /*req*/, Response &res) {
|
||||||
res.set_header("Content-Type", "text/event-stream");
|
res.set_header("Content-Type", "text/event-stream");
|
||||||
res.set_header("Cache-Control", "no-cache");
|
res.set_header("Cache-Control", "no-cache");
|
||||||
res.set_chunked_content_provider([](size_t offset, const DataSink &sink) {
|
res.set_chunked_content_provider([](size_t offset, const DataSink &sink) {
|
||||||
@ -1988,9 +2008,9 @@ TEST(ServerStopTest, StopServerWithChunkedTransmission) {
|
|||||||
{"Connection", "Keep-Alive"}};
|
{"Connection", "Keep-Alive"}};
|
||||||
|
|
||||||
auto get_thread = std::thread([&client, &headers]() {
|
auto get_thread = std::thread([&client, &headers]() {
|
||||||
std::shared_ptr<Response> res =
|
std::shared_ptr<Response> res = client.Get(
|
||||||
client.Get("/events", headers,
|
"/events", headers,
|
||||||
[](const char *data, size_t len) -> bool { return true; });
|
[](const char * /*data*/, size_t /*len*/) -> bool { return true; });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Give GET time to get a few messages.
|
// Give GET time to get a few messages.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user