Merge 15c39c0e51
into d016690e09
commit
8eb3e3cae5
|
@ -4535,6 +4535,7 @@ private:
|
|||
const std::string responseString = "OK";
|
||||
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
httpResponse.set("Content-Length", std::to_string(responseString.size()));
|
||||
httpResponse.set("Content-Type", mimeType);
|
||||
httpResponse.set("Last-Modified", Util::getHttpTimeNow());
|
||||
|
@ -4554,6 +4555,7 @@ private:
|
|||
|
||||
LOG_TRC_S("Favicon request: " << requestDetails.getURI());
|
||||
http::Response response(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(response);
|
||||
response.setContentType("image/vnd.microsoft.icon");
|
||||
std::string faviconPath = Path(Application::instance().commandPath()).parent().toString() + "favicon.ico";
|
||||
if (!File(faviconPath).exists())
|
||||
|
@ -4583,6 +4585,7 @@ private:
|
|||
Poco::replaceInPlace(xml, std::string("%SRV_URI%"), srvUrl);
|
||||
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
httpResponse.setBody(xml, "text/xml");
|
||||
httpResponse.set("Last-Modified", Util::getHttpTimeNow());
|
||||
httpResponse.set("X-Content-Type-Options", "nosniff");
|
||||
|
@ -4601,6 +4604,7 @@ private:
|
|||
const std::string capabilities = getCapabilitiesJson(request, socket);
|
||||
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
httpResponse.set("Last-Modified", Util::getHttpTimeNow());
|
||||
httpResponse.setBody(capabilities, "application/json");
|
||||
httpResponse.set("X-Content-Type-Options", "nosniff");
|
||||
|
@ -4731,6 +4735,7 @@ private:
|
|||
const std::string responseString = "User-agent: *\nDisallow: /\n";
|
||||
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
httpResponse.set("Last-Modified", Util::getHttpTimeNow());
|
||||
httpResponse.set("Content-Length", std::to_string(responseString.size()));
|
||||
httpResponse.set("Content-Type", "text/plain");
|
||||
|
@ -5141,6 +5146,7 @@ private:
|
|||
handler.takeFile();
|
||||
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
httpResponse.set("Content-Length", "0");
|
||||
socket->sendAndShutdown(httpResponse);
|
||||
socket->ignoreInput();
|
||||
|
@ -5197,6 +5203,7 @@ private:
|
|||
serveAsAttachment = attachmentIt->second != "0";
|
||||
|
||||
http::Response response(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(response);
|
||||
|
||||
// Instruct browsers to download the file, not display it
|
||||
// with the exception of SVG where we need the browser to
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "DocumentBroker.hpp"
|
||||
#include "COOLWSD.hpp"
|
||||
#include "FileServer.hpp"
|
||||
#include <common/Common.hpp>
|
||||
#include <common/JsonUtil.hpp>
|
||||
#include <common/Log.hpp>
|
||||
|
@ -1877,6 +1878,7 @@ bool ClientSession::handleKitToClientMessage(const std::shared_ptr<Message>& pay
|
|||
|
||||
const std::string fileName = Poco::Path(resultURL.getPath()).getFileName();
|
||||
http::Response response(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(response);
|
||||
if (!fileName.empty())
|
||||
response.set("Content-Disposition", "attachment; filename=\"" + fileName + '"');
|
||||
response.setContentType("application/octet-stream");
|
||||
|
@ -2307,6 +2309,7 @@ bool ClientSession::handleKitToClientMessage(const std::shared_ptr<Message>& pay
|
|||
const std::string stringJSON = payload->jsonString();
|
||||
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
httpResponse.set("Last-Modified", Util::getHttpTimeNow());
|
||||
httpResponse.set("X-Content-Type-Options", "nosniff");
|
||||
httpResponse.setBody(stringJSON, "application/json");
|
||||
|
@ -2335,6 +2338,7 @@ bool ClientSession::handleKitToClientMessage(const std::shared_ptr<Message>& pay
|
|||
std::string thumbnail(payload->data().data() + firstLineSize, payload->data().size() - firstLineSize);
|
||||
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
httpResponse.set("Last-Modified", Util::getHttpTimeNow());
|
||||
httpResponse.set("X-Content-Type-Options", "nosniff");
|
||||
httpResponse.setBody(thumbnail, "image/png");
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "ClientSession.hpp"
|
||||
#include "Exceptions.hpp"
|
||||
#include "COOLWSD.hpp"
|
||||
#include "FileServer.hpp"
|
||||
#include "Socket.hpp"
|
||||
#include "Storage.hpp"
|
||||
#include "TileCache.hpp"
|
||||
|
@ -814,7 +815,8 @@ bool DocumentBroker::download(const std::shared_ptr<ClientSession>& session, con
|
|||
if (_storage == nullptr)
|
||||
{
|
||||
// We should get an exception, not null.
|
||||
LOG_ERR("Failed to create Storage instance for [" << _docKey << "] in " << jailPath.toString());
|
||||
LOG_ERR("Failed to create Storage instance for [" << _docKey << "] in "
|
||||
<< jailPath.toString());
|
||||
return false;
|
||||
}
|
||||
firstInstance = true;
|
||||
|
@ -909,7 +911,7 @@ bool DocumentBroker::download(const std::shared_ptr<ClientSession>& session, con
|
|||
wopiInfo->set("TemplateSaveAs", wopiFileInfo->getTemplateSaveAs());
|
||||
|
||||
if (!templateSource.empty())
|
||||
wopiInfo->set("TemplateSource", templateSource);
|
||||
wopiInfo->set("TemplateSource", templateSource);
|
||||
|
||||
wopiInfo->set("HidePrintOption", wopiFileInfo->getHidePrintOption());
|
||||
wopiInfo->set("HideSaveOption", wopiFileInfo->getHideSaveOption());
|
||||
|
@ -1113,7 +1115,8 @@ bool DocumentBroker::download(const std::shared_ptr<ClientSession>& session, con
|
|||
// Extension matches, try the conversion. We convert the file to another one in
|
||||
// the same (jail) directory, with just the new extension tacked on.
|
||||
|
||||
const std::string newRootPath = _storage->getRootFilePath() + '.' + newExtension;
|
||||
const std::string newRootPath =
|
||||
_storage->getRootFilePath() + '.' + newExtension;
|
||||
|
||||
// The commandline must contain the space-separated substring @INPUT@ that is
|
||||
// replaced with the input file name, and @OUTPUT@ for the output file name.
|
||||
|
@ -4118,10 +4121,10 @@ bool RenderSearchResultBroker::handleInput(const std::shared_ptr<Message>& messa
|
|||
_aResposeData.resize(messageData.size() - commandStringVector.size());
|
||||
std::copy(messageData.begin() + commandStringVector.size(), messageData.end(), _aResposeData.begin());
|
||||
|
||||
std::string aDataString(_aResposeData.data(), _aResposeData.size());
|
||||
// really not ideal that the response works only with std::string
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
httpResponse.setBody(aDataString, "image/png");
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
httpResponse.setBody(std::string(_aResposeData.data(), _aResposeData.size()), "image/png");
|
||||
httpResponse.set("Connection", "close");
|
||||
_socket->sendAndShutdown(httpResponse);
|
||||
|
||||
|
|
|
@ -72,7 +72,8 @@ using Poco::Util::Application;
|
|||
|
||||
std::map<std::string, std::pair<std::string, std::string>> FileServerRequestHandler::FileHash;
|
||||
|
||||
namespace {
|
||||
namespace
|
||||
{
|
||||
|
||||
int functionConversation(int /*num_msg*/, const struct pam_message** /*msg*/,
|
||||
struct pam_response **reply, void *appdata_ptr)
|
||||
|
@ -424,6 +425,7 @@ bool FileServerRequestHandler::isAdminLoggedIn(const HTTPRequest& request, http:
|
|||
fileInfo->stringify(jsonStream);
|
||||
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
httpResponse.set("Last-Modified", Util::getHttpTime(localFile->fileLastModifiedTime));
|
||||
httpResponse.setBody(jsonStream.str(), "application/json; charset=utf-8");
|
||||
socket->send(httpResponse);
|
||||
|
@ -439,6 +441,7 @@ bool FileServerRequestHandler::isAdminLoggedIn(const HTTPRequest& request, http:
|
|||
ss << inputFile.rdbuf();
|
||||
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
httpResponse.set("Last-Modified", Util::getHttpTime(localFile->fileLastModifiedTime));
|
||||
httpResponse.setBody(ss.str(), "text/plain; charset=utf-8");
|
||||
socket->send(httpResponse);
|
||||
|
@ -483,6 +486,7 @@ bool FileServerRequestHandler::isAdminLoggedIn(const HTTPRequest& request, http:
|
|||
const std::string body = "{\"LastModifiedTime\": \"" +
|
||||
localFile->getLastModifiedTime() + "\" }";
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
httpResponse.setBody(body, "application/json; charset=utf-8");
|
||||
socket->send(httpResponse);
|
||||
return;
|
||||
|
@ -502,22 +506,10 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request,
|
|||
noCache = !COOLWSD::ForceCaching; // for cypress
|
||||
#endif
|
||||
http::Response response(http::StatusCode::OK);
|
||||
hstsHeaders(response);
|
||||
|
||||
const auto& config = Application::instance().config();
|
||||
|
||||
// HSTS hardening. Disabled in debug builds.
|
||||
#if !ENABLE_DEBUG
|
||||
if (COOLWSD::isSSLEnabled() || COOLWSD::isSSLTermination())
|
||||
{
|
||||
if (config.getBool("ssl.sts.enabled", false))
|
||||
{
|
||||
const auto maxAge = config.getInt("ssl.sts.max_age", 31536000); // Default 1 year.
|
||||
response.add("Strict-Transport-Security",
|
||||
"max-age=" + std::to_string(maxAge) + "; includeSubDomains");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Poco::URI requestUri(request.getURI());
|
||||
LOG_TRC("Fileserver request: " << requestUri.toString());
|
||||
requestUri.normalize(); // avoid .'s and ..'s
|
||||
|
@ -564,6 +556,7 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request,
|
|||
LOG_ERR(message.rdbuf());
|
||||
|
||||
http::Response httpResponse(http::StatusCode::OK);
|
||||
FileServerRequestHandler::hstsHeaders(httpResponse);
|
||||
socket->send(httpResponse);
|
||||
return;
|
||||
}
|
||||
|
@ -1412,7 +1405,6 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request,
|
|||
LOG_TRC("Sent file: " << relPath << ": " << preprocess);
|
||||
}
|
||||
|
||||
|
||||
void FileServerRequestHandler::preprocessWelcomeFile(const HTTPRequest& request,
|
||||
const RequestDetails& requestDetails,
|
||||
Poco::MemoryInputStream& message,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <HttpRequest.hpp>
|
||||
#include <Socket.hpp>
|
||||
#include <COOLWSD.hpp>
|
||||
|
||||
#include <Poco/MemoryStream.h>
|
||||
#include <Poco/Util/LayeredConfiguration.h>
|
||||
|
@ -74,6 +75,24 @@ public:
|
|||
|
||||
static const std::string *getUncompressedFile(const std::string &path);
|
||||
|
||||
/// If configured and necessary, sets the HSTS headers.
|
||||
static void hstsHeaders([[maybe_unused]] http::Response& response)
|
||||
{
|
||||
// HSTS hardening. Disabled in debug builds.
|
||||
#if !ENABLE_DEBUG
|
||||
if (COOLWSD::isSSLEnabled() || COOLWSD::isSSLTermination())
|
||||
{
|
||||
if (COOLWSD::getConfigValue<bool>("ssl.sts.enabled", false))
|
||||
{
|
||||
static const auto maxAge =
|
||||
COOLWSD::getConfigValue<int>("ssl.sts.max_age", 31536000); // Default 1 year.
|
||||
response.add("Strict-Transport-Security",
|
||||
"max-age=" + std::to_string(maxAge) + "; includeSubDomains");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
static std::map<std::string, std::pair<std::string, std::string>> FileHash;
|
||||
static void sendError(http::StatusCode errorCode, const Poco::Net::HTTPRequest& request,
|
||||
|
|
Loading…
Reference in New Issue