Nested namespaces

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