Unverified Commit b6189fd7 authored by Kip's avatar Kip Committed by GitHub

Merge pull request #930 from Tachi107/nested-namespaces

Nested namespaces
parents 78a79829 f26fc2ab
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
...@@ -7,24 +7,21 @@ ...@@ -7,24 +7,21 @@
#include <chrono> #include <chrono>
// Allow compile-time overload // Allow compile-time overload
namespace Pistache namespace Pistache::Const
{ {
namespace Const static constexpr size_t MaxBacklog = 128;
{ static constexpr size_t MaxEvents = 1024;
static constexpr size_t MaxBacklog = 128; static constexpr size_t MaxBuffer = 4096;
static constexpr size_t MaxEvents = 1024; static constexpr size_t DefaultWorkers = 1;
static constexpr size_t MaxBuffer = 4096;
static constexpr size_t DefaultWorkers = 1;
static constexpr size_t DefaultTimerPoolSize = 128; static constexpr size_t DefaultTimerPoolSize = 128;
// Defined from CMakeLists.txt in project root // Defined from CMakeLists.txt in project root
static constexpr size_t DefaultMaxRequestSize = 4096; static constexpr size_t DefaultMaxRequestSize = 4096;
static constexpr size_t DefaultMaxResponseSize = std::numeric_limits<uint32_t>::max(); static constexpr size_t DefaultMaxResponseSize = std::numeric_limits<uint32_t>::max();
static constexpr auto DefaultHeaderTimeout = std::chrono::seconds(60); static constexpr auto DefaultHeaderTimeout = std::chrono::seconds(60);
static constexpr auto DefaultBodyTimeout = std::chrono::seconds(60); static constexpr auto DefaultBodyTimeout = std::chrono::seconds(60);
static constexpr size_t ChunkSize = 1024; static constexpr size_t ChunkSize = 1024;
static constexpr uint16_t HTTP_STANDARD_PORT = 80; static constexpr uint16_t HTTP_STANDARD_PORT = 80;
} // namespace Const } // namespace Pistache::Const
} // namespace Pistache
...@@ -16,133 +16,130 @@ ...@@ -16,133 +16,130 @@
#include <pistache/http_defs.h> #include <pistache/http_defs.h>
namespace Pistache namespace Pistache::Http
{ {
namespace Http
struct Cookie
{ {
friend std::ostream& operator<<(std::ostream& os, const Cookie& cookie);
struct Cookie Cookie(std::string name, std::string value);
{
friend std::ostream& operator<<(std::ostream& os, const Cookie& cookie);
Cookie(std::string name, std::string value); std::string name;
std::string value;
std::string name; std::optional<std::string> path;
std::string value; std::optional<std::string> domain;
std::optional<FullDate> expires;
std::optional<std::string> path; std::optional<int> maxAge;
std::optional<std::string> domain; bool secure;
std::optional<FullDate> expires; bool httpOnly;
std::optional<int> maxAge; std::map<std::string, std::string> ext;
bool secure;
bool httpOnly;
std::map<std::string, std::string> ext; static Cookie fromRaw(const char* str, size_t len);
static Cookie fromString(const std::string& str);
static Cookie fromRaw(const char* str, size_t len); private:
static Cookie fromString(const std::string& str); void write(std::ostream& os) const;
};
private: std::ostream& operator<<(std::ostream& os, const Cookie& cookie);
void write(std::ostream& os) const;
};
std::ostream& operator<<(std::ostream& os, const Cookie& cookie); class CookieJar
{
public:
using HashMapCookies = std::unordered_map<std::string, Cookie>; // "value" -> Cookie
using Storage = std::unordered_map<
std::string, HashMapCookies>; // "name" -> Hashmap("value" -> Cookie)
class CookieJar struct iterator : std::iterator<std::bidirectional_iterator_tag, Cookie>
{ {
public: explicit iterator(const Storage::const_iterator& _iterator)
using HashMapCookies = std::unordered_map<std::string, Cookie>; // "value" -> Cookie : iter_storage(_iterator)
using Storage = std::unordered_map< , iter_cookie_values()
std::string, HashMapCookies>; // "name" -> Hashmap("value" -> Cookie) , iter_storage_end()
{ }
struct iterator : std::iterator<std::bidirectional_iterator_tag, Cookie>
iterator(const Storage::const_iterator& _iterator,
const Storage::const_iterator& end)
: iter_storage(_iterator)
, iter_cookie_values()
, iter_storage_end(end)
{ {
explicit iterator(const Storage::const_iterator& _iterator) if (iter_storage != iter_storage_end)
: iter_storage(_iterator)
, iter_cookie_values()
, iter_storage_end()
{ }
iterator(const Storage::const_iterator& _iterator,
const Storage::const_iterator& end)
: iter_storage(_iterator)
, iter_cookie_values()
, iter_storage_end(end)
{ {
if (iter_storage != iter_storage_end) iter_cookie_values = iter_storage->second.begin();
{
iter_cookie_values = iter_storage->second.begin();
}
} }
}
Cookie operator*() const Cookie operator*() const
{ {
return iter_cookie_values->second; // return iter_storage->second; return iter_cookie_values->second; // return iter_storage->second;
} }
const Cookie* operator->() const { return &(iter_cookie_values->second); } const Cookie* operator->() const { return &(iter_cookie_values->second); }
iterator& operator++() iterator& operator++()
{
++iter_cookie_values;
if (iter_cookie_values == iter_storage->second.end())
{ {
++iter_cookie_values; ++iter_storage;
if (iter_cookie_values == iter_storage->second.end()) if (iter_storage != iter_storage_end)
{ iter_cookie_values = iter_storage->second.begin();
++iter_storage;
if (iter_storage != iter_storage_end)
iter_cookie_values = iter_storage->second.begin();
}
return *this;
} }
return *this;
}
iterator operator++(int) iterator operator++(int)
{
iterator ret(iter_storage, iter_storage_end);
++iter_cookie_values;
if (iter_cookie_values == iter_storage->second.end())
{ {
iterator ret(iter_storage, iter_storage_end); ++iter_storage;
++iter_cookie_values; if (iter_storage != iter_storage_end) // this check is important
if (iter_cookie_values == iter_storage->second.end()) iter_cookie_values = iter_storage->second.begin();
{
++iter_storage;
if (iter_storage != iter_storage_end) // this check is important
iter_cookie_values = iter_storage->second.begin();
}
return ret;
} }
bool operator!=(iterator other) const return ret;
{ }
return iter_storage != other.iter_storage;
}
bool operator==(iterator other) const bool operator!=(iterator other) const
{ {
return iter_storage == other.iter_storage; return iter_storage != other.iter_storage;
} }
private: bool operator==(iterator other) const
Storage::const_iterator iter_storage; {
HashMapCookies::const_iterator iter_cookie_values; return iter_storage == other.iter_storage;
Storage::const_iterator }
iter_storage_end; // we need to know where main hashmap ends.
}; private:
Storage::const_iterator iter_storage;
HashMapCookies::const_iterator iter_cookie_values;
Storage::const_iterator
iter_storage_end; // we need to know where main hashmap ends.
};
CookieJar(); CookieJar();
void add(const Cookie& cookie); void add(const Cookie& cookie);
void removeAllCookies(); void removeAllCookies();
void addFromRaw(const char* str, size_t len); void addFromRaw(const char* str, size_t len);
Cookie get(const std::string& name) const; Cookie get(const std::string& name) const;
bool has(const std::string& name) const; bool has(const std::string& name) const;
iterator begin() const { return iterator(cookies.begin(), cookies.end()); } iterator begin() const { return iterator(cookies.begin(), cookies.end()); }
iterator end() const { return iterator(cookies.end()); } iterator end() const { return iterator(cookies.end()); }
private: private:
Storage cookies; Storage cookies;
}; };
} // namespace Http } // namespace Pistache::Http
} // namespace Pistache
This diff is collapsed.
...@@ -13,94 +13,92 @@ ...@@ -13,94 +13,92 @@
#include <chrono> #include <chrono>
namespace Pistache namespace Pistache::Http
{ {
namespace Http
{
class Endpoint class Endpoint
{
public:
struct Options
{ {
public: friend class Endpoint;
struct Options
Options& threads(int val);
Options& threadsName(const std::string& val);
Options& flags(Flags<Tcp::Options> flags);
Options& flags(Tcp::Options tcp_opts)
{
flags(Flags<Tcp::Options>(tcp_opts));
return *this;
}
Options& backlog(int val);
Options& maxRequestSize(size_t val);
Options& maxResponseSize(size_t val);
template <typename Duration>
Options& headerTimeout(Duration timeout)
{ {
friend class Endpoint; headerTimeout_ = std::chrono::duration_cast<std::chrono::milliseconds>(timeout);
return *this;
Options& threads(int val); }
Options& threadsName(const std::string& val);
template <typename Duration>
Options& flags(Flags<Tcp::Options> flags); Options& bodyTimeout(Duration timeout)
Options& flags(Tcp::Options tcp_opts)
{
flags(Flags<Tcp::Options>(tcp_opts));
return *this;
}
Options& backlog(int val);
Options& maxRequestSize(size_t val);
Options& maxResponseSize(size_t val);
template <typename Duration>
Options& headerTimeout(Duration timeout)
{
headerTimeout_ = std::chrono::duration_cast<std::chrono::milliseconds>(timeout);
return *this;
}
template <typename Duration>
Options& bodyTimeout(Duration timeout)
{
bodyTimeout_ = std::chrono::duration_cast<std::chrono::milliseconds>(timeout);
return *this;
}
Options& logger(PISTACHE_STRING_LOGGER_T logger);
[[deprecated("Replaced by maxRequestSize(val)")]] Options&
maxPayload(size_t val);
private:
// Thread options
int threads_;
std::string threadsName_;
// TCP flags
Flags<Tcp::Options> flags_;
// Backlog size
int backlog_;
// Size options
size_t maxRequestSize_;
size_t maxResponseSize_;
// Timeout options
std::chrono::milliseconds headerTimeout_;
std::chrono::milliseconds bodyTimeout_;
PISTACHE_STRING_LOGGER_T logger_;
Options();
};
Endpoint();
explicit Endpoint(const Address& addr);
template <typename... Args>
void initArgs(Args&&... args)
{ {
listener.init(std::forward<Args>(args)...); bodyTimeout_ = std::chrono::duration_cast<std::chrono::milliseconds>(timeout);
return *this;
} }
void init(const Options& options = Options()); Options& logger(PISTACHE_STRING_LOGGER_T logger);
void setHandler(const std::shared_ptr<Handler>& handler);
[[deprecated("Replaced by maxRequestSize(val)")]] Options&
maxPayload(size_t val);
private:
// Thread options
int threads_;
std::string threadsName_;
// TCP flags
Flags<Tcp::Options> flags_;
// Backlog size
int backlog_;
// Size options
size_t maxRequestSize_;
size_t maxResponseSize_;
void bind(); // Timeout options
void bind(const Address& addr); std::chrono::milliseconds headerTimeout_;
std::chrono::milliseconds bodyTimeout_;
void serve(); PISTACHE_STRING_LOGGER_T logger_;
void serveThreaded(); Options();
};
Endpoint();
explicit Endpoint(const Address& addr);
template <typename... Args>
void initArgs(Args&&... args)
{
listener.init(std::forward<Args>(args)...);
}
void shutdown(); void init(const Options& options = Options());
void setHandler(const std::shared_ptr<Handler>& handler);
/*! void bind();
void bind(const Address& addr);
void serve();
void serveThreaded();
void shutdown();
/*!
* \brief Use SSL on this endpoint * \brief Use SSL on this endpoint
* *
* \param[in] cert Server certificate path * \param[in] cert Server certificate path
...@@ -121,9 +119,9 @@ namespace Pistache ...@@ -121,9 +119,9 @@ namespace Pistache
* [1] https://en.wikipedia.org/wiki/BREACH * [1] https://en.wikipedia.org/wiki/BREACH
* [2] https://en.wikipedia.org/wiki/CRIME * [2] https://en.wikipedia.org/wiki/CRIME
*/ */
void useSSL(const std::string& cert, const std::string& key, bool use_compression = false); void useSSL(const std::string& cert, const std::string& key, bool use_compression = false);
/*! /*!
* \brief Use SSL certificate authentication on this endpoint * \brief Use SSL certificate authentication on this endpoint
* *
* \param[in] ca_file Certificate Authority file * \param[in] ca_file Certificate Authority file
...@@ -163,50 +161,49 @@ namespace Pistache ...@@ -163,50 +161,49 @@ namespace Pistache
* *
* [1] https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_verify.html * [1] https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_verify.html
*/ */
void useSSLAuth(std::string ca_file, std::string ca_path = "", void useSSLAuth(std::string ca_file, std::string ca_path = "",
int (*cb)(int, void*) = NULL); int (*cb)(int, void*) = NULL);
bool isBound() const { return listener.isBound(); } bool isBound() const { return listener.isBound(); }
Port getPort() const { return listener.getPort(); } Port getPort() const { return listener.getPort(); }
Async::Promise<Tcp::Listener::Load> Async::Promise<Tcp::Listener::Load>
requestLoad(const Tcp::Listener::Load& old); requestLoad(const Tcp::Listener::Load& old);
static Options options(); static Options options();
private: private:
template <typename Method> template <typename Method>
void serveImpl(Method method) void serveImpl(Method method)
{ {
#define CALL_MEMBER_FN(obj, pmf) ((obj).*(pmf)) #define CALL_MEMBER_FN(obj, pmf) ((obj).*(pmf))
if (!handler_) if (!handler_)
throw std::runtime_error("Must call setHandler() prior to serve()"); throw std::runtime_error("Must call setHandler() prior to serve()");
listener.setHandler(handler_); listener.setHandler(handler_);
listener.bind(); listener.bind();
CALL_MEMBER_FN(listener, method) CALL_MEMBER_FN(listener, method)
(); ();
#undef CALL_MEMBER_FN #undef CALL_MEMBER_FN
} }
std::shared_ptr<Handler> handler_; std::shared_ptr<Handler> handler_;
Tcp::Listener listener; Tcp::Listener listener;
Options options_; Options options_;
PISTACHE_STRING_LOGGER_T logger_ = PISTACHE_NULL_STRING_LOGGER; PISTACHE_STRING_LOGGER_T logger_ = PISTACHE_NULL_STRING_LOGGER;
}; };
template <typename Handler> template <typename Handler>
void listenAndServe(Address addr, void listenAndServe(Address addr,
const Endpoint::Options& options = Endpoint::options()) const Endpoint::Options& options = Endpoint::options())
{ {
Endpoint endpoint(addr); Endpoint endpoint(addr);
endpoint.init(options); endpoint.init(options);
endpoint.setHandler(make_handler<Handler>()); endpoint.setHandler(make_handler<Handler>());
endpoint.serve(); endpoint.serve();
} }
} // namespace Http } // namespace Pistache::Http
} // namespace Pistache
...@@ -2,26 +2,23 @@ ...@@ -2,26 +2,23 @@
#include <stdexcept> #include <stdexcept>
namespace Pistache namespace Pistache::Tcp
{ {
namespace Tcp
{
class SocketError : public std::runtime_error class SocketError : public std::runtime_error
{ {
public: public:
explicit SocketError(const char* what_arg) explicit SocketError(const char* what_arg)
: std::runtime_error(what_arg) : std::runtime_error(what_arg)
{ } { }
}; };
class ServerError : public std::runtime_error class ServerError : public std::runtime_error
{ {
public: public:
explicit ServerError(const char* what_arg) explicit ServerError(const char* what_arg)
: std::runtime_error(what_arg) : std::runtime_error(what_arg)
{ } { }
}; };
} // namespace Tcp } // namespace Pistache::Tcp
} // namespace Pistache \ No newline at end of file
\ No newline at end of file
...@@ -12,10 +12,8 @@ ...@@ -12,10 +12,8 @@
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
namespace Pistache namespace Pistache::Http
{ {
namespace Http
{
#define HTTP_METHODS \ #define HTTP_METHODS \
METHOD(Options, "OPTIONS") \ METHOD(Options, "OPTIONS") \
...@@ -125,126 +123,125 @@ namespace Pistache ...@@ -125,126 +123,125 @@ namespace Pistache
CHARSET(Utf32 - LE, "utf-32le") \ CHARSET(Utf32 - LE, "utf-32le") \
CHARSET(Unicode - 11, "unicode-1-1") CHARSET(Unicode - 11, "unicode-1-1")
enum class Method { enum class Method {
#define METHOD(m, _) m, #define METHOD(m, _) m,
HTTP_METHODS HTTP_METHODS
#undef METHOD #undef METHOD
}; };
enum class Code { enum class Code {
#define CODE(value, name, _) name = value, #define CODE(value, name, _) name = value,
STATUS_CODES STATUS_CODES
#undef CODE #undef CODE
}; };
enum class Version { enum class Version {
Http10, // HTTP/1.0 Http10, // HTTP/1.0
Http11 // HTTP/1.1 Http11 // HTTP/1.1
}; };
enum class ConnectionControl { Close, enum class ConnectionControl { Close,
KeepAlive, KeepAlive,
Ext }; Ext };
enum class Expectation { Continue, enum class Expectation { Continue,
Ext }; Ext };
class CacheDirective class CacheDirective
{ {
public: public:
enum Directive { enum Directive {
NoCache, NoCache,
NoStore, NoStore,
MaxAge, MaxAge,
MaxStale, MaxStale,
MinFresh, MinFresh,
NoTransform, NoTransform,
OnlyIfCached, OnlyIfCached,
Public, Public,
Private, Private,
MustRevalidate, MustRevalidate,
ProxyRevalidate, ProxyRevalidate,
SMaxAge, SMaxAge,
Ext Ext
};
CacheDirective()
: directive_()
, data()
{ }
explicit CacheDirective(Directive directive);
CacheDirective(Directive directive, std::chrono::seconds delta);
Directive directive() const { return directive_; }
std::chrono::seconds delta() const;
private:
void init(Directive directive, std::chrono::seconds delta);
Directive directive_;
// Poor way of representing tagged unions in C++
union
{
uint64_t maxAge;
uint64_t sMaxAge;
uint64_t maxStale;
uint64_t minFresh;
} data;
}; };
// 3.3.1 Full Date CacheDirective()
class FullDate : directive_()
, data()
{ }
explicit CacheDirective(Directive directive);
CacheDirective(Directive directive, std::chrono::seconds delta);
Directive directive() const { return directive_; }
std::chrono::seconds delta() const;
private:
void init(Directive directive, std::chrono::seconds delta);
Directive directive_;
// Poor way of representing tagged unions in C++
union
{ {
public: uint64_t maxAge;
using time_point = std::chrono::system_clock::time_point; uint64_t sMaxAge;
FullDate() uint64_t maxStale;
: date_() uint64_t minFresh;
{ } } data;
};
enum class Type { RFC1123, // 3.3.1 Full Date
RFC850, class FullDate
AscTime }; {
public:
using time_point = std::chrono::system_clock::time_point;
FullDate()
: date_()
{ }
explicit FullDate(time_point date) enum class Type { RFC1123,
: date_(date) RFC850,
{ } AscTime };
time_point date() const { return date_; } explicit FullDate(time_point date)
void write(std::ostream& os, Type type = Type::RFC1123) const; : date_(date)
{ }
static FullDate fromString(const std::string& str); time_point date() const { return date_; }
void write(std::ostream& os, Type type = Type::RFC1123) const;
private: static FullDate fromString(const std::string& str);
time_point date_;
}; private:
time_point date_;
};
const char* methodString(Method method); const char* methodString(Method method);
const char* versionString(Version version); const char* versionString(Version version);
const char* codeString(Code code); const char* codeString(Code code);
std::ostream& operator<<(std::ostream& os, Version version); std::ostream& operator<<(std::ostream& os, Version version);
std::ostream& operator<<(std::ostream& os, Method method); std::ostream& operator<<(std::ostream& os, Method method);
std::ostream& operator<<(std::ostream& os, Code code); std::ostream& operator<<(std::ostream& os, Code code);
struct HttpError : public std::exception struct HttpError : public std::exception
{ {
HttpError(Code code, std::string reason); HttpError(Code code, std::string reason);
HttpError(int code, std::string reason); HttpError(int code, std::string reason);
~HttpError() noexcept { } ~HttpError() noexcept { }
const char* what() const noexcept override { return reason_.c_str(); } const char* what() const noexcept override { return reason_.c_str(); }
int code() const { return code_; } int code() const { return code_; }
std::string reason() const { return reason_; } std::string reason() const { return reason_; }
private: private:
int code_; int code_;
std::string reason_; std::string reason_;
}; };
} // namespace Http } // namespace Pistache::Http
} // namespace Pistache
namespace std namespace std
{ {
......
This diff is collapsed.
This diff is collapsed.
...@@ -26,97 +26,94 @@ ...@@ -26,97 +26,94 @@
#include <openssl/ssl.h> #include <openssl/ssl.h>
#endif /* PISTACHE_USE_SSL */ #endif /* PISTACHE_USE_SSL */
namespace Pistache namespace Pistache::Tcp
{ {
namespace Tcp
{
class Peer; class Peer;
class Transport; class Transport;
void setSocketOptions(Fd fd, Flags<Options> options); void setSocketOptions(Fd fd, Flags<Options> options);
class Listener class Listener
{
public:
struct Load
{ {
public: using TimePoint = std::chrono::system_clock::time_point;
struct Load double global;
{ std::vector<double> workers;
using TimePoint = std::chrono::system_clock::time_point;
double global;
std::vector<double> workers;
std::vector<rusage> raw; std::vector<rusage> raw;
TimePoint tick; TimePoint tick;
}; };
using TransportFactory = std::function<std::shared_ptr<Transport>()>; using TransportFactory = std::function<std::shared_ptr<Transport>()>;
Listener(); Listener();
~Listener(); ~Listener();
explicit Listener(const Address& address); explicit Listener(const Address& address);
void init(size_t workers, void init(size_t workers,
Flags<Options> options = Flags<Options>(Options::None), Flags<Options> options = Flags<Options>(Options::None),
const std::string& workersName = "", const std::string& workersName = "",
int backlog = Const::MaxBacklog, int backlog = Const::MaxBacklog,
PISTACHE_STRING_LOGGER_T logger = PISTACHE_NULL_STRING_LOGGER); PISTACHE_STRING_LOGGER_T logger = PISTACHE_NULL_STRING_LOGGER);
void setTransportFactory(TransportFactory factory); void setTransportFactory(TransportFactory factory);
void setHandler(const std::shared_ptr<Handler>& handler); void setHandler(const std::shared_ptr<Handler>& handler);
void bind(); void bind();
void bind(const Address& address); void bind(const Address& address);
bool isBound() const; bool isBound() const;
Port getPort() const; Port getPort() const;
void run(); void run();
void runThreaded(); void runThreaded();
void shutdown(); void shutdown();
Async::Promise<Load> requestLoad(const Load& old); Async::Promise<Load> requestLoad(const Load& old);
Options options() const; Options options() const;
Address address() const; Address address() const;
void pinWorker(size_t worker, const CpuSet& set); void pinWorker(size_t worker, const CpuSet& set);
void setupSSL(const std::string& cert_path, const std::string& key_path, void setupSSL(const std::string& cert_path, const std::string& key_path,
bool use_compression); bool use_compression);
void setupSSLAuth(const std::string& ca_file, const std::string& ca_path, void setupSSLAuth(const std::string& ca_file, const std::string& ca_path,
int (*cb)(int, void*)); int (*cb)(int, void*));
private: private:
Address addr_; Address addr_;
int listen_fd = -1; int listen_fd = -1;
int backlog_ = Const::MaxBacklog; int backlog_ = Const::MaxBacklog;
NotifyFd shutdownFd; NotifyFd shutdownFd;
Polling::Epoll poller; Polling::Epoll poller;
Flags<Options> options_; Flags<Options> options_;
std::thread acceptThread; std::thread acceptThread;
size_t workers_ = Const::DefaultWorkers; size_t workers_ = Const::DefaultWorkers;
std::string workersName_; std::string workersName_;
std::shared_ptr<Handler> handler_; std::shared_ptr<Handler> handler_;
Aio::Reactor reactor_; Aio::Reactor reactor_;
Aio::Reactor::Key transportKey; Aio::Reactor::Key transportKey;
TransportFactory transportFactory_; TransportFactory transportFactory_;
TransportFactory defaultTransportFactory() const; TransportFactory defaultTransportFactory() const;
void handleNewConnection(); void handleNewConnection();
int acceptConnection(struct sockaddr_in& peer_addr) const; int acceptConnection(struct sockaddr_in& peer_addr) const;
void dispatchPeer(const std::shared_ptr<Peer>& peer); void dispatchPeer(const std::shared_ptr<Peer>& peer);
bool useSSL_ = false; bool useSSL_ = false;
ssl::SSLCtxPtr ssl_ctx_ = nullptr; ssl::SSLCtxPtr ssl_ctx_ = nullptr;
PISTACHE_STRING_LOGGER_T logger_ = PISTACHE_NULL_STRING_LOGGER; PISTACHE_STRING_LOGGER_T logger_ = PISTACHE_NULL_STRING_LOGGER;
}; };
} // namespace Tcp } // namespace Pistache::Tcp
} // namespace Pistache
...@@ -2,19 +2,13 @@ ...@@ -2,19 +2,13 @@
#include <cstdint> #include <cstdint>
namespace Pistache namespace Pistache::Meta::Hash
{ {
namespace Meta static constexpr uint64_t val64 = 0xcbf29ce484222325;
{ static constexpr uint64_t prime64 = 0x100000001b3;
namespace Hash
{
static constexpr uint64_t val64 = 0xcbf29ce484222325;
static constexpr uint64_t prime64 = 0x100000001b3;
inline constexpr uint64_t fnv1a(const char* const str, const uint64_t value = val64) noexcept inline constexpr uint64_t fnv1a(const char* const str, const uint64_t value = val64) noexcept
{ {
return (str[0] == '\0') ? value : fnv1a(&str[1], (value ^ uint64_t(str[0])) * prime64); return (str[0] == '\0') ? value : fnv1a(&str[1], (value ^ uint64_t(str[0])) * prime64);
}
}
} }
} } // namespace Pistache::Meta::Hash
\ No newline at end of file
This diff is collapsed.
...@@ -22,58 +22,55 @@ ...@@ -22,58 +22,55 @@
#endif /* PISTACHE_USE_SSL */ #endif /* PISTACHE_USE_SSL */
namespace Pistache namespace Pistache::Tcp
{ {
namespace Tcp
{
class Transport; class Transport;
class Peer class Peer
{ {
public: public:
friend class Transport; friend class Transport;
friend class Http::Handler; friend class Http::Handler;
friend class Http::Timeout; friend class Http::Timeout;
~Peer(); ~Peer();
static std::shared_ptr<Peer> Create(Fd fd, const Address& addr); static std::shared_ptr<Peer> Create(Fd fd, const Address& addr);
static std::shared_ptr<Peer> CreateSSL(Fd fd, const Address& addr, void* ssl); static std::shared_ptr<Peer> CreateSSL(Fd fd, const Address& addr, void* ssl);
const Address& address() const; const Address& address() const;
const std::string& hostname(); const std::string& hostname();
Fd fd() const; Fd fd() const;
void* ssl() const; void* ssl() const;
void putData(std::string name, std::shared_ptr<void> data); void putData(std::string name, std::shared_ptr<void> data);
std::shared_ptr<void> getData(std::string name) const; std::shared_ptr<void> getData(std::string name) const;
std::shared_ptr<void> tryGetData(std::string name) const; std::shared_ptr<void> tryGetData(std::string name) const;
Async::Promise<ssize_t> send(const RawBuffer& buffer, int flags = 0); Async::Promise<ssize_t> send(const RawBuffer& buffer, int flags = 0);
size_t getID() const; size_t getID() const;
protected: protected:
Peer(Fd fd, const Address& addr, void* ssl); Peer(Fd fd, const Address& addr, void* ssl);
private: private:
void associateTransport(Transport* transport); void associateTransport(Transport* transport);
Transport* transport() const; Transport* transport() const;
static size_t getUniqueId(); static size_t getUniqueId();
Transport* transport_ = nullptr; Transport* transport_ = nullptr;
Fd fd_ = -1; Fd fd_ = -1;
Address addr; Address addr;
std::string hostname_; std::string hostname_;
std::unordered_map<std::string, std::shared_ptr<void>> data_; std::unordered_map<std::string, std::shared_ptr<void>> data_;
void* ssl_ = nullptr; void* ssl_ = nullptr;
const size_t id_; const size_t id_;
}; };
std::ostream& operator<<(std::ostream& os, Peer& peer); std::ostream& operator<<(std::ostream& os, Peer& peer);
} // namespace Tcp } // namespace Pistache::Tcp
} // namespace Pistache
This diff is collapsed.
...@@ -6,76 +6,70 @@ ...@@ -6,76 +6,70 @@
#pragma once #pragma once
namespace Pistache namespace Pistache::Rest::Route
{ {
namespace Rest
{
namespace Route
{
void Get(Router& router, std::string resource, Route::Handler handler); void Get(Router& router, std::string resource, Route::Handler handler);
void Post(Router& router, std::string resource, Route::Handler handler); void Post(Router& router, std::string resource, Route::Handler handler);
void Put(Router& router, std::string resource, Route::Handler handler); void Put(Router& router, std::string resource, Route::Handler handler);
void Delete(Router& router, std::string resource, Route::Handler handler); void Delete(Router& router, std::string resource, Route::Handler handler);
namespace details namespace details
{
template <class... Args>
struct TypeList
{
template <size_t N>
struct At
{ {
template <class... Args> static_assert(N < sizeof...(Args), "Invalid index");
struct TypeList typedef typename std::tuple_element<N, std::tuple<Args...>>::type Type;
{ };
template <size_t N> };
struct At
{
static_assert(N < sizeof...(Args), "Invalid index");
typedef typename std::tuple_element<N, std::tuple<Args...>>::type Type;
};
};
template <typename... Args> template <typename... Args>
void static_checks() void static_checks()
{ {
static_assert(sizeof...(Args) == 2, "Function should take 2 parameters"); static_assert(sizeof...(Args) == 2, "Function should take 2 parameters");
typedef details::TypeList<Args...> Arguments; typedef details::TypeList<Args...> Arguments;
// Disabled now as it // Disabled now as it
// 1/ does not compile // 1/ does not compile
// 2/ might not be relevant // 2/ might not be relevant
#if 0 #if 0
static_assert(std::is_same<Arguments::At<0>::Type, const Rest::Request&>::value, "First argument should be a const Rest::Request&"); static_assert(std::is_same<Arguments::At<0>::Type, const Rest::Request&>::value, "First argument should be a const Rest::Request&");
static_assert(std::is_same<typename Arguments::At<0>::Type, Http::Response>::value, "Second argument should be a Http::Response"); static_assert(std::is_same<typename Arguments::At<0>::Type, Http::Response>::value, "Second argument should be a Http::Response");
#endif #endif
} }
} // namespace details } // namespace details
template <typename Result, typename Cls, typename... Args, typename Obj> template <typename Result, typename Cls, typename... Args, typename Obj>
Route::Handler bind(Result (Cls::*func)(Args...), Obj obj) Route::Handler bind(Result (Cls::*func)(Args...), Obj obj)
{ {
details::static_checks<Args...>(); details::static_checks<Args...>();
return [=](const Rest::Request& request, Http::ResponseWriter response) { return [=](const Rest::Request& request, Http::ResponseWriter response) {
(obj->*func)(request, std::move(response)); (obj->*func)(request, std::move(response));
}; };
} }
template <typename Result, typename Cls, typename... Args, typename Obj> template <typename Result, typename Cls, typename... Args, typename Obj>
Route::Handler bind(Result (Cls::*func)(Args...), std::shared_ptr<Obj> objPtr) Route::Handler bind(Result (Cls::*func)(Args...), std::shared_ptr<Obj> objPtr)
{ {
details::static_checks<Args...>(); details::static_checks<Args...>();
return [=](const Rest::Request& request, Http::ResponseWriter response) { return [=](const Rest::Request& request, Http::ResponseWriter response) {
(objPtr.get()->*func)(request, std::move(response)); (objPtr.get()->*func)(request, std::move(response));
}; };
} }
template <typename Result, typename... Args> template <typename Result, typename... Args>
Route::Handler bind(Result (*func)(Args...)) Route::Handler bind(Result (*func)(Args...))
{ {
details::static_checks<Args...>(); details::static_checks<Args...>();
return [=](const Rest::Request& request, Http::ResponseWriter response) { return [=](const Rest::Request& request, Http::ResponseWriter response) {
func(request, std::move(response)); func(request, std::move(response));
}; };
} }
} // namespace Route } // namespace Pistache::Rest::Route
} // namespace Rest
} // namespace Pistache
This diff is collapsed.
...@@ -6,55 +6,52 @@ ...@@ -6,55 +6,52 @@
#include <memory> #include <memory>
namespace Pistache namespace Pistache::ssl
{ {
namespace ssl
{
struct SSLCtxDeleter struct SSLCtxDeleter
{
void operator()(void* ptr)
{ {
void operator()(void* ptr)
{
#ifdef PISTACHE_USE_SSL #ifdef PISTACHE_USE_SSL
SSL_CTX_free(reinterpret_cast<SSL_CTX*>(ptr)); SSL_CTX_free(reinterpret_cast<SSL_CTX*>(ptr));
// EVP_cleanup call is not related to cleaning SSL_CTX, just global cleanup routine. // EVP_cleanup call is not related to cleaning SSL_CTX, just global cleanup routine.
// TODO: Think about removing EVP_cleanup call at all // TODO: Think about removing EVP_cleanup call at all
// It was deprecated in openssl 1.1.0 version (see // It was deprecated in openssl 1.1.0 version (see
// https://www.openssl.org/news/changelog.txt): // https://www.openssl.org/news/changelog.txt):
// "Make various cleanup routines no-ops and mark them as deprecated." // "Make various cleanup routines no-ops and mark them as deprecated."
EVP_cleanup(); EVP_cleanup();
#else #else
(void)ptr; (void)ptr;
#endif #endif
} }
}; };
struct SSLBioDeleter struct SSLBioDeleter
{
void operator()(void* ptr)
{ {
void operator()(void* ptr)
{
#ifdef PISTACHE_USE_SSL #ifdef PISTACHE_USE_SSL
BIO_free(reinterpret_cast<BIO*>(ptr)); BIO_free(reinterpret_cast<BIO*>(ptr));
#else #else
(void)ptr; (void)ptr;
#endif #endif
} }
}; };
using SSLCtxPtr = std::unique_ptr<void, SSLCtxDeleter>; using SSLCtxPtr = std::unique_ptr<void, SSLCtxDeleter>;
using SSLBioPtr = std::unique_ptr<void, SSLBioDeleter>; using SSLBioPtr = std::unique_ptr<void, SSLBioDeleter>;
#ifdef PISTACHE_USE_SSL #ifdef PISTACHE_USE_SSL
inline SSL_CTX* GetSSLContext(ssl::SSLCtxPtr& ctx) inline SSL_CTX* GetSSLContext(ssl::SSLCtxPtr& ctx)
{ {
return reinterpret_cast<SSL_CTX*>(ctx.get()); return reinterpret_cast<SSL_CTX*>(ctx.get());
} }
inline BIO* GetSSLBio(ssl::SSLBioPtr& ctx) inline BIO* GetSSLBio(ssl::SSLBioPtr& ctx)
{ {
return reinterpret_cast<BIO*>(ctx.get()); return reinterpret_cast<BIO*>(ctx.get());
} }
#endif #endif
} } // namespace Pistache::ssl
}
...@@ -10,45 +10,42 @@ ...@@ -10,45 +10,42 @@
#include <iostream> #include <iostream>
#include <memory> #include <memory>
namespace Pistache namespace Pistache::Log
{ {
namespace Log
enum class Level {
TRACE,
DEBUG,
INFO,
WARN,
ERROR,
FATAL
};
class StringLogger
{ {
public:
virtual void log(Level level, const std::string& message) = 0;
virtual bool isEnabledFor(Level level) const = 0;
enum class Level { virtual ~StringLogger() { }
TRACE, };
DEBUG,
INFO, class StringToStreamLogger : public StringLogger
WARN, {
ERROR, public:
FATAL explicit StringToStreamLogger(Level level, std::ostream* out = &std::cerr)
}; : level_(level)
, out_(out)
class StringLogger { }
{ ~StringToStreamLogger() override { }
public:
virtual void log(Level level, const std::string& message) = 0; void log(Level level, const std::string& message) override;
virtual bool isEnabledFor(Level level) const = 0; bool isEnabledFor(Level level) const override;
virtual ~StringLogger() { } private:
}; Level level_;
std::ostream* out_;
class StringToStreamLogger : public StringLogger };
{
public: } // namespace Pistache::Log
explicit StringToStreamLogger(Level level, std::ostream* out = &std::cerr)
: level_(level)
, out_(out)
{ }
~StringToStreamLogger() override { }
void log(Level level, const std::string& message) override;
bool isEnabledFor(Level level) const override;
private:
Level level_;
std::ostream* out_;
};
} // namespace Log
} // namespace Pistache
...@@ -13,54 +13,51 @@ ...@@ -13,54 +13,51 @@
#include <pistache/flags.h> #include <pistache/flags.h>
#include <pistache/prototype.h> #include <pistache/prototype.h>
namespace Pistache namespace Pistache::Tcp
{ {
namespace Tcp
{
class Peer; class Peer;
class Transport; class Transport;
enum class Options : uint64_t { enum class Options : uint64_t {
None = 0, None = 0,
NoDelay = 1, NoDelay = 1,
Linger = NoDelay << 1, Linger = NoDelay << 1,
FastOpen = Linger << 1, FastOpen = Linger << 1,
QuickAck = FastOpen << 1, QuickAck = FastOpen << 1,
ReuseAddr = QuickAck << 1, ReuseAddr = QuickAck << 1,
ReusePort = ReuseAddr << 1, ReusePort = ReuseAddr << 1,
CloseOnExec = ReusePort << 1, CloseOnExec = ReusePort << 1,
}; };
DECLARE_FLAGS_OPERATORS(Options) DECLARE_FLAGS_OPERATORS(Options)
class Handler : public Prototype<Handler> class Handler : public Prototype<Handler>
{ {
public: public:
friend class Transport; friend class Transport;
Handler(); Handler();
virtual ~Handler(); virtual ~Handler();
virtual void onInput(const char* buffer, size_t len, virtual void onInput(const char* buffer, size_t len,
const std::shared_ptr<Tcp::Peer>& peer) const std::shared_ptr<Tcp::Peer>& peer)
= 0; = 0;
virtual void onConnection(const std::shared_ptr<Tcp::Peer>& peer); virtual void onConnection(const std::shared_ptr<Tcp::Peer>& peer);
virtual void onDisconnection(const std::shared_ptr<Tcp::Peer>& peer); virtual void onDisconnection(const std::shared_ptr<Tcp::Peer>& peer);
private: private:
void associateTransport(Transport* transport); void associateTransport(Transport* transport);
Transport* transport_; Transport* transport_;
protected: protected:
Transport* transport() Transport* transport()
{ {
if (!transport_) if (!transport_)
throw std::logic_error("Orphaned handler"); throw std::logic_error("Orphaned handler");
return transport_; return transport_;
} }
}; };
} // namespace Tcp } // namespace Pistache::Tcp
} // namespace Pistache
This diff is collapsed.
...@@ -6,13 +6,10 @@ ...@@ -6,13 +6,10 @@
#pragma once #pragma once
namespace Pistache { namespace Pistache::Version {
namespace Version {
static constexpr int Major = @VERSION_MAJOR@; static constexpr int Major = @VERSION_MAJOR@;
static constexpr int Minor = @VERSION_MINOR@; static constexpr int Minor = @VERSION_MINOR@;
static constexpr int Patch = @VERSION_PATCH@; static constexpr int Patch = @VERSION_PATCH@;
static constexpr int Git = @VERSION_GIT_DATE@; static constexpr int Git = @VERSION_GIT_DATE@;
} // namespace Version } // namespace Pistache::Version
} // namespace Pistache
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -9,23 +9,20 @@ ...@@ -9,23 +9,20 @@
#include <pistache/string_logger.h> #include <pistache/string_logger.h>
namespace Pistache namespace Pistache::Log
{ {
namespace Log
{
void StringToStreamLogger::log(Level level, const std::string& message) void StringToStreamLogger::log(Level level, const std::string& message)
{
if (out_ && isEnabledFor(level))
{ {
if (out_ && isEnabledFor(level)) (*out_) << message << std::endl;
{
(*out_) << message << std::endl;
}
} }
}
bool StringToStreamLogger::isEnabledFor(Level level) const bool StringToStreamLogger::isEnabledFor(Level level) const
{ {
return static_cast<int>(level) >= static_cast<int>(level_); return static_cast<int>(level) >= static_cast<int>(level_);
} }
} // namespace Log } // namespace Pistache::Log
} // namespace Pistache
...@@ -7,31 +7,28 @@ ...@@ -7,31 +7,28 @@
#include <pistache/peer.h> #include <pistache/peer.h>
#include <pistache/tcp.h> #include <pistache/tcp.h>
namespace Pistache namespace Pistache::Tcp
{ {
namespace Tcp
{
Handler::Handler() Handler::Handler()
: transport_(nullptr) : transport_(nullptr)
{ } { }
Handler::~Handler() { } Handler::~Handler() { }
void Handler::associateTransport(Transport* transport) void Handler::associateTransport(Transport* transport)
{ {
transport_ = transport; transport_ = transport;
} }
void Handler::onConnection(const std::shared_ptr<Tcp::Peer>& peer) void Handler::onConnection(const std::shared_ptr<Tcp::Peer>& peer)
{ {
UNUSED(peer) UNUSED(peer)
} }
void Handler::onDisconnection(const std::shared_ptr<Tcp::Peer>& peer) void Handler::onDisconnection(const std::shared_ptr<Tcp::Peer>& peer)
{ {
UNUSED(peer) UNUSED(peer)
} }
} // namespace Tcp } // namespace Pistache::Tcp
} // namespace Pistache
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment