diff options
author | Alexander Tkachev | 2016-07-06 18:33:34 +0600 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | 8a9d126152f3e0ed1e91daa15dd90f0c18060492 (patch) | |
tree | d9f96a1f15e041ea493a7077ba1ab4ccc52a7da4 | |
parent | ab4361a76b40b56348ec46311121a0552f0c9d6b (diff) | |
download | scummvm-rg350-8a9d126152f3e0ed1e91daa15dd90f0c18060492.tar.gz scummvm-rg350-8a9d126152f3e0ed1e91daa15dd90f0c18060492.tar.bz2 scummvm-rg350-8a9d126152f3e0ed1e91daa15dd90f0c18060492.zip |
CLOUD: Move "/create" to separate Handler
It does redirect to "/files" on success, so user doesn't even see the
strange "/create" URL at all.
This commit is for keeping these handlers small, not making one
(FilesPageHandler in this case) do everything.
-rw-r--r-- | backends/module.mk | 1 | ||||
-rw-r--r-- | backends/networking/sdl_net/handlers/createdirectoryhandler.cpp | 132 | ||||
-rw-r--r-- | backends/networking/sdl_net/handlers/createdirectoryhandler.h | 51 | ||||
-rw-r--r-- | backends/networking/sdl_net/handlers/filespagehandler.cpp | 71 | ||||
-rw-r--r-- | backends/networking/sdl_net/handlers/filespagehandler.h | 11 | ||||
-rw-r--r-- | backends/networking/sdl_net/localwebserver.cpp | 17 | ||||
-rw-r--r-- | backends/networking/sdl_net/localwebserver.h | 4 |
7 files changed, 204 insertions, 83 deletions
diff --git a/backends/module.mk b/backends/module.mk index 7dd29be335..43057a4a1f 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -59,6 +59,7 @@ MODULE_OBJS += \ networking/sdl_net/client.o \ networking/sdl_net/getclienthandler.o \ networking/sdl_net/handlers/basehandler.o \ + networking/sdl_net/handlers/createdirectoryhandler.o \ networking/sdl_net/handlers/filesbasehandler.o \ networking/sdl_net/handlers/filespagehandler.o \ networking/sdl_net/handlers/indexpagehandler.o \ diff --git a/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp b/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp new file mode 100644 index 0000000000..ad8a67a7e8 --- /dev/null +++ b/backends/networking/sdl_net/handlers/createdirectoryhandler.cpp @@ -0,0 +1,132 @@ +/* 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/networking/sdl_net/localwebserver.h" +#include "backends/fs/fs-factory.h" +#include "common/file.h" +#include "common/translation.h" + +namespace Networking { + +#define INDEX_PAGE_NAME ".index.html" + +CreateDirectoryHandler::CreateDirectoryHandler() {} + +CreateDirectoryHandler::~CreateDirectoryHandler() {} + +void CreateDirectoryHandler::handle(Client &client) { + Common::String path = client.queryParameter("path"); + Common::String name = client.queryParameter("directory_name"); + Common::String errorMessage = ""; + + // show an error message if failed to create directory + if (!createDirectory(path, name, errorMessage)) { + handleErrorMessage( + client, + Common::String::format( + "%s<br/><a href=\"files?path=/\">%s</a>", + errorMessage.c_str(), + _("Back to the files manager") + ) + ); + return; + } + + Common::String response = "<html><head><title>ScummVM</title></head><body>{message}</body></html>"; + + // load stylish response page from the archive + Common::SeekableReadStream *const stream = getArchiveFile(INDEX_PAGE_NAME); + if (stream) response = readEverythingFromStream(stream); + + replace(response, "{message}", Common::String::format( + "%s<br/><a href=\"files?path=%s\">%s</a>", + _("Directory created successfully!"), + client.queryParameter("path").c_str(), + _("Back to parent directory") + ) + ); + LocalWebserver::setClientRedirectHandler(client, response, "/files?path=" + client.queryParameter("path")); +} + +void CreateDirectoryHandler::handleErrorMessage(Client &client, Common::String message) { + Common::String response = "<html><head><title>ScummVM</title></head><body>{message}</body></html>"; + + // load stylish response page from the archive + Common::SeekableReadStream *const stream = getArchiveFile(INDEX_PAGE_NAME); + if (stream) response = readEverythingFromStream(stream); + + replace(response, "{message}", message); + LocalWebserver::setClientGetHandler(client, response); +} + +bool CreateDirectoryHandler::createDirectory(Common::String path, Common::String name, Common::String &errorMessage) { + // check that <path> is not an absolute root + if (path == "" || path == "/") { + errorMessage = _("Can't create directory here!"); + return false; + } + + // transform virtual path to actual file system one + Common::String prefixToRemove = "", prefixToAdd = ""; + if (!transformPath(path, prefixToRemove, prefixToAdd) || path.empty()) { + errorMessage = _("Invalid path!"); + return false; + } + + // check that <path> exists and is directory + AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); + if (!node->exists()) { + errorMessage = _("Parent directory doesn't exists!"); + return false; + } + if (!node->isDirectory()) { + errorMessage = _("Can't create a directory within a file!"); + return false; + } + + // 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()) { + errorMessage = _("There is a file with that name in the parent directory!"); + return false; + } else return true; + } + + // create the <directory_name> in <path> + if (!node->create(true)) { + errorMessage = _("Failed to create the directory!"); + return false; + } + + return true; +} + +/// public + +ClientHandlerCallback CreateDirectoryHandler::getHandler() { + return new Common::Callback<CreateDirectoryHandler, Client &>(this, &CreateDirectoryHandler::handle); +} + +} // 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..023c3e74f2 --- /dev/null +++ b/backends/networking/sdl_net/handlers/createdirectoryhandler.h @@ -0,0 +1,51 @@ +/* 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 handle(Client &client); + void handleErrorMessage(Client &client, Common::String message); + + /** + * Creates the directory <name> in <path>. + * + * Fills <errorMessage> on failure. + * + * Returns true on success. + */ + bool createDirectory(Common::String path, Common::String name, Common::String &errorMessage); +public: + CreateDirectoryHandler(); + virtual ~CreateDirectoryHandler(); + + virtual ClientHandlerCallback getHandler(); +}; + +} // End of namespace Networking + +#endif diff --git a/backends/networking/sdl_net/handlers/filespagehandler.cpp b/backends/networking/sdl_net/handlers/filespagehandler.cpp index 327071fc11..2ecb448c3c 100644 --- a/backends/networking/sdl_net/handlers/filespagehandler.cpp +++ b/backends/networking/sdl_net/handlers/filespagehandler.cpp @@ -22,7 +22,6 @@ #include "backends/networking/sdl_net/handlers/filespagehandler.h" #include "backends/networking/sdl_net/localwebserver.h" -#include "backends/fs/fs-factory.h" #include "common/file.h" #include "common/translation.h" @@ -36,11 +35,6 @@ FilesPageHandler::FilesPageHandler() {} FilesPageHandler::~FilesPageHandler() {} void FilesPageHandler::handle(Client &client) { - if (client.path() == "/files") handleFiles(client); - else handleCreateDirectory(client); -} - -void FilesPageHandler::handleFiles(Client &client) { Common::String response = "<html><head><title>ScummVM</title></head><body><table>{content}</table></body></html>"; //TODO: add controls Common::String itemTemplate = "<tr><td><a href=\"{link}\">{name}</a></td><td>{size}</td></tr>\n"; //TODO: load this template too? @@ -77,27 +71,6 @@ void FilesPageHandler::handleFiles(Client &client) { LocalWebserver::setClientGetHandler(client, response); } -void FilesPageHandler::handleCreateDirectory(Client &client) { - Common::String path = client.queryParameter("path"); - Common::String name = client.queryParameter("directory_name"); - Common::String errorMessage = ""; - - // show an error message if failed to create directory - if (!createDirectory(path, name, errorMessage)) { - handleErrorMessage( - client, - Common::String::format( - "%s<br/><a href=\"files?path=/\">%s</a>", - errorMessage.c_str(), - _("Back to the files manager") - ) - ); - return; - } - - handleFiles(client); -} - void FilesPageHandler::handleErrorMessage(Client &client, Common::String message) { Common::String response = "<html><head><title>ScummVM</title></head><body>{message}</body></html>"; @@ -109,50 +82,6 @@ void FilesPageHandler::handleErrorMessage(Client &client, Common::String message LocalWebserver::setClientGetHandler(client, response); } -bool FilesPageHandler::createDirectory(Common::String path, Common::String name, Common::String &errorMessage) { - // check that <path> is not an absolute root - if (path == "" || path == "/") { - errorMessage = _("Can't create directory here!"); - return false; - } - - // transform virtual path to actual file system one - Common::String prefixToRemove = "", prefixToAdd = ""; - if (!transformPath(path, prefixToRemove, prefixToAdd) || path.empty()) { - errorMessage = _("Invalid path!"); - return false; - } - - // check that <path> exists and is directory - AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); - if (!node->exists()) { - errorMessage = _("Parent directory doesn't exists!"); - return false; - } - if (!node->isDirectory()) { - errorMessage = _("Can't create a directory within a file!"); - return false; - } - - // 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()) { - errorMessage = _("There is a file with that name in the parent directory!"); - return false; - } else return true; - } - - // create the <directory_name> in <path> - if (!node->create(true)) { - errorMessage = _("Failed to create the directory!"); - return false; - } - - return true; -} - bool FilesPageHandler::listDirectory(Common::String path, Common::String &content, const Common::String &itemTemplate) { if (path == "" || path == "/") { addItem(content, itemTemplate, true, "/root/", _("File system root")); diff --git a/backends/networking/sdl_net/handlers/filespagehandler.h b/backends/networking/sdl_net/handlers/filespagehandler.h index e5a32c98b0..6205dcd52c 100644 --- a/backends/networking/sdl_net/handlers/filespagehandler.h +++ b/backends/networking/sdl_net/handlers/filespagehandler.h @@ -29,20 +29,9 @@ namespace Networking { class FilesPageHandler: public FilesBaseHandler { void handle(Client &client); - void handleFiles(Client &client); - void handleCreateDirectory(Client &client); void handleErrorMessage(Client &client, Common::String message); /** - * Creates the directory <name> in <path>. - * - * Fills <errorMessage> on failure. - * - * Returns true on success. - */ - bool createDirectory(Common::String path, Common::String name, Common::String &errorMessage); - - /** * Lists the directory <path>. * * Returns true on success. diff --git a/backends/networking/sdl_net/localwebserver.cpp b/backends/networking/sdl_net/localwebserver.cpp index c8f322dad6..b2eff1667f 100644 --- a/backends/networking/sdl_net/localwebserver.cpp +++ b/backends/networking/sdl_net/localwebserver.cpp @@ -44,7 +44,7 @@ LocalWebserver::LocalWebserver(): _set(nullptr), _serverSocket(nullptr), _timerS _stopOnIdle(false), _clients(0), _idlingFrames(0) { addPathHandler("/", _indexPageHandler.getHandler()); addPathHandler("/files", _filesPageHandler.getHandler()); - addPathHandler("/create", _filesPageHandler.getHandler()); //"Create directory" feature + addPathHandler("/create", _createDirectoryHandler.getHandler()); _defaultHandler = _resourceHandler.getHandler(); } @@ -252,6 +252,21 @@ void LocalWebserver::setClientGetHandler(Client &client, Common::SeekableReadStr client.setHandler(handler); } +void LocalWebserver::setClientRedirectHandler(Client &client, Common::String response, Common::String location, const char *mimeType) { + byte *data = new byte[response.size()]; + memcpy(data, response.c_str(), response.size()); + Common::MemoryReadStream *stream = new Common::MemoryReadStream(data, response.size(), DisposeAfterUse::YES); + setClientRedirectHandler(client, stream, location, mimeType); +} + +void LocalWebserver::setClientRedirectHandler(Client &client, Common::SeekableReadStream *responseStream, Common::String location, const char *mimeType) { + GetClientHandler *handler = new GetClientHandler(responseStream); + handler->setResponseCode(302); //redirect + handler->setHeader("Location", location); + if (mimeType) handler->setHeader("Content-Type", mimeType); + client.setHandler(handler); +} + const char *LocalWebserver::determineMimeType(Common::String &filename) { // text if (filename.hasSuffix(".html")) return "text/html"; diff --git a/backends/networking/sdl_net/localwebserver.h b/backends/networking/sdl_net/localwebserver.h index 2e56209ab0..ed1860a937 100644 --- a/backends/networking/sdl_net/localwebserver.h +++ b/backends/networking/sdl_net/localwebserver.h @@ -25,6 +25,7 @@ #include "backends/networking/sdl_net/client.h" #include "backends/networking/sdl_net/handlers/basehandler.h" +#include "backends/networking/sdl_net/handlers/createdirectoryhandler.h" #include "backends/networking/sdl_net/handlers/filespagehandler.h" #include "backends/networking/sdl_net/handlers/indexpagehandler.h" #include "backends/networking/sdl_net/handlers/resourcehandler.h" @@ -59,6 +60,7 @@ class LocalWebserver : public Common::Singleton<LocalWebserver> { ClientHandlerCallback _defaultHandler; IndexPageHandler _indexPageHandler; FilesPageHandler _filesPageHandler; + CreateDirectoryHandler _createDirectoryHandler; ResourceHandler _resourceHandler; uint32 _idlingFrames; Common::Mutex _handleMutex; @@ -86,6 +88,8 @@ public: static void setClientGetHandler(Client &client, Common::String response, long code = 200, const char *mimeType = nullptr); static void setClientGetHandler(Client &client, Common::SeekableReadStream *responseStream, long code = 200, const char *mimeType = nullptr); + static void setClientRedirectHandler(Client &client, Common::String response, Common::String location, const char *mimeType = nullptr); + static void setClientRedirectHandler(Client &client, Common::SeekableReadStream *responseStream, Common::String location, const char *mimeType = nullptr); static const char *determineMimeType(Common::String &filename); static Common::String urlDecode(Common::String value); }; |