Mirror of espurna firmware for wireless switches and more
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

90 lines
2.4 KiB

/*
Part of the WEBSERVER MODULE
Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
*/
#pragma once
#include "web.h"
#include "api.h"
#include "libs/TypeChecks.h"
namespace espurna {
namespace web {
namespace print {
namespace traits {
template <typename T>
using print_callable_t = decltype(std::declval<T>()(std::declval<Print&>()));
template <typename T>
using is_print_callable = is_detected<print_callable_t, T>;
} // namespace traits
void RequestPrint::_onDisconnect() {
#if API_SUPPORT
// TODO: in case this comes from `apiRegister`'ed endpoint, there's still a lingering ApiRequestHelper that we must remove
auto* req = request();
if (req->_tempObject) {
auto* ptr = reinterpret_cast<espurna::api::Request*>(req->_tempObject);
delete ptr;
req->_tempObject = nullptr;
}
#endif
state(State::Done);
}
template <typename CallbackType>
void RequestPrint::_callback(CallbackType&& callback) {
if (State::None != state()) {
return;
}
callback(*this);
flush();
}
template<typename CallbackType>
void RequestPrint::scheduleFromRequest(Config config, AsyncWebServerRequest* request, CallbackType callback) {
static_assert(
traits::is_print_callable<CallbackType>::value,
"CallbackType needs to be a callable with void(Print&)");
// because of async nature of the server, we need to make sure we outlive 'request' object
auto print = std::shared_ptr<RequestPrint>(
new RequestPrint(config, request));
// attach one ptr to onDisconnect capture, so we can detect disconnection before scheduled function runs
request->onDisconnect(
[print]() {
print->_onDisconnect();
});
// attach another capture to the scheduled function, so we execute as soon as we exit next loop()
espurnaRegisterOnce(
[callback, print]() {
print->_callback(callback);
});
}
static constexpr auto DefaultConfig = Config{
.mimeType = "text/plain",
.backlog = {
.count = 2,
.size = TCP_MSS,
.timeout = duration::Seconds(5)
},
};
template <typename CallbackType>
void RequestPrint::scheduleFromRequest(AsyncWebServerRequest* request, CallbackType callback) {
RequestPrint::scheduleFromRequest(DefaultConfig, request, callback);
}
} // namespace print
} // namespace web
} // namespace espurna