Merge pull request #65 from mrozigor/moredocs

documented as much as possible relating to the API reference
This commit is contained in:
Farook Al-Sammarraie 2020-11-20 15:34:21 +03:00 committed by GitHub
commit dce8e63646
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 92 additions and 32 deletions

View File

@ -4,6 +4,7 @@ Crow is a C++ microframework for web. (inspired by Python Flask)
[![Build Status](https://travis-ci.com/mrozigor/crow.svg?branch=master)](https://travis-ci.com/mrozigor/crow) [![Build Status](https://travis-ci.com/mrozigor/crow.svg?branch=master)](https://travis-ci.com/mrozigor/crow)
[![Coverage Status](https://coveralls.io/repos/github/mrozigor/crow/badge.svg?branch=master)](https://coveralls.io/github/mrozigor/crow?branch=master) [![Coverage Status](https://coveralls.io/repos/github/mrozigor/crow/badge.svg?branch=master)](https://coveralls.io/github/mrozigor/crow?branch=master)
[![Documentation](https://img.shields.io/badge/-Documentation-informational)](https://mrozigor.github.io/crow)
[![Gitter](https://badges.gitter.im/crowfork/community.svg)](https://gitter.im/crowfork/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Gitter](https://badges.gitter.im/crowfork/community.svg)](https://gitter.im/crowfork/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
```c++ ```c++
@ -38,6 +39,8 @@ int main()
- Websocket support - Websocket support
## Still in development ## Still in development
- [Informational webpage](https://mrozigor.github.io/crow) (what is crow, guides, examples, etc..)
- [HTTP/2 support](https://github.com/mrozigor/crow/issues/8)
- ~~Built-in ORM~~ - ~~Built-in ORM~~
- Check [sqlpp11](https://github.com/rbock/sqlpp11) if you want one. - Check [sqlpp11](https://github.com/rbock/sqlpp11) if you want one.

View File

@ -6,6 +6,7 @@
namespace crow namespace crow
{ {
/// Hashing function for ci_map (unordered_multimap).
struct ci_hash struct ci_hash
{ {
size_t operator()(const std::string& key) const size_t operator()(const std::string& key) const
@ -22,6 +23,7 @@ namespace crow
} }
}; };
/// Equals function for ci_map (unordered_multimap).
struct ci_key_eq struct ci_key_eq
{ {
bool operator()(const std::string& l, const std::string& r) const bool operator()(const std::string& l, const std::string& r) const

View File

@ -178,6 +178,8 @@ namespace crow
#ifdef CROW_ENABLE_DEBUG #ifdef CROW_ENABLE_DEBUG
static std::atomic<int> connectionCount; static std::atomic<int> connectionCount;
#endif #endif
/// An HTTP connection.
template <typename Adaptor, typename Handler, typename ... Middlewares> template <typename Adaptor, typename Handler, typename ... Middlewares>
class Connection class Connection
{ {
@ -216,6 +218,7 @@ namespace crow
#endif #endif
} }
/// The TCP socket on top of which the connection is established.
decltype(std::declval<Adaptor>().raw_socket())& socket() decltype(std::declval<Adaptor>().raw_socket())& socket()
{ {
return adaptor_.raw_socket(); return adaptor_.raw_socket();
@ -336,6 +339,7 @@ namespace crow
} }
} }
/// Call the after handle middleware and send the write the response to the connection.
void complete_request() void complete_request()
{ {
CROW_LOG_INFO << "Response: " << this << ' ' << req_.raw_url << ' ' << res.code << ' ' << close_connection_; CROW_LOG_INFO << "Response: " << this << ' ' << req_.raw_url << ' ' << res.code << ' ' << close_connection_;

View File

@ -26,12 +26,12 @@ namespace crow
struct request struct request
{ {
HTTPMethod method; HTTPMethod method;
std::string raw_url; /// The full URL containing the host. std::string raw_url; ///< The full URL containing the host.
std::string url; /// The Endpoint. std::string url; ///< The Endpoint.
query_string url_params; /// The parameters associated with the request. (everything after the `?`) query_string url_params; ///< The parameters associated with the request. (everything after the `?`)
ci_map headers; ci_map headers;
std::string body; std::string body;
std::string remoteIpAddress; /// The IP address from which the request was sent. std::string remoteIpAddress; ///< The IP address from which the request was sent.
void* middleware_context{}; void* middleware_context{};
boost::asio::io_service* io_service{}; boost::asio::io_service* io_service{};

View File

@ -26,10 +26,10 @@ namespace crow
template <typename Adaptor, typename Handler, typename ... Middlewares> template <typename Adaptor, typename Handler, typename ... Middlewares>
friend class crow::Connection; friend class crow::Connection;
int code{200}; /// The Status code for the response. int code{200}; ///< The Status code for the response.
std::string body; /// The actual payload containing the response data. std::string body; ///< The actual payload containing the response data.
json::wvalue json_value; /// if the response body is JSON, this would be it. json::wvalue json_value; ///< if the response body is JSON, this would be it.
ci_map headers; /// HTTP headers. ci_map headers; ///< HTTP headers.
/// Set the value of an existing header in the response. /// Set the value of an existing header in the response.
void set_header(std::string key, std::string value) void set_header(std::string key, std::string value)

View File

@ -108,7 +108,7 @@ namespace crow
namespace detail namespace detail
{ {
/// A read string implementation with comparison functionality.
struct r_string struct r_string
: boost::less_than_comparable<r_string>, : boost::less_than_comparable<r_string>,
boost::less_than_comparable<r_string, std::string>, boost::less_than_comparable<r_string, std::string>,
@ -166,8 +166,8 @@ namespace crow
using iterator = const char*; using iterator = const char*;
using const_iterator = const char*; using const_iterator = const char*;
char* s_; char* s_; ///< Start.
mutable char* e_; mutable char* e_; ///< End.
uint8_t owned_{0}; uint8_t owned_{0};
friend std::ostream& operator << (std::ostream& os, const r_string& s) friend std::ostream& operator << (std::ostream& os, const r_string& s)
{ {
@ -210,6 +210,11 @@ namespace crow
} }
} }
/// JSON read value.
///
/// Value can mean any json value, including a JSON object.
/// Read means this class is used to primarily read strings into a JSON value.
class rvalue class rvalue
{ {
static const int cached_bit = 2; static const int cached_bit = 2;
@ -289,6 +294,7 @@ namespace crow
return (int)i(); return (int)i();
} }
/// The type of the JSON value.
type t() const type t() const
{ {
#ifndef CROW_JSON_NO_ERROR_CHECK #ifndef CROW_JSON_NO_ERROR_CHECK
@ -300,6 +306,7 @@ namespace crow
return t_; return t_;
} }
/// The number type of the JSON value.
num_type nt() const num_type nt() const
{ {
#ifndef CROW_JSON_NO_ERROR_CHECK #ifndef CROW_JSON_NO_ERROR_CHECK
@ -311,6 +318,7 @@ namespace crow
return nt_; return nt_;
} }
/// The integer value.
int64_t i() const int64_t i() const
{ {
#ifndef CROW_JSON_NO_ERROR_CHECK #ifndef CROW_JSON_NO_ERROR_CHECK
@ -327,6 +335,7 @@ namespace crow
return boost::lexical_cast<int64_t>(start_, end_-start_); return boost::lexical_cast<int64_t>(start_, end_-start_);
} }
/// The unsigned integer value.
uint64_t u() const uint64_t u() const
{ {
#ifndef CROW_JSON_NO_ERROR_CHECK #ifndef CROW_JSON_NO_ERROR_CHECK
@ -341,6 +350,7 @@ namespace crow
return boost::lexical_cast<uint64_t>(start_, end_-start_); return boost::lexical_cast<uint64_t>(start_, end_-start_);
} }
/// The double precision floating-point number value.
double d() const double d() const
{ {
#ifndef CROW_JSON_NO_ERROR_CHECK #ifndef CROW_JSON_NO_ERROR_CHECK
@ -350,6 +360,7 @@ namespace crow
return boost::lexical_cast<double>(start_, end_-start_); return boost::lexical_cast<double>(start_, end_-start_);
} }
/// The boolean value.
bool b() const bool b() const
{ {
#ifndef CROW_JSON_NO_ERROR_CHECK #ifndef CROW_JSON_NO_ERROR_CHECK
@ -359,6 +370,18 @@ namespace crow
return t() == type::True; return t() == type::True;
} }
/// The string value.
detail::r_string s() const
{
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::String)
throw std::runtime_error("value is not string");
#endif
unescape();
return detail::r_string{start_, end_};
}
/// Convert escaped string character to their original form ("\\n" -> '\n').
void unescape() const void unescape() const
{ {
if (*(start_-1)) if (*(start_-1))
@ -424,16 +447,6 @@ namespace crow
} }
} }
detail::r_string s() const
{
#ifndef CROW_JSON_NO_ERROR_CHECK
if (t() != type::String)
throw std::runtime_error("value is not string");
#endif
unescape();
return detail::r_string{start_, end_};
}
bool has(const char* str) const bool has(const char* str) const
{ {
return has(std::string(str)); return has(std::string(str));
@ -615,7 +628,7 @@ namespace crow
lremain_ --; lremain_ --;
} }
// determines num_type from the string /// determines num_type from the string.
void determine_num_type() void determine_num_type()
{ {
if (t_ != type::Number) if (t_ != type::Number)
@ -1142,26 +1155,31 @@ namespace crow
return load(str.data(), str.size()); return load(str.data(), str.size());
} }
/// JSON write value.
///
/// Value can mean any json value, including a JSON object.
/// Write means this class is used to primarily assemble JSON objects using keys and values and export those into a string.
class wvalue class wvalue
{ {
friend class crow::mustache::template_t; friend class crow::mustache::template_t;
public: public:
type t() const { return t_; } type t() const { return t_; }
private: private:
type t_{type::Null}; type t_{type::Null}; ///< The type of the value.
num_type nt{num_type::Null}; num_type nt{num_type::Null}; ///< The specific type of the number if \ref t_ is a number.
union { union {
double d; double d;
int64_t si; int64_t si;
uint64_t ui {}; uint64_t ui {};
} num; } num; ///< Value if type is a number.
std::string s; std::string s; ///< Value if type is a string.
std::unique_ptr<std::vector<wvalue>> l; std::unique_ptr<std::vector<wvalue>> l; ///< Value if type is a list.
std::unique_ptr<std::unordered_map<std::string, wvalue>> o; std::unique_ptr<std::unordered_map<std::string, wvalue>> o; ///< Value if type is a JSON object.
public: public:
wvalue() {} wvalue() {}
/// Create a write value from a read value (useful for editing JSON strings).
wvalue(const rvalue& r) wvalue(const rvalue& r)
{ {
t_ = r.t(); t_ = r.t();
@ -1215,6 +1233,7 @@ namespace crow
return *this; return *this;
} }
/// Used for compatibility, same as \ref reset()
void clear() void clear()
{ {
reset(); reset();

View File

@ -8,6 +8,8 @@ namespace crow
{ {
namespace detail namespace detail
{ {
template <typename ... Middlewares> template <typename ... Middlewares>
struct partial_context struct partial_context
: public black_magic::pop_back<Middlewares...>::template rebind<partial_context> : public black_magic::pop_back<Middlewares...>::template rebind<partial_context>
@ -24,6 +26,8 @@ namespace crow
} }
}; };
template <> template <>
struct partial_context<> struct partial_context<>
{ {
@ -31,9 +35,13 @@ namespace crow
using partial = partial_context; using partial = partial_context;
}; };
template <int N, typename Context, typename Container, typename CurrentMW, typename ... Middlewares> template <int N, typename Context, typename Container, typename CurrentMW, typename ... Middlewares>
bool middleware_call_helper(Container& middlewares, request& req, response& res, Context& ctx); bool middleware_call_helper(Container& middlewares, request& req, response& res, Context& ctx);
template <typename ... Middlewares> template <typename ... Middlewares>
struct context : private partial_context<Middlewares...> struct context : private partial_context<Middlewares...>
//struct context : private Middlewares::context... // simple but less type-safe //struct context : private Middlewares::context... // simple but less type-safe

View File

@ -49,6 +49,7 @@ namespace crow
{} {}
}; };
/// A mustache template object.
class template_t class template_t
{ {
public: public:

View File

@ -10,6 +10,10 @@
namespace crow namespace crow
{ {
/// A wrapper for `nodejs/http-parser`.
/// Used to generate a \ref crow.request from the TCP socket buffer.
///
template <typename Handler> template <typename Handler>
struct HTTPParser : public http_parser struct HTTPParser : public http_parser
{ {
@ -93,6 +97,7 @@ namespace crow
} }
// return false on error // return false on error
/// Parse a buffer into the different sections of an HTTP request.
bool feed(const char* buffer, int length) bool feed(const char* buffer, int length)
{ {
const static http_parser_settings settings_{ const static http_parser_settings settings_{
@ -137,6 +142,7 @@ namespace crow
handler_->handle(); handler_->handle();
} }
/// Take the parsed HTTP request data and convert it to a \ref crow.request
request to_request() const request to_request() const
{ {
return request{(HTTPMethod)method, std::move(raw_url), std::move(url), std::move(url_params), std::move(headers), std::move(body)}; return request{(HTTPMethod)method, std::move(raw_url), std::move(url), std::move(url_params), std::move(headers), std::move(body)};
@ -159,9 +165,9 @@ namespace crow
std::string header_field; std::string header_field;
std::string header_value; std::string header_value;
ci_map headers; ci_map headers;
query_string url_params; query_string url_params; ///< What comes after the `?` in the URL.
std::string body; std::string body;
Handler* handler_; Handler* handler_; ///< This is currently an HTTP connection object (\ref crow.Connection).
}; };
} }

View File

@ -287,6 +287,7 @@ inline char * qs_scanvalue(const char * key, const char * qs, char * val, size_t
namespace crow namespace crow
{ {
/// A class to represent any data coming after the `?` in the request URL into key-value pairs.
class query_string class query_string
{ {
public: public:

View File

@ -17,6 +17,10 @@
namespace crow namespace crow
{ {
/// A base class for all rules.
/// Used to provide a common interface for code dealing with different types of rules.
/// A Rule provides a URL, allowed HTTP methods, and handlers.
class BaseRule class BaseRule
{ {
public: public:
@ -267,6 +271,10 @@ namespace crow
} }
} }
/// A rule dealing with websockets.
/// Provides the interface for the user to put in the necessary handlers for a websocket to work.
///
class WebSocketRule : public BaseRule class WebSocketRule : public BaseRule
{ {
using self_t = WebSocketRule; using self_t = WebSocketRule;
@ -340,6 +348,9 @@ namespace crow
std::function<bool(const crow::request&)> accept_handler_; std::function<bool(const crow::request&)> accept_handler_;
}; };
/// Allows the user to assign parameters using functions.
///
/// `rule.name("name").methods(HTTPMethod::POST)`
template <typename T> template <typename T>
struct RuleParameterTraits struct RuleParameterTraits
{ {
@ -373,6 +384,7 @@ namespace crow
}; };
/// A rule that can change its parameters during runtime.
class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule> class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule>
{ {
public: public:
@ -447,6 +459,7 @@ namespace crow
}; };
/// Default rule created when CROW_ROUTE is called.
template <typename ... Args> template <typename ... Args>
class TaggedRule : public BaseRule, public RuleParameterTraits<TaggedRule<Args...>> class TaggedRule : public BaseRule, public RuleParameterTraits<TaggedRule<Args...>>
{ {
@ -560,6 +573,7 @@ namespace crow
const int RULE_SPECIAL_REDIRECT_SLASH = 1; const int RULE_SPECIAL_REDIRECT_SLASH = 1;
/// A search tree.
class Trie class Trie
{ {
public: public:
@ -888,6 +902,7 @@ public:
std::vector<Node> nodes_; std::vector<Node> nodes_;
}; };
/// Handles matching requests to existing rules and upgrade requests.
class Router class Router
{ {
public: public:
@ -931,7 +946,7 @@ public:
per_methods_[method].trie.add(rule, per_methods_[method].rules.size() - 1); per_methods_[method].trie.add(rule, per_methods_[method].rules.size() - 1);
// directory case: // directory case:
// request to `/about' url matches `/about/' rule // request to '/about' url matches '/about/' rule
if (has_trailing_slash) if (has_trailing_slash)
{ {
per_methods_[method].trie.add(rule_without_trailing_slash, RULE_SPECIAL_REDIRECT_SLASH); per_methods_[method].trie.add(rule_without_trailing_slash, RULE_SPECIAL_REDIRECT_SLASH);

View File

@ -24,6 +24,7 @@ namespace crow
return i >= len ? throw OutOfRange(i, len) : i; return i >= len ? throw OutOfRange(i, len) : i;
} }
/// A constant string implementation.
class const_str class const_str
{ {
const char * const begin_; const char * const begin_;