More API docs

This commit is contained in:
lganzzzo 2019-03-20 03:38:53 +02:00
parent 9f756c0f89
commit c3f6a09d7b
19 changed files with 994 additions and 172 deletions

View File

@ -30,17 +30,40 @@
namespace oatpp { namespace concurrency {
/**
* SpinLock implementation based on atomic.
*/
class SpinLock {
public:
/**
* Convenience typedef for atomic bool.
*/
typedef std::atomic<bool> Atom;
private:
Atom* m_atom;
public:
/**
* Constructor. Lock on construction.
* @param atom - atomic boolean.
*/
SpinLock(Atom& atom);
/**
* Non virtual destructor. Unlock on destruction.
*/
~SpinLock();
/**
* Spin-Lock using atomic boolean.
* @param atom - atomic boolean.
*/
static void lock(Atom& atom);
/**
* Spin-Unlock using atomic boolean.
* @param atom - atomic boolean.
*/
static void unlock(Atom& atom);
};

View File

@ -29,15 +29,19 @@
namespace oatpp { namespace data {
/**
* Represents I/O handle (ex.: file descriptor).
*/
typedef int v_io_handle;
/**
* All I/O buffer operations (like read/write(buffer, size)) should return
* v_io_size.
* All I/O buffer operations (like read/write(buffer, size)) should return v_io_size. <br>
*
* Possible return values:
* On Success - [1..max_int64]
* On Error - IOError values.
* <ul>
* <li>**On Success** - [1..max_int64].</li>
* <li>**On Error** - IOError values.</li>
* </ul>
*
* All other values are considered to be a fatal error.
* application should be terminated.

View File

@ -48,6 +48,9 @@ namespace __class {
}
/**
* Mapping-enables String is &id:oatpp::data::mapping::type::ObjectWrapper; over &id:oatpp::base::StrBuffer;
*/
class String : public oatpp::data::mapping::type::ObjectWrapper<oatpp::base::StrBuffer, __class::String> {
public:
String(const std::shared_ptr<oatpp::base::StrBuffer>& ptr, const type::Type* const valueType);
@ -124,14 +127,22 @@ public:
String operator + (const char* a, const String& b);
String operator + (const String& b, const char* a);
String operator + (const String& a, const String& b);
/**
* Template for primitive mapping-enabled types.
* @tparam ValueType - type of the value ex.: v_int32.
* @tparam Clazz - Class holding static class information.
*/
template<typename ValueType, class Clazz>
class Primitive : public oatpp::base::Countable {
public:
OBJECT_POOL(Primitive_Type_Pool, Primitive, 32)
SHARED_OBJECT_POOL(Shared_Primitive_Type_Pool, Primitive, 32)
public:
/**
* ObjectWrapper template for &l:Primitive;.
*/
class ObjectWrapper : public oatpp::data::mapping::type::ObjectWrapper<Primitive, Clazz> {
public:
ObjectWrapper(const std::shared_ptr<Primitive>& ptr, const type::Type* const valueType)
@ -205,35 +216,84 @@ private:
ValueType m_value;
public:
/**
* Constructor.
* @param value - initial value.
*/
Primitive(const ValueType& value)
: m_value(value)
{}
public:
/**
* Create shared primitive.
* @param value - initial value.
* @return - `std::shared_ptr` to Primitive.
*/
static std::shared_ptr<Primitive> createShared(const ValueType& value){
return Shared_Primitive_Type_Pool::allocateShared(value);
}
/**
* Create shared primitive upcasted to &id:oatpp::base::Countable;.
* @param value - initial value.
* @return - `std::shared_ptr` to primitive upcasted to &id:oatpp::base::Countable;.
*/
static std::shared_ptr<Countable> createAbstract(const ValueType& value){
return std::static_pointer_cast<Countable>(Shared_Primitive_Type_Pool::allocateShared(value));
}
/**
* Set value.
* @param value.
*/
void setValue(const ValueType& value) {
m_value = value;
}
/**
* Get value.
* @return - value.
*/
ValueType getValue() {
return m_value;
}
};
/**
* Int8 is an ObjectWrapper over &l:Primitive; and __class::Int8.
*/
typedef Primitive<v_int8, __class::Int8>::ObjectWrapper Int8;
/**
* Int16 is an ObjectWrapper over &l:Primitive; and __class::Int16.
*/
typedef Primitive<v_int16, __class::Int16>::ObjectWrapper Int16;
/**
* Int32 is an ObjectWrapper over &l:Primitive; and __class::Int32.
*/
typedef Primitive<v_int32, __class::Int32>::ObjectWrapper Int32;
/**
* Int64 is an ObjectWrapper over &l:Primitive; and __class::Int64.
*/
typedef Primitive<v_int64, __class::Int64>::ObjectWrapper Int64;
/**
* Float32 is an ObjectWrapper over &l:Primitive; and __class::Float32.
*/
typedef Primitive<v_float32, __class::Float32>::ObjectWrapper Float32;
/**
* Float64 is an ObjectWrapper over &l:Primitive; and __class::Float64.
*/
typedef Primitive<v_float64, __class::Float64>::ObjectWrapper Float64;
/**
* Boolean is an ObjectWrapper over &l:Primitive; and __class::Boolean.
*/
typedef Primitive<bool, __class::Boolean>::ObjectWrapper Boolean;
namespace __class {

View File

@ -51,45 +51,110 @@ public:
static const char* const ERROR_ASYNC_UNKNOWN_CODE;
};
/**
* Output Stream.
*/
class OutputStream {
public:
/**
* Write data to stream up to count bytes, and return number of bytes actually written
* It is a legal case if return result < count. Caller should handle this!
* @param data - data to write.
* @param count - number of bytes to write.
* @return - actual number of bytes written. &id:oatpp::data::v_io_size;.
*/
virtual data::v_io_size write(const void *data, data::v_io_size count) = 0;
/**
* Same as `write((p_char8)data, std::strlen(data));`.
* @param data - data to write.
* @return - actual number of bytes written. &id:oatpp::data::v_io_size;.
*/
data::v_io_size write(const char* data){
return write((p_char8)data, std::strlen(data));
}
/**
* Same as `write(str->getData(), str->getSize());`
* @param str - data to write.
* @return - actual number of bytes written. &id:oatpp::data::v_io_size;.
*/
data::v_io_size write(const oatpp::String& str){
return write(str->getData(), str->getSize());
}
/**
* Same as `write(&c, 1);`.
* @param c - one char to write.
* @return - actual number of bytes written. &id:oatpp::data::v_io_size;.
*/
data::v_io_size writeChar(v_char8 c){
return write(&c, 1);
}
/**
* Convert value to string and write to stream.
* @param value
* @return - actual number of bytes written. &id:oatpp::data::v_io_size;. <br>
* **Careful!!!** - use this method on your own risk as it's hard to understand if all data was written to stream.
*/
data::v_io_size writeAsString(v_int32 value);
/**
* Convert value to string and write to stream.
* @param value
* @return - actual number of bytes written. &id:oatpp::data::v_io_size;. <br>
* **Careful!!!** - use this method on your own risk as it's hard to understand if all data was written to stream.
*/
data::v_io_size writeAsString(v_int64 value);
/**
* Convert value to string and write to stream.
* @param value
* @return - actual number of bytes written. &id:oatpp::data::v_io_size;. <br>
* **Careful!!!** - use this method on your own risk as it's hard to understand if all data was written to stream.
*/
data::v_io_size writeAsString(v_float32 value);
/**
* Convert value to string and write to stream.
* @param value
* @return - actual number of bytes written. &id:oatpp::data::v_io_size;. <br>
* **Careful!!!** - use this method on your own risk as it's hard to understand if all data was written to stream.
*/
data::v_io_size writeAsString(v_float64 value);
/**
* Convert value to string and write to stream.
* @param value
* @return - actual number of bytes written. &id:oatpp::data::v_io_size;. <br>
* **Careful!!!** - use this method on your own risk as it's hard to understand if all data was written to stream.
*/
data::v_io_size writeAsString(bool value);
};
/**
* Input Stream.
*/
class InputStream {
public:
/**
* Read data from stream up to count bytes, and return number of bytes actually read
* It is a legal case if return result < count. Caller should handle this!
* @param data - buffer to read dat to.
* @param count - size of the buffer.
* @return - actual number of bytes read.
*/
virtual data::v_io_size read(void *data, data::v_io_size count) = 0;
};
/**
* I/O Stream.
*/
class IOStream : public InputStream, public OutputStream {
public:
typedef data::v_io_size v_size;

View File

@ -29,7 +29,10 @@
#include "oatpp/core/data/stream/Stream.hpp"
namespace oatpp { namespace network {
/**
* TCP Connection implementation. Extends &id:oatpp::base::Countable; and &id:oatpp::data::stream::IOStream;.
*/
class Connection : public oatpp::base::Countable, public oatpp::data::stream::IOStream {
public:
OBJECT_POOL(Connection_Pool, Connection, 32);
@ -37,20 +40,53 @@ public:
private:
data::v_io_handle m_handle;
public:
/**
* Constructor.
* @param handle - file descriptor (socket handle). See &id:oatpp::data::v_io_handle;.
*/
Connection(data::v_io_handle handle);
public:
/**
* Create shared Connection.
* @param handle - file descriptor (socket handle). See &id:oatpp::data::v_io_handle;.
* @return - shared_ptr to Connection.
*/
static std::shared_ptr<Connection> createShared(data::v_io_handle handle){
return Shared_Connection_Pool::allocateShared(handle);
}
/**
* Virtual Destructor (See &id:oatpp::base::Countable;).
* Close socket handle.
*/
~Connection();
/**
* Implementation of &id:oatpp::data::stream::IOStream::write;.
* @param buff - buffer containing data to write.
* @param count - bytes count you want to write.
* @return - actual amount of bytes written. See &id:oatpp::data::v_io_size;.
*/
data::v_io_size write(const void *buff, data::v_io_size count) override;
/**
* Implementation of &id:oatpp::data::stream::IOStream::read;.
* @param buff - buffer to read data to.
* @param count - buffer size.
* @return - actual amount of bytes read. See &id:oatpp::data::v_io_size;.
*/
data::v_io_size read(void *buff, data::v_io_size count) override;
/**
* Close socket handle.
*/
void close();
/**
* Get socket handle.
* @return - socket handle. &id:oatpp::data::v_io_handle;.
*/
data::v_io_handle getHandle(){
return m_handle;
}

View File

@ -33,30 +33,63 @@
namespace oatpp { namespace network {
/**
* Abstract ConnectionProvider.
* It may be anything that returns oatpp::data::stream::IOStream
* Abstract ConnectionProvider. <br>
* Basically it returns whatever stream (&id:oatpp::data::stream::IOStream;). <br>
* User of ConnectionProvider should care about IOStream only.
* All other properties are optional
* All other properties are optional.
*/
class ConnectionProvider {
public:
/**
* Predefined property key for HOST.
*/
static const char* const PROPERTY_HOST;
/**
* Predefined property key for PORT.
*/
static const char* const PROPERTY_PORT;
public:
/**
* Convenience typedef for &id:oatpp::data::stream::IOStream;.
*/
typedef oatpp::data::stream::IOStream IOStream;
/**
* Convenience typedef for &id:oatpp::async::Action;.
*/
typedef oatpp::async::Action Action;
typedef oatpp::async::Action (oatpp::async::AbstractCoroutine::*AsyncCallback)(const std::shared_ptr<IOStream>&);
private:
std::unordered_map<oatpp::data::share::StringKeyLabelCI, oatpp::data::share::StringKeyLabel> m_properties;
protected:
/**
/*
* Set optional property
*/
void setProperty(const oatpp::String& key, const oatpp::String& value);
public:
virtual ~ConnectionProvider() {}
/**
* Virtual default destructor.
*/
virtual ~ConnectionProvider() = default;
/**
* Implement this method.
* Get IOStream representing connection to resource.
* @return - &id:oatpp::data::stream::IOStream;.
*/
virtual std::shared_ptr<IOStream> getConnection() = 0;
/**
* Implement this method.
* Obtain IOStream representing connection to resource.
* IOStream should be returned as a parameter to callback.
* @param parentCoroutine - caller coroutine. &id:oatpp::async::AbstractCoroutine;.
* @param callback - pointer to callback function.
* @return - &id:oatpp::async::Action;.
*/
virtual Action getConnectionAsync(oatpp::async::AbstractCoroutine* parentCoroutine,
AsyncCallback callback) = 0;
@ -66,8 +99,8 @@ public:
virtual void close() = 0;
/**
* Some optional properties that user might want to know.
* All properties are optional and user should not rely on this
* Some optional properties that user might want to know. <br>
* Note: All properties are optional and user should not rely on this.
*/
const std::unordered_map<oatpp::data::share::StringKeyLabelCI, oatpp::data::share::StringKeyLabel>& getProperties();

View File

@ -35,67 +35,97 @@
namespace oatpp { namespace network {
// TODO - refactor to use oatpp::data::share::MemoryLabel
/**
* Class holding URL information.
*/
class Url : public oatpp::base::Countable {
public:
/**
* Convenience typedef for &id:oatpp::data::share::StringKeyLabel;.
*/
typedef oatpp::data::share::StringKeyLabel StringKeyLabel;
public:
/**
* Parameters - map string to string.
*/
typedef std::unordered_map<oatpp::String, oatpp::String> Parameters;
/**
* Parameters as &id:oatpp::data::share::StringKeyLabel;.
* Advantage of oatpp::data::share::StringKeyLabel - is that there is no memory allocations needed to create "Memory Label".
*/
typedef std::unordered_map<StringKeyLabel, StringKeyLabel> ParametersAsLabels;
public:
/**
* Structure representing URL Authority information.
*/
struct Authority {
/**
* User info.
*/
oatpp::String userInfo;
/**
* Host.
*/
oatpp::String host;
/**
* Port. Treat -1 as undefined or as default.
*/
v_int32 port = -1;
};
public:
/**
* Url parser.
*/
class Parser {
public:
/**
* parse "<scheme>:"
* example "http", "https", "ftp"
* returns lowercase string before ':' char
* caret should be at the first char of the scheme
* parse `<scheme>`:
* example "http", "https", "ftp"
* returns lowercase string before ':' char
* caret should be at the first char of the scheme
*/
static oatpp::String parseScheme(oatpp::parser::Caret& caret);
/**
* parse url authority components.
* userinfo is not parsed into login and password separately as
* inclusion of password in userinfo is deprecated and ignored here
* caret should be at the first char of the authority (not at "//")
* parse url authority components.
* userinfo is not parsed into login and password separately as
* inclusion of password in userinfo is deprecated and ignored here
* caret should be at the first char of the authority (not at "//")
*/
static Url::Authority parseAuthority(oatpp::parser::Caret& caret);
/**
* parse path of the url
* caret should be at the first char of the path
* parse path of the url
* caret should be at the first char of the path
*/
static oatpp::String parsePath(oatpp::parser::Caret& caret);
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by ParsingCaret
* and put that params to Parameters map
* parse query params in form of `"?<paramName>=<paramValue>&<paramName>=<paramValue>..."` referred by ParsingCaret
* and put that params to Parameters map
*/
static void parseQueryParamsToMap(Url::Parameters& params, oatpp::parser::Caret& caret);
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by str
* and put that params to Parameters map
* parse query params in form of `"?<paramName>=<paramValue>&<paramName>=<paramValue>..."` referred by str
* and put that params to Parameters map
*/
static void parseQueryParamsToMap(Url::Parameters& params, const oatpp::String& str);
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by ParsingCaret
* parse query params in form of `"?<paramName>=<paramValue>&<paramName>=<paramValue>..."` referred by ParsingCaret
*/
static Url::Parameters parseQueryParams(oatpp::parser::Caret& caret);
/**
* parse query params in form of "?<paramName>=<paramValue>&<paramName>=<paramValue>..." referred by str
* parse query params in form of `"?<paramName>=<paramValue>&<paramName>=<paramValue>..."` referred by str
*/
static Url::Parameters parseQueryParams(const oatpp::String& str);
@ -103,7 +133,7 @@ public:
* Same as parseQueryParams() but use StringKeyLabel instead of a String.
* Zero allocations. Use this method for better performance.
* @param str
* @return std::unordered_map<StringKeyLabel, StringKeyLabel>
* @return `std::unordered_map<StringKeyLabel, StringKeyLabel>`. See &l:Url::StringKeyLabel;.
*/
static ParametersAsLabels labelQueryParams(const oatpp::String& str);
@ -124,10 +154,25 @@ public:
};
public:
/**
* Url scheme. Ex.: [http, https, ftp, etc.]
*/
oatpp::String scheme;
/**
* Utl authority.
*/
Authority authority;
/**
* Path to resource.
*/
oatpp::String path;
/**
* Query params.
*/
Parameters queryParams;
};

View File

@ -29,13 +29,16 @@
namespace oatpp { namespace network { namespace server {
/**
* Abstract ConnectionHandler.
*/
class ConnectionHandler {
public:
/**
* Handle provided connection here
* @param connection
* @param connection - see &id:oatpp::data::stream::IOStream;.
*/
virtual void handleConnection(const std::shared_ptr<oatpp::data::stream::IOStream>& connection) = 0;

View File

@ -124,6 +124,64 @@ oatpp::web::protocol::http::Protocol::Headers ApiClient::convertParamsMap(const
}
return result;
}
oatpp::String ApiClient::formatPath(const PathPattern& pathPattern,
const std::shared_ptr<StringToParamMap>& pathParams,
const std::shared_ptr<StringToParamMap>& queryParams)
{
oatpp::data::stream::ChunkedBuffer stream;
formatPath(&stream, pathPattern, pathParams);
if(queryParams) {
addPathQueryParams(&stream, queryParams);
}
return stream.toString();
}
std::shared_ptr<RequestExecutor::ConnectionHandle> ApiClient::getConnection() {
return m_requestExecutor->getConnection();
}
oatpp::async::Action ApiClient::getConnectionAsync(oatpp::async::AbstractCoroutine* parentCoroutine, RequestExecutor::AsyncConnectionCallback callback) {
return m_requestExecutor->getConnectionAsync(parentCoroutine, callback);
}
std::shared_ptr<ApiClient::Response> ApiClient::executeRequest(const oatpp::String& method,
const PathPattern& pathPattern,
const std::shared_ptr<StringToParamMap>& headers,
const std::shared_ptr<StringToParamMap>& pathParams,
const std::shared_ptr<StringToParamMap>& queryParams,
const std::shared_ptr<RequestExecutor::Body>& body,
const std::shared_ptr<RequestExecutor::ConnectionHandle>& connectionHandle) {
return m_requestExecutor->execute(method,
formatPath(pathPattern, pathParams, queryParams),
convertParamsMap(headers),
body,
connectionHandle);
}
oatpp::async::Action ApiClient::executeRequestAsync(oatpp::async::AbstractCoroutine* parentCoroutine,
AsyncCallback callback,
const oatpp::String& method,
const PathPattern& pathPattern,
const std::shared_ptr<StringToParamMap>& headers,
const std::shared_ptr<StringToParamMap>& pathParams,
const std::shared_ptr<StringToParamMap>& queryParams,
const std::shared_ptr<RequestExecutor::Body>& body,
const std::shared_ptr<RequestExecutor::ConnectionHandle>& connectionHandle) {
return m_requestExecutor->executeAsync(parentCoroutine,
callback,
method,
formatPath(pathPattern, pathParams, queryParams),
convertParamsMap(headers),
body,
connectionHandle);
}
}}}

View File

@ -175,42 +175,33 @@ public:
protected:
virtual oatpp::String formatPath(const PathPattern& pathPattern,
const std::shared_ptr<StringToParamMap>& pathParams,
const std::shared_ptr<StringToParamMap>& queryParams) {
oatpp::data::stream::ChunkedBuffer stream;
formatPath(&stream, pathPattern, pathParams);
if(queryParams) {
addPathQueryParams(&stream, queryParams);
}
return stream.toString();
}
const std::shared_ptr<StringToParamMap>& pathParams,
const std::shared_ptr<StringToParamMap>& queryParams);
public:
virtual std::shared_ptr<RequestExecutor::ConnectionHandle> getConnection() {
return m_requestExecutor->getConnection();
}
virtual oatpp::async::Action getConnectionAsync(oatpp::async::AbstractCoroutine* parentCoroutine, RequestExecutor::AsyncConnectionCallback callback) {
return m_requestExecutor->getConnectionAsync(parentCoroutine, callback);
}
/**
* Call &id:oatpp::web::client::RequestExecutor::getConnection;.
* @return - &id:oatpp::web::client::RequestExecutor::ConnectionHandle;.
*/
virtual std::shared_ptr<RequestExecutor::ConnectionHandle> getConnection();
/**
* Call &id:oatpp::web::client::RequestExecutor::getConnectionAsync;.
* @param parentCoroutine - caller coroutine as &id:oatpp::async::AbstractCoroutine;*.
* @param callback - function pointer to asynchronous callback.
* @return - &id:oatpp::async::Action;.
*/
virtual oatpp::async::Action getConnectionAsync(oatpp::async::AbstractCoroutine* parentCoroutine, RequestExecutor::AsyncConnectionCallback callback);
virtual std::shared_ptr<Response> executeRequest(const oatpp::String& method,
const PathPattern& pathPattern,
const std::shared_ptr<StringToParamMap>& headers,
const std::shared_ptr<StringToParamMap>& pathParams,
const std::shared_ptr<StringToParamMap>& queryParams,
const std::shared_ptr<RequestExecutor::Body>& body,
const std::shared_ptr<RequestExecutor::ConnectionHandle>& connectionHandle = nullptr) {
return m_requestExecutor->execute(method,
formatPath(pathPattern, pathParams, queryParams),
convertParamsMap(headers),
body,
connectionHandle);
}
const std::shared_ptr<RequestExecutor::ConnectionHandle>& connectionHandle = nullptr);
virtual oatpp::async::Action executeRequestAsync(oatpp::async::AbstractCoroutine* parentCoroutine,
AsyncCallback callback,
@ -220,17 +211,7 @@ public:
const std::shared_ptr<StringToParamMap>& pathParams,
const std::shared_ptr<StringToParamMap>& queryParams,
const std::shared_ptr<RequestExecutor::Body>& body,
const std::shared_ptr<RequestExecutor::ConnectionHandle>& connectionHandle = nullptr) {
return m_requestExecutor->executeAsync(parentCoroutine,
callback,
method,
formatPath(pathPattern, pathParams, queryParams),
convertParamsMap(headers),
body,
connectionHandle);
}
const std::shared_ptr<RequestExecutor::ConnectionHandle>& connectionHandle = nullptr);
};

View File

@ -28,35 +28,75 @@
#include "oatpp/core/data/IODefinitions.hpp"
namespace oatpp { namespace web { namespace protocol {
/**
* Communication Error
*/
class CommunicationError : public std::runtime_error {
private:
oatpp::data::v_io_size m_ioStatus;
oatpp::String m_message;
public:
/**
* Constructor.
* @param ioStatus - I/O error. See &id:oatpp::data::v_io_size;.
* @param message - error message.
*/
CommunicationError(oatpp::data::v_io_size ioStatus, const oatpp::String& message);
/**
* Get I/O error. See &id:oatpp::data::v_io_size;.
* @return &id:oatpp::data::v_io_size;.
*/
oatpp::data::v_io_size getIOStatus();
/**
* Get error message.
* @return - error message.
*/
oatpp::String& getMessage();
};
/**
* Protocol Error template.
* @tparam Status - arbitrary data type.
*/
template<class Status>
class ProtocolError : public CommunicationError {
public:
/**
* Protocol Error Info.
*/
struct Info {
/**
* Default Constructor.
*/
Info()
: ioStatus(0)
{}
/**
* Constructor.
* @param pIOStatus - I/O level error. See &id:oatpp::data::v_io_size;.
* @param pStatus - configurable arbitrary data type.
*/
Info(oatpp::data::v_io_size pIOStatus, const Status& pStatus)
: ioStatus(pIOStatus)
, status(pStatus)
{}
/**
* Get I/O level error.
*/
oatpp::data::v_io_size ioStatus;
/**
* Configurable arbitrary data type.
*/
Status status;
};
@ -64,12 +104,21 @@ public:
private:
Info m_info;
public:
/**
* Constructor.
* @param info - &l:ProtocolError::Info ;.
* @param message - error message.
*/
ProtocolError(const Info& info, const oatpp::String& message)
: CommunicationError(info.ioStatus, message)
, m_info(info)
{}
/**
* Get error info.
* @return - error info.
*/
Info getInfo() {
return m_info;
}

View File

@ -38,88 +38,349 @@
#include <unordered_map>
namespace oatpp { namespace web { namespace protocol { namespace http {
/**
* Http status.
*/
class Status{
public:
/**
* Continue.
*/
static const Status CODE_100;// Continue
/**
* Switching Protocols.
*/
static const Status CODE_101;// Switching
/**
* Processing.
*/
static const Status CODE_102;// Processing
/**
* OK.
*/
static const Status CODE_200;// OK
/**
* Created.
*/
static const Status CODE_201;// Created
/**
* Accepted.
*/
static const Status CODE_202;// Accepted
/**
* Non-Authoritative Information.
*/
static const Status CODE_203;// Non-Authoritative Information
/**
* No Content.
*/
static const Status CODE_204;// No Content
/**
* Reset Content.
*/
static const Status CODE_205;// Reset Content
/**
* Partial Content.
*/
static const Status CODE_206;// Partial Content
/**
* Multi-Status.
*/
static const Status CODE_207;// Multi-Status
/**
* IM Used.
*/
static const Status CODE_226;// IM Used
/**
* Multiple Choices.
*/
static const Status CODE_300;// Multiple Choices
/**
* Moved Permanently.
*/
static const Status CODE_301;// Moved Permanently
/**
* Moved Temporarily.
*/
static const Status CODE_302;// Moved Temporarily
/**
* See Other.
*/
static const Status CODE_303;// See Other
/**
* Not Modified.
*/
static const Status CODE_304;// Not Modified
/**
* Use Proxy.
*/
static const Status CODE_305;// Use Proxy
/**
* Reserved.
*/
static const Status CODE_306;// Reserved
/**
* Temporary Redirect.
*/
static const Status CODE_307;// Temporary Redirect
/**
* Bad Request.
*/
static const Status CODE_400;// Bad Request
/**
* Unauthorized.
*/
static const Status CODE_401;// Unauthorized
/**
* Payment Required.
*/
static const Status CODE_402;// Payment Required
/**
* Forbidden.
*/
static const Status CODE_403;// Forbidden
/**
* Not Found.
*/
static const Status CODE_404;// Not Found
/**
* Method Not Allowed.
*/
static const Status CODE_405;// Method Not Allowed
/**
* Not Acceptable.
*/
static const Status CODE_406;// Not Acceptable
/**
* Proxy Authentication Required.
*/
static const Status CODE_407;// Proxy Authentication Required
/**
* Request Timeout.
*/
static const Status CODE_408;// Request Timeout
/**
* Conflict.
*/
static const Status CODE_409;// Conflict
/**
* Gone
*/
static const Status CODE_410;// Gone
/**
* Length Required.
*/
static const Status CODE_411;// Length Required
/**
* Precondition Failed.
*/
static const Status CODE_412;// Precondition Failed
/**
* Request Entity Too Large.
*/
static const Status CODE_413;// Request Entity Too Large
/**
* Request-URI Too Large.
*/
static const Status CODE_414;// Request-URI Too Large
/**
* Unsupported Media Type.
*/
static const Status CODE_415;// Unsupported Media Type
/**
* Requested Range Not Satisfiable.
*/
static const Status CODE_416;// Requested Range Not Satisfiable
/**
* Expectation Failed.
*/
static const Status CODE_417;// Expectation Failed
/**
* Unprocessable Entity.
*/
static const Status CODE_422;// Unprocessable Entity
/**
* Locked.
*/
static const Status CODE_423;// Locked
/**
* Failed Dependency.
*/
static const Status CODE_424;// Failed Dependency
/**
* Unordered Collection.
*/
static const Status CODE_425;// Unordered Collection
/**
* Upgrade Required.
*/
static const Status CODE_426;// Upgrade Required
/**
* Precondition Required.
*/
static const Status CODE_428;// Precondition Required
/**
* Too Many Requests.
*/
static const Status CODE_429;// Too Many Requests
/**
* Request Header Fields Too Large.
*/
static const Status CODE_431;// Request Header Fields Too Large
/**
* Requested host unavailable.
*/
static const Status CODE_434;// Requested host unavailable
/**
* Close connection withot sending headers.
*/
static const Status CODE_444;// Close connection withot sending headers
/**
* Retry With.
*/
static const Status CODE_449;// Retry With
/**
* Unavailable For Legal Reasons.
*/
static const Status CODE_451;// Unavailable For Legal Reasons
/**
* Internal Server Error.
*/
static const Status CODE_500;// Internal Server Error
/**
* Not Implemented.
*/
static const Status CODE_501;// Not Implemented
/**
* Bad Gateway.
*/
static const Status CODE_502;// Bad Gateway
/**
* Service Unavailable.
*/
static const Status CODE_503;// Service Unavailable
/**
* Gateway Timeout.
*/
static const Status CODE_504;// Gateway Timeout
/**
* HTTP Version Not Supported.
*/
static const Status CODE_505;// HTTP Version Not Supported
/**
* Variant Also Negotiates.
*/
static const Status CODE_506;// Variant Also Negotiates
/**
* Insufficient Storage.
*/
static const Status CODE_507;// Insufficient Storage
/**
* Loop Detected.
*/
static const Status CODE_508;// Loop Detected
/**
* Bandwidth Limit Exceeded.
*/
static const Status CODE_509;// Bandwidth Limit Exceeded
/**
* Not Extended.
*/
static const Status CODE_510;// Not Extended
/**
* Network Authentication Required.
*/
static const Status CODE_511;// Network Authentication Required
/**
* Constructor.
*/
Status()
: code(0)
, description(nullptr)
{}
/**
* Constructor.
* @param pCode - status code.
* @param pDesc - description.
*/
Status(v_int32 pCode, const char* pDesc)
: code(pCode)
, description(pDesc)
{}
/**
* Status code.
*/
v_int32 code;
/**
* Description.
*/
const char* description;
bool operator==(const Status& other) const {
@ -131,25 +392,51 @@ public:
}
};
/**
* HttpError extends &id:oatpp::web::protocol::ProtocolError;<&l:Status;>.
*/
class HttpError : public protocol::ProtocolError<Status> {
public:
/**
* Constructor.
* @param info
* @param message
*/
HttpError(const Info& info, const oatpp::String& message)
: protocol::ProtocolError<Status>(info, message)
{}
/**
* Constructor.
* @param status
* @param message
*/
HttpError(const Status& status, const oatpp::String& message)
: protocol::ProtocolError<Status>(Info(0, status), message)
{}
};
/**
* Throw &l:HttpError; if assertion failed.
* @param COND - boolean statement. If evaluates to false - throw error.
* @param STATUS - &l:Status;.
* @param MESSAGE - String message.
*/
#define OATPP_ASSERT_HTTP(COND, STATUS, MESSAGE) \
if(!(COND)) { throw oatpp::web::protocol::http::HttpError(STATUS, MESSAGE); }
/**
* Collection of HTTP Header constants.
*/
class Header {
public:
/**
* Possible values for headers.
*/
class Value {
public:
static const char* const CONNECTION_CLOSE;

View File

@ -36,7 +36,10 @@
#include "oatpp/core/async/Executor.hpp"
namespace oatpp { namespace web { namespace server {
/**
* Asynchronous &id:oatpp::network::server::ConnectionHandler; for handling http communication.
*/
class AsyncHttpConnectionHandler : public base::Countable, public network::server::ConnectionHandler {
private:
typedef oatpp::web::protocol::http::incoming::BodyDecoder BodyDecoder;

View File

@ -41,7 +41,11 @@
#include "oatpp/core/data/buffer/IOBuffer.hpp"
namespace oatpp { namespace web { namespace server {
/**
* Simple ConnectionHandler (&id:oatpp::network::server::ConnectionHandler;) for handling HTTP communication. <br>
* Will create one thread per each connection to handle communication.
*/
class HttpConnectionHandler : public base::Countable, public network::server::ConnectionHandler {
private:
@ -76,14 +80,42 @@ private:
std::shared_ptr<handler::ErrorHandler> m_errorHandler;
HttpProcessor::RequestInterceptors m_requestInterceptors;
public:
/**
* Constructor.
* @param router - &id:oatpp::web::server::HttpRouter; to route incoming requests.
*/
HttpConnectionHandler(const std::shared_ptr<HttpRouter>& router);
public:
/**
* Create shared HttpConnectionHandler.
* @param router - &id:oatpp::web::server::HttpRouter; to route incoming requests.
* @return - `std::shared_ptr` to HttpConnectionHandler.
*/
static std::shared_ptr<HttpConnectionHandler> createShared(const std::shared_ptr<HttpRouter>& router);
/**
* Set root error handler for all requests coming through this Connection Handler.
* All unhandled errors will be handled by this error handler.
* @param errorHandler - &id:oatpp::web::server::handler::ErrorHandler;.
*/
void setErrorHandler(const std::shared_ptr<handler::ErrorHandler>& errorHandler);
/**
* Set request interceptor. Request intercepted after route is resolved but before corresponding route subscriber is called.
* @param interceptor - &id:oatpp::web::server::handler::RequestInterceptor;.
*/
void addRequestInterceptor(const std::shared_ptr<handler::RequestInterceptor>& interceptor);
/**
* Implementation of &id:oatpp::network::server::ConnectionHandler::handleConnection;.
* @param connection - &id:oatpp::data::stream::IOStream; representing connection.
*/
void handleConnection(const std::shared_ptr<oatpp::data::stream::IOStream>& connection) override;
/**
* Tell all worker threads to exit when done.
*/
void stop() override;
};

View File

@ -23,3 +23,42 @@
***************************************************************************/
#include "HttpRouter.hpp"
namespace oatpp { namespace web { namespace server {
HttpRouter::HttpRouter()
{}
const std::shared_ptr<HttpRouter::BranchRouter>& HttpRouter::getBranch(const StringKeyLabel& name){
auto it = m_branchMap.find(name);
if(it == m_branchMap.end()){
m_branchMap[name] = BranchRouter::createShared();
}
return m_branchMap[name];
}
std::shared_ptr<HttpRouter> HttpRouter::createShared() {
return std::make_shared<HttpRouter>();
}
void HttpRouter::addSubscriber(const oatpp::String& method,
const oatpp::String& urlPattern,
const std::shared_ptr<Subscriber>& subscriber) {
getBranch(method)->addSubscriber(urlPattern, subscriber);
}
HttpRouter::BranchRouter::Route HttpRouter::getRoute(const StringKeyLabel& method, const StringKeyLabel& url){
auto it = m_branchMap.find(method);
if(it != m_branchMap.end()) {
return m_branchMap[method]->getRoute(url);
}
return BranchRouter::Route();
}
void HttpRouter::logRouterMappings() {
for(auto it : m_branchMap) {
it.second->logRouterMappings();
}
}
}}}

View File

@ -31,57 +31,78 @@
#include "oatpp/web/url/mapping/Router.hpp"
namespace oatpp { namespace web { namespace server {
/**
* HttpRouter is responsible for routing http requests by method and path-pattern.
*/
class HttpRouter : public oatpp::base::Countable {
private:
/**
* Convenience typedef for &id:oatpp::data::share::StringKeyLabel;.
*/
typedef oatpp::data::share::StringKeyLabel StringKeyLabel;
public:
/**
* &id:oatpp::web::url::mapping::Router; of &id:oatpp::web::protocol::http::incoming::Request; and
* &id:oatpp::web::protocol::http::outgoing::Response;. Meaning router for Subscribers which accept
* incoming request as an input parameter and return outgoing request as an output parameter.
*/
typedef oatpp::web::url::mapping::Router<
std::shared_ptr<oatpp::web::protocol::http::incoming::Request>,
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
> BranchRouter;
/**
* Subscriber which accept
* incoming request as an input parameter and return outgoing request as an output parameter.
* See &l:HttpRouter::BranchRouter;.
*/
typedef BranchRouter::UrlSubscriber Subscriber;
/**
* Http method to &l:HttpRouter::BranchRouter; map.
* Meaning that for each http method like ["GET", "POST", ...] there is a separate &l:HttpRouter::BranchRouter;.
*/
typedef std::unordered_map<StringKeyLabel, std::shared_ptr<BranchRouter>> BranchMap;
protected:
BranchMap m_branchMap;
protected:
const std::shared_ptr<BranchRouter>& getBranch(const StringKeyLabel& name){
auto it = m_branchMap.find(name);
if(it == m_branchMap.end()){
m_branchMap[name] = BranchRouter::createShared();
}
return m_branchMap[name];
}
const std::shared_ptr<BranchRouter>& getBranch(const StringKeyLabel& name);
public:
HttpRouter() {}
public:
static std::shared_ptr<HttpRouter> createShared() {
return std::make_shared<HttpRouter>();
}
void addSubscriber(const oatpp::String& method,
const oatpp::String& urlPattern,
const std::shared_ptr<Subscriber>& subscriber) {
getBranch(method)->addSubscriber(urlPattern, subscriber);
}
BranchRouter::Route getRoute(const StringKeyLabel& method,
const StringKeyLabel& url){
auto it = m_branchMap.find(method);
if(it != m_branchMap.end()) {
return m_branchMap[method]->getRoute(url);
}
return BranchRouter::Route();
}
void logRouterMappings() {
for(auto it : m_branchMap) {
it.second->logRouterMappings();
}
}
/**
* Constructor.
*/
HttpRouter();
/**
* Create shared HttpRouter.
* @return - `std::shared_ptr` to HttpRouter.
*/
static std::shared_ptr<HttpRouter> createShared();
/**
* Add url pattern Subscriber (handler for all requests resolved by specified url-pattern).
* @param method - http method like ["GET", "POST", etc.].
* @param urlPattern - url path pattern. ex.: `"/path/to/resource/with/{param1}/{param2}"`.
* @param subscriber - &l:HttpRouter::Subscriber;.
*/
void addSubscriber(const oatpp::String& method, const oatpp::String& urlPattern, const std::shared_ptr<Subscriber>& subscriber);
/**
* Resolve http method and path to &id:oatpp::web::url::mapping::Router::Route;
* @param method - http method like ["GET", "POST", etc.].
* @param url - url path. "Path" part of url only.
* @return - &id:oatpp::web::url::mapping::Router::Route;.
*/
BranchRouter::Route getRoute(const StringKeyLabel& method, const StringKeyLabel& url);
/**
* Print out all router mapping.
*/
void logRouterMappings();
};

View File

@ -29,26 +29,51 @@
#include "oatpp/web/protocol/http/Http.hpp"
namespace oatpp { namespace web { namespace server { namespace handler {
/**
* Error Handler.
*/
class ErrorHandler {
public:
/**
* Implement this method!
* @param status - &id:oatpp::web::protocol::http::Status;.
* @param message- &id:oatpp::String;.
* @return - &id:oatpp::web::protocol::http::outgoing::Response;.
*/
virtual
std::shared_ptr<protocol::http::outgoing::Response>
handleError(const protocol::http::Status& status, const oatpp::String& message) = 0;
};
/**
* Default Error Handler.
*/
class DefaultErrorHandler : public oatpp::base::Countable, public ErrorHandler {
public:
/**
* Constructor.
*/
DefaultErrorHandler()
{}
public:
/**
* Create shared DefaultErrorHandler.
* @return - `std::shared_ptr` to DefaultErrorHandler.
*/
static std::shared_ptr<DefaultErrorHandler> createShared() {
return std::make_shared<DefaultErrorHandler>();
}
/**
* Implementation of &l:ErrorHandler::handleError ();
* @param status - &id:oatpp::web::protocol::http::Status;.
* @param message - &id:oatpp::String;.
* @return - &id:oatpp::web::protocol::http::outgoing::Response;.
*/
std::shared_ptr<protocol::http::outgoing::Response>
handleError(const protocol::http::Status& status, const oatpp::String& message) override;

View File

@ -30,10 +30,20 @@
#include "oatpp/web/protocol/http/Http.hpp"
namespace oatpp { namespace web { namespace server { namespace handler {
/**
* RequestInterceptor.
*/
class RequestInterceptor {
public:
/**
* Convenience typedef for &id:oatpp::web::protocol::http::incoming::Request;.
*/
typedef oatpp::web::protocol::http::incoming::Request IncomingRequest;
/**
* Convenience typedef for &id:oatpp::web::protocol::http::outgoing::Response;.
*/
typedef oatpp::web::protocol::http::outgoing::Response OutgoingResponse;
public:

View File

@ -37,33 +37,68 @@
#include "oatpp/core/base/Environment.hpp"
namespace oatpp { namespace web { namespace url { namespace mapping {
/**
* Class responsible to map "path-pattern" to "Subscriber".
* @tparam Param - input parameter for Subscriber.
* @tparam ReturnType - output parameter of Subscriber.
*/
template<class Param, class ReturnType>
class Router : public base::Countable{
public:
/**
* Convenience typedef for &id:oatpp::web::url::mapping::Subscriber;.
*/
typedef Subscriber<Param, ReturnType> UrlSubscriber;
private:
/**
* Convenience typedef &id:oatpp::data::share::StringKeyLabel;.
*/
typedef oatpp::data::share::StringKeyLabel StringKeyLabel;
public:
/**
* Resolved "Route" for "path-pattern"
*/
class Route {
private:
UrlSubscriber* m_subscriber;
public:
/**
* Default constructor.
*/
Route()
: m_subscriber(nullptr)
{}
/**
* Constructor.
* @param subscriber - &id:Router::UrlSubscriber;.
* @param pMatchMap - Match map of resolved path containing resolved path variables.
*/
Route(UrlSubscriber* subscriber, const Pattern::MatchMap& pMatchMap)
: m_subscriber(subscriber)
, matchMap(pMatchMap)
{}
/**
* Call &id:oatpp::web::url::mapping::Subscriber::processUrl; with corresponding parameter.
* @param param
* @return - corresponding ReturnType.
*/
ReturnType processUrl(const Param& param) const {
return m_subscriber->processUrl(param);
}
/**
* Call &id:oatpp::web::url::mapping::Subscriber::processUrlAsync; with corresponding parameter.
* @param parentCoroutine - caller coroutine. &id:oatpp::async::AbstractCoroutine;.
* @param callback - pointer to callback function.
* @param param
* @return - &id:oatpp::async::Action;.
*/
oatpp::async::Action processUrlAsync(oatpp::async::AbstractCoroutine* parentCoroutine,
typename UrlSubscriber::AsyncCallback callback,
const Param& param) const {
@ -73,7 +108,10 @@ public:
explicit operator bool() const {
return m_subscriber != nullptr;
}
/**
* Match map of resolved path containing resolved path variables.
*/
Pattern::MatchMap matchMap;
};
@ -108,14 +146,24 @@ public:
static std::shared_ptr<Router> createShared(){
return std::make_shared<Router>();
}
/**
* Add path-pattern subscriber.
* @param urlPattern
* @param subscriber
*/
void addSubscriber(const oatpp::String& urlPattern,
const std::shared_ptr<UrlSubscriber>& subscriber){
auto pattern = Pattern::parse(urlPattern);
auto pair = Pair::createShared(pattern, subscriber);
m_subscribers->pushBack(pair);
}
/**
* Resolve path to corresponding subscriber.
* @param url
* @return - &id:Router::Route;.
*/
Route getRoute(const StringKeyLabel& url){
auto curr = m_subscribers->getFirstNode();
while(curr != nullptr) {