WSServer: reimplement protocol

This commit is contained in:
Stéphane Lepin 2019-11-15 21:07:58 +01:00
parent 2f244ae37e
commit 5864864123
6 changed files with 132 additions and 62 deletions

View File

@ -48,6 +48,7 @@ set(obs-websocket_SOURCES
src/Utils.cpp src/Utils.cpp
src/rpc/RpcRequest.cpp src/rpc/RpcRequest.cpp
src/rpc/RpcResponse.h src/rpc/RpcResponse.h
src/protocol/OBSRemoteProtocol.cpp
src/forms/settings-dialog.cpp) src/forms/settings-dialog.cpp)
set(obs-websocket_HEADERS set(obs-websocket_HEADERS
@ -60,6 +61,7 @@ set(obs-websocket_HEADERS
src/Utils.h src/Utils.h
src/rpc/RpcRequest.h src/rpc/RpcRequest.h
src/rpc/RpcResponse.h src/rpc/RpcResponse.h
src/protocol/OBSRemoteProtocol.h
src/forms/settings-dialog.h) src/forms/settings-dialog.h)
# --- Platform-independent build settings --- # --- Platform-independent build settings ---

View File

@ -156,38 +156,7 @@ WSRequestHandler::WSRequestHandler(ConnectionProperties& connProperties) :
{ {
} }
// std::string WSRequestHandler::processIncomingMessage(std::string& textMessage) {
// if (GetConfig()->DebugEnabled) {
// blog(LOG_INFO, "Request >> '%s'", textMessage.c_str());
// }
// OBSDataAutoRelease responseData = processRequest(textMessage);
// std::string response = obs_data_get_json(responseData);
// if (GetConfig()->DebugEnabled) {
// blog(LOG_INFO, "Response << '%s'", response.c_str());
// }
// return response;
// }
RpcResponse WSRequestHandler::processRequest(const RpcRequest& request){ RpcResponse WSRequestHandler::processRequest(const RpcRequest& request){
// std::string msgContainer(textMessage);
// const char* msg = msgContainer.c_str();
// data = obs_data_create_from_json(msg);
// if (!data) {
// blog(LOG_ERROR, "invalid JSON payload received for '%s'", msg);
// return SendErrorResponse("invalid JSON payload");
// }
// if (!hasField("request-type") || !hasField("message-id")) {
// return SendErrorResponse("missing request parameters");
// }
// _requestType = obs_data_get_string(data, "request-type");
// _messageId = obs_data_get_string(data, "message-id");
if (GetConfig()->AuthRequired if (GetConfig()->AuthRequired
&& (!authNotRequired.contains(request.methodName())) && (!authNotRequired.contains(request.methodName()))
&& (!_connProperties.isAuthenticated())) && (!_connProperties.isAuthenticated()))
@ -202,30 +171,3 @@ RpcResponse WSRequestHandler::processRequest(const RpcRequest& request){
return std::bind(handlerFunc, this, _1)(request); return std::bind(handlerFunc, this, _1)(request);
} }
// HandlerResponse WSRequestHandler::SendOKResponse(obs_data_t* additionalFields) {
// return SendResponse("ok", additionalFields);
// }
// HandlerResponse WSRequestHandler::SendErrorResponse(QString errorMessage) {
// OBSDataAutoRelease fields = obs_data_create();
// obs_data_set_string(fields, "error", errorMessage.toUtf8().constData());
// return SendResponse("error", fields);
// }
// HandlerResponse WSRequestHandler::SendErrorResponse(obs_data_t* additionalFields) {
// return SendResponse("error", additionalFields);
// }
// HandlerResponse WSRequestHandler::SendResponse(const char* status, obs_data_t* fields) {
// obs_data_t* response = obs_data_create();
// obs_data_set_string(response, "message-id", _messageId);
// obs_data_set_string(response, "status", status);
// if (fields) {
// obs_data_apply(response, fields);
// }
// return response;
// }

View File

@ -31,6 +31,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include "obs-websocket.h" #include "obs-websocket.h"
#include "Config.h" #include "Config.h"
#include "Utils.h" #include "Utils.h"
#include "protocol/OBSRemoteProtocol.h"
QT_USE_NAMESPACE QT_USE_NAMESPACE
@ -171,8 +172,17 @@ void WSServer::onMessage(connection_hdl hdl, server::message_ptr message)
ConnectionProperties& connProperties = _connectionProperties[hdl]; ConnectionProperties& connProperties = _connectionProperties[hdl];
locker.unlock(); locker.unlock();
WSRequestHandler handler(connProperties); if (GetConfig()->DebugEnabled) {
std::string response = handler.processIncomingMessage(payload); blog(LOG_INFO, "Request >> '%s'", payload.c_str());
}
WSRequestHandler requestHandler(connProperties);
OBSRemoteProtocol protocol(requestHandler);
std::string response = protocol.processMessage(payload);
if (GetConfig()->DebugEnabled) {
blog(LOG_INFO, "Response << '%s'", response.c_str());
}
websocketpp::lib::error_code errorCode; websocketpp::lib::error_code errorCode;
_server.send(hdl, response, websocketpp::frame::opcode::text, errorCode); _server.send(hdl, response, websocketpp::frame::opcode::text, errorCode);

View File

@ -0,0 +1,82 @@
/*
obs-websocket
Copyright (C) 2016-2019 Stéphane Lepin <stephane.lepin@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <https://www.gnu.org/licenses/>
*/
#include "OBSRemoteProtocol.h"
#include "../WSRequestHandler.h"
std::string buildResponse(QString messageId, QString status, obs_data_t* fields = nullptr) {
obs_data_t* response = obs_data_create();
obs_data_set_string(response, "message-id", messageId.toUtf8().constData());
obs_data_set_string(response, "status", status.toUtf8().constData());
if (fields) {
obs_data_apply(response, fields);
}
std::string responseString = obs_data_get_json(response);
return responseString;
}
std::string successResponse(QString messageId, obs_data_t* fields = nullptr) {
return buildResponse(messageId, "ok", fields);
}
std::string errorResponse(QString messageId, QString errorMessage, obs_data_t* additionalFields = nullptr) {
OBSDataAutoRelease fields = obs_data_create();
obs_data_set_string(fields, "error", errorMessage.toUtf8().constData());
return buildResponse(messageId, "error", fields);
}
OBSRemoteProtocol::OBSRemoteProtocol(WSRequestHandler& requestHandler) :
_requestHandler(requestHandler)
{
}
std::string OBSRemoteProtocol::processMessage(std::string message)
{
std::string msgContainer(message);
const char* msg = msgContainer.c_str();
OBSDataAutoRelease data = obs_data_create_from_json(msg);
if (!data) {
blog(LOG_ERROR, "invalid JSON payload received for '%s'", msg);
return errorResponse(nullptr, "invalid JSON payload");
}
if (!obs_data_has_user_value(data, "request-type") || !obs_data_has_user_value(data, "message-id")) {
return errorResponse(nullptr, "missing request parameters");
}
QString methodName = obs_data_get_string(data, "request-type");
QString messageId = obs_data_get_string(data, "message-id");
OBSDataAutoRelease params = obs_data_create();
RpcRequest request(messageId, methodName, params);
RpcResponse response = _requestHandler.processRequest(request);
OBSData additionalFields = response.additionalFields();
switch (response.status()) {
case Ok:
return successResponse(messageId, additionalFields);
case Error:
return errorResponse(messageId, response.errorMessage(), additionalFields);
}
return std::string();
}

View File

@ -0,0 +1,34 @@
/*
obs-websocket
Copyright (C) 2016-2019 Stéphane Lepin <stephane.lepin@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <https://www.gnu.org/licenses/>
*/
#pragma once
#include <string>
#include <obs-data.h>
class WSRequestHandler;
class OBSRemoteProtocol
{
public:
explicit OBSRemoteProtocol(WSRequestHandler& requestHandler);
std::string processMessage(std::string message);
private:
WSRequestHandler& _requestHandler;
};

View File

@ -57,8 +57,8 @@ public:
return _errorMessage; return _errorMessage;
} }
const obs_data_t* parameters() const { const OBSData additionalFields() const {
return _additionalFields; return OBSData(_additionalFields);
} }
private: private: