diff --git a/src/oatpp/web/protocol/http/incoming/BodyDecoder.cpp b/src/oatpp/web/protocol/http/incoming/BodyDecoder.cpp index 5f3a42c0..e5ca3d23 100644 --- a/src/oatpp/web/protocol/http/incoming/BodyDecoder.cpp +++ b/src/oatpp/web/protocol/http/incoming/BodyDecoder.cpp @@ -28,6 +28,21 @@ namespace oatpp { namespace web { namespace protocol { namespace http { namespace incoming { +BodyDecoder::ToStringDecoder::ToStringDecoder(const BodyDecoder* decoder, + const Protocol::Headers& headers, + const std::shared_ptr& bodyStream) + : m_decoder(decoder) + , m_headers(headers) + , m_bodyStream(bodyStream) + , m_chunkedBuffer(oatpp::data::stream::ChunkedBuffer::createShared()) +{} +async::Action BodyDecoder::ToStringDecoder::act() { + return m_decoder->decodeAsync(this, yieldTo(&ToStringDecoder::onDecoded), m_headers, m_bodyStream, m_chunkedBuffer); +} + +async::Action BodyDecoder::ToStringDecoder::onDecoded() { + return _return(m_chunkedBuffer->toString()); +} }}}}} diff --git a/src/oatpp/web/protocol/http/incoming/BodyDecoder.hpp b/src/oatpp/web/protocol/http/incoming/BodyDecoder.hpp index bf2a6821..6066eced 100644 --- a/src/oatpp/web/protocol/http/incoming/BodyDecoder.hpp +++ b/src/oatpp/web/protocol/http/incoming/BodyDecoder.hpp @@ -39,24 +39,15 @@ private: const BodyDecoder* m_decoder; Protocol::Headers m_headers; std::shared_ptr m_bodyStream; - std::shared_ptr m_chunkedBuffer = oatpp::data::stream::ChunkedBuffer::createShared(); + std::shared_ptr m_chunkedBuffer; public: ToStringDecoder(const BodyDecoder* decoder, const Protocol::Headers& headers, - const std::shared_ptr& bodyStream) - : m_decoder(decoder) - , m_headers(headers) - , m_bodyStream(bodyStream) - {} + const std::shared_ptr& bodyStream); - Action act() override { - return m_decoder->decodeAsync(this, yieldTo(&ToStringDecoder::onDecoded), m_headers, m_bodyStream, m_chunkedBuffer); - } - - Action onDecoded() { - return _return(m_chunkedBuffer->toString()); - } + Action act() override; + Action onDecoded(); }; diff --git a/src/oatpp/web/protocol/http/incoming/Request.cpp b/src/oatpp/web/protocol/http/incoming/Request.cpp index 7c84bc7d..3a7ffd0f 100644 --- a/src/oatpp/web/protocol/http/incoming/Request.cpp +++ b/src/oatpp/web/protocol/http/incoming/Request.cpp @@ -23,3 +23,77 @@ ***************************************************************************/ #include "Request.hpp" + +namespace oatpp { namespace web { namespace protocol { namespace http { namespace incoming { + +Request::Request(const http::RequestStartingLine& startingLine, + const url::mapping::Pattern::MatchMap& pathVariables, + const http::Protocol::Headers& headers, + const std::shared_ptr& bodyStream, + const std::shared_ptr& bodyDecoder) + : m_startingLine(startingLine) + , m_pathVariables(pathVariables) + , m_headers(headers) + , m_bodyStream(bodyStream) + , m_bodyDecoder(bodyDecoder) +{} + +std::shared_ptr Request::createShared(const http::RequestStartingLine& startingLine, + const url::mapping::Pattern::MatchMap& pathVariables, + const http::Protocol::Headers& headers, + const std::shared_ptr& bodyStream, + const std::shared_ptr& bodyDecoder) { + return Shared_Incoming_Request_Pool::allocateShared(startingLine, pathVariables, headers, bodyStream, bodyDecoder); +} + +const http::RequestStartingLine& Request::getStartingLine() const { + return m_startingLine; +} + +const url::mapping::Pattern::MatchMap& Request::getPathVariables() const { + return m_pathVariables; +} + +const http::Protocol::Headers& Request::getHeaders() const { + return m_headers; +} + +std::shared_ptr Request::getBodyStream() const { + return m_bodyStream; +} + +std::shared_ptr Request::getBodyDecoder() const { + return m_bodyDecoder; +} + +oatpp::String Request::getHeader(const oatpp::data::share::StringKeyLabelCI_FAST& headerName) const{ + auto it = m_headers.find(headerName); + if(it != m_headers.end()) { + return it->second.toString(); + } + return nullptr; +} + +oatpp::String Request::getPathVariable(const oatpp::data::share::StringKeyLabel& name) const { + return m_pathVariables.getVariable(name); +} + +oatpp::String Request::getPathTail() const { + return m_pathVariables.getTail(); +} + +void Request::streamBody(const std::shared_ptr& toStream) const { + m_bodyDecoder->decode(m_headers, m_bodyStream, toStream); +} + +oatpp::String Request::readBodyToString() const { + return m_bodyDecoder->decodeToString(m_headers, m_bodyStream); +} + +oatpp::async::Action Request::streamBodyAsync(oatpp::async::AbstractCoroutine* parentCoroutine, + const oatpp::async::Action& actionOnReturn, + const std::shared_ptr& toStream) const { + return m_bodyDecoder->decodeAsync(parentCoroutine, actionOnReturn, m_headers, m_bodyStream, toStream); +} + +}}}}} \ No newline at end of file diff --git a/src/oatpp/web/protocol/http/incoming/Request.hpp b/src/oatpp/web/protocol/http/incoming/Request.hpp index 29f5185a..a35e292d 100644 --- a/src/oatpp/web/protocol/http/incoming/Request.hpp +++ b/src/oatpp/web/protocol/http/incoming/Request.hpp @@ -30,7 +30,10 @@ #include "oatpp/web/url/mapping/Pattern.hpp" namespace oatpp { namespace web { namespace protocol { namespace http { namespace incoming { - + +/** + * Class http::incoming::Request AKA IncomingRequest represents client's incoming request + */ class Request : public oatpp::base::Controllable { public: OBJECT_POOL(Incoming_Request_Pool, Request, 32) @@ -41,108 +44,140 @@ private: http::Protocol::Headers m_headers; std::shared_ptr m_bodyStream; - /** + /* * Request should be preconfigured with default BodyDecoder. * Custom BodyDecoder can be set on demand */ std::shared_ptr m_bodyDecoder; public: - /* - Request(const std::shared_ptr& pBodyDecoder) - : bodyDecoder(pBodyDecoder) - {} - */ Request(const http::RequestStartingLine& startingLine, const url::mapping::Pattern::MatchMap& pathVariables, const http::Protocol::Headers& headers, const std::shared_ptr& bodyStream, - const std::shared_ptr& bodyDecoder) - : m_startingLine(startingLine) - , m_pathVariables(pathVariables) - , m_headers(headers) - , m_bodyStream(bodyStream) - , m_bodyDecoder(bodyDecoder) - {} + const std::shared_ptr& bodyDecoder); public: static std::shared_ptr createShared(const http::RequestStartingLine& startingLine, const url::mapping::Pattern::MatchMap& pathVariables, const http::Protocol::Headers& headers, const std::shared_ptr& bodyStream, - const std::shared_ptr& bodyDecoder) { - return Shared_Incoming_Request_Pool::allocateShared(startingLine, pathVariables, headers, bodyStream, bodyDecoder); - } - - const http::RequestStartingLine& getStartingLine() const { - return m_startingLine; - } - - const url::mapping::Pattern::MatchMap& getPathVariables() const { - return m_pathVariables; - } - - const http::Protocol::Headers& getHeaders() const { - return m_headers; - } - - std::shared_ptr getBodyStream() const { - return m_bodyStream; - } - - std::shared_ptr getBodyDecoder() const { - return m_bodyDecoder; - } - - oatpp::String getHeader(const oatpp::String& headerName) const{ - auto it = m_headers.find(headerName); - if(it != m_headers.end()) { - return it->second.toString(); - } - return nullptr; - } - - oatpp::String getPathVariable(const oatpp::data::share::StringKeyLabel& name) const { - return m_pathVariables.getVariable(name); - } - - oatpp::String getPathTail() const { - return m_pathVariables.getTail(); - } - - void streamBody(const std::shared_ptr& toStream) const { - m_bodyDecoder->decode(m_headers, m_bodyStream, toStream); - } - - oatpp::String readBodyToString() const { - return m_bodyDecoder->decodeToString(m_headers, m_bodyStream); - } - + const std::shared_ptr& bodyDecoder); + + /** + * Get request starting line. (method, path, protocol) + * @return starting line structure + */ + const http::RequestStartingLine& getStartingLine() const; + + /** + * Get path variables according to path-pattern. + * Ex. given request path="/sum/19/1" for path-pattern="/sum/{a}/{b}" + * getPathVariables().getVariable("a") == 19, getPathVariables().getVariable("b") == 1. + * + * @return url MatchMap + */ + const url::mapping::Pattern::MatchMap& getPathVariables() const; + + /** + * Get request's headers map + * @return Headers map + */ + const http::Protocol::Headers& getHeaders() const; + + /** + * Get request's body stream + * @return body stream + */ + std::shared_ptr getBodyStream() const; + + /** + * Get body decoder. + * @return Body decoder + */ + std::shared_ptr getBodyDecoder() const; + + /** + * Get header value + * @param headerName + * @return header value + */ + oatpp::String getHeader(const oatpp::data::share::StringKeyLabelCI_FAST& headerName) const; + + /** + * Get path variable according to path-pattern + * @param name + * @return matched value for path-pattern + */ + oatpp::String getPathVariable(const oatpp::data::share::StringKeyLabel& name) const; + + /** + * Get path tail according to path-pattern + * Ex. given request path="/hello/path/tail" for path-pattern="/hello/\*" + * tail == "path/tail" + * note '/' symbol is required before '*' + * @return matched tail-value for path-pattern + */ + oatpp::String getPathTail() const; + + /** + * Stream content of the body-stream to toStream + * @param toStream + */ + void streamBody(const std::shared_ptr& toStream) const; + + /** + * Transfer body stream to string + * @return body as string + */ + oatpp::String readBodyToString() const; + + /** + * Transfer body to String and parse it as DTO + * @tparam Type + * @param objectMapper + * @return DTO + */ template typename Type::ObjectWrapper readBodyToDto(const std::shared_ptr& objectMapper) const { return objectMapper->readFromString(m_bodyDecoder->decodeToString(m_headers, m_bodyStream)); } - template - void readBodyToDto(oatpp::data::mapping::type::PolymorphicWrapper& objectWrapper, - const std::shared_ptr& objectMapper) const { - objectWrapper = objectMapper->readFromString(m_bodyDecoder->decodeToString(m_headers, m_bodyStream)); - } - // Async - + + /** + * Transfer body stream to toStream Async + * @param parentCoroutine + * @param actionOnReturn + * @param toStream + * @return Start Coroutine Action + */ oatpp::async::Action streamBodyAsync(oatpp::async::AbstractCoroutine* parentCoroutine, const oatpp::async::Action& actionOnReturn, - const std::shared_ptr& toStream) const { - return m_bodyDecoder->decodeAsync(parentCoroutine, actionOnReturn, m_headers, m_bodyStream, toStream); - } - + const std::shared_ptr& toStream) const; + + /** + * Transfer body stream to string Async + * @tparam ParentCoroutineType + * @param parentCoroutine + * @param callback + * @return Start Coroutine Action + */ template oatpp::async::Action readBodyToStringAsync(oatpp::async::AbstractCoroutine* parentCoroutine, oatpp::async::Action (ParentCoroutineType::*callback)(const oatpp::String&)) const { return m_bodyDecoder->decodeToStringAsync(parentCoroutine, callback, m_headers, m_bodyStream); } - + + /** + * Transfer body to String and parse it as DTO + * @tparam DtoType + * @tparam ParentCoroutineType + * @param parentCoroutine + * @param callback + * @param objectMapper + * @return Start Coroutine Action + */ template oatpp::async::Action readBodyToDtoAsync(oatpp::async::AbstractCoroutine* parentCoroutine, oatpp::async::Action (ParentCoroutineType::*callback)(const typename DtoType::ObjectWrapper&), diff --git a/src/oatpp/web/protocol/http/incoming/Response.cpp b/src/oatpp/web/protocol/http/incoming/Response.cpp index 0e43d1e4..18094c7d 100644 --- a/src/oatpp/web/protocol/http/incoming/Response.cpp +++ b/src/oatpp/web/protocol/http/incoming/Response.cpp @@ -25,5 +25,59 @@ #include "./Response.hpp" namespace oatpp { namespace web { namespace protocol { namespace http { namespace incoming { - + +Response::Response(v_int32 statusCode, + const oatpp::String& statusDescription, + const http::Protocol::Headers& headers, + const std::shared_ptr& bodyStream, + const std::shared_ptr& bodyDecoder) + : m_statusCode(statusCode) + , m_statusDescription(statusDescription) + , m_headers(headers) + , m_bodyStream(bodyStream) + , m_bodyDecoder(bodyDecoder) +{} + +std::shared_ptr Response::createShared(v_int32 statusCode, + const oatpp::String& statusDescription, + const http::Protocol::Headers& headers, + const std::shared_ptr& bodyStream, + const std::shared_ptr& bodyDecoder) { + return Shared_Incoming_Response_Pool::allocateShared(statusCode, statusDescription, headers, bodyStream, bodyDecoder); +} + +v_int32 Response::getStatusCode() const { + return m_statusCode; +} + +oatpp::String Response::getStatusDescription() const { + return m_statusDescription; +} + +const http::Protocol::Headers& Response::getHeaders() const { + return m_headers; +} + +std::shared_ptr Response::getBodyStream() const { + return m_bodyStream; +} + +std::shared_ptr Response::getBodyDecoder() const { + return m_bodyDecoder; +} + +void Response::streamBody(const std::shared_ptr& toStream) const { + m_bodyDecoder->decode(m_headers, m_bodyStream, toStream); +} + +oatpp::String Response::readBodyToString() const { + return m_bodyDecoder->decodeToString(m_headers, m_bodyStream); +} + +oatpp::async::Action Response::streamBodyAsync(oatpp::async::AbstractCoroutine* parentCoroutine, + const oatpp::async::Action& actionOnReturn, + const std::shared_ptr& toStream) const { + return m_bodyDecoder->decodeAsync(parentCoroutine, actionOnReturn, m_headers, m_bodyStream, toStream); +} + }}}}} diff --git a/src/oatpp/web/protocol/http/incoming/Response.hpp b/src/oatpp/web/protocol/http/incoming/Response.hpp index aa3058ca..10903e9c 100644 --- a/src/oatpp/web/protocol/http/incoming/Response.hpp +++ b/src/oatpp/web/protocol/http/incoming/Response.hpp @@ -29,7 +29,10 @@ #include "oatpp/web/protocol/http/incoming/BodyDecoder.hpp" namespace oatpp { namespace web { namespace protocol { namespace http { namespace incoming { - + +/** + * Class http::incoming::Response AKA IncomingResponse represents server's incoming response + */ class Response : public oatpp::base::Controllable { public: OBJECT_POOL(Incoming_Response_Pool, Response, 32) @@ -54,50 +57,28 @@ public: const oatpp::String& statusDescription, const http::Protocol::Headers& headers, const std::shared_ptr& bodyStream, - const std::shared_ptr& bodyDecoder) - : m_statusCode(statusCode) - , m_statusDescription(statusDescription) - , m_headers(headers) - , m_bodyStream(bodyStream) - , m_bodyDecoder(bodyDecoder) - {} + const std::shared_ptr& bodyDecoder); public: static std::shared_ptr createShared(v_int32 statusCode, const oatpp::String& statusDescription, const http::Protocol::Headers& headers, const std::shared_ptr& bodyStream, - const std::shared_ptr& bodyDecoder) { - return Shared_Incoming_Response_Pool::allocateShared(statusCode, statusDescription, headers, bodyStream, bodyDecoder); - } + const std::shared_ptr& bodyDecoder); - v_int32 getStatusCode() const { - return m_statusCode; - } + v_int32 getStatusCode() const; - oatpp::String getStatusDescription() const { - return m_statusDescription; - } + oatpp::String getStatusDescription() const; - const http::Protocol::Headers& getHeaders() const { - return m_headers; - } + const http::Protocol::Headers& getHeaders() const; - std::shared_ptr getBodyStream() const { - return m_bodyStream; - } + std::shared_ptr getBodyStream() const; - std::shared_ptr getBodyDecoder() const { - return m_bodyDecoder; - } + std::shared_ptr getBodyDecoder() const; - void streamBody(const std::shared_ptr& toStream) const { - m_bodyDecoder->decode(m_headers, m_bodyStream, toStream); - } + void streamBody(const std::shared_ptr& toStream) const; - oatpp::String readBodyToString() const { - return m_bodyDecoder->decodeToString(m_headers, m_bodyStream); - } + oatpp::String readBodyToString() const; template typename Type::ObjectWrapper readBodyToDto(const std::shared_ptr& objectMapper) const { @@ -108,9 +89,7 @@ public: oatpp::async::Action streamBodyAsync(oatpp::async::AbstractCoroutine* parentCoroutine, const oatpp::async::Action& actionOnReturn, - const std::shared_ptr& toStream) const { - return m_bodyDecoder->decodeAsync(parentCoroutine, actionOnReturn, m_headers, m_bodyStream, toStream); - } + const std::shared_ptr& toStream) const; template oatpp::async::Action readBodyToStringAsync(oatpp::async::AbstractCoroutine* parentCoroutine, diff --git a/src/oatpp/web/protocol/http/outgoing/BufferBody.cpp b/src/oatpp/web/protocol/http/outgoing/BufferBody.cpp index 0425790e..da33072f 100644 --- a/src/oatpp/web/protocol/http/outgoing/BufferBody.cpp +++ b/src/oatpp/web/protocol/http/outgoing/BufferBody.cpp @@ -23,3 +23,42 @@ ***************************************************************************/ #include "BufferBody.hpp" + +namespace oatpp { namespace web { namespace protocol { namespace http { namespace outgoing { + +BufferBody::WriteToStreamCoroutine::WriteToStreamCoroutine(const std::shared_ptr& body, + const std::shared_ptr& stream) + : m_body(body) + , m_stream(stream) + , m_currData(m_body->m_buffer->getData()) + , m_currDataSize(m_body->m_buffer->getSize()) +{} + +async::Action BufferBody::WriteToStreamCoroutine::act() { + return oatpp::data::stream::writeExactSizeDataAsyncInline(m_stream.get(), m_currData, m_currDataSize, finish()); +} + +BufferBody::BufferBody(const oatpp::String& buffer) + : m_buffer(buffer) +{} + +std::shared_ptr BufferBody::createShared(const oatpp::String& buffer) { + return Shared_Http_Outgoing_BufferBody_Pool::allocateShared(buffer); +} + +void BufferBody::declareHeaders(Headers& headers) noexcept { + headers[oatpp::web::protocol::http::Header::CONTENT_LENGTH] = oatpp::utils::conversion::int32ToStr(m_buffer->getSize()); +} + +void BufferBody::writeToStream(const std::shared_ptr& stream) noexcept { + oatpp::data::stream::writeExactSizeData(stream.get(), m_buffer->getData(), m_buffer->getSize()); +} + + +async::Action BufferBody::writeToStreamAsync(oatpp::async::AbstractCoroutine* parentCoroutine, + const Action& actionOnReturn, + const std::shared_ptr& stream) { + return parentCoroutine->startCoroutine(actionOnReturn, getSharedPtr(), stream); +} + +}}}}} \ No newline at end of file diff --git a/src/oatpp/web/protocol/http/outgoing/BufferBody.hpp b/src/oatpp/web/protocol/http/outgoing/BufferBody.hpp index e8bf964d..13291fec 100644 --- a/src/oatpp/web/protocol/http/outgoing/BufferBody.hpp +++ b/src/oatpp/web/protocol/http/outgoing/BufferBody.hpp @@ -38,22 +38,12 @@ public: private: oatpp::String m_buffer; public: - BufferBody(const oatpp::String& buffer) - : m_buffer(buffer) - {} + BufferBody(const oatpp::String& buffer); public: - static std::shared_ptr createShared(const oatpp::String& buffer) { - return Shared_Http_Outgoing_BufferBody_Pool::allocateShared(buffer); - } - - void declareHeaders(Headers& headers) noexcept override { - headers[oatpp::web::protocol::http::Header::CONTENT_LENGTH] = oatpp::utils::conversion::int32ToStr(m_buffer->getSize()); - } - - void writeToStream(const std::shared_ptr& stream) noexcept override { - oatpp::data::stream::writeExactSizeData(stream.get(), m_buffer->getData(), m_buffer->getSize()); - } + static std::shared_ptr createShared(const oatpp::String& buffer); + void declareHeaders(Headers& headers) noexcept override; + void writeToStream(const std::shared_ptr& stream) noexcept override; public: @@ -66,16 +56,9 @@ public: public: WriteToStreamCoroutine(const std::shared_ptr& body, - const std::shared_ptr& stream) - : m_body(body) - , m_stream(stream) - , m_currData(m_body->m_buffer->getData()) - , m_currDataSize(m_body->m_buffer->getSize()) - {} + const std::shared_ptr& stream); - Action act() override { - return oatpp::data::stream::writeExactSizeDataAsyncInline(m_stream.get(), m_currData, m_currDataSize, finish()); - } + Action act() override; }; @@ -83,9 +66,7 @@ public: Action writeToStreamAsync(oatpp::async::AbstractCoroutine* parentCoroutine, const Action& actionOnReturn, - const std::shared_ptr& stream) override { - return parentCoroutine->startCoroutine(actionOnReturn, getSharedPtr(), stream); - } + const std::shared_ptr& stream) override; }; diff --git a/src/oatpp/web/protocol/http/outgoing/ChunkedBufferBody.cpp b/src/oatpp/web/protocol/http/outgoing/ChunkedBufferBody.cpp index 9c8ccfdc..e4afa3df 100644 --- a/src/oatpp/web/protocol/http/outgoing/ChunkedBufferBody.cpp +++ b/src/oatpp/web/protocol/http/outgoing/ChunkedBufferBody.cpp @@ -27,5 +27,105 @@ namespace oatpp { namespace web { namespace protocol { namespace http { namespace outgoing { const char* ChunkedBufferBody::ERROR_FAILED_TO_WRITE_DATA = "ERROR_FAILED_TO_WRITE_DATA"; - + +ChunkedBufferBody::ChunkedBufferBody(const std::shared_ptr& buffer, bool chunked) + : m_buffer(buffer) + , m_chunked(chunked) +{} + + +std::shared_ptr ChunkedBufferBody::createShared(const std::shared_ptr& buffer) { + return Shared_Http_Outgoing_ChunkedBufferBody_Pool::allocateShared(buffer, false); +} + +std::shared_ptr ChunkedBufferBody::createShared(const std::shared_ptr& buffer, bool chunked) { + return Shared_Http_Outgoing_ChunkedBufferBody_Pool::allocateShared(buffer, chunked); +} + +void ChunkedBufferBody::declareHeaders(Headers& headers) noexcept { + if(m_chunked){ + headers[oatpp::web::protocol::http::Header::TRANSFER_ENCODING] = oatpp::web::protocol::http::Header::Value::TRANSFER_ENCODING_CHUNKED; + } else { + headers[oatpp::web::protocol::http::Header::CONTENT_LENGTH] = oatpp::utils::conversion::int64ToStr(m_buffer->getSize()); + } +} + +void ChunkedBufferBody::writeToStream(const std::shared_ptr& stream) noexcept { + if(m_chunked) { + auto chunks = m_buffer->getChunks(); + auto curr = chunks->getFirstNode(); + while (curr != nullptr) { + stream->write(oatpp::utils::conversion::primitiveToStr(curr->getData()->size, "%X")); + stream->write("\r\n", 2); + stream->write(curr->getData()->data, curr->getData()->size); + stream->write("\r\n", 2); + curr = curr->getNext(); + } + stream->write("0\r\n\r\n", 5); + } else { + m_buffer->flushToStream(stream); + } +} + +ChunkedBufferBody::WriteToStreamCoroutine::WriteToStreamCoroutine(const std::shared_ptr& body, + const std::shared_ptr& stream) + : m_body(body) + , m_stream(stream) + , m_chunks(m_body->m_buffer->getChunks()) + , m_currChunk(m_chunks->getFirstNode()) + , m_currData(nullptr) + , m_currDataSize(0) + , m_nextAction(Action(Action::TYPE_FINISH, nullptr, nullptr)) +{} + +async::Action ChunkedBufferBody::WriteToStreamCoroutine::act() { + if(m_currChunk == nullptr) { + return yieldTo(&WriteToStreamCoroutine::writeEndOfChunks); + } + return yieldTo(&WriteToStreamCoroutine::writeChunkSize); +} + +async::Action ChunkedBufferBody::WriteToStreamCoroutine::writeChunkSize() { + m_currDataSize = oatpp::utils::conversion::primitiveToCharSequence(m_currChunk->getData()->size, m_buffer, "%X\r\n"); + m_currData = m_buffer; + m_nextAction = yieldTo(&WriteToStreamCoroutine::writeChunkData); + return yieldTo(&WriteToStreamCoroutine::writeCurrData); +} + +async::Action ChunkedBufferBody::WriteToStreamCoroutine::writeChunkData() { + m_currData = m_currChunk->getData()->data; + m_currDataSize = (v_int32) m_currChunk->getData()->size; + m_nextAction = yieldTo(&WriteToStreamCoroutine::writeChunkSeparator); + return yieldTo(&WriteToStreamCoroutine::writeCurrData); +} + +async::Action ChunkedBufferBody::WriteToStreamCoroutine::writeChunkSeparator() { + m_currData = (void*) "\r\n"; + m_currDataSize = 2; + m_currChunk = m_currChunk->getNext(); + m_nextAction = yieldTo(&WriteToStreamCoroutine::act); + return yieldTo(&WriteToStreamCoroutine::writeCurrData); +} + +async::Action ChunkedBufferBody::WriteToStreamCoroutine::writeEndOfChunks() { + m_currData = (void*) "0\r\n\r\n"; + m_currDataSize = 5; + m_nextAction = finish(); + return yieldTo(&WriteToStreamCoroutine::writeCurrData); +} + +async::Action ChunkedBufferBody::WriteToStreamCoroutine::writeCurrData() { + return oatpp::data::stream::writeExactSizeDataAsyncInline(m_stream.get(), m_currData, m_currDataSize, m_nextAction); +} + +async::Action ChunkedBufferBody::writeToStreamAsync(oatpp::async::AbstractCoroutine* parentCoroutine, + const Action& actionOnFinish, + const std::shared_ptr& stream) { + if(m_chunked) { + return parentCoroutine->startCoroutine(actionOnFinish, getSharedPtr(), stream); + } else { + return m_buffer->flushToStreamAsync(parentCoroutine, actionOnFinish, stream); + } +} + }}}}} diff --git a/src/oatpp/web/protocol/http/outgoing/ChunkedBufferBody.hpp b/src/oatpp/web/protocol/http/outgoing/ChunkedBufferBody.hpp index f43a59d0..2219b565 100644 --- a/src/oatpp/web/protocol/http/outgoing/ChunkedBufferBody.hpp +++ b/src/oatpp/web/protocol/http/outgoing/ChunkedBufferBody.hpp @@ -42,46 +42,16 @@ protected: std::shared_ptr m_buffer; bool m_chunked; public: - ChunkedBufferBody(const std::shared_ptr& buffer, - bool chunked) - : m_buffer(buffer) - , m_chunked(chunked) - {} + ChunkedBufferBody(const std::shared_ptr& buffer, bool chunked); public: - static std::shared_ptr createShared(const std::shared_ptr& buffer) { - return Shared_Http_Outgoing_ChunkedBufferBody_Pool::allocateShared(buffer, false); - } + static std::shared_ptr createShared(const std::shared_ptr& buffer); - static std::shared_ptr createShared(const std::shared_ptr& buffer, - bool chunked) { - return Shared_Http_Outgoing_ChunkedBufferBody_Pool::allocateShared(buffer, chunked); - } + static std::shared_ptr createShared(const std::shared_ptr& buffer, bool chunked); - void declareHeaders(Headers& headers) noexcept override { - if(m_chunked){ - headers[oatpp::web::protocol::http::Header::TRANSFER_ENCODING] = oatpp::web::protocol::http::Header::Value::TRANSFER_ENCODING_CHUNKED; - } else { - headers[oatpp::web::protocol::http::Header::CONTENT_LENGTH] = oatpp::utils::conversion::int64ToStr(m_buffer->getSize()); - } - } + void declareHeaders(Headers& headers) noexcept override; - void writeToStream(const std::shared_ptr& stream) noexcept override { - if(m_chunked){ - auto chunks = m_buffer->getChunks(); - auto curr = chunks->getFirstNode(); - while (curr != nullptr) { - stream->write(oatpp::utils::conversion::primitiveToStr(curr->getData()->size, "%X")); - stream->write("\r\n", 2); - stream->write(curr->getData()->data, curr->getData()->size); - stream->write("\r\n", 2); - curr = curr->getNext(); - } - stream->write("0\r\n\r\n", 5); - } else { - m_buffer->flushToStream(stream); - } - } + void writeToStream(const std::shared_ptr& stream) noexcept override; public: @@ -98,67 +68,20 @@ public: public: WriteToStreamCoroutine(const std::shared_ptr& body, - const std::shared_ptr& stream) - : m_body(body) - , m_stream(stream) - , m_chunks(m_body->m_buffer->getChunks()) - , m_currChunk(m_chunks->getFirstNode()) - , m_currData(nullptr) - , m_currDataSize(0) - , m_nextAction(Action(Action::TYPE_FINISH, nullptr, nullptr)) - {} + const std::shared_ptr& stream); - Action act() override { - if(m_currChunk == nullptr) { - return yieldTo(&WriteToStreamCoroutine::writeEndOfChunks); - } - return yieldTo(&WriteToStreamCoroutine::writeChunkSize); - } - - Action writeChunkSize() { - m_currDataSize = oatpp::utils::conversion::primitiveToCharSequence(m_currChunk->getData()->size, m_buffer, "%X\r\n"); - m_currData = m_buffer; - m_nextAction = yieldTo(&WriteToStreamCoroutine::writeChunkData); - return yieldTo(&WriteToStreamCoroutine::writeCurrData); - } - - Action writeChunkData() { - m_currData = m_currChunk->getData()->data; - m_currDataSize = (v_int32) m_currChunk->getData()->size; - m_nextAction = yieldTo(&WriteToStreamCoroutine::writeChunkSeparator); - return yieldTo(&WriteToStreamCoroutine::writeCurrData); - } - - Action writeChunkSeparator() { - m_currData = (void*) "\r\n"; - m_currDataSize = 2; - m_currChunk = m_currChunk->getNext(); - m_nextAction = yieldTo(&WriteToStreamCoroutine::act); - return yieldTo(&WriteToStreamCoroutine::writeCurrData); - } - - Action writeEndOfChunks() { - m_currData = (void*) "0\r\n\r\n"; - m_currDataSize = 5; - m_nextAction = finish(); - return yieldTo(&WriteToStreamCoroutine::writeCurrData); - } - - Action writeCurrData() { - return oatpp::data::stream::writeExactSizeDataAsyncInline(m_stream.get(), m_currData, m_currDataSize, m_nextAction); - } + Action act() override; + Action writeChunkSize(); + Action writeChunkData(); + Action writeChunkSeparator(); + Action writeEndOfChunks(); + Action writeCurrData(); }; Action writeToStreamAsync(oatpp::async::AbstractCoroutine* parentCoroutine, const Action& actionOnFinish, - const std::shared_ptr& stream) override { - if(m_chunked) { - return parentCoroutine->startCoroutine(actionOnFinish, getSharedPtr(), stream); - } else { - return m_buffer->flushToStreamAsync(parentCoroutine, actionOnFinish, stream); - } - } + const std::shared_ptr& stream) override; }; diff --git a/src/oatpp/web/protocol/http/outgoing/DtoBody.cpp b/src/oatpp/web/protocol/http/outgoing/DtoBody.cpp index e85f229e..584dbb71 100644 --- a/src/oatpp/web/protocol/http/outgoing/DtoBody.cpp +++ b/src/oatpp/web/protocol/http/outgoing/DtoBody.cpp @@ -23,3 +23,38 @@ ***************************************************************************/ #include "./DtoBody.hpp" + +namespace oatpp { namespace web { namespace protocol { namespace http { namespace outgoing { + +DtoBody::DtoBody(const oatpp::data::mapping::type::AbstractObjectWrapper& dto, + oatpp::data::mapping::ObjectMapper* objectMapper, + bool chunked) + : ChunkedBufferBody(oatpp::data::stream::ChunkedBuffer::createShared(), chunked) + , m_dto(dto) + , m_objectMapper(objectMapper) +{} + +std::shared_ptr DtoBody::createShared(const oatpp::data::mapping::type::AbstractObjectWrapper& dto, + oatpp::data::mapping::ObjectMapper* objectMapper) { + return Shared_Http_Outgoing_DtoBody_Pool::allocateShared(dto, objectMapper, false); +} + +std::shared_ptr DtoBody::createShared(const oatpp::data::mapping::type::AbstractObjectWrapper& dto, + oatpp::data::mapping::ObjectMapper* objectMapper, + bool chunked) { + return Shared_Http_Outgoing_DtoBody_Pool::allocateShared(dto, objectMapper, chunked); +} + +void DtoBody::declareHeaders(Headers& headers) noexcept { + if(m_dto) { + m_objectMapper->write(m_buffer, m_dto); + } + ChunkedBufferBody::declareHeaders(headers); + + auto it = headers.find(Header::CONTENT_TYPE); + if(it == headers.end()) { + headers[Header::CONTENT_TYPE] = m_objectMapper->getInfo().http_content_type; + } +} + +}}}}} \ No newline at end of file diff --git a/src/oatpp/web/protocol/http/outgoing/DtoBody.hpp b/src/oatpp/web/protocol/http/outgoing/DtoBody.hpp index 4f8940be..1590c306 100644 --- a/src/oatpp/web/protocol/http/outgoing/DtoBody.hpp +++ b/src/oatpp/web/protocol/http/outgoing/DtoBody.hpp @@ -42,35 +42,17 @@ private: public: DtoBody(const oatpp::data::mapping::type::AbstractObjectWrapper& dto, oatpp::data::mapping::ObjectMapper* objectMapper, - bool chunked) - : ChunkedBufferBody(oatpp::data::stream::ChunkedBuffer::createShared(), chunked) - , m_dto(dto) - , m_objectMapper(objectMapper) - {} + bool chunked); public: static std::shared_ptr createShared(const oatpp::data::mapping::type::AbstractObjectWrapper& dto, - oatpp::data::mapping::ObjectMapper* objectMapper) { - return Shared_Http_Outgoing_DtoBody_Pool::allocateShared(dto, objectMapper, false); - } + oatpp::data::mapping::ObjectMapper* objectMapper); static std::shared_ptr createShared(const oatpp::data::mapping::type::AbstractObjectWrapper& dto, oatpp::data::mapping::ObjectMapper* objectMapper, - bool chunked) { - return Shared_Http_Outgoing_DtoBody_Pool::allocateShared(dto, objectMapper, chunked); - } + bool chunked); - void declareHeaders(Headers& headers) noexcept override { - if(m_dto) { - m_objectMapper->write(m_buffer, m_dto); - } - ChunkedBufferBody::declareHeaders(headers); - - auto it = headers.find(Header::CONTENT_TYPE); - if(it == headers.end()) { - headers[Header::CONTENT_TYPE] = m_objectMapper->getInfo().http_content_type; - } - } + void declareHeaders(Headers& headers) noexcept override; }; diff --git a/src/oatpp/web/protocol/http/outgoing/Request.cpp b/src/oatpp/web/protocol/http/outgoing/Request.cpp index 4fbafb64..ac9172b7 100644 --- a/src/oatpp/web/protocol/http/outgoing/Request.cpp +++ b/src/oatpp/web/protocol/http/outgoing/Request.cpp @@ -26,7 +26,55 @@ #include "oatpp/core/data/stream/ChunkedBuffer.hpp" namespace oatpp { namespace web { namespace protocol { namespace http { namespace outgoing { - + +Request::Request() {} + +Request::Request(const oatpp::data::share::StringKeyLabel& method, + const oatpp::data::share::StringKeyLabel& path, + const Headers& headers, + const std::shared_ptr& body) + : m_method(method) + , m_path(path) + , m_headers(headers) + , m_body(body) +{} + +std::shared_ptr Request::createShared(const oatpp::data::share::StringKeyLabel& method, + const oatpp::data::share::StringKeyLabel& path, + const Headers& headers, + const std::shared_ptr& body) { + return Shared_Outgoing_Request_Pool::allocateShared(method, path, headers, body); +} + +const oatpp::data::share::StringKeyLabel& Request::getMethod() const { + return m_method; +} + +const oatpp::data::share::StringKeyLabel& Request::getPath() const { + return m_path; +} + +protocol::http::Protocol::Headers& Request::getHeaders() { + return m_headers; +} + +void Request::putHeader(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value) { + m_headers[key] = value; +} + +bool Request::putHeaderIfNotExists(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value) { + auto it = m_headers.find(key); + if(it == m_headers.end()) { + m_headers.insert({key, value}); + return true; + } + return false; +} + +std::shared_ptr Request::getBody() { + return m_body; +} + void Request::send(const std::shared_ptr& stream){ if(m_body){ diff --git a/src/oatpp/web/protocol/http/outgoing/Request.hpp b/src/oatpp/web/protocol/http/outgoing/Request.hpp index 52515ee4..9d2d7fc4 100644 --- a/src/oatpp/web/protocol/http/outgoing/Request.hpp +++ b/src/oatpp/web/protocol/http/outgoing/Request.hpp @@ -43,55 +43,31 @@ private: std::shared_ptr m_body; public: - Request() {} + Request(); Request(const oatpp::data::share::StringKeyLabel& method, const oatpp::data::share::StringKeyLabel& path, const Headers& headers, - const std::shared_ptr& body) - : m_method(method) - , m_path(path) - , m_headers(headers) - , m_body(body) - {} + const std::shared_ptr& body); public: static std::shared_ptr createShared(const oatpp::data::share::StringKeyLabel& method, const oatpp::data::share::StringKeyLabel& path, const Headers& headers, - const std::shared_ptr& body) { - return Shared_Outgoing_Request_Pool::allocateShared(method, path, headers, body); - } + const std::shared_ptr& body); - const oatpp::data::share::StringKeyLabel& getMethod() const { - return m_method; - } + const oatpp::data::share::StringKeyLabel& getMethod() const; - const oatpp::data::share::StringKeyLabel& getPath() const { - return m_path; - } + const oatpp::data::share::StringKeyLabel& getPath() const; - Headers& getHeaders() { - return m_headers; - } + Headers& getHeaders(); - void putHeader(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value) { - m_headers[key] = value; - } + void putHeader(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value); - bool putHeaderIfNotExists(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value) { - auto it = m_headers.find(key); - if(it == m_headers.end()) { - m_headers.insert({key, value}); - return true; - } - return false; - } + bool putHeaderIfNotExists(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value); - std::shared_ptr getBody() { - return m_body; - } + std::shared_ptr getBody(); void send(const std::shared_ptr& stream); diff --git a/src/oatpp/web/protocol/http/outgoing/Response.cpp b/src/oatpp/web/protocol/http/outgoing/Response.cpp index 760de47b..c8d39aca 100644 --- a/src/oatpp/web/protocol/http/outgoing/Response.cpp +++ b/src/oatpp/web/protocol/http/outgoing/Response.cpp @@ -27,7 +27,47 @@ #include "oatpp/core/data/stream/ChunkedBuffer.hpp" namespace oatpp { namespace web { namespace protocol { namespace http { namespace outgoing { - + +Response::Response(const Status& status, + const std::shared_ptr& body) + : m_status(status) + , m_body(body) +{} + +std::shared_ptr Response::createShared(const Status& status, + const std::shared_ptr& body) { + return Shared_Outgoing_Response_Pool::allocateShared(status, body); +} + +const Status& Response::getStatus() const { + return m_status; +} + +protocol::http::Protocol::Headers& Response::getHeaders() { + return m_headers; +} + +void Response::putHeader(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value) { + m_headers[key] = value; +} + +bool Response::putHeaderIfNotExists(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value) { + auto it = m_headers.find(key); + if(it == m_headers.end()) { + m_headers.insert({key, value}); + return true; + } + return false; +} + +void Response::setConnectionUpgradeHandler(const std::shared_ptr& handler) { + m_connectionUpgradeHandler = handler; +} + +std::shared_ptr Response::getConnectionUpgradeHandler() { + return m_connectionUpgradeHandler; +} + void Response::send(const std::shared_ptr& stream) { if(m_body){ diff --git a/src/oatpp/web/protocol/http/outgoing/Response.hpp b/src/oatpp/web/protocol/http/outgoing/Response.hpp index 31db02b2..ef9a7bef 100644 --- a/src/oatpp/web/protocol/http/outgoing/Response.hpp +++ b/src/oatpp/web/protocol/http/outgoing/Response.hpp @@ -44,46 +44,22 @@ private: std::shared_ptr m_body; std::shared_ptr m_connectionUpgradeHandler; public: - Response(const Status& status, - const std::shared_ptr& body) - : m_status(status) - , m_body(body) - {} + Response(const Status& status, const std::shared_ptr& body); public: - static std::shared_ptr createShared(const Status& status, - const std::shared_ptr& body) { - return Shared_Outgoing_Response_Pool::allocateShared(status, body); - } + static std::shared_ptr createShared(const Status& status, const std::shared_ptr& body); - const Status& getStatus() const { - return m_status; - } + const Status& getStatus() const; - Headers& getHeaders() { - return m_headers; - } + Headers& getHeaders(); - void putHeader(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value) { - m_headers[key] = value; - } + void putHeader(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value); - bool putHeaderIfNotExists(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value) { - auto it = m_headers.find(key); - if(it == m_headers.end()) { - m_headers.insert({key, value}); - return true; - } - return false; - } + bool putHeaderIfNotExists(const oatpp::data::share::StringKeyLabelCI_FAST& key, const oatpp::data::share::StringKeyLabel& value); - void setConnectionUpgradeHandler(const std::shared_ptr& handler) { - m_connectionUpgradeHandler = handler; - } + void setConnectionUpgradeHandler(const std::shared_ptr& handler); - std::shared_ptr getConnectionUpgradeHandler() { - return m_connectionUpgradeHandler; - } + std::shared_ptr getConnectionUpgradeHandler(); void send(const std::shared_ptr& stream); diff --git a/test/oatpp/AllTestsMain.cpp b/test/oatpp/AllTestsMain.cpp index ea2c1a05..14a819b0 100644 --- a/test/oatpp/AllTestsMain.cpp +++ b/test/oatpp/AllTestsMain.cpp @@ -50,7 +50,7 @@ public: }; void runTests() { - + OATPP_RUN_TEST(oatpp::test::base::RegRuleTest); OATPP_RUN_TEST(oatpp::test::base::CommandLineArgumentsTest);