SpiecsEngine
 
Loading...
Searching...
No Matches
HttpServer.cpp
Go to the documentation of this file.
1/**
2* @file HttpServer.cpp.
3* @brief The HttpServer Class Implementation.
4* @author Spices & Muduo.
5*/
6
7#include "Pchheader.h"
8#include "HttpServer.h"
9#include "HttpRequest.h"
10#include "HttpResponse.h"
11#include "HttpContext.h"
12
13namespace Spices {
14
15namespace Net {
16
18 const InetAddress& listenAddress ,
19 int idleSeconds ,
20 TcpServer::Option option
21 )
23 , m_HttpCallback(nullptr)
24 , m_IdleSeconds(idleSeconds)
25 {
27
28 m_Server.AddConnectionCallback(std::bind(&HttpServer::OnConnection, this, std::placeholders::_1));
29 m_Server.AddMessageCallback(std::bind(&HttpServer::OnMessage, this, std::placeholders::_1, std::placeholders::_2));
30 }
31
32 void HttpServer::Start(int threadSize) const
33 {
35
36 m_Server.Start(threadSize);
37 }
38
39 void HttpServer::OnConnection(const TcpConnectionPtr& connection)
40 {
42
43 if (connection->Connected())
44 {
45 SPICES_CORE_INFO("New Http Connection")
46
47 m_ConnectionList.push_back(connection);
48
49 Node node = --m_ConnectionList.end();
50 m_NameNodeMap[connection->GetName()] = node;
51 }
52 else
53 {
54 SPICES_CORE_INFO("Http Connection Closed")
55
56 assert(m_NameNodeMap.count(connection->GetName()));
57 const Node& node = m_NameNodeMap[connection->GetName()];
58 m_NameNodeMap.erase(connection->GetName());
59 m_ConnectionList.erase(node);
60 }
61 }
62
63 void HttpServer::OnMessage(const TcpConnectionPtr& connection, Buffer* buf)
64 {
66
67 auto context = std::make_unique<HttpContext>();
68
69 assert(m_NameNodeMap.count(connection->GetName()));
70 Node node = m_NameNodeMap[connection->GetName()];
71
72 m_ConnectionList.splice(m_ConnectionList.end(), m_ConnectionList, node);
73 assert(node == --m_ConnectionList.end());
74
75 if (!context->ParseRequest(buf))
76 {
77 SPICES_CORE_INFO("HttpContext ParseRequest Failed")
78
79 connection->Send("HTTP/1.1 400 Bad Request\r\n\r\n");
80 connection->ShutDown();
81 }
82
83 if (context->GotAll())
84 {
85 SPICES_CORE_INFO("HttpContext ParseRequest Succeed")
86
87 OnRequest(connection, context->GetRequest());
88 context->Reset();
89 }
90 }
91
92 void HttpServer::OnRequest(const TcpConnectionPtr& connection, const HttpRequest& request)
93 {
95
96 std::string connectionHeader = request.GetHeader("Connection");
97
98 bool close = connectionHeader == "close" || (request.GetVersion() == HttpRequest::Version::HTTP10 && connectionHeader != "Keep-Alive");
99
100 HttpResponse response(close);
101 m_HttpCallback(request, &response);
102
103 Buffer buf;
104 response.AppendToBuffer(&buf);
105 connection->Send(buf.RetrieveAllAsString());
106
107 if (response.CloseConnection())
108 {
109 connection->ShutDown();
110 }
111 }
112
113}
114
115}
#define SPICES_PROFILE_ZONE
Wrapper of readwrite buffer.
Definition Buffer.h:19
const Version GetVersion() const
Get Http Version.
Definition HttpRequest.h:89
std::string GetHeader(const std::string &name) const
Get a Header from this HttpRequest.
Http Request body.
Definition HttpRequest.h:18
HttpResponse(bool close)
Constructor Function.
void AppendToBuffer(Buffer *output)
Append this response to Buffer.
bool CloseConnection() const
Get CloseConnection.
void OnRequest(const TcpConnectionPtr &connection, const HttpRequest &request)
void OnConnection(const TcpConnectionPtr &connection)
HttpServer(const InetAddress &listenAddress, int idleSeconds, TcpServer::Option option=TcpServer::Option::NoReusePort)
Constructor Function.
void Start(int threadSize) const
Start ThreadPool and call listen on acceptor.
void OnMessage(const TcpConnectionPtr &connection, Buffer *buf)
This class is Wrapper of current socket address.
Definition InetAddress.h:22
Sample of a TcpServer.
Definition TcpServer.h:29