Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
meven committed Nov 6, 2024
1 parent 13c95fd commit b19d6aa
Showing 1 changed file with 139 additions and 9 deletions.
148 changes: 139 additions & 9 deletions wsd/ClientRequestDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

#include <ClientRequestDispatcher.hpp>
#include <cstdio>
#include <exception>
#include <istream>
#include <stdexcept>

#if ENABLE_FEATURE_LOCK
#include "CommandControl.hpp"
Expand All @@ -35,6 +37,7 @@
#include <ProxyRequestHandler.hpp>
#include <RequestDetails.hpp>
#include <Socket.hpp>
#include <ServerSocket.hpp>
#include <UserMessages.hpp>
#include <Util.hpp>
#include <net/AsyncDNS.hpp>
Expand Down Expand Up @@ -1111,31 +1114,87 @@ bool ClientRequestDispatcher::handleWopiAccessCheckRequest(const Poco::Net::HTTP

LOG_DBG("Wopi Access Check request: " << request.getURI());

Poco::MemoryInputStream startmessage(&socket->getInBuffer()[0], socket->getInBuffer().size());
StreamSocket::MessageMap map;

// Poco::JSON
Poco::JSON::Parser jsonParser;
Poco::Dynamic::Var parsingResult;
Poco::JSON::Object::Ptr object;
Poco::JSON::Object::Ptr jsonObject;
Poco::URI uri;

std::string text(std::istreambuf_iterator<char>(message), {});
LOG_DBG("Wopi Access Check request text: " << text);

std::string callbackUrlStr;
try
{
parsingResult = jsonParser.parse(text);
object = parsingResult.extract<Poco::JSON::Object::Ptr>();
jsonObject = parsingResult.extract<Poco::JSON::Object::Ptr>();
}
catch (const std::exception& exception)
{
LOG_ERR_S("Wopi Access Check request error, json object expected got ["
<< text << "] on request to URL: " << request.getURI() << exception.what());

auto callbackUrlStr = object->getValue<std::string>("callbackUrl");
HttpHelper::sendErrorAndShutdown(http::StatusCode::BadRequest, socket);
return false;
}

uri = Poco::URI(callbackUrlStr);
try
{
callbackUrlStr = jsonObject->getValue<std::string>("callbackUrl");
}
catch (const std::exception& exception)
{
LOG_ERR_S("Wopi Access Check request error, json object expected got ["
LOG_ERR_S("Wopi Access Check request error, missing key callbackUrl expected got ["
<< text << "] on request to URL: " << request.getURI() << exception.what());

HttpHelper::sendErrorAndShutdown(http::StatusCode::BadRequest, socket);
return false;
}

LOG_DBG("Wopi Access Check request callbackUrlStr: " << callbackUrlStr);

std::string scheme, host, portStr, url;
if (!net::parseUri(callbackUrlStr, scheme, host, portStr, url)) {
HttpHelper::sendErrorAndShutdown(http::StatusCode::BadRequest, socket);
return false;
}
http::Session::Protocol protocol = http::Session::Protocol::HttpSsl;
ulong port = 443;
if (scheme == "https://" || scheme.empty()) {
} else if (scheme == "http://") {

Check notice

Code scanning / CodeQL

Empty branch of conditional Note

Empty block without comment.
protocol = http::Session::Protocol::HttpUnencrypted;
port = 80;
} else {
LOG_ERR_S("Wopi Access Check request error, bad request protocol ["
<< text << "] on request to URL: " << request.getURI() << scheme);

HttpHelper::sendErrorAndShutdown(http::StatusCode::BadRequest, socket);
return false;
}
LOG_DBG("Wopi Access Check request scheme: " << scheme << port << portStr);

if (!portStr.empty()) {
try {
LOG_DBG("Wopi Access Check parsing portStr:" << portStr);
port = std::stoul(portStr);

} catch(std::invalid_argument &exception) {
LOG_DBG("Wopi Access Check erro parsing invalid_argument:" << portStr);
} catch(std::exception &exception) {

LOG_DBG("Wopi Access Check erro parsing portStr:" << portStr);

LOG_ERR_S("Wopi Access Check request error, bad request stoul ["
<< text << "] on request to URL: " << request.getURI());

HttpHelper::sendErrorAndShutdown(http::StatusCode::BadRequest, socket);
return false;
}
}

enum class CheckStatus
{
Ok = 0,
Expand All @@ -1151,7 +1210,7 @@ bool ClientRequestDispatcher::handleWopiAccessCheckRequest(const Poco::Net::HTTP
NoScheme,
Timeout,
};
std::map<CheckStatus, std::string> checkStatusNames = {
const std::map<CheckStatus, std::string> checkStatusNames = {
{ CheckStatus::Ok, "Ok" },
{ CheckStatus::NotHttpSucess, "NOT_HTTP_SUCESS" },
{ CheckStatus::HostNotFound, "HOST_NOT_FOUND" },
Expand All @@ -1167,16 +1226,86 @@ bool ClientRequestDispatcher::handleWopiAccessCheckRequest(const Poco::Net::HTTP

CheckStatus result = CheckStatus::Ok;

if (uri.getScheme().empty())
if (scheme.empty())
{
result = CheckStatus::NoScheme;
}
else if (uri.getScheme() != "https")
else if (protocol != http::Session::Protocol::HttpSsl)
{
result = CheckStatus::NotHttps;
}
else
{
LOG_DBG("Wopi Access Check about to prepare http session");

http::Request httpRequest(url);
auto httpProbeSession = http::Session::create(host, protocol, port);
httpProbeSession->setTimeout(std::chrono::seconds(2));


LOG_DBG("Wopi Access Check preparing http session");

// thread to probe http

/*
std::shared_ptr<SocketFactory> factory;
#if ENABLE_SSL
if (protocol == http::Session::Protocol::HttpUnencrypted)
factory = std::make_shared<SslSocketFactory>();
else
#endif
factory = std::make_shared<PlainSocketFactory>();
static std::shared_ptr<TerminatingPoll> httpProbingServerPoll(new TerminatingPoll("HttpProbeThread"));
auto httpServerSocket = ServerSocket::create(ServerSocket::Type::Local, port, Socket::Type::IPv4,
*httpProbingServerPoll, factory);
httpProbingServerPoll->insertNewSocket(httpServerSocket);
*/

Check notice

Code scanning / CodeQL

Commented-out code Note

This comment appears to contain commented-out code.

httpProbeSession->setFinishedHandler([=, this, &result](const std::shared_ptr<http::Session>&probeSession) {
LOG_INF("contacted successfully.");
auto httpResponse = probeSession->response();

if (httpResponse->state() == http::Response::State::Timeout) {
result = CheckStatus::Timeout;
}

if (httpResponse->state() == http::Response::State::Error) {
// are TLS errors here ?
result = CheckStatus::UnspecifiedError;
}

// construct the result
Poco::JSON::Object::Ptr status = new Poco::JSON::Object;
status->set("status", (int)result);
status->set("details", checkStatusNames.at(result));

std::ostringstream ostrJSON;
status->stringify(ostrJSON);
const auto output = ostrJSON.str();

http::Response jsonResponse(http::StatusCode::OK);
FileServerRequestHandler::hstsHeaders(jsonResponse);
jsonResponse.set("Last-Modified", Util::getHttpTimeNow());
jsonResponse.setBody(output, "application/json");
jsonResponse.set("X-Content-Type-Options", "nosniff");


socket->sendAndShutdown(jsonResponse);
LOG_INF("Sent wopiAccessCheck.json successfully.");

});

LOG_DBG("Wopi Access Check requesting: " << httpRequest.getUrl());

httpProbeSession->asyncRequest(httpRequest, *COOLWSD::getWebServerPoll());

///auto response = session->response();

Check notice

Code scanning / CodeQL

Commented-out code Note

This comment appears to contain commented-out code.

// httpRequest.async
//if (!httpRequest->asyncRequest(requestProxy, *COOLWSD::getWebServerPoll())) {

/*
// request the url
try
{
Expand Down Expand Up @@ -1232,12 +1361,13 @@ bool ClientRequestDispatcher::handleWopiAccessCheckRequest(const Poco::Net::HTTP
result = CheckStatus::UnspecifiedError;
}
*/

Check notice

Code scanning / CodeQL

Commented-out code Note

This comment appears to contain commented-out code.
}

// construct the result
Poco::JSON::Object::Ptr status = new Poco::JSON::Object;
status->set("status", (int)result);
status->set("details", checkStatusNames[result]);
status->set("details", checkStatusNames.at(result));

std::ostringstream ostrJSON;
status->stringify(ostrJSON);
Expand Down

0 comments on commit b19d6aa

Please sign in to comment.