/** * * HttpRequestParser.h * An Tao * * Copyright 2018, An Tao. All rights reserved. * https://github.com/an-tao/drogon * Use of this source code is governed by a MIT license * that can be found in the License file. * * Drogon * */ #pragma once #include #include #include #include #include #include #include #include "impl_forwards.h" namespace drogon { class HttpRequestParser : public trantor::NonCopyable, public std::enable_shared_from_this { public: enum class HttpRequestParseStatus { kExpectMethod, kExpectRequestLine, kExpectHeaders, kExpectBody, kExpectChunkLen, kExpectChunkBody, kExpectLastEmptyChunk, kGotAll, }; explicit HttpRequestParser(const trantor::TcpConnectionPtr &connPtr); int parseRequest(trantor::MsgBuffer *buf); bool gotAll() const { return status_ == HttpRequestParseStatus::kGotAll; } void reset(); const HttpRequestImplPtr &requestImpl() const { return request_; } bool firstReq() { if (firstRequest_) { firstRequest_ = false; return true; } return false; } const WebSocketConnectionImplPtr &webSocketConn() const { return websockConnPtr_; } void setWebsockConnection(const WebSocketConnectionImplPtr &conn) { websockConnPtr_ = conn; } // to support request pipelining(rfc2616-8.1.2.2) void pushRequestToPipelining(const HttpRequestPtr &, bool isHeadMethod); bool pushResponseToPipelining(const HttpRequestPtr &, HttpResponsePtr); void popReadyResponses(std::vector> &); size_t numberOfRequestsInPipelining() const { return requestPipelining_.size(); } bool emptyPipelining() { return requestPipelining_.empty(); } bool isStop() const { return stopWorking_; } void stop() { stopWorking_ = true; } size_t numberOfRequestsParsed() const { return requestsCounter_; } trantor::MsgBuffer &getBuffer() { return sendBuffer_; } std::vector> &getResponseBuffer() { assert(loop_->isInLoopThread()); if (!responseBuffer_) { responseBuffer_ = std::unique_ptr>>( new std::vector>); } return *responseBuffer_; } std::vector &getRequestBuffer() { assert(loop_->isInLoopThread()); if (!requestBuffer_) { requestBuffer_ = std::unique_ptr>( new std::vector); } return *requestBuffer_; } private: HttpRequestImplPtr makeRequestForPool(HttpRequestImpl *p); bool processRequestLine(const char *begin, const char *end); HttpRequestParseStatus status_; trantor::EventLoop *loop_; HttpRequestImplPtr request_; bool firstRequest_{true}; WebSocketConnectionImplPtr websockConnPtr_; std::deque>> requestPipelining_; size_t requestsCounter_{0}; std::weak_ptr conn_; bool stopWorking_{false}; trantor::MsgBuffer sendBuffer_; std::unique_ptr>> responseBuffer_; std::unique_ptr> requestBuffer_; std::vector requestsPool_; size_t currentChunkLength_{0}; size_t remainContentLength_{0}; }; } // namespace drogon