|
|
- /*
-
- 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
|