diff --git a/README.md b/README.md index c0d4e2f36..b75081f77 100644 --- a/README.md +++ b/README.md @@ -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) [![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) ```c++ @@ -38,6 +39,8 @@ int main() - Websocket support ## 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~~ - Check [sqlpp11](https://github.com/rbock/sqlpp11) if you want one. diff --git a/include/crow/ci_map.h b/include/crow/ci_map.h index 155d54f72..4bf055ff1 100644 --- a/include/crow/ci_map.h +++ b/include/crow/ci_map.h @@ -6,6 +6,7 @@ namespace crow { + /// Hashing function for ci_map (unordered_multimap). struct ci_hash { 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 { bool operator()(const std::string& l, const std::string& r) const diff --git a/include/crow/http_connection.h b/include/crow/http_connection.h index 93b9b1e46..d000db97e 100644 --- a/include/crow/http_connection.h +++ b/include/crow/http_connection.h @@ -178,6 +178,8 @@ namespace crow #ifdef CROW_ENABLE_DEBUG static std::atomic connectionCount; #endif + + /// An HTTP connection. template class Connection { @@ -216,6 +218,7 @@ namespace crow #endif } + /// The TCP socket on top of which the connection is established. decltype(std::declval().raw_socket())& 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() { CROW_LOG_INFO << "Response: " << this << ' ' << req_.raw_url << ' ' << res.code << ' ' << close_connection_; diff --git a/include/crow/http_request.h b/include/crow/http_request.h index 4bc92fd78..e625b6b2a 100644 --- a/include/crow/http_request.h +++ b/include/crow/http_request.h @@ -26,12 +26,12 @@ namespace crow struct request { HTTPMethod method; - std::string raw_url; /// The full URL containing the host. - std::string url; /// The Endpoint. - query_string url_params; /// The parameters associated with the request. (everything after the `?`) + std::string raw_url; ///< The full URL containing the host. + std::string url; ///< The Endpoint. + query_string url_params; ///< The parameters associated with the request. (everything after the `?`) ci_map headers; 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{}; boost::asio::io_service* io_service{}; diff --git a/include/crow/http_response.h b/include/crow/http_response.h index 0b46aaecb..e3fc39a38 100644 --- a/include/crow/http_response.h +++ b/include/crow/http_response.h @@ -26,10 +26,10 @@ namespace crow template friend class crow::Connection; - int code{200}; /// The Status code for the response. - std::string body; /// The actual payload containing the response data. - json::wvalue json_value; /// if the response body is JSON, this would be it. - ci_map headers; /// HTTP headers. + int code{200}; ///< The Status code for the response. + std::string body; ///< The actual payload containing the response data. + json::wvalue json_value; ///< if the response body is JSON, this would be it. + ci_map headers; ///< HTTP headers. /// Set the value of an existing header in the response. void set_header(std::string key, std::string value) diff --git a/include/crow/json.h b/include/crow/json.h index 4c217d0c1..2bed8330d 100644 --- a/include/crow/json.h +++ b/include/crow/json.h @@ -108,7 +108,7 @@ namespace crow namespace detail { - + /// A read string implementation with comparison functionality. struct r_string : boost::less_than_comparable, boost::less_than_comparable, @@ -166,8 +166,8 @@ namespace crow using iterator = const char*; using const_iterator = const char*; - char* s_; - mutable char* e_; + char* s_; ///< Start. + mutable char* e_; ///< End. uint8_t owned_{0}; 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 { static const int cached_bit = 2; @@ -289,6 +294,7 @@ namespace crow return (int)i(); } + /// The type of the JSON value. type t() const { #ifndef CROW_JSON_NO_ERROR_CHECK @@ -300,6 +306,7 @@ namespace crow return t_; } + /// The number type of the JSON value. num_type nt() const { #ifndef CROW_JSON_NO_ERROR_CHECK @@ -311,6 +318,7 @@ namespace crow return nt_; } + /// The integer value. int64_t i() const { #ifndef CROW_JSON_NO_ERROR_CHECK @@ -327,6 +335,7 @@ namespace crow return boost::lexical_cast(start_, end_-start_); } + /// The unsigned integer value. uint64_t u() const { #ifndef CROW_JSON_NO_ERROR_CHECK @@ -341,6 +350,7 @@ namespace crow return boost::lexical_cast(start_, end_-start_); } + /// The double precision floating-point number value. double d() const { #ifndef CROW_JSON_NO_ERROR_CHECK @@ -350,6 +360,7 @@ namespace crow return boost::lexical_cast(start_, end_-start_); } + /// The boolean value. bool b() const { #ifndef CROW_JSON_NO_ERROR_CHECK @@ -359,6 +370,18 @@ namespace crow 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 { 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 { return has(std::string(str)); @@ -615,7 +628,7 @@ namespace crow lremain_ --; } - // determines num_type from the string + /// determines num_type from the string. void determine_num_type() { if (t_ != type::Number) @@ -1142,26 +1155,31 @@ namespace crow 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 { friend class crow::mustache::template_t; public: type t() const { return t_; } private: - type t_{type::Null}; - num_type nt{num_type::Null}; + type t_{type::Null}; ///< The type of the value. + num_type nt{num_type::Null}; ///< The specific type of the number if \ref t_ is a number. union { double d; int64_t si; uint64_t ui {}; - } num; - std::string s; - std::unique_ptr> l; - std::unique_ptr> o; + } num; ///< Value if type is a number. + std::string s; ///< Value if type is a string. + std::unique_ptr> l; ///< Value if type is a list. + std::unique_ptr> o; ///< Value if type is a JSON object. public: wvalue() {} - + /// Create a write value from a read value (useful for editing JSON strings). wvalue(const rvalue& r) { t_ = r.t(); @@ -1215,6 +1233,7 @@ namespace crow return *this; } + /// Used for compatibility, same as \ref reset() void clear() { reset(); diff --git a/include/crow/middleware_context.h b/include/crow/middleware_context.h index 6885c139d..b4924c820 100644 --- a/include/crow/middleware_context.h +++ b/include/crow/middleware_context.h @@ -8,6 +8,8 @@ namespace crow { namespace detail { + + template struct partial_context : public black_magic::pop_back::template rebind @@ -24,6 +26,8 @@ namespace crow } }; + + template <> struct partial_context<> { @@ -31,9 +35,13 @@ namespace crow using partial = partial_context; }; + + template bool middleware_call_helper(Container& middlewares, request& req, response& res, Context& ctx); + + template struct context : private partial_context //struct context : private Middlewares::context... // simple but less type-safe diff --git a/include/crow/mustache.h b/include/crow/mustache.h index f722af6b0..a76140c1f 100644 --- a/include/crow/mustache.h +++ b/include/crow/mustache.h @@ -49,6 +49,7 @@ namespace crow {} }; + /// A mustache template object. class template_t { public: diff --git a/include/crow/parser.h b/include/crow/parser.h index 61f5aeeaa..aa3e56201 100644 --- a/include/crow/parser.h +++ b/include/crow/parser.h @@ -10,6 +10,10 @@ namespace crow { + /// A wrapper for `nodejs/http-parser`. + + /// Used to generate a \ref crow.request from the TCP socket buffer. + /// template struct HTTPParser : public http_parser { @@ -93,6 +97,7 @@ namespace crow } // return false on error + /// Parse a buffer into the different sections of an HTTP request. bool feed(const char* buffer, int length) { const static http_parser_settings settings_{ @@ -137,6 +142,7 @@ namespace crow handler_->handle(); } + /// Take the parsed HTTP request data and convert it to a \ref crow.request 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)}; @@ -159,9 +165,9 @@ namespace crow std::string header_field; std::string header_value; ci_map headers; - query_string url_params; + query_string url_params; ///< What comes after the `?` in the URL. std::string body; - Handler* handler_; + Handler* handler_; ///< This is currently an HTTP connection object (\ref crow.Connection). }; } diff --git a/include/crow/query_string.h b/include/crow/query_string.h index ee61e30af..c3931a4bf 100644 --- a/include/crow/query_string.h +++ b/include/crow/query_string.h @@ -287,6 +287,7 @@ inline char * qs_scanvalue(const char * key, const char * qs, char * val, size_t namespace crow { + /// A class to represent any data coming after the `?` in the request URL into key-value pairs. class query_string { public: diff --git a/include/crow/routing.h b/include/crow/routing.h index 0ddf72dfa..f8f68b0cd 100644 --- a/include/crow/routing.h +++ b/include/crow/routing.h @@ -17,6 +17,10 @@ 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 { 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 { using self_t = WebSocketRule; @@ -340,6 +348,9 @@ namespace crow std::function accept_handler_; }; + /// Allows the user to assign parameters using functions. + /// + /// `rule.name("name").methods(HTTPMethod::POST)` template struct RuleParameterTraits { @@ -373,6 +384,7 @@ namespace crow }; + /// A rule that can change its parameters during runtime. class DynamicRule : public BaseRule, public RuleParameterTraits { public: @@ -447,6 +459,7 @@ namespace crow }; + /// Default rule created when CROW_ROUTE is called. template class TaggedRule : public BaseRule, public RuleParameterTraits> { @@ -560,6 +573,7 @@ namespace crow const int RULE_SPECIAL_REDIRECT_SLASH = 1; + /// A search tree. class Trie { public: @@ -888,6 +902,7 @@ public: std::vector nodes_; }; + /// Handles matching requests to existing rules and upgrade requests. class Router { public: @@ -931,7 +946,7 @@ public: per_methods_[method].trie.add(rule, per_methods_[method].rules.size() - 1); // directory case: - // request to `/about' url matches `/about/' rule + // request to '/about' url matches '/about/' rule if (has_trailing_slash) { per_methods_[method].trie.add(rule_without_trailing_slash, RULE_SPECIAL_REDIRECT_SLASH); diff --git a/include/crow/utility.h b/include/crow/utility.h index 43503e810..0e6d2af53 100644 --- a/include/crow/utility.h +++ b/include/crow/utility.h @@ -24,6 +24,7 @@ namespace crow return i >= len ? throw OutOfRange(i, len) : i; } + /// A constant string implementation. class const_str { const char * const begin_;