diff options
Diffstat (limited to 'backends/networking/sdl_net/handlers')
19 files changed, 1469 insertions, 0 deletions
diff --git a/backends/networking/sdl_net/handlers/basehandler.h b/backends/networking/sdl_net/handlers/basehandler.h new file mode 100644 index 0000000000..060fa70b14 --- /dev/null +++ b/backends/networking/sdl_net/handlers/basehandler.h @@ -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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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 diff --git a/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp b/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp new file mode 100644 index 0000000000..d315ad2ee3 --- /dev/null +++ b/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp @@ -0,0 +1,129 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "backends/networking/sdl_net/handlers/createdirectoryhandler.h" +#include "backends/fs/fs-factory.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, Common::String message) const { + if (client.queryParameter("answer_json") == "true") + setJsonResponseHandler(client, "error", message); + else + HandlerUtils::setFilesManagerErrorMessageHandler(client, message); +} + +void CreateDirectoryHandler::setJsonResponseHandler(Client &client, Common::String type, 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, _("Can't create directory here!")); + return; + } + + // check that <path> contains no '../' + if (HandlerUtils::hasForbiddenCombinations(path)) { + handleError(client, _("Invalid path!")); + return; + } + + // transform virtual path to actual file system one + Common::String prefixToRemove = "", prefixToAdd = ""; + if (!transformPath(path, prefixToRemove, prefixToAdd) || path.empty()) { + handleError(client, _("Invalid path!")); + return; + } + + // check that <path> exists, is directory and isn't forbidden + AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); + if (!HandlerUtils::permittedPath(node->getPath())) { + handleError(client, _("Invalid path!")); + return; + } + if (!node->exists()) { + handleError(client, _("Parent directory doesn't exists!")); + return; + } + if (!node->isDirectory()) { + handleError(client, _("Can't create a directory within a file!")); + return; + } + + // check that <directory_name> doesn't exist or is directory + if (path.lastChar() != '/' && path.lastChar() != '\\') + path += '/'; + node = g_system->getFilesystemFactory()->makeFileNodePath(path + name); + if (node->exists()) { + if (!node->isDirectory()) { + handleError(client, _("There is a file with that name in the parent directory!")); + return; + } + } else { + // create the <directory_name> in <path> + if (!node->create(true)) { + handleError(client, _("Failed to create the directory!")); + return; + } + } + + // if json requested, respond with it + if (client.queryParameter("answer_json") == "true") { + setJsonResponseHandler(client, "success", _("Directory created successfully!")); + return; + } + + // set redirect on success + HandlerUtils::setMessageHandler( + client, + Common::String::format( + "%s<br/><a href=\"files?path=%s\">%s</a>", + _("Directory created successfully!"), + client.queryParameter("path").c_str(), + _("Back to parent directory") + ), + (client.queryParameter("ajax") == "true" ? "/filesAJAX?path=" : "/files?path=") + + LocalWebserver::urlEncodeQueryParameterValue(client.queryParameter("path")) + ); +} + +} // End of namespace Networking diff --git a/backends/networking/sdl_net/handlers/createdirectoryhandler.h b/backends/networking/sdl_net/handlers/createdirectoryhandler.h new file mode 100644 index 0000000000..3991686fdd --- /dev/null +++ b/backends/networking/sdl_net/handlers/createdirectoryhandler.h @@ -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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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, Common::String message) const; + void setJsonResponseHandler(Client &client, Common::String type, Common::String message) const; +public: + CreateDirectoryHandler(); + virtual ~CreateDirectoryHandler(); + + virtual void handle(Client &client); +}; + +} // End of namespace Networking + +#endif diff --git a/backends/networking/sdl_net/handlers/downloadfilehandler.cpp b/backends/networking/sdl_net/handlers/downloadfilehandler.cpp new file mode 100644 index 0000000000..281be2d27f --- /dev/null +++ b/backends/networking/sdl_net/handlers/downloadfilehandler.cpp @@ -0,0 +1,88 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "backends/networking/sdl_net/handlers/downloadfilehandler.h" +#include "backends/fs/fs-factory.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, _("Invalid path!")); + return; + } + + // check that <path> contains no '../' + if (HandlerUtils::hasForbiddenCombinations(path)) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + return; + } + + // transform virtual path to actual file system one + Common::String prefixToRemove = "", prefixToAdd = ""; + if (!transformPath(path, prefixToRemove, prefixToAdd, false) || path.empty()) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + return; + } + + // check that <path> exists, is directory and isn't forbidden + AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); + if (!HandlerUtils::permittedPath(node->getPath())) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + return; + } + if (!node->exists()) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("The file doesn't exist!")); + return; + } + if (node->isDirectory()) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Can't download a directory!")); + return; + } + Common::SeekableReadStream *stream = node->createReadStream(); + if (stream == nullptr) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("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->getDisplayName() + "\""); + handler->setHeader("Content-Transfer-Encoding", "binary"); + client.setHandler(handler); +} + +} // End of namespace Networking diff --git a/backends/networking/sdl_net/handlers/downloadfilehandler.h b/backends/networking/sdl_net/handlers/downloadfilehandler.h new file mode 100644 index 0000000000..80ee779d08 --- /dev/null +++ b/backends/networking/sdl_net/handlers/downloadfilehandler.h @@ -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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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(); + virtual ~DownloadFileHandler(); + + virtual void handle(Client &client); +}; + +} // End of namespace Networking + +#endif diff --git a/backends/networking/sdl_net/handlers/filesajaxpagehandler.cpp b/backends/networking/sdl_net/handlers/filesajaxpagehandler.cpp new file mode 100644 index 0000000000..55b7a62dd1 --- /dev/null +++ b/backends/networking/sdl_net/handlers/filesajaxpagehandler.cpp @@ -0,0 +1,81 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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(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, _("The page is not available without the resources.")); + return; + } + + Common::String response = HandlerUtils::readEverythingFromStream(stream); + Common::String path = client.queryParameter("path"); + + //these occur twice: + replace(response, "{create_directory_button}", _("Create directory")); + replace(response, "{create_directory_button}", _("Create directory")); + replace(response, "{upload_files_button}", _("Upload files")); //tab + replace(response, "{upload_file_button}", _("Upload files")); //button in the tab + replace(response, "{create_directory_desc}", _("Type new directory name:")); + replace(response, "{upload_file_desc}", _("Select a file to upload:")); + replace(response, "{or_upload_directory_desc}", _("Or select a directory (works in Chrome only):")); + replace(response, "{index_of}", _("Index of ")); + replace(response, "{loading}", _("Loading...")); + replace(response, "{error}", _("Error occurred")); + replace(response, "{start_path}", encodeDoubleQuotesAndSlashes(path)); + LocalWebserver::setClientGetHandler(client, response); +} + +} // End of namespace Networking diff --git a/backends/networking/sdl_net/handlers/filesajaxpagehandler.h b/backends/networking/sdl_net/handlers/filesajaxpagehandler.h new file mode 100644 index 0000000000..142376b3ff --- /dev/null +++ b/backends/networking/sdl_net/handlers/filesajaxpagehandler.h @@ -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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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(); + virtual ~FilesAjaxPageHandler(); + + virtual void handle(Client &client); +}; + +} // End of namespace Networking + +#endif diff --git a/backends/networking/sdl_net/handlers/filesbasehandler.cpp b/backends/networking/sdl_net/handlers/filesbasehandler.cpp new file mode 100644 index 0000000000..f12f88a308 --- /dev/null +++ b/backends/networking/sdl_net/handlers/filesbasehandler.cpp @@ -0,0 +1,91 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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(Common::String path) { + if (path.size() && (path.lastChar() == '/' || path.lastChar() == '\\')) path.deleteLastChar(); + if (!path.empty()) { + for (int i = path.size() - 1; i >= 0; --i) + if (i == 0 || path[i] == '/' || path[i] == '\\') { + path.erase(i); + break; + } + } + if (path.size() && path.lastChar() != '/' && path.lastChar() != '\\') + path += '/'; + return path; +} + +bool FilesBaseHandler::transformPath(Common::String &path, Common::String &prefixToRemove, Common::String &prefixToAdd, bool isDirectory) { + // <path> is not empty, but could lack the trailing slash + if (isDirectory && path.lastChar() != '/' && path.lastChar() != '\\') + path += '/'; + + if (path.hasPrefix("/root") && ConfMan.hasKey("rootpath", "cloud")) { + prefixToAdd = "/root/"; + prefixToRemove = ConfMan.get("rootpath", "cloud"); + if (prefixToRemove.size() && prefixToRemove.lastChar() != '/' && prefixToRemove.lastChar() != '\\') + prefixToRemove += '/'; + if (prefixToRemove == "/") prefixToRemove = ""; + path.erase(0, 5); + if (path.size() && (path[0] == '/' || path[0] == '\\')) + path.deleteChar(0); // if that was "/root/ab/c", it becomes "/ab/c", but we need "ab/c" + path = prefixToRemove + path; + if (path == "") + path = "/"; // absolute root is '/' + return true; + } + + if (path.hasPrefix("/saves")) { + prefixToAdd = "/saves/"; + + // determine savepath (prefix to remove) +#ifdef USE_LIBCURL + DefaultSaveFileManager *manager = dynamic_cast<DefaultSaveFileManager *>(g_system->getSavefileManager()); + prefixToRemove = (manager ? manager->concatWithSavesPath("") : ConfMan.get("savepath")); +#else + prefixToRemove = ConfMan.get("savepath"); +#endif + if (prefixToRemove.size() && prefixToRemove.lastChar() != '/' && prefixToRemove.lastChar() != '\\') + prefixToRemove += '/'; + + path.erase(0, 6); + if (path.size() && (path[0] == '/' || path[0] == '\\')) + path.deleteChar(0); + path = prefixToRemove + path; + return true; + } + + return false; +} + +} // End of namespace Networking diff --git a/backends/networking/sdl_net/handlers/filesbasehandler.h b/backends/networking/sdl_net/handlers/filesbasehandler.h new file mode 100644 index 0000000000..c30d91d341 --- /dev/null +++ b/backends/networking/sdl_net/handlers/filesbasehandler.h @@ -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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BACKENDS_NETWORKING_SDL_NET_FILESBASEHANDLER_H +#define BACKENDS_NETWORKING_SDL_NET_FILESBASEHANDLER_H + +#include "backends/networking/sdl_net/handlers/basehandler.h" + +namespace Networking { + +class FilesBaseHandler: public BaseHandler { +protected: + Common::String parentPath(Common::String path); + + /** + * Transforms virtual <path> into actual file system path. + * + * Fills prefixes with actual file system prefix ("to remove") + * and virtual path prefix ("to add"). + * + * Returns true on success. + */ + bool transformPath(Common::String &path, Common::String &prefixToRemove, Common::String &prefixToAdd, bool isDirectory = true); +public: + FilesBaseHandler(); + virtual ~FilesBaseHandler(); + + virtual void handle(Client &client) = 0; +}; + +} // End of namespace Networking + +#endif diff --git a/backends/networking/sdl_net/handlers/filespagehandler.cpp b/backends/networking/sdl_net/handlers/filespagehandler.cpp new file mode 100644 index 0000000000..01b40c3bcb --- /dev/null +++ b/backends/networking/sdl_net/handlers/filespagehandler.cpp @@ -0,0 +1,237 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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(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(Common::String s) { + Common::String result = ""; + for (uint32 i = 0; i < s.size(); ++i) + if (s[i] == '<') + result += "<"; + else if (s[i] == '>') + result += ">"; + else if (s[i] == '&') + result += "&"; + else if (s[i] > 0x7F) + result += Common::String::format("&#%d;", (int)s[i]); + else result += s[i]; + return result; +} + +Common::String getDisplayPath(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(Common::String path, Common::String &content, const Common::String &itemTemplate) { + if (path == "" || path == "/") { + if (ConfMan.hasKey("rootpath", "cloud")) + addItem(content, itemTemplate, IT_DIRECTORY, "/root/", _("File system root")); + addItem(content, itemTemplate, IT_DIRECTORY, "/saves/", _("Saved games")); + return true; + } + + if (HandlerUtils::hasForbiddenCombinations(path)) + return false; + + Common::String prefixToRemove = "", prefixToAdd = ""; + if (!transformPath(path, prefixToRemove, prefixToAdd)) + return false; + + Common::FSNode node = Common::FSNode(path); + if (path == "/") + node = node.getParent(); // absolute root + + 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::String filePath = path; + if (filePath.hasPrefix(prefixToRemove)) + filePath.erase(0, prefixToRemove.size()); + if (filePath == "" || filePath == "/" || filePath == "\\") + filePath = "/"; + else + filePath = parentPath(prefixToAdd + filePath); + addItem(content, itemTemplate, IT_PARENT_DIRECTORY, filePath, _("Parent directory")); + } + + // fill the content + for (Common::FSList::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) { + Common::String name = i->getDisplayName(); + if (i->isDirectory()) + name += "/"; + + Common::String filePath = i->getPath(); + if (filePath.hasPrefix(prefixToRemove)) + filePath.erase(0, prefixToRemove.size()); + filePath = prefixToAdd + filePath; + + 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, Common::String path, Common::String name, 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></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, _("ScummVM couldn't list the directory you specified.")); + return; + } + + //these occur twice: + replace(response, "{create_directory_button}", _("Create directory")); + replace(response, "{create_directory_button}", _("Create directory")); + replace(response, "{path}", encodeDoubleQuotes(client.queryParameter("path"))); + replace(response, "{path}", encodeDoubleQuotes(client.queryParameter("path"))); + replace(response, "{upload_files_button}", _("Upload files")); //tab + replace(response, "{upload_file_button}", _("Upload files")); //button in the tab + replace(response, "{create_directory_desc}", _("Type new directory name:")); + replace(response, "{upload_file_desc}", _("Select a file to upload:")); + replace(response, "{or_upload_directory_desc}", _("Or select a directory (works in Chrome only):")); + replace(response, "{index_of_directory}", Common::String::format(_("Index of %s"), encodeHtmlEntities(getDisplayPath(client.queryParameter("path"))).c_str())); + replace(response, "{content}", content); + LocalWebserver::setClientGetHandler(client, response); +} + +} // End of namespace Networking diff --git a/backends/networking/sdl_net/handlers/filespagehandler.h b/backends/networking/sdl_net/handlers/filespagehandler.h new file mode 100644 index 0000000000..8841ab8657 --- /dev/null +++ b/backends/networking/sdl_net/handlers/filespagehandler.h @@ -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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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(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, Common::String path, Common::String name, Common::String size = "") const; + +public: + FilesPageHandler(); + virtual ~FilesPageHandler(); + + virtual void handle(Client &client); +}; + +} // End of namespace Networking + +#endif diff --git a/backends/networking/sdl_net/handlers/indexpagehandler.cpp b/backends/networking/sdl_net/handlers/indexpagehandler.cpp new file mode 100644 index 0000000000..04a3f45eff --- /dev/null +++ b/backends/networking/sdl_net/handlers/indexpagehandler.cpp @@ -0,0 +1,65 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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" +#include "gui/storagewizarddialog.h" + +namespace Networking { + +IndexPageHandler::IndexPageHandler(): CommandSender(nullptr) {} + +IndexPageHandler::~IndexPageHandler() {} + +/// public + +Common::String IndexPageHandler::code() const { return _code; } + +void IndexPageHandler::handle(Client &client) { + Common::String code = client.queryParameter("code"); + + if (code == "") { + // redirect to "/filesAJAX" + HandlerUtils::setMessageHandler( + client, + Common::String::format( + "%s<br/><a href=\"files\">%s</a>", + _("This is a local webserver index page."), + _("Open Files manager") + ), + "/filesAJAX" + ); + return; + } + + _code = code; + sendCommand(GUI::kStorageCodePassedCmd, 0); + HandlerUtils::setMessageHandler(client, _("ScummVM got the code and already connects to your cloud storage!")); +} + +bool IndexPageHandler::minimalModeSupported() { + return true; +} + +} // End of namespace Networking diff --git a/backends/networking/sdl_net/handlers/indexpagehandler.h b/backends/networking/sdl_net/handlers/indexpagehandler.h new file mode 100644 index 0000000000..0d8e616395 --- /dev/null +++ b/backends/networking/sdl_net/handlers/indexpagehandler.h @@ -0,0 +1,45 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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 { + Common::String _code; +public: + IndexPageHandler(); + virtual ~IndexPageHandler(); + + Common::String code() const; + virtual void handle(Client &client); + virtual bool minimalModeSupported(); +}; + +} // End of namespace Networking + +#endif diff --git a/backends/networking/sdl_net/handlers/listajaxhandler.cpp b/backends/networking/sdl_net/handlers/listajaxhandler.cpp new file mode 100644 index 0000000000..7c2801539d --- /dev/null +++ b/backends/networking/sdl_net/handlers/listajaxhandler.cpp @@ -0,0 +1,157 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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/json.h" +#include "common/translation.h" + +namespace Networking { + +ListAjaxHandler::ListAjaxHandler() {} + +ListAjaxHandler::~ListAjaxHandler() {} + +Common::JSONObject ListAjaxHandler::listDirectory(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/", _("File system root")); + addItem(itemsList, IT_DIRECTORY, "/saves/", _("Saved games")); + successResult.setVal("items", new Common::JSONValue(itemsList)); + return successResult; + } + + if (HandlerUtils::hasForbiddenCombinations(path)) + return errorResult; + + Common::String prefixToRemove = "", prefixToAdd = ""; + if (!transformPath(path, prefixToRemove, prefixToAdd)) + return errorResult; + + Common::FSNode node = Common::FSNode(path); + if (path == "/") + node = node.getParent(); // absolute root + + 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::String filePath = path; + if (filePath.hasPrefix(prefixToRemove)) + filePath.erase(0, prefixToRemove.size()); + if (filePath == "" || filePath == "/" || filePath == "\\") + filePath = "/"; + else + filePath = parentPath(prefixToAdd + filePath); + addItem(itemsList, IT_PARENT_DIRECTORY, filePath, _("Parent directory")); + } + + // fill the content + for (Common::FSList::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) { + Common::String name = i->getDisplayName(); + if (i->isDirectory()) name += "/"; + + Common::String filePath = i->getPath(); + if (filePath.hasPrefix(prefixToRemove)) + filePath.erase(0, prefixToRemove.size()); + filePath = prefixToAdd + filePath; + + addItem(itemsList, detectType(i->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, Common::String path, Common::String name, 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 diff --git a/backends/networking/sdl_net/handlers/listajaxhandler.h b/backends/networking/sdl_net/handlers/listajaxhandler.h new file mode 100644 index 0000000000..27929aeb4a --- /dev/null +++ b/backends/networking/sdl_net/handlers/listajaxhandler.h @@ -0,0 +1,63 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BACKENDS_NETWORKING_SDL_NET_LISTAJAXHANDLER_H +#define BACKENDS_NETWORKING_SDL_NET_LISTAJAXHANDLER_H + +#include "backends/networking/sdl_net/handlers/filesbasehandler.h" +#include "common/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(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, Common::String path, Common::String name, Common::String size = ""); + +public: + ListAjaxHandler(); + virtual ~ListAjaxHandler(); + + virtual void handle(Client &client); +}; + +} // End of namespace Networking + +#endif diff --git a/backends/networking/sdl_net/handlers/resourcehandler.cpp b/backends/networking/sdl_net/handlers/resourcehandler.cpp new file mode 100644 index 0000000000..ecd8eb296a --- /dev/null +++ b/backends/networking/sdl_net/handlers/resourcehandler.cpp @@ -0,0 +1,75 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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(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(); + filename.deleteChar(0); + + // if archive hidden file is requested, ignore + if (filename.size() && 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 diff --git a/backends/networking/sdl_net/handlers/resourcehandler.h b/backends/networking/sdl_net/handlers/resourcehandler.h new file mode 100644 index 0000000000..47ecfcbacd --- /dev/null +++ b/backends/networking/sdl_net/handlers/resourcehandler.h @@ -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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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(Common::String &filename); +public: + ResourceHandler(); + virtual ~ResourceHandler(); + + virtual void handle(Client &client); + virtual bool minimalModeSupported(); +}; + +} // End of namespace Networking + +#endif diff --git a/backends/networking/sdl_net/handlers/uploadfilehandler.cpp b/backends/networking/sdl_net/handlers/uploadfilehandler.cpp new file mode 100644 index 0000000000..6b8be15f1f --- /dev/null +++ b/backends/networking/sdl_net/handlers/uploadfilehandler.cpp @@ -0,0 +1,79 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "backends/networking/sdl_net/handlers/uploadfilehandler.h" +#include "backends/networking/sdl_net/handlerutils.h" +#include "backends/networking/sdl_net/uploadfileclienthandler.h" +#include "backends/fs/fs-factory.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, _("Invalid path!")); + return; + } + + // check that <path> contains no '../' + if (HandlerUtils::hasForbiddenCombinations(path)) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + return; + } + + // transform virtual path to actual file system one + Common::String prefixToRemove = "", prefixToAdd = ""; + if (!transformPath(path, prefixToRemove, prefixToAdd, false) || path.empty()) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + return; + } + + // check that <path> exists, is directory and isn't forbidden + AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); + if (!HandlerUtils::permittedPath(node->getPath())) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + return; + } + if (!node->exists()) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("The parent directory doesn't exist!")); + return; + } + if (!node->isDirectory()) { + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Can't upload into a file!")); + return; + } + + // if all OK, set special handler + client.setHandler(new UploadFileClientHandler(path)); +} + +} // End of namespace Networking diff --git a/backends/networking/sdl_net/handlers/uploadfilehandler.h b/backends/networking/sdl_net/handlers/uploadfilehandler.h new file mode 100644 index 0000000000..8ea7cdc7e1 --- /dev/null +++ b/backends/networking/sdl_net/handlers/uploadfilehandler.h @@ -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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#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(); + virtual ~UploadFileHandler(); + + virtual void handle(Client &client); +}; + +} // End of namespace Networking + +#endif |