Response.hpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /***************************************************************************
  2. *
  3. * Project _____ __ ____ _ _
  4. * ( _ ) /__\ (_ _)_| |_ _| |_
  5. * )(_)( /(__)\ )( (_ _)(_ _)
  6. * (_____)(__)(__)(__) |_| |_|
  7. *
  8. *
  9. * Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. *
  23. ***************************************************************************/
  24. #ifndef oatpp_web_protocol_http_incoming_Response_hpp
  25. #define oatpp_web_protocol_http_incoming_Response_hpp
  26. #include "oatpp/web/protocol/http/Http.hpp"
  27. #include "oatpp/web/protocol/http/incoming/BodyDecoder.hpp"
  28. #include "oatpp/core/data/Bundle.hpp"
  29. namespace oatpp { namespace web { namespace protocol { namespace http { namespace incoming {
  30. /**
  31. * Class http::incoming::Response AKA IncomingResponse represents server's incoming response
  32. */
  33. class Response : public oatpp::base::Countable {
  34. private:
  35. v_int32 m_statusCode;
  36. oatpp::String m_statusDescription;
  37. http::Headers m_headers;
  38. std::shared_ptr<oatpp::data::stream::InputStream> m_bodyStream;
  39. /*
  40. * Response should be preconfigured with default BodyDecoder.
  41. * Entity that created response object is responsible for providing correct BodyDecoder.
  42. * Custom BodyDecoder can be set on demand
  43. */
  44. std::shared_ptr<const http::incoming::BodyDecoder> m_bodyDecoder;
  45. std::shared_ptr<oatpp::data::stream::IOStream> m_connection;
  46. data::Bundle m_bundle;
  47. public:
  48. /**
  49. * Constructor.
  50. * @param statusCode - http status code.
  51. * @param statusDescription - http status description.
  52. * @param headers - &id:oatpp::web::protocol::http::Headers;.
  53. * @param bodyStream - &id:oatpp::data::stream::InputStream;.
  54. * @param bodyDecoder - &id:oatpp::web::protocol::http::incoming::BodyDecoder;.
  55. */
  56. Response(v_int32 statusCode,
  57. const oatpp::String& statusDescription,
  58. const http::Headers& headers,
  59. const std::shared_ptr<oatpp::data::stream::InputStream>& bodyStream,
  60. const std::shared_ptr<const http::incoming::BodyDecoder>& bodyDecoder);
  61. public:
  62. /**
  63. * Create shared Response.
  64. * @param statusCode - http status code.
  65. * @param statusDescription - http status description.
  66. * @param headers - &id:oatpp::web::protocol::http::Headers;.
  67. * @param bodyStream - &id:oatpp::data::stream::InputStream;.
  68. * @param bodyDecoder - &id:oatpp::web::protocol::http::incoming::BodyDecoder;.
  69. * @return - `std::shared_ptr` to Response.
  70. */
  71. static std::shared_ptr<Response> createShared(v_int32 statusCode,
  72. const oatpp::String& statusDescription,
  73. const http::Headers& headers,
  74. const std::shared_ptr<oatpp::data::stream::InputStream>& bodyStream,
  75. const std::shared_ptr<const http::incoming::BodyDecoder>& bodyDecoder);
  76. /**
  77. * Get http status code.
  78. * @return - http status code.
  79. */
  80. v_int32 getStatusCode() const;
  81. /**
  82. * Get http status description.
  83. * @return - http status description.
  84. */
  85. oatpp::String getStatusDescription() const;
  86. /**
  87. * Get response http headers as &id:oatpp::web::protocol::http::Headers;.
  88. * @return - response http headers as &id:oatpp::web::protocol::http::Headers;.
  89. */
  90. const http::Headers& getHeaders() const;
  91. /**
  92. * Add http header.
  93. * @param key - &id:oatpp::String;.
  94. * @param value - &id:oatpp::String;.
  95. */
  96. void putHeader(const oatpp::String& key, const oatpp::String& value);
  97. /**
  98. * Add http header if not already exists.
  99. * @param key - &id:oatpp::String;.
  100. * @param value - &id:oatpp::String;.
  101. * @return - `true` if header was added.
  102. */
  103. bool putHeaderIfNotExists(const oatpp::String& key, const oatpp::String& value);
  104. /**
  105. * Replaces or adds header.
  106. * @param key - &id:oatpp::String;.
  107. * @param value - &id:oatpp::String;.
  108. * @return - `true` if header was replaces, `false` if header was added.
  109. */
  110. bool putOrReplaceHeader(const oatpp::String& key, const oatpp::String& value);
  111. /**
  112. * Replaces or adds header.
  113. * @param key - &id:oatpp::data::share::StringKeyLabelCI;.
  114. * @param value - &id:oatpp::data::share::StringKeyLabel;.
  115. * @return - `true` if header was replaces, `false` if header was added.
  116. */
  117. bool putOrReplaceHeader_Unsafe(const oatpp::data::share::StringKeyLabelCI& key, const oatpp::data::share::StringKeyLabel& value);
  118. /**
  119. * Add http header.
  120. * @param key - &id:oatpp::data::share::StringKeyLabelCI;.
  121. * @param value - &id:oatpp::data::share::StringKeyLabel;.
  122. */
  123. void putHeader_Unsafe(const oatpp::data::share::StringKeyLabelCI& key, const oatpp::data::share::StringKeyLabel& value);
  124. /**
  125. * Add http header if not already exists.
  126. * @param key - &id:oatpp::data::share::StringKeyLabelCI;.
  127. * @param value - &id:oatpp::data::share::StringKeyLabel;.
  128. * @return - `true` if header was added.
  129. */
  130. bool putHeaderIfNotExists_Unsafe(const oatpp::data::share::StringKeyLabelCI& key, const oatpp::data::share::StringKeyLabel& value);
  131. /**
  132. * Get header value
  133. * @param headerName - &id:oatpp::data::share::StringKeyLabelCI;.
  134. * @return - &id:oatpp::String;.
  135. */
  136. oatpp::String getHeader(const oatpp::data::share::StringKeyLabelCI& headerName) const;
  137. /**
  138. * Put data to bundle.
  139. * @param key
  140. * @param polymorph
  141. */
  142. void putBundleData(const oatpp::String& key, const oatpp::Void& polymorph);
  143. /**
  144. * Get data from bundle by key.
  145. * @tparam WrapperType
  146. * @param key
  147. * @return
  148. */
  149. template<typename WrapperType>
  150. WrapperType getBundleData(const oatpp::String& key) const {
  151. return m_bundle.template get<WrapperType>(key);
  152. }
  153. /**
  154. * Get bundle object.
  155. * @return
  156. */
  157. const data::Bundle& getBundle() const;
  158. /**
  159. * Get raw body stream.
  160. * @return - raw body stream as &id:oatpp::data::stream::InputStream;.
  161. */
  162. std::shared_ptr<data::stream::InputStream> getBodyStream() const;
  163. /**
  164. * Get body decoder configured for this response.
  165. * @return - &id:oatpp::web::protocol::http::incoming::BodyDecoder;.
  166. */
  167. std::shared_ptr<const http::incoming::BodyDecoder> getBodyDecoder() const;
  168. /**
  169. * Transfer body. <br>
  170. * Read body chunk by chunk and pass chunks to the `writeCallback`.
  171. * @param writeCallback - &id:oatpp::data::stream::WriteCallback;.
  172. */
  173. void transferBody(const base::ObjectHandle<data::stream::WriteCallback>& writeCallback) const;
  174. /**
  175. * Decode and transfer body to toStream.
  176. * Use case example - stream huge body directly to file using relatively small buffer.
  177. * @param toStream - pointer to &id:oatpp::data::stream::OutputStream;.
  178. */
  179. void transferBodyToStream(const base::ObjectHandle<data::stream::OutputStream>& toStream) const;
  180. /**
  181. * Decode and read body to &id:oatpp::String;.
  182. * @return - &id:oatpp::String;.
  183. */
  184. oatpp::String readBodyToString() const;
  185. /**
  186. * Read body stream, decode, and deserialize it as DTO Object (see [Data Transfer Object (DTO)](https://oatpp.io/docs/components/dto/)).
  187. * @tparam Wrapper - ObjectWrapper type.
  188. * @param objectMapper - `std::shared_ptr` to &id:oatpp::data::mapping::ObjectMapper;.
  189. * @return - deserialized DTO object.
  190. */
  191. template<class Wrapper>
  192. Wrapper readBodyToDto(const base::ObjectHandle<data::mapping::ObjectMapper>& objectMapper) const {
  193. return m_bodyDecoder->decodeToDto<Wrapper>(m_headers, m_bodyStream.get(), m_connection.get(), objectMapper.get());
  194. }
  195. // Async
  196. /**
  197. * Transfer body in Asynchronous manner. <br>
  198. * Read body chunk by chunk and pass chunks to the `writeCallback`.
  199. * @param writeCallback - `std::shared_ptr` to &id:oatpp::data::stream::WriteCallback;.
  200. * @return - &id:oatpp::async::CoroutineStarter;.
  201. */
  202. async::CoroutineStarter transferBodyAsync(const std::shared_ptr<data::stream::WriteCallback>& writeCallback) const;
  203. /**
  204. * Same as &l:Response::readBodyToDto (); but Async.
  205. * @param toStream - `std::shared_ptr` to &id:oatpp::data::stream::OutputStream;.
  206. * @return - &id:oatpp::async::CoroutineStarter;.
  207. */
  208. oatpp::async::CoroutineStarter transferBodyToStreamAsync(const std::shared_ptr<data::stream::OutputStream>& toStream) const;
  209. /**
  210. * Same as &l:Response::readBodyToString (); but Async.
  211. * @return - &id:oatpp::async::CoroutineStarterForResult;.
  212. */
  213. oatpp::async::CoroutineStarterForResult<const oatpp::String&> readBodyToStringAsync() const {
  214. return m_bodyDecoder->decodeToStringAsync(m_headers, m_bodyStream, m_connection);
  215. }
  216. /**
  217. * Same as &l:Response::readBodyToDto (); but Async.
  218. * @tparam Wrapper - ObjectWrapper type.
  219. * @param objectMapper - `std::shared_ptr` to &id:oatpp::data::mapping::ObjectMapper;.
  220. * @return - &id:oatpp::async::CoroutineStarterForResult;.
  221. */
  222. template<class Wrapper>
  223. oatpp::async::CoroutineStarterForResult<const Wrapper&>
  224. readBodyToDtoAsync(const std::shared_ptr<data::mapping::ObjectMapper>& objectMapper) const {
  225. return m_bodyDecoder->decodeToDtoAsync<Wrapper>(m_headers, m_bodyStream, m_connection, objectMapper);
  226. }
  227. };
  228. }}}}}
  229. #endif /* oatpp_web_protocol_http_incoming_Response_hpp */