Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_NETWORKING_SDL_NET_BASEHANDLER_H
#define BACKENDS_NETWORKING_SDL_NET_BASEHANDLER_H
#include "backends/networking/sdl_net/client.h"
namespace Networking {
class BaseHandler {
public:
BaseHandler() {}
virtual ~BaseHandler() {}
virtual void handle(Client &) = 0;
virtual bool minimalModeSupported() { return false; }
};
} // End of namespace Networking
#endif

View File

@@ -0,0 +1,144 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/networking/sdl_net/handlers/connectcloudhandler.h"
#include "backends/fs/fs-factory.h"
#include "backends/cloud/cloudmanager.h"
#include "backends/networking/http/httpjsonrequest.h"
#include "backends/networking/sdl_net/getclienthandler.h"
#include "backends/networking/sdl_net/handlerutils.h"
#include "backends/networking/sdl_net/localwebserver.h"
#include "backends/networking/sdl_net/reader.h"
#include "common/formats/json.h"
#include "common/memstream.h"
#include "common/callback.h"
namespace Networking {
ConnectCloudHandler::ConnectCloudHandler() : _storageConnectionCallback(nullptr) {}
ConnectCloudHandler::~ConnectCloudHandler() {}
void ConnectCloudHandler::handle(Client &client) {
client.setHandler(new ConnectCloudClientHandler(this));
}
void ConnectCloudHandler::storageConnected(const Networking::ErrorResponse &response) const {
if (_storageConnectionCallback)
(*_storageConnectionCallback)(response);
}
//
ConnectCloudClientHandler::ConnectCloudClientHandler(const ConnectCloudHandler *cloudHandler):
_cloudHandler(cloudHandler), _clientContent(DisposeAfterUse::YES), _client(nullptr) {}
ConnectCloudClientHandler::~ConnectCloudClientHandler() {}
void ConnectCloudClientHandler::respond(Client &client, const Common::String &response, long responseCode) const {
Common::SeekableReadStream *responseStream = HandlerUtils::makeResponseStreamFromString(response);
GetClientHandler *responseHandler = new GetClientHandler(responseStream);
responseHandler->setResponseCode(responseCode);
responseHandler->setHeader("Access-Control-Allow-Origin", "https://cloud.scummvm.org");
responseHandler->setHeader("Access-Control-Allow-Methods", "POST");
responseHandler->setHeader("Access-Control-Allow-Headers", "Content-Type");
client.setHandler(responseHandler);
}
void ConnectCloudClientHandler::respondWithJson(Client &client, bool error, const Common::String &message, long responseCode) const {
Common::JSONObject response;
response.setVal("error", new Common::JSONValue(error));
response.setVal("message", new Common::JSONValue(message));
Common::JSONValue json = response;
respond(client, json.stringify(true), responseCode);
}
void ConnectCloudClientHandler::handleError(Client &client, const Common::String &message, long responseCode) const {
respondWithJson(client, true, message, responseCode);
}
void ConnectCloudClientHandler::handleSuccess(Client &client, const Common::String &message) const {
respondWithJson(client, false, message);
}
/// public
void ConnectCloudClientHandler::handle(Client *client) {
if (client == nullptr) {
warning("ConnectCloudClientHandler::handle(): empty client pointer");
return;
}
_client = client;
if (client->method() == "OPTIONS") {
respond(*client, "", 200);
return;
}
if (client->method() != "POST") {
handleError(*client, "Method Not Allowed", 405);
return;
}
if (_clientContent.size() > SUSPICIOUS_CONTENT_SIZE) {
handleError(*client, "Bad Request", 400);
return;
}
if (!client->readContent(&_clientContent))
return;
char *contents = Common::JSON::zeroTerminateContents(_clientContent);
Common::JSONValue *json = Common::JSON::parse(contents);
if (json == nullptr) {
handleError(*client, "Not Acceptable", 406);
return;
}
Networking::ErrorCallback callback = new Common::Callback<ConnectCloudClientHandler, const Networking::ErrorResponse &>(this, &ConnectCloudClientHandler::storageConnectionCallback);
Networking::JsonResponse jsonResponse(nullptr, json);
if (!CloudMan.connectStorage(jsonResponse, callback)) { // JSON doesn't have "storage" in it or it was invalid
delete json;
delete callback;
handleError(*client, "Not Acceptable", 406);
}
}
void ConnectCloudClientHandler::storageConnectionCallback(const Networking::ErrorResponse &response) {
if (response.failed || response.interrupted) {
Common::String message = "Failed to connect storage.";
if (response.failed) {
message += " Context: ";
message += response.response.c_str();
}
handleError(*_client, message, 200);
} else {
handleSuccess(*_client, "Storage connected.");
}
_cloudHandler->storageConnected(response);
}
} // End of namespace Networking

View File

@@ -0,0 +1,70 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_NETWORKING_SDL_NET_CONNECTCLOUDHANDLER_H
#define BACKENDS_NETWORKING_SDL_NET_CONNECTCLOUDHANDLER_H
#include "backends/networking/sdl_net/handlers/basehandler.h"
#include "backends/networking/sdl_net/client.h"
#include "backends/networking/http/request.h"
#include "common/memstream.h"
namespace Networking {
class ConnectCloudHandler: public BaseHandler {
void handleError(Client &client, const Common::String &message) const;
void setJsonResponseHandler(Client &client, const Common::String &type, const Common::String &message) const;
Networking::ErrorCallback _storageConnectionCallback;
public:
ConnectCloudHandler();
~ConnectCloudHandler() override;
void handle(Client &client) override;
bool minimalModeSupported() override { return true; }
void setStorageConnectionCallback(Networking::ErrorCallback cb) { _storageConnectionCallback = cb; }
void storageConnected(const Networking::ErrorResponse& response) const;
};
class ConnectCloudClientHandler : public ClientHandler {
const ConnectCloudHandler *_cloudHandler;
Common::MemoryWriteStreamDynamic _clientContent;
Client *_client;
static const int32 SUSPICIOUS_CONTENT_SIZE = 640 * 1024; // 640K ought to be enough for anybody
void respond(Client &client, const Common::String &response, long responseCode = 200) const;
void respondWithJson(Client &client, bool error, const Common::String &message, long responseCode = 200) const;
void handleError(Client &client, const Common::String &message, long responseCode) const;
void handleSuccess(Client &client, const Common::String &message) const;
void storageConnectionCallback(const Networking::ErrorResponse &response);
public:
ConnectCloudClientHandler(const ConnectCloudHandler* cloudHandler);
~ConnectCloudClientHandler() override;
void handle(Client *client) override;
};
} // End of namespace Networking
#endif

View File

@@ -0,0 +1,126 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/networking/sdl_net/handlers/createdirectoryhandler.h"
#include "backends/networking/sdl_net/handlerutils.h"
#include "backends/networking/sdl_net/localwebserver.h"
#include "common/translation.h"
#include "common/callback.h"
namespace Networking {
CreateDirectoryHandler::CreateDirectoryHandler() {}
CreateDirectoryHandler::~CreateDirectoryHandler() {}
void CreateDirectoryHandler::handleError(Client &client, const Common::String &message) const {
if (client.queryParameter("answer_json") == "true")
setJsonResponseHandler(client, "error", message);
else
HandlerUtils::setFilesManagerErrorMessageHandler(client, message);
}
void CreateDirectoryHandler::setJsonResponseHandler(Client &client, const Common::String &type, const Common::String &message) const {
Common::JSONObject response;
response.setVal("type", new Common::JSONValue(type));
response.setVal("message", new Common::JSONValue(message));
Common::JSONValue json = response;
LocalWebserver::setClientGetHandler(client, json.stringify(true));
}
/// public
void CreateDirectoryHandler::handle(Client &client) {
Common::String path = client.queryParameter("path");
Common::String name = client.queryParameter("directory_name");
// check that <path> is not an absolute root
if (path == "" || path == "/") {
handleError(client, Common::convertFromU32String(_("Can't create directory here!")));
return;
}
// check that <path> contains no '../'
if (HandlerUtils::hasForbiddenCombinations(path)) {
handleError(client, Common::convertFromU32String(_("Invalid path!")));
return;
}
// transform virtual path to actual file system one
Common::String basePath;
Common::Path baseFSPath, fsPath;
if (!urlToPath(path, fsPath, basePath, baseFSPath)) {
handleError(client, Common::convertFromU32String(_("Invalid path!")));
return;
}
// check that <path> exists, is directory and isn't forbidden
Common::FSNode node(fsPath);
if (!HandlerUtils::permittedPath(node.getPath())) {
handleError(client, Common::convertFromU32String(_("Invalid path!")));
return;
}
if (!node.exists()) {
handleError(client, Common::convertFromU32String(_("Parent directory doesn't exists!")));
return;
}
if (!node.isDirectory()) {
handleError(client, Common::convertFromU32String(_("Can't create a directory within a file!")));
return;
}
// check that <directory_name> doesn't exist or is directory
node = Common::FSNode(fsPath.appendComponent(name));
if (node.exists()) {
if (!node.isDirectory()) {
handleError(client, Common::convertFromU32String(_("There is a file with that name in the parent directory!")));
return;
}
} else {
// create the <directory_name> in <path>
if (!node.createDirectory()) {
handleError(client, Common::convertFromU32String(_("Failed to create the directory!")));
return;
}
}
// if json requested, respond with it
if (client.queryParameter("answer_json") == "true") {
setJsonResponseHandler(client, "success", Common::convertFromU32String(_("Directory created successfully!")));
return;
}
// set redirect on success
HandlerUtils::setMessageHandler(
client,
Common::String::format(
"%s<br/><a href=\"files?path=%s\">%s</a>",
Common::convertFromU32String(_("Directory created successfully!")).c_str(),
client.queryParameter("path").c_str(),
Common::convertFromU32String(_("Back to parent directory")).c_str()
),
(client.queryParameter("ajax") == "true" ? "/filesAJAX?path=" : "/files?path=") +
LocalWebserver::urlEncodeQueryParameterValue(client.queryParameter("path"))
);
}
} // End of namespace Networking

View File

@@ -0,0 +1,41 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_NETWORKING_SDL_NET_CREATEDIRECTORYHANDLER_H
#define BACKENDS_NETWORKING_SDL_NET_CREATEDIRECTORYHANDLER_H
#include "backends/networking/sdl_net/handlers/filesbasehandler.h"
namespace Networking {
class CreateDirectoryHandler: public FilesBaseHandler {
void handleError(Client &client, const Common::String &message) const;
void setJsonResponseHandler(Client &client, const Common::String &type, const Common::String &message) const;
public:
CreateDirectoryHandler();
~CreateDirectoryHandler() override;
void handle(Client &client) override;
};
} // End of namespace Networking
#endif

View File

@@ -0,0 +1,87 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/networking/sdl_net/handlers/downloadfilehandler.h"
#include "backends/networking/sdl_net/getclienthandler.h"
#include "backends/networking/sdl_net/handlerutils.h"
#include "backends/networking/sdl_net/localwebserver.h"
#include "common/translation.h"
namespace Networking {
DownloadFileHandler::DownloadFileHandler() {}
DownloadFileHandler::~DownloadFileHandler() {}
/// public
void DownloadFileHandler::handle(Client &client) {
Common::String path = client.queryParameter("path");
// check that <path> is not an absolute root
if (path == "" || path == "/") {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
return;
}
// check that <path> contains no '../'
if (HandlerUtils::hasForbiddenCombinations(path)) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
return;
}
// transform virtual path to actual file system one
Common::String basePath;
Common::Path baseFSPath, fsPath;
if (!urlToPath(path, fsPath, basePath, baseFSPath, false) || path.empty()) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
return;
}
// check that <path> exists, is directory and isn't forbidden
Common::FSNode node(fsPath);
if (!HandlerUtils::permittedPath(node.getPath())) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
return;
}
if (!node.exists()) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("The file doesn't exist!")));
return;
}
if (node.isDirectory()) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Can't download a directory!")));
return;
}
Common::SeekableReadStream *stream = node.createReadStream();
if (stream == nullptr) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Failed to read the file!")));
return;
}
GetClientHandler *handler = new GetClientHandler(stream);
handler->setResponseCode(200);
handler->setHeader("Content-Type", "application/force-download");
handler->setHeader("Content-Disposition", "attachment; filename=\"" + node.getName() + "\"");
handler->setHeader("Content-Transfer-Encoding", "binary");
client.setHandler(handler);
}
} // End of namespace Networking

View File

@@ -0,0 +1,39 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_NETWORKING_SDL_NET_DOWNLOADFILEHANDLER_H
#define BACKENDS_NETWORKING_SDL_NET_DOWNLOADFILEHANDLER_H
#include "backends/networking/sdl_net/handlers/filesbasehandler.h"
namespace Networking {
class DownloadFileHandler: public FilesBaseHandler {
public:
DownloadFileHandler();
~DownloadFileHandler() override;
void handle(Client &client) override;
};
} // End of namespace Networking
#endif

View File

@@ -0,0 +1,80 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/networking/sdl_net/handlers/filesajaxpagehandler.h"
#include "backends/networking/sdl_net/handlerutils.h"
#include "backends/networking/sdl_net/localwebserver.h"
#include "common/translation.h"
namespace Networking {
#define FILES_PAGE_NAME ".filesAJAX.html"
FilesAjaxPageHandler::FilesAjaxPageHandler() {}
FilesAjaxPageHandler::~FilesAjaxPageHandler() {}
namespace {
Common::String encodeDoubleQuotesAndSlashes(const Common::String &s) {
Common::String result = "";
for (uint32 i = 0; i < s.size(); ++i)
if (s[i] == '"') {
result += "\\\"";
} else if (s[i] == '\\') {
result += "\\\\";
} else {
result += s[i];
}
return result;
}
}
/// public
void FilesAjaxPageHandler::handle(Client &client) {
// load stylish response page from the archive
Common::SeekableReadStream *const stream = HandlerUtils::getArchiveFile(FILES_PAGE_NAME);
if (stream == nullptr) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("The page is not available without the resources. Make sure file wwwroot.zip from ScummVM distribution is available in 'themepath'.")));
return;
}
Common::String response = HandlerUtils::readEverythingFromStream(stream);
Common::String path = client.queryParameter("path");
//these occur twice:
replace(response, "{create_directory_button}", _("Create directory").encode());
replace(response, "{create_directory_button}", _("Create directory").encode());
replace(response, "{upload_files_button}", _("Upload files").encode()); //tab
replace(response, "{upload_file_button}", _("Upload files").encode()); //button in the tab
replace(response, "{create_directory_desc}", _("Type new directory name:").encode());
replace(response, "{upload_file_desc}", _("Select a file to upload:").encode());
replace(response, "{or_upload_directory_desc}", _("Or select a directory (works in Chrome only):").encode());
replace(response, "{index_of}", _("Index of ").encode());
replace(response, "{loading}", ("Loading..."));
replace(response, "{error}", _("Error occurred").encode());
replace(response, "{start_path}", encodeDoubleQuotesAndSlashes(path));
LocalWebserver::setClientGetHandler(client, response);
}
} // End of namespace Networking

View File

@@ -0,0 +1,39 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_NETWORKING_SDL_NET_FILESAJAXPAGEHANDLER_H
#define BACKENDS_NETWORKING_SDL_NET_FILESAJAXPAGEHANDLER_H
#include "backends/networking/sdl_net/handlers/filesbasehandler.h"
namespace Networking {
class FilesAjaxPageHandler: public FilesBaseHandler {
public:
FilesAjaxPageHandler();
~FilesAjaxPageHandler() override;
void handle(Client &client) override;
};
} // End of namespace Networking
#endif

View File

@@ -0,0 +1,83 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/networking/sdl_net/handlers/filesbasehandler.h"
#include "backends/saves/default/default-saves.h"
#include "common/config-manager.h"
#include "common/system.h"
namespace Networking {
FilesBaseHandler::FilesBaseHandler() {}
FilesBaseHandler::~FilesBaseHandler() {}
Common::String FilesBaseHandler::parentPath(const Common::String &path) {
Common::String result = path;
if (result.size() && (result.lastChar() == '/' || result.lastChar() == '\\')) result.deleteLastChar();
if (!result.empty()) {
for (int i = result.size() - 1; i >= 0; --i)
if (i == 0 || result[i] == '/' || result[i] == '\\') {
result.erase(i);
break;
}
}
if (result.size() && result.lastChar() != '/' && result.lastChar() != '\\')
result += '/';
return result;
}
bool FilesBaseHandler::urlToPath(Common::String &url, Common::Path &path, Common::String &baseUrl, Common::Path &basePath, bool isDirectory) {
// <url> is not empty, but could lack the trailing slash
if (isDirectory && url.lastChar() != '/')
url += '/';
if (url.hasPrefix("/root") && ConfMan.hasKey("rootpath", "cloud")) {
baseUrl = "/root/";
basePath = ConfMan.getPath("rootpath", "cloud");
url.erase(0, 5);
if (url.size() && url[0] == '/')
url.deleteChar(0); // if that was "/root/ab/c", it becomes "/ab/c", but we need "ab/c"
path = basePath.join(url, '/');
return true;
}
if (url.hasPrefix("/saves")) {
baseUrl = "/saves/";
// determine savepath (prefix to remove)
#ifdef USE_CLOUD
DefaultSaveFileManager *manager = dynamic_cast<DefaultSaveFileManager *>(g_system->getSavefileManager());
basePath = (manager ? manager->concatWithSavesPath("") : ConfMan.getPath("savepath"));
#else
basePath = ConfMan.getPath("savepath");
#endif
url.erase(0, 6);
if (url.size() && url[0] == '/')
url.deleteChar(0);
path = basePath.join(url, '/');
return true;
}
return false;
}
} // End of namespace Networking

View File

@@ -0,0 +1,53 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_NETWORKING_SDL_NET_FILESBASEHANDLER_H
#define BACKENDS_NETWORKING_SDL_NET_FILESBASEHANDLER_H
#include "backends/networking/sdl_net/handlers/basehandler.h"
namespace Common {
class Path;
}
namespace Networking {
class FilesBaseHandler: public BaseHandler {
protected:
Common::String parentPath(const Common::String &path);
/**
* Transforms virtual <url> into actual file system path.
*
* Fills base path with actual file system prefix
* and base URL with virtual prefix
*
* Returns true on success.
*/
bool urlToPath(Common::String &url, Common::Path &path, Common::String &baseUrl, Common::Path &basePath, bool isDirectory = true);
public:
FilesBaseHandler();
~FilesBaseHandler() override;
};
} // End of namespace Networking
#endif

View File

@@ -0,0 +1,233 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/networking/sdl_net/handlers/filespagehandler.h"
#include "backends/networking/sdl_net/handlerutils.h"
#include "backends/networking/sdl_net/localwebserver.h"
#include "common/config-manager.h"
#include "common/translation.h"
namespace Networking {
#define INDEX_PAGE_NAME ".index.html"
#define FILES_PAGE_NAME ".files.html"
FilesPageHandler::FilesPageHandler() {}
FilesPageHandler::~FilesPageHandler() {}
namespace {
Common::String encodeDoubleQuotes(const Common::String &s) {
Common::String result = "";
for (uint32 i = 0; i < s.size(); ++i)
if (s[i] == '"') {
result += "\\\"";
} else {
result += s[i];
}
return result;
}
Common::String encodeHtmlEntities(const Common::String &s) {
Common::String result = "";
for (uint32 i = 0; i < s.size(); ++i)
if (s[i] == '<')
result += "&lt;";
else if (s[i] == '>')
result += "&gt;";
else if (s[i] == '&')
result += "&amp;";
else if ((byte)s[i] > (byte)0x7F)
result += Common::String::format("&#%d;", (int)s[i]);
else result += s[i];
return result;
}
Common::String getDisplayPath(const Common::String &s) {
Common::String result = "";
for (uint32 i = 0; i < s.size(); ++i)
if (s[i] == '\\')
result += '/';
else
result += s[i];
if (result == "")
return "/";
return result;
}
}
bool FilesPageHandler::listDirectory(const Common::String &path_, Common::String &content, const Common::String &itemTemplate) {
if (path_ == "" || path_ == "/") {
if (ConfMan.hasKey("rootpath", "cloud"))
addItem(content, itemTemplate, IT_DIRECTORY, "/root/", Common::convertFromU32String(_("File system root")));
addItem(content, itemTemplate, IT_DIRECTORY, "/saves/", Common::convertFromU32String(_("Saved games")));
return true;
}
if (HandlerUtils::hasForbiddenCombinations(path_))
return false;
Common::String path = path_;
Common::String basePath;
Common::Path baseFSPath, fsPath;
if (!urlToPath(path, fsPath, basePath, baseFSPath))
return false;
Common::FSNode node = Common::FSNode(fsPath);
if (!HandlerUtils::permittedPath(node.getPath()))
return false;
if (!node.isDirectory())
return false;
// list directory
Common::FSList _nodeContent;
if (!node.getChildren(_nodeContent, Common::FSNode::kListAll, false)) // do not show hidden files
_nodeContent.clear();
else
Common::sort(_nodeContent.begin(), _nodeContent.end());
// add parent directory link
{
Common::Path relPath = fsPath.relativeTo(baseFSPath);
relPath = relPath.getParent();
Common::String filePath("/");
if (!relPath.empty())
filePath = basePath + relPath.toString('/');
addItem(content, itemTemplate, IT_PARENT_DIRECTORY, filePath, Common::convertFromU32String(_("Parent directory")));
}
// fill the content
for (auto &i : _nodeContent) {
Common::String name = i.getName();
if (i.isDirectory())
name += "/";
Common::Path relPath = i.getPath().relativeTo(baseFSPath);
Common::String filePath(basePath);
filePath += relPath.toString('/');
addItem(content, itemTemplate, detectType(i.isDirectory(), name), filePath, name);
}
return true;
}
FilesPageHandler::ItemType FilesPageHandler::detectType(bool isDirectory, const Common::String &name) {
if (isDirectory)
return IT_DIRECTORY;
if (name.hasSuffix(".txt"))
return IT_TXT;
if (name.hasSuffix(".zip"))
return IT_ZIP;
if (name.hasSuffix(".7z"))
return IT_7Z;
return IT_UNKNOWN;
}
void FilesPageHandler::addItem(Common::String &content, const Common::String &itemTemplate, ItemType itemType, const Common::String &path, const Common::String &name, const Common::String &size) const {
Common::String item = itemTemplate, icon;
bool isDirectory = (itemType == IT_DIRECTORY || itemType == IT_PARENT_DIRECTORY);
switch (itemType) {
case IT_DIRECTORY:
icon = "dir.png";
break;
case IT_PARENT_DIRECTORY:
icon = "up.png";
break;
case IT_TXT:
icon = "txt.png";
break;
case IT_ZIP:
icon = "zip.png";
break;
case IT_7Z:
icon = "7z.png";
break;
default:
icon = "unk.png";
}
replace(item, "{icon}", icon);
replace(item, "{link}", (isDirectory ? "files?path=" : "download?path=") + LocalWebserver::urlEncodeQueryParameterValue(path));
replace(item, "{name}", encodeHtmlEntities(name));
replace(item, "{size}", size);
content += item;
}
/// public
void FilesPageHandler::handle(Client &client) {
Common::String response =
"<html>" \
"<head><title>ScummVM</title><meta charset=\"utf-8\"/></head>" \
"<body>" \
"<p>{create_directory_desc}</p>" \
"<form action=\"create\">" \
"<input type=\"hidden\" name=\"path\" value=\"{path}\"/>" \
"<input type=\"text\" name=\"directory_name\" value=\"\"/>" \
"<input type=\"submit\" value=\"{create_directory_button}\"/>" \
"</form>" \
"<hr/>" \
"<p>{upload_file_desc}</p>" \
"<form action=\"upload?path={path}\" method=\"post\" enctype=\"multipart/form-data\">" \
"<input type=\"file\" name=\"upload_file-f\" allowdirs multiple/>" \
"<span>{or_upload_directory_desc}</span>" \
"<input type=\"file\" name=\"upload_file-d\" directory webkitdirectory multiple/>" \
"<input type=\"submit\" value=\"{upload_file_button}\"/>" \
"</form>"
"<hr/>" \
"<h1>{index_of_directory}</h1>" \
"<table>{content}</table>" \
"</body>" \
"</html>";
Common::String itemTemplate = "<tr><td><img src=\"icons/{icon}\"/></td><td><a href=\"{link}\">{name}</a></td><td>{size}</td></tr>\n"; //TODO: load this template too?
// load stylish response page from the archive
Common::SeekableReadStream *const stream = HandlerUtils::getArchiveFile(FILES_PAGE_NAME);
if (stream)
response = HandlerUtils::readEverythingFromStream(stream);
Common::String path = client.queryParameter("path");
Common::String content = "";
// show an error message if failed to list directory
if (!listDirectory(path, content, itemTemplate)) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("ScummVM couldn't list the directory you specified.")).c_str());
return;
}
//some of these occur twice:
replace(response, "{create_directory_button}", _("Create directory").encode());
replace(response, "{create_directory_button}", _("Create directory").encode());
replace(response, "{path}", encodeDoubleQuotes(client.queryParameter("path")));
replace(response, "{path}", encodeDoubleQuotes(client.queryParameter("path")));
replace(response, "{upload_files_button}", _("Upload files").encode()); //tab
replace(response, "{upload_file_button}", _("Upload files").encode()); //button in the tab
replace(response, "{create_directory_desc}", _("Type new directory name:").encode());
replace(response, "{upload_file_desc}", _("Select a file to upload:").encode());
replace(response, "{or_upload_directory_desc}", _("Or select a directory (works in Chrome only):").encode());
replace(response, "{index_of_directory}", Common::String::format("%s %s", _("Index of").encode().c_str(), encodeHtmlEntities(getDisplayPath(client.queryParameter("path"))).c_str()));
replace(response, "{content}", content);
LocalWebserver::setClientGetHandler(client, response);
}
} // End of namespace Networking

View File

@@ -0,0 +1,61 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_NETWORKING_SDL_NET_FILESPAGEHANDLER_H
#define BACKENDS_NETWORKING_SDL_NET_FILESPAGEHANDLER_H
#include "backends/networking/sdl_net/handlers/filesbasehandler.h"
namespace Networking {
class FilesPageHandler: public FilesBaseHandler {
enum ItemType {
IT_DIRECTORY,
IT_PARENT_DIRECTORY,
IT_TXT,
IT_ZIP,
IT_7Z,
IT_UNKNOWN
};
/**
* Lists the directory <path>.
*
* Returns true on success.
*/
bool listDirectory(const Common::String &path, Common::String &content, const Common::String &itemTemplate);
/** Helper method for detecting items' type. */
static ItemType detectType(bool isDirectory, const Common::String &name);
/** Helper method for adding items into the files list. */
void addItem(Common::String &content, const Common::String &itemTemplate, ItemType itemType, const Common::String &path, const Common::String &name, const Common::String &size = Common::String()) const;
public:
FilesPageHandler();
~FilesPageHandler() override;
void handle(Client &client) override;
};
} // End of namespace Networking
#endif

View File

@@ -0,0 +1,52 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/networking/sdl_net/handlers/indexpagehandler.h"
#include "backends/networking/sdl_net/handlerutils.h"
#include "backends/networking/sdl_net/localwebserver.h"
#include "common/translation.h"
namespace Networking {
IndexPageHandler::IndexPageHandler(): CommandSender(nullptr) {}
IndexPageHandler::~IndexPageHandler() {}
/// public
void IndexPageHandler::handle(Client &client) {
// redirect to "/filesAJAX"
HandlerUtils::setMessageHandler(
client,
Common::String::format(
"%s<br/><a href=\"files\">%s</a>",
Common::convertFromU32String(_("This is a local webserver index page.")).c_str(),
Common::convertFromU32String(_("Open Files manager")).c_str()
),
"/filesAJAX"
);
}
bool IndexPageHandler::minimalModeSupported() {
return true;
}
} // End of namespace Networking

View File

@@ -0,0 +1,42 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_NETWORKING_SDL_NET_INDEXPAGEHANDLER_H
#define BACKENDS_NETWORKING_SDL_NET_INDEXPAGEHANDLER_H
#include "backends/networking/sdl_net/handlers/basehandler.h"
#include "gui/object.h"
namespace Networking {
class LocalWebserver;
class IndexPageHandler: public BaseHandler, public GUI::CommandSender {
public:
IndexPageHandler();
~IndexPageHandler() override;
void handle(Client &client) override;
bool minimalModeSupported() override;
};
} // End of namespace Networking
#endif

View File

@@ -0,0 +1,155 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/networking/sdl_net/handlers/listajaxhandler.h"
#include "backends/networking/sdl_net/handlerutils.h"
#include "backends/networking/sdl_net/localwebserver.h"
#include "common/config-manager.h"
#include "common/formats/json.h"
#include "common/translation.h"
namespace Networking {
ListAjaxHandler::ListAjaxHandler() {}
ListAjaxHandler::~ListAjaxHandler() {}
Common::JSONObject ListAjaxHandler::listDirectory(const Common::String &path_) {
Common::JSONArray itemsList;
Common::JSONObject errorResult;
Common::JSONObject successResult;
successResult.setVal("type", new Common::JSONValue("success"));
errorResult.setVal("type", new Common::JSONValue("error"));
if (path_ == "" || path_ == "/") {
if (ConfMan.hasKey("rootpath", "cloud"))
addItem(itemsList, IT_DIRECTORY, "/root/", Common::convertFromU32String(_("File system root")));
addItem(itemsList, IT_DIRECTORY, "/saves/", Common::convertFromU32String(_("Saved games")));
successResult.setVal("items", new Common::JSONValue(itemsList));
return successResult;
}
if (HandlerUtils::hasForbiddenCombinations(path_))
return errorResult;
Common::String path = path_;
Common::String basePath;
Common::Path baseFSPath, fsPath;
if (!urlToPath(path, fsPath, basePath, baseFSPath))
return errorResult;
Common::FSNode node = Common::FSNode(fsPath);
if (!HandlerUtils::permittedPath(node.getPath()))
return errorResult;
if (!node.isDirectory())
return errorResult;
// list directory
Common::FSList _nodeContent;
if (!node.getChildren(_nodeContent, Common::FSNode::kListAll, false)) // do not show hidden files
_nodeContent.clear();
else
Common::sort(_nodeContent.begin(), _nodeContent.end());
// add parent directory link
{
Common::Path relPath = fsPath.relativeTo(baseFSPath);
relPath = relPath.getParent();
Common::String filePath("/");
if (!relPath.empty())
filePath = basePath + relPath.toString('/');
addItem(itemsList, IT_PARENT_DIRECTORY, filePath, Common::convertFromU32String(_("Parent directory")));
}
// fill the content
for (auto &curNode : _nodeContent) {
Common::String name = curNode.getName();
if (curNode.isDirectory())
name += "/";
Common::Path relPath = curNode.getPath().relativeTo(baseFSPath);
Common::String filePath(basePath);
filePath += relPath.toString('/');
addItem(itemsList, detectType(curNode.isDirectory(), name), filePath, name);
}
successResult.setVal("items", new Common::JSONValue(itemsList));
return successResult;
}
ListAjaxHandler::ItemType ListAjaxHandler::detectType(bool isDirectory, const Common::String &name) {
if (isDirectory)
return IT_DIRECTORY;
if (name.hasSuffix(".txt"))
return IT_TXT;
if (name.hasSuffix(".zip"))
return IT_ZIP;
if (name.hasSuffix(".7z"))
return IT_7Z;
return IT_UNKNOWN;
}
void ListAjaxHandler::addItem(Common::JSONArray &responseItemsList, ItemType itemType, const Common::String &path, const Common::String &name, const Common::String &size) {
Common::String icon;
bool isDirectory = (itemType == IT_DIRECTORY || itemType == IT_PARENT_DIRECTORY);
switch (itemType) {
case IT_DIRECTORY:
icon = "dir.png";
break;
case IT_PARENT_DIRECTORY:
icon = "up.png";
break;
case IT_TXT:
icon = "txt.png";
break;
case IT_ZIP:
icon = "zip.png";
break;
case IT_7Z:
icon = "7z.png";
break;
default:
icon = "unk.png";
}
Common::JSONObject item;
item.setVal("name", new Common::JSONValue(name));
item.setVal("path", new Common::JSONValue(path));
item.setVal("isDirectory", new Common::JSONValue(isDirectory));
item.setVal("size", new Common::JSONValue(size));
item.setVal("icon", new Common::JSONValue(icon));
responseItemsList.push_back(new Common::JSONValue(item));
}
/// public
void ListAjaxHandler::handle(Client &client) {
Common::String path = client.queryParameter("path");
Common::JSONValue jsonResponse = listDirectory(path);
Common::String response = jsonResponse.stringify(true);
LocalWebserver::setClientGetHandler(client, response);
}
} // End of namespace Networking

View File

@@ -0,0 +1,62 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_NETWORKING_SDL_NET_LISTAJAXHANDLER_H
#define BACKENDS_NETWORKING_SDL_NET_LISTAJAXHANDLER_H
#include "backends/networking/sdl_net/handlers/filesbasehandler.h"
#include "common/formats/json.h"
namespace Networking {
class ListAjaxHandler: public FilesBaseHandler {
enum ItemType {
IT_DIRECTORY,
IT_PARENT_DIRECTORY,
IT_TXT,
IT_ZIP,
IT_7Z,
IT_UNKNOWN
};
/**
* Lists the directory <path>.
*
* Returns JSON with either listed directory or error response.
*/
Common::JSONObject listDirectory(const Common::String &path);
/** Helper method for detecting items' type. */
static ItemType detectType(bool isDirectory, const Common::String &name);
/** Helper method for adding items into the files list. */
static void addItem(Common::JSONArray &responseItemsList, ItemType itemType, const Common::String &path, const Common::String &name, const Common::String &size = "");
public:
ListAjaxHandler();
~ListAjaxHandler() override;
void handle(Client &client) override;
};
} // End of namespace Networking
#endif

View File

@@ -0,0 +1,77 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/networking/sdl_net/handlers/resourcehandler.h"
#include "backends/networking/sdl_net/handlerutils.h"
#include "backends/networking/sdl_net/localwebserver.h"
namespace Networking {
ResourceHandler::ResourceHandler() {}
ResourceHandler::~ResourceHandler() {}
const char *ResourceHandler::determineMimeType(const Common::String &filename) {
// text
if (filename.hasSuffix(".html")) return "text/html";
if (filename.hasSuffix(".css")) return "text/css";
if (filename.hasSuffix(".txt")) return "text/plain";
if (filename.hasSuffix(".js")) return "application/javascript";
// images
if (filename.hasSuffix(".jpeg") || filename.hasSuffix(".jpg") || filename.hasSuffix(".jpe")) return "image/jpeg";
if (filename.hasSuffix(".gif")) return "image/gif";
if (filename.hasSuffix(".png")) return "image/png";
if (filename.hasSuffix(".svg")) return "image/svg+xml";
if (filename.hasSuffix(".tiff")) return "image/tiff";
if (filename.hasSuffix(".ico")) return "image/vnd.microsoft.icon";
if (filename.hasSuffix(".wbmp")) return "image/vnd.wap.wbmp";
if (filename.hasSuffix(".zip")) return "application/zip";
return "application/octet-stream";
}
/// public
void ResourceHandler::handle(Client &client) {
Common::String filename = client.path();
// remove leading slash
if (filename.size() > 0 && filename[0] == '/')
filename.deleteChar(0);
// if archive hidden file is requested, ignore
if (filename.size() > 0 && filename[0] == '.')
return;
// if file not found, don't set handler either
Common::SeekableReadStream *file = HandlerUtils::getArchiveFile(filename);
if (file == nullptr)
return;
LocalWebserver::setClientGetHandler(client, file, 200, determineMimeType(filename));
}
bool ResourceHandler::minimalModeSupported() {
return true;
}
} // End of namespace Networking

View File

@@ -0,0 +1,41 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_NETWORKING_SDL_NET_RESOURCEHANDLER_H
#define BACKENDS_NETWORKING_SDL_NET_RESOURCEHANDLER_H
#include "backends/networking/sdl_net/handlers/basehandler.h"
namespace Networking {
class ResourceHandler: public BaseHandler {
static const char *determineMimeType(const Common::String &filename);
public:
ResourceHandler();
~ResourceHandler() override;
void handle(Client &client) override;
bool minimalModeSupported() override;
};
} // End of namespace Networking
#endif

View File

@@ -0,0 +1,78 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "backends/networking/sdl_net/handlers/uploadfilehandler.h"
#include "backends/networking/sdl_net/handlerutils.h"
#include "backends/networking/sdl_net/uploadfileclienthandler.h"
#include "common/system.h"
#include "common/translation.h"
namespace Networking {
UploadFileHandler::UploadFileHandler() {}
UploadFileHandler::~UploadFileHandler() {}
/// public
void UploadFileHandler::handle(Client &client) {
Common::String path = client.queryParameter("path");
// check that <path> is not an absolute root
if (path == "" || path == "/" || path == "\\") {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
return;
}
// check that <path> contains no '../'
if (HandlerUtils::hasForbiddenCombinations(path)) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
return;
}
// transform virtual path to actual file system one
Common::String basePath;
Common::Path baseFSPath, fsPath;
if (!urlToPath(path, fsPath, basePath, baseFSPath)) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
return;
}
// check that <path> exists, is directory and isn't forbidden
Common::FSNode node(fsPath);
if (!HandlerUtils::permittedPath(node.getPath())) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Invalid path!")));
return;
}
if (!node.exists()) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("The parent directory doesn't exist!")));
return;
}
if (!node.isDirectory()) {
HandlerUtils::setFilesManagerErrorMessageHandler(client, Common::convertFromU32String(_("Can't upload into a file!")));
return;
}
// if all OK, set special handler
client.setHandler(new UploadFileClientHandler(fsPath));
}
} // End of namespace Networking

View File

@@ -0,0 +1,39 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_NETWORKING_SDL_NET_UPLOADFILEHANDLER_H
#define BACKENDS_NETWORKING_SDL_NET_UPLOADFILEHANDLER_H
#include "backends/networking/sdl_net/handlers/filesbasehandler.h"
namespace Networking {
class UploadFileHandler: public FilesBaseHandler {
public:
UploadFileHandler();
~UploadFileHandler() override;
void handle(Client &client) override;
};
} // End of namespace Networking
#endif