Skip to content

Commit f01aa62

Browse files
Accept multiple connections on port 80, one connection on port 8080
1 parent f38fd36 commit f01aa62

File tree

13 files changed

+188
-48
lines changed

13 files changed

+188
-48
lines changed

amp-embedded-infra-lib

postmaster/frontend/ReportingHttpServer.cpp

Lines changed: 88 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,93 @@ namespace application
1414
reporter(false, services::IPAddress());
1515
}
1616

17-
ReportingHttpServer::ReportingHttpServer(infra::BoundedString& buffer, services::ConnectionFactory& connectionFactory, uint16_t port, const infra::Function<void(bool open, services::IPAddress address)>& reporter)
18-
: SingleConnectionListener(connectionFactory, port, { connectionCreator })
17+
ReportingHttpServer::ReportingHttpServer(ConnectionAllocator& allocator, services::ConnectionFactory& connectionFactory, uint16_t port, const infra::Function<void(bool open, services::IPAddress address)>& reporter)
18+
: connectionAllocator(allocator)
1919
, reporter(reporter)
20-
, buffer(buffer)
21-
, connectionCreator([this](infra::Optional<ReportingHttpServerConnectionObserver>& value, services::IPAddress address)
22-
{
23-
value.Emplace(this->buffer, *this, this->reporter, address);
24-
})
25-
{}
20+
{
21+
listener = connectionFactory.Listen(port, *this, services::IPVersions::both);
22+
}
23+
24+
void ReportingHttpServer::Stop(const infra::Function<void()>& onDone, bool force)
25+
{
26+
listener = nullptr;
27+
waitingCreatedObserver = nullptr;
28+
29+
StopConnections(onDone, force);
30+
}
31+
32+
void ReportingHttpServer::SetNewConnectionStrategy(services::NewConnectionStrategy& newConnectionStrategy)
33+
{
34+
this->newConnectionStrategy = &newConnectionStrategy;
35+
}
36+
37+
void ReportingHttpServer::StopCurrentConnection(void* listener)
38+
{
39+
StopConnections([this]()
40+
{
41+
newConnectionStrategy->StartNewConnection();
42+
},
43+
false);
44+
}
45+
46+
void ReportingHttpServer::StartNewConnection()
47+
{
48+
connectionAllocator.OnAllocatable(nullptr);
49+
auto connectionObserver = connectionAllocator.Allocate(*this, reporter, waitingAddress);
50+
if (connectionObserver != nullptr)
51+
waitingCreatedObserver(connectionObserver);
52+
else
53+
{
54+
connectionAllocator.OnAllocatable([this]()
55+
{
56+
newConnectionStrategy->StartNewConnection();
57+
});
58+
59+
CloseOrAbortAllConnections(false);
60+
}
61+
}
62+
63+
void ReportingHttpServer::ConnectionAccepted(infra::AutoResetFunction<void(infra::SharedPtr<services::ConnectionObserver> connectionObserver)>&& createdObserver, services::IPAddress address)
64+
{
65+
waitingCreatedObserver = std::move(createdObserver);
66+
waitingAddress = address;
67+
68+
newConnectionStrategy->StartNewConnection();
69+
}
70+
71+
void ReportingHttpServer::StopConnections(const infra::Function<void()>& onDone, bool force)
72+
{
73+
onStopConnectionsDone = onDone;
74+
75+
if (connectionAllocator.NoneAllocated())
76+
onStopConnectionsDone();
77+
else
78+
connectionAllocator.OnAllocatable([this, force]()
79+
{
80+
StopConnections(onStopConnectionsDone, force);
81+
});
82+
83+
CloseOrAbortAllConnections(force);
84+
}
85+
86+
void ReportingHttpServer::CloseOrAbortAllConnections(bool force)
87+
{
88+
for (auto& connection : connections)
89+
if (force)
90+
connection.Abort();
91+
else
92+
connection.Close();
93+
}
94+
95+
ReportingHttpServer::Connection::Connection(ReportingHttpServer& httpServer, const infra::Function<void(bool open, services::IPAddress address)>& reporter, services::IPAddress address)
96+
: ReportingHttpServerConnectionObserver::WithBuffer<BufferSize>(httpServer, reporter, address)
97+
, httpServer(httpServer)
98+
{
99+
httpServer.connections.push_back(*this);
100+
}
101+
102+
ReportingHttpServer::Connection::~Connection()
103+
{
104+
httpServer.connections.erase(*this);
105+
}
26106
}

postmaster/frontend/ReportingHttpServer.hpp

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef POSTMASTER_REPORTING_HTTP_SERVER_HPP
22
#define POSTMASTER_REPORTING_HTTP_SERVER_HPP
33

4+
#include "infra/util/IntrusiveList.hpp"
5+
#include "infra/util/SharedObjectAllocatorFixedSize.hpp"
46
#include "services/network/HttpServer.hpp"
57

68
namespace application
@@ -9,6 +11,10 @@ namespace application
911
: public services::HttpServerConnectionObserver
1012
{
1113
public:
14+
template<size_t BufferSize>
15+
using WithBuffer = infra::WithStorage<ReportingHttpServerConnectionObserver,
16+
infra::BoundedString::WithStorage<BufferSize>>;
17+
1218
ReportingHttpServerConnectionObserver(infra::BoundedString& buffer, HttpPageServer& httpServer, const infra::Function<void(bool open, services::IPAddress address)>& reporter, services::IPAddress address);
1319
~ReportingHttpServerConnectionObserver();
1420

@@ -17,19 +23,63 @@ namespace application
1723
};
1824

1925
class ReportingHttpServer
20-
: public services::SingleConnectionListener
21-
, public services::HttpPageServer
26+
: public services::HttpPageServer
27+
, public services::NewConnectionStrategy
28+
, private services::ServerConnectionObserverFactory
2229
{
2330
public:
24-
template<::size_t BufferSize>
25-
using WithBuffer = infra::WithStorage<ReportingHttpServer, infra::BoundedString::WithStorage<BufferSize>>;
31+
static constexpr std::size_t BufferSize = 8192;
32+
33+
class Connection
34+
: public infra::IntrusiveList<Connection>::NodeType
35+
, public ReportingHttpServerConnectionObserver::WithBuffer<BufferSize>
36+
{
37+
public:
38+
Connection(ReportingHttpServer& httpServer, const infra::Function<void(bool open, services::IPAddress address)>& reporter, services::IPAddress address);
39+
Connection(const Connection& other) = delete;
40+
Connection& operator=(const Connection& other) = delete;
41+
~Connection();
42+
43+
private:
44+
ReportingHttpServer& httpServer;
45+
};
46+
47+
using ConnectionAllocator = infra::SharedObjectAllocator<Connection, void(ReportingHttpServer& httpServer, const infra::Function<void(bool open, services::IPAddress address)>& reporter, services::IPAddress address)>;
48+
49+
using ConnectionAllocatorFixedSize = infra::SharedObjectAllocatorFixedSize<Connection,
50+
void(ReportingHttpServer& httpServer, const infra::Function<void(bool open, services::IPAddress address)>& reporter, services::IPAddress address)>;
51+
52+
template<std::size_t Connections>
53+
using WithConnections = infra::WithStorage<ReportingHttpServer, typename ConnectionAllocatorFixedSize::template WithStorage<Connections>>;
54+
55+
ReportingHttpServer(ConnectionAllocator& allocator, services::ConnectionFactory& connectionFactory, uint16_t port, const infra::Function<void(bool open, services::IPAddress address)>& reporter);
2656

27-
ReportingHttpServer(infra::BoundedString& buffer, services::ConnectionFactory& connectionFactory, uint16_t port, const infra::Function<void(bool open, services::IPAddress address)>& reporter);
57+
void Stop(const infra::Function<void()>& onDone, bool force);
58+
void SetNewConnectionStrategy(services::NewConnectionStrategy& newConnectionStrategy);
59+
60+
// Implementation of NewConnectionStrategy
61+
void StopCurrentConnection(void* listener) override;
62+
void StartNewConnection() override;
63+
64+
private:
65+
// Implementation of ServerConnectionObserverFactory
66+
void ConnectionAccepted(infra::AutoResetFunction<void(infra::SharedPtr<services::ConnectionObserver> connectionObserver)>&& createdObserver, services::IPAddress address) override;
67+
68+
void StopConnections(const infra::Function<void()>& onDone, bool force);
69+
void CloseOrAbortAllConnections(bool force);
2870

2971
private:
72+
services::NewConnectionStrategy* newConnectionStrategy = this;
3073
infra::Function<void(bool open, services::IPAddress address)> reporter;
31-
infra::BoundedString& buffer;
32-
infra::Creator<services::ConnectionObserver, ReportingHttpServerConnectionObserver, void(services::IPAddress address)> connectionCreator;
74+
infra::SharedPtr<void> listener;
75+
76+
ConnectionAllocator& connectionAllocator;
77+
infra::IntrusiveList<Connection> connections;
78+
79+
infra::AutoResetFunction<void(infra::SharedPtr<services::ConnectionObserver> connectionObserver)> waitingCreatedObserver;
80+
services::IPAddress waitingAddress;
81+
82+
infra::Function<void()> onStopConnectionsDone;
3383
};
3484
}
3585

postmaster/instantiations/EchoServer.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,24 @@ namespace main_
2121
return echoConnection;
2222
}
2323

24-
SingleConnectionLink::SingleConnectionLink(services::SingleConnectionListener& listener1, services::SingleConnectionListener& listener2)
24+
SingleConnectionLink::SingleConnectionLink(application::ReportingHttpServer& listener1, services::SingleConnectionListener& listener2)
2525
: listener1(listener1)
2626
, listener2(listener2)
2727
{
2828
listener1.SetNewConnectionStrategy(*this);
2929
listener2.SetNewConnectionStrategy(*this);
3030
}
3131

32-
void SingleConnectionLink::StopCurrentConnection(services::SingleConnectionListener& listener)
32+
void SingleConnectionLink::StopCurrentConnection(void* listener)
3333
{
34-
if (&listener == &listener1)
34+
if (listener == &listener1)
3535
listener1RequestedNewConnection = true;
36-
if (&listener == &listener2)
36+
if (listener == &listener2)
3737
listener2RequestedNewConnection = true;
3838

3939
numStopped = 0;
40-
listener1.StopCurrentConnection(listener1);
41-
listener2.StopCurrentConnection(listener2);
40+
listener1.StopCurrentConnection(&listener1);
41+
listener2.StopCurrentConnection(&listener2);
4242
}
4343

4444
void SingleConnectionLink::StartNewConnection()
@@ -53,7 +53,7 @@ namespace main_
5353
listener1.StartNewConnection();
5454

5555
if (listener2RequestedNewConnection)
56-
StopCurrentConnection(listener1);
56+
StopCurrentConnection(&listener1);
5757
}
5858
else if (listener2RequestedNewConnection)
5959
{

postmaster/instantiations/EchoServer.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include "postmaster/frontend/ReportingHttpServer.hpp"
12
#include "postmaster/instantiations/UartCreator.hpp"
23
#include "protobuf/echo/ServiceForwarder.hpp"
34
#include "services/network/Connection.hpp"
@@ -42,15 +43,15 @@ namespace main_
4243
: private services::NewConnectionStrategy
4344
{
4445
public:
45-
SingleConnectionLink(services::SingleConnectionListener& listener1, services::SingleConnectionListener& listener2);
46+
SingleConnectionLink(application::ReportingHttpServer& listener1, services::SingleConnectionListener& listener2);
4647

4748
private:
48-
void StopCurrentConnection(services::SingleConnectionListener& listener) override;
49+
void StopCurrentConnection(void* listener) override;
4950
void StartNewConnection() override;
5051

5152
private:
5253
uint32_t numStopped = 0;
53-
services::SingleConnectionListener& listener1;
54+
application::ReportingHttpServer& listener1;
5455
services::SingleConnectionListener& listener2;
5556

5657
bool listener1RequestedNewConnection = false;

postmaster/instantiations/HttpServer.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22

33
namespace main_
44
{
5-
HttpServer::HttpServer(services::ConnectionFactory& connectionFactory, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
5+
HttpServer::HttpServer(application::ReportingHttpServer::ConnectionAllocator& allocator, services::ConnectionFactory& connectionFactory, uint16_t port, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
66
services::ConfigurationStoreAccess<infra::BoundedString>& attributes, services::ConfigurationStoreAccess<infra::BoundedString>& password,
77
application::Authentication& authentication, application::PostmasterDiscovery& postmasterDiscovery,
88
const infra::Function<void(bool open, services::IPAddress address)>& reporter, const infra::Function<void(bool receiving)>& receivingTarget, const infra::Function<void(bool receiving)>& receivingSelf)
9-
: HttpServerFrontEnd(connectionFactory, hostname, attributes, password, authentication, reporter, receivingTarget, receivingSelf)
9+
: HttpServerFrontEnd(allocator, connectionFactory, port, hostname, attributes, password, authentication, reporter, receivingTarget, receivingSelf)
1010
, discovery("discovery", postmasterDiscovery)
1111
{
1212
server.AddPage(discovery);
1313
}
1414

15-
HttpServerSingleConnection::HttpServerSingleConnection(services::ConnectionFactory& connectionFactory, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
15+
HttpServerSingleConnection::HttpServerSingleConnection(services::ConnectionFactory& connectionFactory, uint16_t port, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
1616
services::ConfigurationStoreAccess<infra::BoundedString>& attributes, services::ConfigurationStoreAccess<infra::BoundedString>& password,
1717
application::Authentication& authentication, application::PostmasterDiscovery& postmasterDiscovery,
1818
UartCreator& uartProgrammerCreator, UartCreator& uartExternalCreator, hal::Flash& upgradeFlash, hal::Reset& reset, const infra::Function<void(bool open, services::IPAddress address)>& reporter, const infra::Function<void(bool receiving)>& receivingTarget, const infra::Function<void(bool receiving)>& receivingSelf, hal::GpioPin& resetTarget, hal::GpioPin& boot0)
19-
: HttpServer(connectionFactory, hostname, attributes, password, authentication, postmasterDiscovery, reporter, receivingTarget, receivingSelf)
19+
: HttpServer::WithConnections<1>(connectionFactory, port, hostname, attributes, password, authentication, postmasterDiscovery, reporter, receivingTarget, receivingSelf)
2020
, uartProgrammerCreator(uartProgrammerCreator)
2121
, uartExternalCreator(uartExternalCreator)
2222
, selfFirmwarePage{ authentication, "firmware/self" }

postmaster/instantiations/HttpServer.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ namespace main_
1313
struct HttpServer
1414
: public HttpServerFrontEnd
1515
{
16-
HttpServer(services::ConnectionFactory& connectionFactory, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
16+
template<std::size_t Connections>
17+
using WithConnections = infra::WithStorage<HttpServer, application::ReportingHttpServer::ConnectionAllocatorFixedSize::WithStorage<Connections>>;
18+
19+
HttpServer(application::ReportingHttpServer::ConnectionAllocator& allocator, services::ConnectionFactory& connectionFactory, uint16_t port, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
1720
services::ConfigurationStoreAccess<infra::BoundedString>& attributes, services::ConfigurationStoreAccess<infra::BoundedString>& password,
1821
application::Authentication& authentication, application::PostmasterDiscovery& postmasterDiscovery,
1922
const infra::Function<void(bool open, services::IPAddress address)>& reporter, const infra::Function<void(bool receiving)>& receivingTarget, const infra::Function<void(bool receiving)>& receivingSelf);
@@ -22,9 +25,9 @@ namespace main_
2225
};
2326

2427
struct HttpServerSingleConnection
25-
: public HttpServer
28+
: public HttpServer::WithConnections<1>
2629
{
27-
HttpServerSingleConnection(services::ConnectionFactory& connectionFactory, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
30+
HttpServerSingleConnection(services::ConnectionFactory& connectionFactory, uint16_t port, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
2831
services::ConfigurationStoreAccess<infra::BoundedString>& attributes, services::ConfigurationStoreAccess<infra::BoundedString>& password,
2932
application::Authentication& authentication, application::PostmasterDiscovery& postmasterDiscovery,
3033
UartCreator& uartProgrammerCreator, UartCreator& uartExternalCreator, hal::Flash& upgradeFlash, hal::Reset& reset, const infra::Function<void(bool open, services::IPAddress address)>& reporter, const infra::Function<void(bool receiving)>& receivingTarget, const infra::Function<void(bool receiving)>& receivingSelf, hal::GpioPin& resetTarget, hal::GpioPin& boot0);

postmaster/instantiations/HttpServerFrontEnd.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
namespace main_
44
{
5-
HttpServerFrontEnd::HttpServerFrontEnd(services::ConnectionFactory& connectionFactory, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
5+
HttpServerFrontEnd::HttpServerFrontEnd(application::ReportingHttpServer::ConnectionAllocator& allocator, services::ConnectionFactory& connectionFactory, uint16_t port, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
66
services::ConfigurationStoreAccess<infra::BoundedString>& attributes, services::ConfigurationStoreAccess<infra::BoundedString>& password, application::Authentication& authentication,
77
const infra::Function<void(bool open, services::IPAddress address)>& reporter, const infra::Function<void(bool receiving)>& receivingTarget,
88
const infra::Function<void(bool receiving)>& receivingSelf)
99
: configuration{ authentication, "configuration", hostname, attributes, password }
10-
, server{ connectionFactory, 80, reporter }
10+
, server{ allocator, connectionFactory, port, reporter }
1111
{
1212
server.AddPage(frontendHtml);
1313
server.AddPage(frontendCss);

postmaster/instantiations/HttpServerFrontEnd.hpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,22 @@
1313
namespace main_
1414
{
1515
struct HttpServerFrontEnd
16-
: public services::Stoppable
1716
{
18-
HttpServerFrontEnd(services::ConnectionFactory& connectionFactory, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
17+
HttpServerFrontEnd(application::ReportingHttpServer::ConnectionAllocator& allocator, services::ConnectionFactory& connectionFactory, uint16_t port, services::ConfigurationStoreAccess<infra::BoundedString>& hostname,
1918
services::ConfigurationStoreAccess<infra::BoundedString>& attributes, services::ConfigurationStoreAccess<infra::BoundedString>& password,
2019
application::Authentication& authentication, const infra::Function<void(bool open, services::IPAddress address)>& reporter, const infra::Function<void(bool receiving)>& receivingTarget, const infra::Function<void(bool receiving)>& receivingSelf);
2120

22-
void Stop(const infra::Function<void()>& onDone) override
21+
void Stop(const infra::Function<void()>& onDone)
2322
{
24-
server.Stop(onDone);
23+
server.Stop(onDone, true);
2524
}
2625

2726
services::HttpPageWithContent frontendHtml{ "", page_contents::indexHtml, "text/html;charset=UTF-8" };
2827
services::HttpPageWithContent frontendCss{ "style.css", page_contents::styleCss, "text/css" };
2928
services::HttpPageWithContent frontendJs{ "upload.js", page_contents::uploadJs, "text/javascript" };
3029
application::AuthenticatedHttpPage::WithPage<application::HttpPageConfiguration> configuration;
3130

32-
application::ReportingHttpServer::WithBuffer<8192> server;
31+
application::ReportingHttpServer server;
3332
};
3433
}
3534

postmaster/instantiations_st/EthernetPostmaster.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ namespace main_
4242
application::Authentication authentication;
4343
infra::Creator<services::Stoppable, main_::NetworkConnected, void(services::LightweightIp& lightweightIp)> networkCreator;
4444

45-
main_::Ethernet<3, 0, 4> ethernet;
45+
main_::Ethernet<4, 0, 9> ethernet;
4646
};
4747
}
4848

0 commit comments

Comments
 (0)