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 4, 2024
1 parent adfceea commit 8cb5fe5
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 12 deletions.
1 change: 1 addition & 0 deletions common/Util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <LibreOfficeKit/LibreOfficeKitEnums.h>

#include <StringVector.hpp>
#include "config.h"

#define STRINGIFY(X) #X

Expand Down
4 changes: 3 additions & 1 deletion docker/from-source-gh-action/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ FROM ubuntu:24.04 AS builder

ENV CORE_ASSETS https://github.com/CollaboraOnline/online/releases/download/for-code-assets/core-co-24.04-assets.tar.gz
ENV BUILDDIR /build
ENV ONLINE_EXTRA_BUILD_OPTIONS --enable-experimental
ENV ONLINE_EXTRA_BUILD_OPTIONS --enable-experimental --disable-werror
ENV COLLABORA_ONLINE_REPO https://github.com/Rash419/online.git
ENV COLLABORA_ONLINE_BRANCH live-cluster-upgrading

WORKDIR /build

Expand Down
2 changes: 1 addition & 1 deletion docker/from-source-gh-action/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ fi

# Clone online repo
if test ! -d online ; then
git clone --depth=1 "$COLLABORA_ONLINE_REPO" online || exit 1
git clone "$COLLABORA_ONLINE_REPO" online || exit 1
fi

( cd online && git fetch --all && git checkout -f $COLLABORA_ONLINE_BRANCH && git clean -f -d && git pull -r ) || exit 1
Expand Down
51 changes: 50 additions & 1 deletion 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 Down Expand Up @@ -41,7 +45,6 @@

using namespace COOLProtocol;

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

const int Admin::MinStatsIntervalMs = 50;
Expand Down Expand Up @@ -418,6 +421,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 @@ -1307,6 +1314,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.try_emplace(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 @@ -187,6 +189,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 @@ -254,6 +264,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: */
84 changes: 78 additions & 6 deletions wsd/ClientRequestDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "Log.hpp"
#include <config.h>
#include <config_version.h>

#include <ClientRequestDispatcher.hpp>

Expand Down Expand Up @@ -677,7 +679,7 @@ void ClientRequestDispatcher::handleIncomingMessage(SocketDisposition& dispositi

// re-write ServiceRoot and cache.
RequestDetails requestDetails(request, COOLWSD::ServiceRoot);
// LOG_TRC("Request details " << requestDetails.toString());
LOG_DBG("Request details " << requestDetails.toString());

// Config & security ...
if (requestDetails.isProxy())
Expand Down Expand Up @@ -717,18 +719,33 @@ void ClientRequestDispatcher::handleIncomingMessage(SocketDisposition& dispositi
{
bool served = false;

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("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 (uri.ends_with("lokit-extra-img.svg"))
if (path.ends_with("lokit-extra-img.svg"))
{
ProxyRequestHandler::handleRequest(uri.substr(pos + ProxyRemoteLen), socket,
ProxyRequestHandler::handleRequest(path.substr(pos + ProxyRemoteLen), socket,
ProxyRequestHandler::getProxyRatingServer());
served = true;
}
Expand All @@ -742,12 +759,67 @@ void ClientRequestDispatcher::handleIncomingMessage(SocketDisposition& dispositi
const std::string& serverUri =
unlockImageUri.getScheme() + "://" + unlockImageUri.getAuthority();
ProxyRequestHandler::handleRequest(
uri.substr(pos + sizeof("/remote/static") - 1), socket, serverUri);
path.substr(pos + sizeof("/remote/static") - 1), socket, serverUri);
served = true;
}
}
#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);
}

std::string hash(gitHash);
hash.resize(std::min(8, (int)hash.length()));
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());
served = true;
}
}
else
{
FileServerRequestHandler::ResourceAccessDetails accessDetails;
Expand Down
9 changes: 6 additions & 3 deletions wsd/ProxyRequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,12 @@ void ProxyRequestHandler::handleRequest(const std::string& relPath,
return;
}

uriProxy.setPath(relPath);
auto sessionProxy = http::Session::create(uriProxy.getHost(),
http::Session::Protocol::HttpSsl,
uriProxy.setPathEtc(relPath);
LOG_DBG("uriProxy[" << uriProxy.getPathAndQuery() << ']');
auto protocol = uriProxy.getScheme() == "https" ? http::Session::Protocol::HttpSsl
: http::Session::Protocol::HttpUnencrypted;

auto sessionProxy = http::Session::create(uriProxy.getHost(), protocol,
uriProxy.getPort());
sessionProxy->setTimeout(std::chrono::seconds(10));
http::Request requestProxy(uriProxy.getPathAndQuery());
Expand Down
2 changes: 2 additions & 0 deletions 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 @@ -20,6 +21,7 @@ class ProxyRequestHandler
static void handleRequest(const std::string& relPath,
const std::shared_ptr<StreamSocket>& socket,
const std::string& serverUri);

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

private:
Expand Down

0 comments on commit 8cb5fe5

Please sign in to comment.