mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2025-05-02 13:47:56 +02:00
157 lines
4.0 KiB
C++
157 lines
4.0 KiB
C++
/**
|
|
*
|
|
* 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 "core/http_server_callbacks.h"
|
|
|
|
#include <core/http_types.h>
|
|
|
|
#include <trantor/utils/NonCopyable.h>
|
|
#include <trantor/net/TcpConnection.h>
|
|
#include <trantor/utils/MsgBuffer.h>
|
|
#include <mutex>
|
|
#include <deque>
|
|
|
|
namespace drogon
|
|
{
|
|
class HttpRequestParser : public trantor::NonCopyable,
|
|
public std::enable_shared_from_this<HttpRequestParser>
|
|
{
|
|
public:
|
|
enum class HttpRequestParseStatus
|
|
{
|
|
kExpectMethod,
|
|
kExpectRequestLine,
|
|
kExpectHeaders,
|
|
kExpectBody,
|
|
kExpectChunkLen,
|
|
kExpectChunkBody,
|
|
kExpectLastEmptyChunk,
|
|
kGotAll,
|
|
};
|
|
|
|
explicit HttpRequestParser(const trantor::TcpConnectionPtr &connPtr);
|
|
|
|
// return false if any error
|
|
bool parseRequest(trantor::MsgBuffer *buf);
|
|
|
|
bool gotAll() const
|
|
{
|
|
return status_ == HttpRequestParseStatus::kGotAll;
|
|
}
|
|
|
|
void reset();
|
|
|
|
const HttpRequestPtr &requestImpl() const
|
|
{
|
|
return request_;
|
|
}
|
|
|
|
bool firstReq()
|
|
{
|
|
if (firstRequest_)
|
|
{
|
|
firstRequest_ = false;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
const WebSocketConnectionPtr &webSocketConn() const
|
|
{
|
|
return websockConnPtr_;
|
|
}
|
|
void setWebsockConnection(const WebSocketConnectionPtr &conn)
|
|
{
|
|
websockConnPtr_ = conn;
|
|
}
|
|
// to support request pipelining(rfc2616-8.1.2.2)
|
|
void pushRequestToPipelining(const HttpRequestPtr &req);
|
|
HttpRequestPtr getFirstRequest() const;
|
|
std::pair<HttpResponsePtr, bool> getFirstResponse() const;
|
|
void popFirstRequest();
|
|
void pushResponseToPipelining(const HttpRequestPtr &req,
|
|
const HttpResponsePtr &resp,
|
|
bool isHeadMethod);
|
|
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<std::pair<HttpResponsePtr, bool>> &getResponseBuffer()
|
|
{
|
|
assert(loop_->isInLoopThread());
|
|
if (!responseBuffer_)
|
|
{
|
|
responseBuffer_ =
|
|
std::unique_ptr<std::vector<std::pair<HttpResponsePtr, bool>>>(
|
|
new std::vector<std::pair<HttpResponsePtr, bool>>);
|
|
}
|
|
return *responseBuffer_;
|
|
}
|
|
std::vector<HttpRequestPtr> &getRequestBuffer()
|
|
{
|
|
assert(loop_->isInLoopThread());
|
|
if (!requestBuffer_)
|
|
{
|
|
requestBuffer_ = std::unique_ptr<std::vector<HttpRequestPtr>>(
|
|
new std::vector<HttpRequestPtr>);
|
|
}
|
|
return *requestBuffer_;
|
|
}
|
|
|
|
private:
|
|
HttpRequestPtr makeRequestForPool(HttpRequest *p);
|
|
void shutdownConnection(HttpStatusCode code);
|
|
bool processRequestLine(const char *begin, const char *end);
|
|
HttpRequestParseStatus status_;
|
|
trantor::EventLoop *loop_;
|
|
HttpRequestPtr request_;
|
|
bool firstRequest_{true};
|
|
WebSocketConnectionPtr websockConnPtr_;
|
|
std::deque<std::pair<HttpRequestPtr, std::pair<HttpResponsePtr, bool>>>
|
|
requestPipelining_;
|
|
size_t requestsCounter_{0};
|
|
std::weak_ptr<trantor::TcpConnection> conn_;
|
|
bool stopWorking_{false};
|
|
trantor::MsgBuffer sendBuffer_;
|
|
std::unique_ptr<std::vector<std::pair<HttpResponsePtr, bool>>>
|
|
responseBuffer_;
|
|
std::unique_ptr<std::vector<HttpRequestPtr>> requestBuffer_;
|
|
std::vector<HttpRequestPtr> requestsPool_;
|
|
size_t currentChunkLength_;
|
|
size_t currentContentLength_{0};
|
|
};
|
|
|
|
} // namespace drogon
|