Skip to content

Commit

Permalink
wip commit
Browse files Browse the repository at this point in the history
Signed-off-by: Rashesh Padia <[email protected]>
Change-Id: I848f853be8c14d3367f8501c603114a3e23a617b
  • Loading branch information
Rash419 committed Sep 10, 2024
1 parent e7966c8 commit 5f9bd18
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 23 deletions.
7 changes: 7 additions & 0 deletions common/Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,13 @@ namespace Util
hash.resize(std::min(8, (int)hash.length()));
}

std::string getCoolVersionHash()
{
std::string hash(COOLWSD_VERSION_HASH);
hash.resize(std::min(8, (int)hash.length()));
return hash;
}

const std::string& getProcessIdentifier()
{
static std::string id = Util::rng::getHexString(8);
Expand Down
3 changes: 3 additions & 0 deletions common/Util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ namespace Util
/// Get version information
void getVersionInfo(std::string& version, std::string& hash);

/// Returns the COOL Version Hash string.
std::string getCoolVersionHash();

///< A random hex string that identifies the current process.
const std::string& getProcessIdentifier();

Expand Down
55 changes: 52 additions & 3 deletions wsd/Admin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <Poco/JSON/Array.h>
#include <Poco/JSON/Object.h>
#include <config.h>

#include <chrono>
#include <cstddef>
#include <iomanip>
#include <string>
#include <sys/poll.h>
#include <unistd.h>

Expand All @@ -23,6 +27,7 @@
#include "Admin.hpp"
#include "AdminModel.hpp"
#include "Auth.hpp"
#include "HttpRequest.hpp"
#include <Common.hpp>
#include <Log.hpp>
#include <Protocol.hpp>
Expand All @@ -41,7 +46,6 @@

using namespace COOLProtocol;

using Poco::Net::HTTPResponse;
using Poco::Util::Application;

const int Admin::MinStatsIntervalMs = 50;
Expand Down Expand Up @@ -416,6 +420,10 @@ void AdminSocketHandler::handleMessage(const std::vector<char> &payload)
{
_admin->setCloseMonitorFlag();
}
else if (tokens.equals(0, "rollingupdate") && tokens.size() > 1)
{
_admin->setRollingUpdateInfo(tokens[1]);
}
}

AdminSocketHandler::AdminSocketHandler(Admin* adminManager,
Expand Down Expand Up @@ -496,8 +504,7 @@ bool AdminSocketHandler::handleInitialRequest(
return true;
}

HTTPResponse response;
response.setStatusAndReason(HTTPResponse::HTTP_BAD_REQUEST);
http::Response response(http::StatusCode::BadRequest);
response.setContentLength(0);
LOG_INF_S("Admin::handleInitialRequest bad request");
socket->send(response);
Expand Down Expand Up @@ -1293,6 +1300,48 @@ void Admin::deleteMonitorSocket(const std::string& uriWithoutParam)
}
}

void Admin::setRollingUpdateInfo(const std::string& jsonString)
{
Poco::JSON::Object::Ptr object;
if (JsonUtil::parseJSON(jsonString, object))
{
bool status = JsonUtil::getJSONValue<bool>(object, "inprogress");
setRollingUpdateStatus(status);
Poco::JSON::Array::Ptr infoArray = object->getArray("serverinfo");
if (!infoArray.isNull())
{
for(size_t i=0; i < infoArray->size(); i++)
{
if (!infoArray->isObject(i))
{
return;
}
const auto serverInfoObject = infoArray->getObject(i);
const std::string gitHash = JsonUtil::getJSONValue<std::string>(serverInfoObject , "gitHash");
const std::string serverId = JsonUtil::getJSONValue<std::string>(serverInfoObject, "serverId");
const std::string routeToken = JsonUtil::getJSONValue<std::string>(serverInfoObject, "routeToken");
_rollingUpdateInfo.insert_or_assign(gitHash, RollingUpdateServerInfo(gitHash, serverId, routeToken));
}
}
}
}

std::string Admin::getBuddyServer(const std::string& gitHash)
{
LOG_DBG("Getting routeToken for gitHash[" << gitHash << ']');
for (auto iterator : _rollingUpdateInfo)
{
LOG_DBG("gitHash[" << iterator.first << "] routeToken[" << iterator.second.getRouteToken()
<< "] serverId[" << iterator.second.getRouteToken() << ']');
}
auto iterator = _rollingUpdateInfo.find(gitHash);
if (iterator != _rollingUpdateInfo.end())
{
return iterator->second.getRouteToken();
}
return std::string();
}

void Admin::stop()
{
joinThread();
Expand Down
34 changes: 34 additions & 0 deletions wsd/Admin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

#include "net/WebSocketHandler.hpp"
#include "COOLWSD.hpp"
#include <string>
#include <vector>

class Admin;

Expand Down Expand Up @@ -186,6 +188,14 @@ class Admin : public SocketPoll

void setCloseMonitorFlag() { _closeMonitor = true; }

void setRollingUpdateInfo(const std::string& jsonString);

void setRollingUpdateStatus(bool status) { _rollingUpdateStatus = status; }

bool getRollingUpdateStatus() { return _rollingUpdateStatus; }

std::string getBuddyServer(const std::string& gitHash);

private:
/// Notify Forkit of changed settings.
void notifyForkit();
Expand Down Expand Up @@ -253,6 +263,30 @@ class Admin : public SocketPoll
std::map<std::string, std::shared_ptr<MonitorSocketHandler>> _monitorSockets;

std::atomic<bool> _closeMonitor = false;

class RollingUpdateServerInfo
{
public:
std::string getGitHash() { return _gitHash; }
std::string getServerId() { return _serverId; }
std::string getRouteToken() { return _routeToken; }

RollingUpdateServerInfo(const std::string& gitHash, const std::string& serverId,
const std::string& routeToken)
: _gitHash(gitHash)
, _serverId(serverId)
, _routeToken(routeToken)
{
}

private:
std::string _gitHash;
std::string _serverId;
std::string _routeToken;
};

std::map<std::string, RollingUpdateServerInfo> _rollingUpdateInfo;
std::atomic<bool> _rollingUpdateStatus;
};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
88 changes: 80 additions & 8 deletions wsd/COOLWSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4321,22 +4321,41 @@ class ClientRequestDispatcher final : public SimpleSocketHandler
{
// Unit testing, nothing to do here
}
else if (requestDetails.equals(RequestDetails::Field::Type, "browser") || requestDetails.equals(RequestDetails::Field::Type, "wopi"))
else if (requestDetails.equals(RequestDetails::Field::Type, "browser") ||
requestDetails.equals(RequestDetails::Field::Type, "wopi"))
{

std::string protocol = "http";
if (socket->sniffSSL())
protocol = "https";

Poco::URI requestUri(protocol + "://" + request.getHost() + request.getURI());
const std::string& path = requestUri.getPath();
bool versionMismatch = false;
if ((path.find("browser/" COOLWSD_VERSION_HASH "/") == std::string::npos &&
path.find("browser/" + Util::getCoolVersionHash() + "/") == std::string::npos) &&
path.find("admin/") == std::string::npos)
{
LOG_DBG("Client - server version mismatch, proxy request to different server "
"Expected: " COOLWSD_VERSION_HASH
"; Actual URI path with version hash: "
<< path);
versionMismatch = true;
}

// File server
assert(socket && "Must have a valid socket");
constexpr auto ProxyRemote = "/remote/";
constexpr auto ProxyRemoteLen = sizeof(ProxyRemote) - 1;
constexpr auto ProxyRemoteStatic = "/remote/static/";
const auto uri = requestDetails.getURI();
const auto pos = uri.find(ProxyRemoteStatic);
const auto pos = path.find(ProxyRemoteStatic);
if (pos != std::string::npos)
{
if (Util::endsWith(uri, "lokit-extra-img.svg"))
if (Util::endsWith(path, "lokit-extra-img.svg"))
{
ProxyRequestHandler::handleRequest(
uri.substr(pos + ProxyRemoteLen), socket,
ProxyRequestHandler::getProxyRatingServer());
path.substr(pos + ProxyRemoteLen), socket,
ProxyRequestHandler::getProxyRatingServer(), "GET");
}
#if ENABLE_FEATURE_LOCK
else
Expand All @@ -4347,12 +4366,65 @@ class ClientRequestDispatcher final : public SimpleSocketHandler
{
const std::string& serverUri =
unlockImageUri.getScheme() + "://" + unlockImageUri.getAuthority();
ProxyRequestHandler::handleRequest(uri.substr(pos + sizeof("/remote/static") - 1),
socket, serverUri);
ProxyRequestHandler::handleRequest(
path.substr(pos + sizeof("/remote/static") - 1), socket, serverUri, "GET");
}
}
#endif
}
else if (COOLWSD::IndirectionServerEnabled && versionMismatch &&
Admin::instance().getRollingUpdateStatus())
{
std::string searchString = "/browser/";
size_t startHashPos = path.find(searchString);
if (startHashPos != std::string::npos)
{
startHashPos += searchString.length();
size_t endHashPos = path.find('/', startHashPos);

std::string gitHash;
if (endHashPos != std::string::npos)
{
gitHash = path.substr(startHashPos, endHashPos - startHashPos);
}
else
{
gitHash = path.substr(startHashPos);
}

const std::string& hash = Util::getCoolVersionHash();
std::string routeToken = Admin::instance().getBuddyServer(hash);
if (!routeToken.empty())
{
Poco::URI::QueryParameters params = requestUri.getQueryParameters();
const auto routeTokenIt =
std::find_if(params.begin(), params.end(),
[](const std::pair<std::string, std::string>& element)
{ return element.first == "RouteToken"; });
if (routeTokenIt == params.end())
{
LOG_DBG("Adding routeToken[" << routeToken
<< "] as a parameter to requestUri["
<< requestUri.toString() << ']');

requestUri.addQueryParameter("RouteToken", routeToken);
}
else
{
LOG_DBG("Updating routeToken[" << routeToken
<< "] parameter in requestUri["
<< requestUri.toString() << ']');

routeTokenIt->second = routeToken;
requestUri.setQueryParameters(params);
}
}

ProxyRequestHandler::handleRequest(requestUri.getPathAndQuery(), socket,
requestUri.getScheme() + "://" +
requestUri.getAuthority(), request.getMethod());
}
}
else
{
COOLWSD::FileRequestHandler->handleRequest(request, requestDetails, message, socket);
Expand Down
27 changes: 16 additions & 11 deletions wsd/ProxyRequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ std::chrono::system_clock::time_point ProxyRequestHandler::MaxAge;

void ProxyRequestHandler::handleRequest(const std::string& relPath,
const std::shared_ptr<StreamSocket>& socket,
const std::string& serverUri)
const std::string& serverUri,
const std::string& verb)
{

Poco::URI uriProxy(serverUri);
Expand All @@ -36,19 +37,23 @@ void ProxyRequestHandler::handleRequest(const std::string& relPath,
MaxAge = zero;
}

const auto cacheEntry = CacheFileHash.find(relPath);
if (cacheEntry != CacheFileHash.end())
{
socket->sendAndShutdown(*cacheEntry->second);
return;
}
// const auto cacheEntry = CacheFileHash.find(relPath);
// if (cacheEntry != CacheFileHash.end())
// {
// socket->sendAndShutdown(*cacheEntry->second);
// return;
// }

uriProxy.setPathEtc(relPath);
LOG_DBG("uriProxy[" << uriProxy.getPathAndQuery() << ']');

auto protocol = uriProxy.getScheme() == "https" ? http::Session::Protocol::HttpSsl
: http::Session::Protocol::HttpUnencrypted;

uriProxy.setPath(relPath);
auto sessionProxy = http::Session::create(uriProxy.getHost(),
http::Session::Protocol::HttpSsl,
uriProxy.getPort());
auto sessionProxy = http::Session::create(uriProxy.getHost(), protocol, uriProxy.getPort());
sessionProxy->setTimeout(std::chrono::seconds(10));
http::Request requestProxy(uriProxy.getPathAndQuery());
requestProxy.setVerb(verb);
http::Session::FinishedCallback proxyCallback =
[socket, zero](const std::shared_ptr<http::Session>& httpSession)
{
Expand Down
5 changes: 4 additions & 1 deletion wsd/ProxyRequestHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#pragma once

#include <Poco/URI.h>
#include <string>
#include "Socket.hpp"

Expand All @@ -19,7 +20,9 @@ class ProxyRequestHandler
public:
static void handleRequest(const std::string& relPath,
const std::shared_ptr<StreamSocket>& socket,
const std::string& serverUri);
const std::string& serverUri,
const std::string& verb);

static std::string getProxyRatingServer() { return ProxyRatingServer; }

private:
Expand Down

0 comments on commit 5f9bd18

Please sign in to comment.