-
Notifications
You must be signed in to change notification settings - Fork 0
/
WebServer.hpp
112 lines (91 loc) · 2.43 KB
/
WebServer.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#pragma once
#include <array>
#include <functional>
#include "HttpRequest.hpp"
#include "HttpResponse.hpp"
#include "TcpSocket.hpp"
#include <vector>
namespace OlympusWebServer
{
class WebServer
{
private: // data
std::vector<TcpSocket> clients;
unsigned short port;
TcpSocket socket;
public: // data
std::function<HttpResponse(HttpRequest)> PostResponse;
public: // methods
WebServer(WebServer&& b)
{
*this = std::move(b);
}
WebServer& operator=(WebServer&& b)
{
clients = std::move(b.clients);
port = b.port;
socket = std::move(socket);
return *this;
}
explicit WebServer(unsigned short port_ = 8800) :
port(port_)
{
static const auto maxOpenAttempts = 100;
while (!socket.Open(true, port, false) && port < port_ + maxOpenAttempts)
{
++port;
}
}
HttpResponse HandleRequest(HttpRequest request)
{
return HttpResponse();
}
bool IsRunning() const
{
return socket.IsOpen() && socket.IsListening();
}
void Update()
{
if (!socket.IsOpen())
{
return;
}
// Accept a new client.
auto client = TcpSocket();
if (socket.Accept(client, false))
{
clients.push_back(std::move(client));
}
auto clientsToRemove = std::vector<std::size_t>();
for (auto i = 0u; i < clients.size(); ++i)
{
auto& client = clients[i];
// Remove a client if it is no longer open.
if (!client.IsOpen())
{
clientsToRemove.push_back(i);
continue;
}
// Receive the request from the client.
auto requestString = client.Receive();
if (requestString.empty())
{
continue;
}
auto request = HttpRequest(std::move(requestString));
// Send a continue if it is requested.
if (request.GetHttpVersion() == 1.1f && request["Expect"] == "100-continue")
{
client.Send(HttpResponse(HttpStatus::Continue).GetFormattedResponse());
}
// Process a response for the request.
client.Send(HandleRequest(std::move(request)).GetFormattedResponse());
}
// Destroy all clients that should be removed.
for (auto rit = clientsToRemove.rbegin(); rit != clientsToRemove.rend(); ++rit)
{
clients.erase(clients.begin() + *rit);
}
}
};
} // namespace OlympusWebServer