From 36af7f6f58e6222ad21466e79bf153058d293e48 Mon Sep 17 00:00:00 2001 From: tt2468 Date: Sun, 2 May 2021 19:48:44 -0700 Subject: [PATCH] base: Lots of stuff, including RequestHandler progress --- CMakeLists.txt | 2 - src/WebSocketProtocol.cpp | 55 ++++++++- src/WebSocketProtocol.h | 1 + src/WebSocketServer.cpp | 4 +- src/WebSocketServer.h | 6 +- src/WebSocketSession.h | 4 + src/requesthandler/RequestHandler.cpp | 24 ++++ src/requesthandler/RequestHandler.h | 137 ++++++++++++++++++++++- src/requesthandler/rpc/Request.h | 10 ++ src/requesthandler/rpc/RequestResult.cpp | 3 - src/requesthandler/rpc/RequestResult.h | 3 - 11 files changed, 232 insertions(+), 17 deletions(-) delete mode 100644 src/requesthandler/rpc/RequestResult.cpp delete mode 100644 src/requesthandler/rpc/RequestResult.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 03f636e7..f8a4e340 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,6 @@ set(obs-websocket_SOURCES src/WebSocketSession.cpp src/requesthandler/RequestHandler.cpp src/requesthandler/rpc/Request.cpp - src/requesthandler/rpc/RequestResult.cpp src/forms/SettingsDialog.cpp src/utils/Json.cpp src/utils/Crypto.cpp @@ -90,7 +89,6 @@ set(obs-websocket_HEADERS src/WebSocketSession.h src/requesthandler/RequestHandler.h src/requesthandler/rpc/Request.h - src/requesthandler/rpc/RequestResult.h src/forms/SettingsDialog.h src/utils/Utils.h) diff --git a/src/WebSocketProtocol.cpp b/src/WebSocketProtocol.cpp index 64f337ed..3a04ba82 100644 --- a/src/WebSocketProtocol.cpp +++ b/src/WebSocketProtocol.cpp @@ -67,7 +67,7 @@ WebSocketProtocol::ProcessResult WebSocketProtocol::ProcessMessage(SessionPtr se } if (!session->IgnoreInvalidMessages()) { ret.closeCode = WebSocketServer::WebSocketCloseCode::UnknownMessageType; - ret.closeReason = "Your request is missing a `messageType`"; + ret.closeReason = "Your request is missing a `messageType`."; } return ret; } @@ -81,7 +81,44 @@ WebSocketProtocol::ProcessResult WebSocketProtocol::ProcessMessage(SessionPtr se } if (messageType == "Request") { - ; + // RequestID checking has to be done here where we are able to close the connection. + if (!incomingMessage.contains("requestId")) { + if (!session->IgnoreInvalidMessages()) { + ret.closeCode = WebSocketServer::WebSocketCloseCode::RequestMissingRequiredField; + ret.closeReason = "Your request is missing a `requestId`."; + } + return ret; + } + + if (!incomingMessage.contains("requestType")) { + if (!session->IgnoreInvalidMessages()) { + ret.closeCode = WebSocketServer::WebSocketCloseCode::RequestMissingRequiredField; + ret.closeReason = "Your request is missing a `requestType`."; + } + return ret; + } + + auto requestHandler = RequestHandler(session); + RequestHandler::RequestResult result; + if (incomingMessage.contains("requestData")) { + result = requestHandler.ProcessRequest(incomingMessage["requestType"], incomingMessage["requestData"]); + } else { + result = requestHandler.ProcessRequest(incomingMessage["requestType"]); + } + + ret.result["messageType"] = "RequestResponse"; + ret.result["requestType"] = incomingMessage["requestType"]; + ret.result["requestId"] = incomingMessage["requestId"]; + ret.result["requestStatus"] = { + {"result", result.statusCode == RequestHandler::RequestStatus::Success}, + {"code", result.statusCode} + }; + if (result.comment != "") + ret.result["requestStatus"]["comment"] = result.comment; + if (!result.responseData.is_null()) + ret.result["responseData"] = result.responseData; + + return ret; } else if (messageType == "RequestBatch") { ; } else if (messageType == "Identify") { @@ -157,3 +194,17 @@ WebSocketProtocol::ProcessResult WebSocketProtocol::ProcessMessage(SessionPtr se return ret; } + +std::vector WebSocketProtocol::GetRequestList() +{ + std::vector ret; + + return ret; +} + +std::vector WebSocketProtocol::GetEventList() +{ + std::vector ret; + + return ret; +} diff --git a/src/WebSocketProtocol.h b/src/WebSocketProtocol.h index e02ac13f..739a32ee 100644 --- a/src/WebSocketProtocol.h +++ b/src/WebSocketProtocol.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include diff --git a/src/WebSocketServer.cpp b/src/WebSocketServer.cpp index 4b21eaf6..26a6ca8c 100644 --- a/src/WebSocketServer.cpp +++ b/src/WebSocketServer.cpp @@ -277,8 +277,8 @@ void WebSocketServer::onOpen(websocketpp::connection_hdl hdl) helloMessage["messageType"] = "Hello"; helloMessage["obsWebSocketVersion"] = OBS_WEBSOCKET_VERSION; helloMessage["rpcVersion"] = OBS_WEBSOCKET_RPC_VERSION; - //helloMessage["availableRequests"] = WebSocketProtocol::GetRequestList(); - //helloMessage["availableEvents"] = WebSocketProtocol::GetEventList(); + helloMessage["availableRequests"] = WebSocketProtocol::GetRequestList(); + helloMessage["availableEvents"] = WebSocketProtocol::GetEventList(); if (AuthenticationRequired) { std::string sessionChallenge = Utils::Crypto::GenerateSalt(); session->SetChallenge(sessionChallenge); diff --git a/src/WebSocketServer.h b/src/WebSocketServer.h index ebdb16bf..da00fb39 100644 --- a/src/WebSocketServer.h +++ b/src/WebSocketServer.h @@ -4,7 +4,6 @@ #include #include #include -#include #include #include @@ -13,7 +12,6 @@ #include "WebSocketSession.h" using json = nlohmann::json; -typedef std::shared_ptr SessionPtr; class WebSocketServer : QObject { @@ -37,8 +35,8 @@ class WebSocketServer : QObject AuthenticationFailed = 4005, // There was an invalid parameter the client's `Identify` message InvalidIdentifyParameter = 4006, - // A `Request` or `RequestBatch` was missing its `requestId` - RequestMissingRequestId = 4007, + // A `Request` or `RequestBatch` was missing its `requestId` or `requestType` + RequestMissingRequiredField = 4007, // The websocket session has been invalidated by the obs-websocket server. SessionInvalidated = 4008, // The server detected the usage of an old version of the obs-websocket protocol. diff --git a/src/WebSocketSession.h b/src/WebSocketSession.h index a9c58dd4..2ec918b7 100644 --- a/src/WebSocketSession.h +++ b/src/WebSocketSession.h @@ -3,6 +3,10 @@ #include #include #include +#include + +class WebSocketSession; +typedef std::shared_ptr SessionPtr; class WebSocketSession { diff --git a/src/requesthandler/RequestHandler.cpp b/src/requesthandler/RequestHandler.cpp index 2ee52efb..844fc407 100644 --- a/src/requesthandler/RequestHandler.cpp +++ b/src/requesthandler/RequestHandler.cpp @@ -1,3 +1,27 @@ +#include +#include + #include "RequestHandler.h" #include "../plugin-macros.generated.h" + +RequestHandler::RequestHandler(bool ignoreNonFatalRequestChecks, uint8_t rpcVersion) : + _ignoreNonFatalRequestChecks(ignoreNonFatalRequestChecks), + _rpcVersion(rpcVersion) +{ +} + +RequestHandler::RequestHandler(SessionPtr session) : + _ignoreNonFatalRequestChecks(session->IgnoreNonFatalRequestChecks()), + _rpcVersion(session->RpcVersion()) +{ +} + +RequestHandler::RequestResult RequestHandler::ProcessRequest(std::string requestType, json requestData) +{ + RequestHandler::RequestResult ret; + + ret.statusCode = RequestHandler::RequestStatus::Success; + + return ret; +} \ No newline at end of file diff --git a/src/requesthandler/RequestHandler.h b/src/requesthandler/RequestHandler.h index 68333399..2cbcd2ec 100644 --- a/src/requesthandler/RequestHandler.h +++ b/src/requesthandler/RequestHandler.h @@ -1,4 +1,139 @@ #pragma once +#include + #include "rpc/Request.h" -#include "rpc/RequestResult.h" +#include "../WebSocketSession.h" + +using json = nlohmann::json; + +class RequestHandler { + public: + enum RequestStatus: uint16_t { + Unknown = 0, + + // For internal use to signify a successful parameter check + NoError = 10, + + Success = 100, + + // The request is denied because the client is not authenticated + AuthenticationMissing = 200, + // Connection has already been authenticated (for modules utilizing a request to provide authentication) + AlreadyAuthenticated = 201, + // Authentication request was denied (for modules utilizing a request to provide authentication) + AuthenticationDenied = 202, + // The `requestType` field is missing from the request data + RequestTypeMissing = 203, + // The request type is invalid (does not exist) + InvalidRequestType = 204, + // Generic error code (comment is expected to be provided) + GenericError = 205, + + // A required request parameter is missing + MissingRequestParameter = 300, + + // Generic invalid request parameter message + InvalidRequestParameter = 400, + // A request parameter has the wrong data type + InvalidRequestParameterDataType = 401, + // A request parameter (float or int) is out of valid range + RequestParameterOutOfRange = 402, + // A request parameter (string or array) is empty and cannot be + RequestParameterEmpty = 403, + + // An output is running and cannot be in order to perform the request (generic) + OutputRunning = 500, + // An output is not running and should be + OutputNotRunning = 501, + // Stream is running and cannot be + StreamRunning = 502, + // Stream is not running and should be + StreamNotRunning = 503, + // Record is running and cannot be + RecordRunning = 504, + // Record is not running and should be + RecordNotRunning = 505, + // Record is paused and cannot be + RecordPaused = 506, + // Replay buffer is running and cannot be + ReplayBufferRunning = 507, + // Replay buffer is not running and should be + ReplayBufferNotRunning = 508, + // Replay buffer is disabled and cannot be + ReplayBufferDisabled = 509, + // Studio mode is active and cannot be + StudioModeActive = 510, + // Studio mode is not active and should be + StudioModeNotActive = 511, + + // The specified source (obs_source_t) was of the invalid type (Eg. input instead of scene) + InvalidSourceType = 600, + // The specified source (obs_source_t) was not found (generic for input, filter, transition, scene) + SourceNotFound = 601, + // The specified source (obs_source_t) already exists. Applicable to inputs, filters, transitions, scenes + SourceAlreadyExists = 602, + // The specified input (obs_source_t-OBS_SOURCE_TYPE_FILTER) was not found + InputNotFound = 603, + // The specified input (obs_source_t-OBS_SOURCE_TYPE_INPUT) had the wrong kind + InvalidInputKind = 604, + // The specified filter (obs_source_t-OBS_SOURCE_TYPE_FILTER) was not found + FilterNotFound = 605, + // The specified transition (obs_source_t-OBS_SOURCE_TYPE_TRANSITION) was not found + TransitionNotFound = 606, + // The specified transition (obs_source_t-OBS_SOURCE_TYPE_TRANSITION) does not support setting its position (transition is of fixed type) + TransitionDurationFixed = 607, + // The specified scene (obs_source_t-OBS_SOURCE_TYPE_SCENE), (obs_scene_t) was not found + SceneNotFound = 608, + // The specified scene item (obs_sceneitem_t) was not found + SceneItemNotFound = 609, + // The specified scene collection was not found + SceneCollectionNotFound = 610, + // The specified profile was not found + ProfileNotFound = 611, + // The specified output (obs_output_t) was not found + OutputNotFound = 612, + // The specified encoder (obs_encoder_t) was not found + EncoderNotFound = 613, + // The specified service (obs_service_t) was not found + ServiceNotFound = 614, + // The specified hotkey was not found + HotkeyNotFound = 615, + // The specified directory was not found + DirectoryNotFound = 616, + // The specified config item (obs_config_t) was not found. Could be section or parameter name. + ConfigParameterNotFound = 617, + // The specified property (obs_properties_t) was not found + PropertyNotFound = 618, + + // Processing the request failed unexpectedly + RequestProcessingFailed = 700, + // Starting the Output failed + OutputStartFailed = 701, + // Duplicating the scene item failed + SceneItemDuplicationFailed = 702, + // Rendering the screenshot failed + ScreenshotRenderFailed = 703, + // Encoding the screenshot failed + ScreenshotEncodeFailed = 704, + // Saving the screenshot failed + ScreenshotSaveFailed = 705, + // Creating the directory failed + DirectoryCreationFailed = 706, + }; + + struct RequestResult { + RequestStatus statusCode; + json responseData = nullptr; + std::string comment; + }; + + RequestHandler(bool ignoreNonFatalRequestChecks, uint8_t rpcVersion); + RequestHandler(SessionPtr session); + + RequestResult ProcessRequest(std::string requestType, json requestData = json::object()); + + private: + bool _ignoreNonFatalRequestChecks; + uint8_t _rpcVersion; +}; \ No newline at end of file diff --git a/src/requesthandler/rpc/Request.h b/src/requesthandler/rpc/Request.h index 5227ca76..94e3c265 100644 --- a/src/requesthandler/rpc/Request.h +++ b/src/requesthandler/rpc/Request.h @@ -1,3 +1,13 @@ #pragma once #include + +#include "../RequestHandler.h" + +class Request +{ + public: + ; + private: + ; +}; \ No newline at end of file diff --git a/src/requesthandler/rpc/RequestResult.cpp b/src/requesthandler/rpc/RequestResult.cpp deleted file mode 100644 index 9d17a045..00000000 --- a/src/requesthandler/rpc/RequestResult.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "RequestResult.h" - -#include "../../plugin-macros.generated.h" diff --git a/src/requesthandler/rpc/RequestResult.h b/src/requesthandler/rpc/RequestResult.h deleted file mode 100644 index 5227ca76..00000000 --- a/src/requesthandler/rpc/RequestResult.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#include