Skip to content

Commit

Permalink
wsd: move special brokers to a new home
Browse files Browse the repository at this point in the history
Change-Id: I0787ce6bb5635e7af37fc65fd110ae5009c70c05
Signed-off-by: Ashod Nakashian <[email protected]>
  • Loading branch information
Ashod committed Sep 11, 2024
1 parent 36429d0 commit 44afe21
Show file tree
Hide file tree
Showing 7 changed files with 554 additions and 470 deletions.
30 changes: 16 additions & 14 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -138,22 +138,23 @@ coolwsd_sources = common/Crypto.cpp \
wsd/Admin.cpp \
wsd/AdminModel.cpp \
wsd/Auth.cpp \
wsd/DocumentBroker.cpp \
wsd/ProxyProtocol.cpp \
wsd/COOLWSD.cpp \
wsd/ClientRequestDispatcher.cpp \
wsd/ClientSession.cpp \
wsd/DocumentBroker.cpp \
wsd/FileServer.cpp \
wsd/ProxyRequestHandler.cpp \
wsd/FileServerUtil.cpp \
wsd/RequestDetails.cpp \
wsd/RequestVettingStation.cpp \
wsd/Storage.cpp \
wsd/HostUtil.cpp \
wsd/TileCache.cpp \
wsd/ProofKey.cpp \
wsd/ProxyProtocol.cpp \
wsd/ProxyRequestHandler.cpp \
wsd/QuarantineUtil.cpp \
wsd/RequestDetails.cpp \
wsd/RequestVettingStation.cpp \
wsd/ServerAuditUtil.cpp \
wsd/SpecialBrokers.cpp \
wsd/Storage.cpp \
wsd/TileCache.cpp \
wsd/wopi/CheckFileInfo.cpp \
wsd/wopi/StorageConnectionManager.cpp \
wsd/wopi/WopiProxy.cpp \
Expand Down Expand Up @@ -325,28 +326,29 @@ coolsocketdump_SOURCES = tools/WebSocketDump.cpp \
wsd_headers = wsd/Admin.hpp \
wsd/AdminModel.hpp \
wsd/Auth.hpp \
wsd/COOLWSD.hpp \
wsd/ClientRequestDispatcher.hpp \
wsd/ClientSession.hpp \
wsd/ContentSecurityPolicy.hpp \
wsd/DocumentBroker.hpp \
wsd/ProxyProtocol.hpp \
wsd/Exceptions.hpp \
wsd/FileServer.hpp \
wsd/ProxyRequestHandler.hpp \
wsd/COOLWSD.hpp \
wsd/ClientRequestDispatcher.hpp \
wsd/HostUtil.hpp \
wsd/ProofKey.hpp \
wsd/ProxyProtocol.hpp \
wsd/ProxyRequestHandler.hpp \
wsd/QuarantineUtil.hpp \
wsd/RequestDetails.hpp \
wsd/RequestVettingStation.hpp \
wsd/SenderQueue.hpp \
wsd/ServerAuditUtil.hpp \
wsd/ServerURL.hpp \
wsd/SpecialBrokers.hpp \
wsd/Storage.hpp \
wsd/TileCache.hpp \
wsd/TileDesc.hpp \
wsd/TraceFile.hpp \
wsd/UserMessages.hpp \
wsd/QuarantineUtil.hpp \
wsd/HostUtil.hpp \
wsd/ServerAuditUtil.hpp \
wsd/wopi/CheckFileInfo.hpp \
wsd/wopi/StorageConnectionManager.hpp \
wsd/wopi/WopiProxy.hpp \
Expand Down
3 changes: 2 additions & 1 deletion wsd/COOLWSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "CommandControl.hpp"
#endif
#if !MOBILEAPP
#include <wsd/SpecialBrokers.hpp>
#include <HostUtil.hpp>
#endif // !MOBILEAPP

Expand Down Expand Up @@ -120,7 +121,7 @@ using Poco::Net::PartHandler;
#include <Clipboard.hpp>
#include <Crypto.hpp>
#include <DelaySocket.hpp>
#include "DocumentBroker.hpp"
#include <wsd/DocumentBroker.hpp>
#include <common/JsonUtil.hpp>
#include <common/FileUtil.hpp>
#include <common/JailUtil.hpp>
Expand Down
3 changes: 2 additions & 1 deletion wsd/ClientRequestDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <COOLWSD.hpp>
#include <ClientSession.hpp>
#include <ConfigUtil.hpp>
#include <DocumentBroker.hpp>
#include <wsd/DocumentBroker.hpp>
#include <Exceptions.hpp>
#include <FileServer.hpp>
#include <HttpRequest.hpp>
Expand All @@ -35,6 +35,7 @@
#include <net/AsyncDNS.hpp>
#include <net/HttpHelper.hpp>
#if !MOBILEAPP
#include <wsd/SpecialBrokers.hpp>
#include <HostUtil.hpp>
#endif // !MOBILEAPP

Expand Down
274 changes: 0 additions & 274 deletions wsd/DocumentBroker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4297,280 +4297,6 @@ void DocumentBroker::getIOStats(uint64_t &sent, uint64_t &recv)
}
}

#if !MOBILEAPP

void StatelessBatchBroker::removeFile(const std::string &uriOrig)
{
// Remove and report errors on failure.
FileUtil::removeFile(uriOrig);
const std::string dir = Poco::Path(uriOrig).parent().toString();
if (FileUtil::isEmptyDirectory(dir))
FileUtil::removeFile(dir);
}

static std::atomic<std::size_t> gConvertToBrokerInstanceCouter;

std::size_t ConvertToBroker::getInstanceCount()
{
return gConvertToBrokerInstanceCouter;
}

ConvertToBroker::ConvertToBroker(const std::string& uri,
const Poco::URI& uriPublic,
const std::string& docKey,
const std::string& format,
const std::string& sOptions,
const std::string& lang)
: StatelessBatchBroker(uri, uriPublic, docKey)
, _format(format)
, _sOptions(sOptions)
, _lang(lang)
{
LOG_TRC("Created ConvertToBroker: uri: [" << uri << "], uriPublic: [" << uriPublic.toString()
<< "], docKey: [" << docKey << "], format: ["
<< format << "], options: [" << sOptions << "], lang: ["
<< lang << "].");

CONFIG_STATIC const std::chrono::seconds limit_convert_secs(
COOLWSD::getConfigValue<int>("per_document.limit_convert_secs", 100));
_limitLifeSeconds = limit_convert_secs;
++gConvertToBrokerInstanceCouter;
}

ConvertToBroker::~ConvertToBroker()
{}

bool ConvertToBroker::startConversion(SocketDisposition &disposition, const std::string &id)
{
std::shared_ptr<ConvertToBroker> docBroker = std::static_pointer_cast<ConvertToBroker>(shared_from_this());

// Create a session to load the document.
const bool isReadOnly = docBroker->isReadOnly();
// FIXME: associate this with moveSocket (?)
std::shared_ptr<ProtocolHandlerInterface> nullPtr;
RequestDetails requestDetails("convert-to");
_clientSession = std::make_shared<ClientSession>(nullPtr, id, docBroker, getPublicUri(), isReadOnly, requestDetails);
_clientSession->construct();

docBroker->setupTransfer(disposition, [docBroker] (const std::shared_ptr<Socket> &moveSocket)
{
auto streamSocket = std::static_pointer_cast<StreamSocket>(moveSocket);
docBroker->_clientSession->setSaveAsSocket(streamSocket);

// First add and load the session.
docBroker->addSession(docBroker->_clientSession);

// Load the document manually and request saving in the target format.
std::string encodedFrom;
Poco::URI::encode(docBroker->getPublicUri().getPath(), "", encodedFrom);

docBroker->sendStartMessage(docBroker->_clientSession, encodedFrom);

// Save is done in the setLoaded
});
return true;
}

void ConvertToBroker::sendStartMessage(const std::shared_ptr<ClientSession>& clientSession,
const std::string& encodedFrom)
{
// add batch mode, no interactive dialogs
std::string load = "load url=" + encodedFrom + " batch=true";
if (!getLang().empty())
load += " lang=" + getLang();
std::vector<char> loadRequest(load.begin(), load.end());
clientSession->handleMessage(loadRequest);
}

void ExtractLinkTargetsBroker::sendStartMessage(const std::shared_ptr<ClientSession>& clientSession,
const std::string& encodedFrom)
{
ConvertToBroker::sendStartMessage(clientSession, encodedFrom);

const auto command = "extractlinktargets url=" + encodedFrom;
forwardToChild(clientSession, command);
}

void ExtractDocumentStructureBroker::sendStartMessage(const std::shared_ptr<ClientSession>& clientSession,
const std::string& encodedFrom)
{
ConvertToBroker::sendStartMessage(clientSession, encodedFrom);

std::string command = "extractdocumentstructure url=" + encodedFrom;
if (!_filter.empty())
command += " filter=" + _filter;
forwardToChild(clientSession, command);
}

void TransformDocumentStructureBroker::sendStartMessage(const std::shared_ptr<ClientSession>& clientSession,
const std::string& encodedFrom)
{
ConvertToBroker::sendStartMessage(clientSession, encodedFrom);

const auto command = "transformdocumentstructure url=" + encodedFrom + " transform=" + _transformJSON;
forwardToChild(clientSession, command);
}

void GetThumbnailBroker::sendStartMessage(const std::shared_ptr<ClientSession>& clientSession,
const std::string& encodedFrom)
{
clientSession->setThumbnailSession(true);
clientSession->setThumbnailTarget(_target);

ConvertToBroker::sendStartMessage(clientSession, encodedFrom);
}

void ConvertToBroker::dispose()
{
if (!_uriOrig.empty())
{
gConvertToBrokerInstanceCouter--;
removeFile(_uriOrig);
_uriOrig.clear();
}
}

void ConvertToBroker::setLoaded()
{
DocumentBroker::setLoaded();

if (isGetThumbnail())
return;

// FIXME: Check for security violations.
Poco::Path toPath(getPublicUri().getPath());
toPath.setExtension(_format);

// file:///user/docs/filename.ext normally, file:///<jail-root>/user/docs/filename.ext in the nocaps case
const std::string toJailURL = "file://" +
(COOLWSD::NoCapsForKit? getJailRoot(): "") +
std::string(JAILED_DOCUMENT_ROOT) + toPath.getFileName();

std::string encodedTo;
Poco::URI::encode(toJailURL, "", encodedTo);

// Convert it to the requested format.
const std::string saveAsCmd = "saveas url=" + encodedTo + " format=" + _format + " options=" + _sOptions;

// Send the save request ...
std::vector<char> saveasRequest(saveAsCmd.begin(), saveAsCmd.end());

_clientSession->handleMessage(saveasRequest);
}


static std::atomic<std::size_t> gRenderSearchResultBrokerInstanceCouter;

std::size_t RenderSearchResultBroker::getInstanceCount()
{
return gRenderSearchResultBrokerInstanceCouter;
}

RenderSearchResultBroker::RenderSearchResultBroker(
std::string const& uri,
Poco::URI const& uriPublic,
std::string const& docKey,
std::shared_ptr<std::vector<char>> const& pSearchResultContent)
: StatelessBatchBroker(uri, uriPublic, docKey)
, _pSearchResultContent(pSearchResultContent)
{
LOG_TRC("Created RenderSearchResultBroker: uri: [" << uri << "], uriPublic: [" << uriPublic.toString()
<< "], docKey: [" << docKey << "].");
gConvertToBrokerInstanceCouter++;
}

RenderSearchResultBroker::~RenderSearchResultBroker()
{}

bool RenderSearchResultBroker::executeCommand(SocketDisposition& disposition, std::string const& id)
{
std::shared_ptr<RenderSearchResultBroker> docBroker = std::static_pointer_cast<RenderSearchResultBroker>(shared_from_this());

const bool isReadOnly = true;

std::shared_ptr<ProtocolHandlerInterface> emptyProtocolHandler;
RequestDetails requestDetails("render-search-result");
_clientSession = std::make_shared<ClientSession>(emptyProtocolHandler, id, docBroker, getPublicUri(), isReadOnly, requestDetails);
_clientSession->construct();

docBroker->setupTransfer(disposition, [docBroker] (std::shared_ptr<Socket>const & moveSocket)
{
docBroker->setResponseSocket(std::static_pointer_cast<StreamSocket>(moveSocket));

// First add and load the session.
docBroker->addSession(docBroker->_clientSession);

// Load the document manually.
std::string encodedFrom;
Poco::URI::encode(docBroker->getPublicUri().getPath(), "", encodedFrom);
// add batch mode, no interactive dialogs
const std::string _load = "load url=" + encodedFrom + " batch=true";
std::vector<char> loadRequest(_load.begin(), _load.end());
docBroker->_clientSession->handleMessage(loadRequest);
});

return true;
}

void RenderSearchResultBroker::setLoaded()
{
DocumentBroker::setLoaded();

// Send the rendersearchresult request ...
const std::string renderSearchResultCmd = "rendersearchresult ";
std::vector<char> renderSearchResultRequest(renderSearchResultCmd.begin(), renderSearchResultCmd.end());
renderSearchResultRequest.resize(renderSearchResultCmd.size() + _pSearchResultContent->size());
std::copy(_pSearchResultContent->begin(), _pSearchResultContent->end(), renderSearchResultRequest.begin() + renderSearchResultCmd.size());
_clientSession->handleMessage(renderSearchResultRequest);
}

void RenderSearchResultBroker::dispose()
{
if (!_uriOrig.empty())
{
gRenderSearchResultBrokerInstanceCouter--;
removeFile(_uriOrig);
_uriOrig.clear();
}
}

bool RenderSearchResultBroker::handleInput(const std::shared_ptr<Message>& message)
{
bool bResult = DocumentBroker::handleInput(message);

if (bResult)
{
auto const& messageData = message->data();

static std::string commandString = "rendersearchresult:\n";
static std::vector<char> commandStringVector(commandString.begin(), commandString.end());

if (messageData.size() >= commandStringVector.size())
{
bool bEquals = std::equal(commandStringVector.begin(), commandStringVector.end(),
messageData.begin());
if (bEquals)
{
_aResposeData.resize(messageData.size() - commandStringVector.size());
std::copy(messageData.begin() + commandStringVector.size(), messageData.end(), _aResposeData.begin());

http::Response httpResponse(http::StatusCode::OK);
FileServerRequestHandler::hstsHeaders(httpResponse);
// really not ideal that the response works only with std::string
httpResponse.setBody(std::string(_aResposeData.data(), _aResposeData.size()), "image/png");
httpResponse.header().setConnectionToken(http::Header::ConnectionToken::Close);
_socket->sendAndShutdown(httpResponse);

removeSession(_clientSession);
stop("Finished RenderSearchResult handler.");
}
}
}
return bResult;
}

#endif

std::vector<std::shared_ptr<ClientSession>> DocumentBroker::getSessionsTestOnlyUnsafe()
{
std::vector<std::shared_ptr<ClientSession>> result;
Expand Down
Loading

0 comments on commit 44afe21

Please sign in to comment.