wsd: support synchronous CheckFileInfo

In certain scenarios, such as with Proxy.php,
we don't have CheckFileInfo in advance and
need to request it before proceeding further.

This adds a wrapper to wait for the
CheckFileInfo request to complete.

Change-Id: I8afa955f841899eb667c02168a29a68c1dffb21b
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
pull/8790/head
Ashod Nakashian 2024-04-16 03:32:39 -04:00 committed by Andras Timar
parent 4c5adb70e6
commit e690a739da
3 changed files with 41 additions and 3 deletions

View File

@ -20,6 +20,7 @@
#include <ios>
#include <fstream>
#include <memory>
#include <stdexcept>
#include <string>
#include <sstream>
@ -34,6 +35,7 @@
#include "Admin.hpp"
#include "Authorization.hpp"
#include "ClientSession.hpp"
#include "Common.hpp"
#include "Exceptions.hpp"
#include "COOLWSD.hpp"
#include "Socket.hpp"
@ -53,6 +55,7 @@
#include <CommandControl.hpp>
#if !MOBILEAPP
#include <wopi/CheckFileInfo.hpp>
#include <net/HttpHelper.hpp>
#endif
#include <sys/types.h>
@ -878,6 +881,20 @@ bool DocumentBroker::download(
{
LOG_DBG("CheckFileInfo for docKey [" << _docKey << ']');
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
if (!wopiFileInfo)
{
auto poller = std::make_shared<TerminatingPoll>("CFISynReqPoll");
poller->startThread();
CheckFileInfo checkFileInfo(poller, session->getPublicUri(), [](CheckFileInfo&) {});
checkFileInfo.checkFileInfoSync(RedirectionLimit);
wopiFileInfo = checkFileInfo.wopiFileInfo(session->getPublicUri());
if (!wopiFileInfo)
{
throw std::runtime_error(
"CheckFileInfo failed or timed out while adding session #" + session->getId());
}
}
wopiStorage->handleWOPIFileInfo(*wopiFileInfo, *_lockCtx);
checkFileInfoCallDurationMs = std::chrono::duration_cast<std::chrono::milliseconds>(

View File

@ -24,7 +24,7 @@
#include <common/JsonUtil.hpp>
#include <Util.hpp>
void CheckFileInfo::checkFileInfo(int redirectLimit)
bool CheckFileInfo::checkFileInfo(int redirectLimit)
{
const std::string uriAnonym = COOLWSD::anonymizeUrl(_url.toString());
@ -136,6 +136,9 @@ void CheckFileInfo::checkFileInfo(int redirectLimit)
{
_onFinishCallback(*this);
}
std::lock_guard<std::mutex> lock(_mutex);
_cv.notify_all();
};
_httpSession->setFinishedHandler(std::move(finishedCallback));
@ -151,11 +154,21 @@ void CheckFileInfo::checkFileInfo(int redirectLimit)
_onFinishCallback(*this);
}
return;
return false;
}
// We're in business.
_state = State::Active;
return true;
}
void CheckFileInfo::checkFileInfoSync(int redirectionLimit)
{
std::unique_lock<std::mutex> lock(_mutex);
if (checkFileInfo(redirectionLimit))
{
_cv.wait_for(lock, std::chrono::seconds(30));
}
}
std::unique_ptr<WopiStorage::WOPIFileInfo>

View File

@ -11,6 +11,8 @@
#pragma once
#include <chrono>
#include <condition_variable>
#if MOBILEAPP
#error This file should be excluded from Mobile App builds
#endif // MOBILEAPP
@ -65,7 +67,11 @@ public:
std::unique_ptr<WopiStorage::WOPIFileInfo> wopiFileInfo(const Poco::URI& uriPublic) const;
/// Start the actual request.
void checkFileInfo(int redirectionLimit);
bool checkFileInfo(int redirectionLimit);
/// Start the request and wait for the response.
/// In some scenarios we can't proceed without CheckFileInfo results.
void checkFileInfoSync(int redirectionLimit);
private:
inline void logPrefix(std::ostream& os) const
@ -84,4 +90,6 @@ private:
std::atomic<State> _state;
Poco::JSON::Object::Ptr _wopiInfo;
ProfileZone _profileZone;
std::mutex _mutex;
std::condition_variable _cv;
};