123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- /***************************************************************************
- *
- * Project _____ __ ____ _ _
- * ( _ ) /__\ (_ _)_| |_ _| |_
- * )(_)( /(__)\ )( (_ _)(_ _)
- * (_____)(__)(__)(__) |_| |_|
- *
- *
- * Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ***************************************************************************/
- #ifndef oatpp_web_protocol_http_incoming_Request_hpp
- #define oatpp_web_protocol_http_incoming_Request_hpp
- #include "oatpp/web/protocol/http/Http.hpp"
- #include "oatpp/web/protocol/http/incoming/BodyDecoder.hpp"
- #include "oatpp/web/url/mapping/Pattern.hpp"
- #include "oatpp/network/Url.hpp"
- #include "oatpp/core/data/Bundle.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::Countable {
- private:
- std::shared_ptr<oatpp::data::stream::IOStream> m_connection;
- http::RequestStartingLine m_startingLine;
- url::mapping::Pattern::MatchMap m_pathVariables;
- http::Headers m_headers;
- std::shared_ptr<oatpp::data::stream::InputStream> m_bodyStream;
-
- /*
- * Request should be preconfigured with default BodyDecoder.
- * Custom BodyDecoder can be set on demand
- */
- std::shared_ptr<const http::incoming::BodyDecoder> m_bodyDecoder;
- mutable bool m_queryParamsParsed; // used for lazy parsing of QueryParams
- mutable http::QueryParams m_queryParams;
- data::Bundle m_bundle;
- public:
-
- Request(const std::shared_ptr<oatpp::data::stream::IOStream>& connection,
- const http::RequestStartingLine& startingLine,
- const http::Headers& headers,
- const std::shared_ptr<oatpp::data::stream::InputStream>& bodyStream,
- const std::shared_ptr<const http::incoming::BodyDecoder>& bodyDecoder);
- public:
-
- static std::shared_ptr<Request> createShared(const std::shared_ptr<oatpp::data::stream::IOStream>& connection,
- const http::RequestStartingLine& startingLine,
- const http::Headers& headers,
- const std::shared_ptr<oatpp::data::stream::InputStream>& bodyStream,
- const std::shared_ptr<const http::incoming::BodyDecoder>& bodyDecoder);
- /**
- * Get raw connection stream.
- * @return - &id:std::shared_ptr<oatpp::data::stream::IOStream> m_connection;.
- */
- std::shared_ptr<oatpp::data::stream::IOStream> getConnection();
- /**
- * Get map of url query parameters.
- * Query parameters will be lazy parsed from url "tail"
- * Please note: lazy parsing of query parameters is not thread-safe!
- * @return map<key, value> for "&key=value"
- */
- const http::QueryParams& getQueryParameters() const;
- /**
- * Get query parameter value by name
- * @param name
- * @return query parameter value
- */
- oatpp::String getQueryParameter(const oatpp::data::share::StringKeyLabel& name) const;
- /**
- * Get query parameter value by name with defaultValue
- * @param name
- * @param defaultValue
- * @return query parameter value or defaultValue if no such parameter found
- */
- oatpp::String getQueryParameter(const oatpp::data::share::StringKeyLabel& name, const oatpp::String& defaultValue) const;
- /**
- * Get request starting line. (method, path, protocol)
- * @return starting line structure
- */
- const http::RequestStartingLine& getStartingLine() const;
- /**
- * Set request path variables.
- * @param pathVariables - &id:oatpp::web::url::mapping::Pattern::MatchMap;.
- */
- void setPathVariables(const url::mapping::Pattern::MatchMap& pathVariables);
- /**
- * Get path variables according to path-pattern. <br>
- * Ex. given request path="/sum/19/1" for path-pattern="/sum/{a}/{b}" <br>
- * 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::Headers& getHeaders() const;
- /**
- * Get request's body stream
- * @return body stream
- */
- std::shared_ptr<oatpp::data::stream::InputStream> getBodyStream() const;
- /**
- * Get body decoder.
- * @return Body decoder
- */
- std::shared_ptr<const http::incoming::BodyDecoder> getBodyDecoder() const;
- /**
- * Add http header.
- * @param key - &id:oatpp::String;.
- * @param value - &id:oatpp::String;.
- */
- void putHeader(const oatpp::String& key, const oatpp::String& value);
- /**
- * Add http header if not already exists.
- * @param key - &id:oatpp::String;.
- * @param value - &id:oatpp::String;.
- * @return - `true` if header was added.
- */
- bool putHeaderIfNotExists(const oatpp::String& key, const oatpp::String& value);
- /**
- * Replaces or adds header.
- * @param key - &id:oatpp::String;.
- * @param value - &id:oatpp::String;.
- * @return - `true` if header was replaces, `false` if header was added.
- */
- bool putOrReplaceHeader(const oatpp::String& key, const oatpp::String& value);
- /**
- * Replaces or adds header.
- * @param key - &id:oatpp::data::share::StringKeyLabelCI;.
- * @param value - &id:oatpp::data::share::StringKeyLabel;.
- * @return - `true` if header was replaces, `false` if header was added.
- */
- bool putOrReplaceHeader_Unsafe(const oatpp::data::share::StringKeyLabelCI& key, const oatpp::data::share::StringKeyLabel& value);
- /**
- * Add http header.
- * @param key - &id:oatpp::data::share::StringKeyLabelCI;.
- * @param value - &id:oatpp::data::share::StringKeyLabel;.
- */
- void putHeader_Unsafe(const oatpp::data::share::StringKeyLabelCI& key, const oatpp::data::share::StringKeyLabel& value);
- /**
- * Add http header if not already exists.
- * @param key - &id:oatpp::data::share::StringKeyLabelCI;.
- * @param value - &id:oatpp::data::share::StringKeyLabel;.
- * @return - `true` if header was added.
- */
- bool putHeaderIfNotExists_Unsafe(const oatpp::data::share::StringKeyLabelCI& key, const oatpp::data::share::StringKeyLabel& value);
- /**
- * Get header value
- * @param headerName - &id:oatpp::data::share::StringKeyLabelCI;.
- * @return - &id:oatpp::String;.
- */
- oatpp::String getHeader(const oatpp::data::share::StringKeyLabelCI& 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;
- /**
- * Put data to bundle.
- * @param key
- * @param polymorph
- */
- void putBundleData(const oatpp::String& key, const oatpp::Void& polymorph);
- /**
- * Get data from bundle by key.
- * @tparam WrapperType
- * @param key
- * @return
- */
- template<typename WrapperType>
- WrapperType getBundleData(const oatpp::String& key) const {
- return m_bundle.template get<WrapperType>(key);
- }
- /**
- * Get bundle object.
- * @return
- */
- const data::Bundle& getBundle() const;
- /**
- * Transfer body. <br>
- * Read body chunk by chunk and pass chunks to the `writeCallback`.
- * @param writeCallback - &id:oatpp::data::stream::WriteCallback;.
- */
- void transferBody(const base::ObjectHandle<data::stream::WriteCallback>& writeCallback) const;
- /**
- * Stream content of the body-stream to toStream
- * @param toStream
- */
- void transferBodyToStream(const base::ObjectHandle<data::stream::OutputStream>& 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 Wrapper - ObjectWrapper type.
- * @param objectMapper
- * @return DTO
- */
- template<class Wrapper>
- Wrapper readBodyToDto(const base::ObjectHandle<data::mapping::ObjectMapper>& objectMapper) const {
- return objectMapper->readFromString<Wrapper>(m_bodyDecoder->decodeToString(m_headers, m_bodyStream.get(), m_connection.get()));
- }
-
- // Async
- /**
- * Transfer body in Asynchronous manner. <br>
- * Read body chunk by chunk and pass chunks to the `writeCallback`.
- * @param writeCallback - `std::shared_ptr` to &id:oatpp::data::stream::WriteCallback;.
- * @return - &id:oatpp::async::CoroutineStarter;.
- */
- async::CoroutineStarter transferBodyAsync(const std::shared_ptr<data::stream::WriteCallback>& writeCallback) const;
- /**
- * Transfer body stream to toStream Async
- * @param toStream
- * @return - &id:oatpp::async::CoroutineStarter;.
- */
- oatpp::async::CoroutineStarter transferBodyToStreamAsync(const std::shared_ptr<oatpp::data::stream::OutputStream>& toStream) const;
- /**
- * Transfer body stream to string Async.
- * @return - &id:oatpp::async::CoroutineStarterForResult;.
- */
- async::CoroutineStarterForResult<const oatpp::String&> readBodyToStringAsync() const;
- /**
- * Transfer body to String and parse it as DTO
- * @tparam Wrapper - DTO `ObjectWrapper`.
- * @param objectMapper
- * @return - &id:oatpp::async::CoroutineStarterForResult;.
- */
- template<class Wrapper>
- oatpp::async::CoroutineStarterForResult<const Wrapper&>
- readBodyToDtoAsync(const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& objectMapper) const {
- return m_bodyDecoder->decodeToDtoAsync<Wrapper>(m_headers, m_bodyStream, m_connection, objectMapper);
- }
-
- };
-
- }}}}}
- #endif /* oatpp_web_protocol_http_incoming_Request_hpp */
|