#ifndef HttpEndpoint_h #define HttpEndpoint_h #include #include #include #include #define HTTP_ENDPOINT_ORIGIN_ID "http" #define HTTPS_ENDPOINT_ORIGIN_ID "https" using namespace std::placeholders; // for `_1` etc template class HttpEndpoint { protected: JsonStateReader _stateReader; JsonStateUpdater _stateUpdater; StatefulService * _statefulService; size_t _bufferSize; SecurityManager * _securityManager; AuthenticationPredicate _authenticationPredicate; PsychicHttpServer * _server; const char * _servicePath; public: HttpEndpoint(JsonStateReader stateReader, JsonStateUpdater stateUpdater, StatefulService * statefulService, PsychicHttpServer * server, const char * servicePath, SecurityManager * securityManager, AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN, size_t bufferSize = DEFAULT_BUFFER_SIZE) : _stateReader(stateReader) , _stateUpdater(stateUpdater) , _statefulService(statefulService) , _server(server) , _servicePath(servicePath) , _securityManager(securityManager) , _authenticationPredicate(authenticationPredicate) , _bufferSize(bufferSize) { } // register the web server on() endpoints void registerURI() { _server->on(_servicePath, HTTP_GET, _securityManager->wrapRequest( [this](PsychicRequest * request) { PsychicJsonResponse response = PsychicJsonResponse(request, false, _bufferSize); JsonObject jsonObject = response.getRoot(); _statefulService->read(jsonObject, _stateReader); return response.send(); }, _authenticationPredicate)); _server->on(_servicePath, HTTP_POST, _securityManager->wrapCallback( [this](PsychicRequest * request, JsonVariant & json) { if (!json.is()) { return request->reply(400); } JsonObject jsonObject = json.as(); StateUpdateResult outcome = _statefulService->updateWithoutPropagation(jsonObject, _stateUpdater); if (outcome == StateUpdateResult::ERROR) { return request->reply(400); } else if ((outcome == StateUpdateResult::CHANGED) || (outcome == StateUpdateResult::CHANGED_RESTART)) { // persist the changes to the FS _statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID); } PsychicJsonResponse response = PsychicJsonResponse(request, false, _bufferSize); jsonObject = response.getRoot(); _statefulService->read(jsonObject, _stateReader); if (outcome == StateUpdateResult::CHANGED_RESTART) { response.setCode(205); // reboot required } return response.send(); }, _authenticationPredicate)); } }; #endif