diff options
author | Alexander Tkachev | 2016-07-09 15:49:18 +0600 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | e4bb7c4e750d53434140a8d1a401e7fa6ee221ab (patch) | |
tree | 4b6d555163353d71b51e64308e5a4dccc85f2216 /backends/networking/sdl_net/handlers | |
parent | a424ebbc28549c0e06b9a8ca4985bf799179c404 (diff) | |
download | scummvm-rg350-e4bb7c4e750d53434140a8d1a401e7fa6ee221ab.tar.gz scummvm-rg350-e4bb7c4e750d53434140a8d1a401e7fa6ee221ab.tar.bz2 scummvm-rg350-e4bb7c4e750d53434140a8d1a401e7fa6ee221ab.zip |
CLOUD: Add UploadFileClientHandler
Now Client reads the first headers block, then LocalWebserver decides
which Handler to use. In case of "/upload", UploadFileHandler is used.
But now it only knows the "path" parameter. If that's valid, actual
UploadFileClientHandler is created, which reads the contents of the
request and, when finds there an "upload_file" field, starts saving it
in the directory specified by "path".
With that we don't need temp files approach from Reader class.
Diffstat (limited to 'backends/networking/sdl_net/handlers')
-rw-r--r-- | backends/networking/sdl_net/handlers/uploadfilehandler.cpp | 138 | ||||
-rw-r--r-- | backends/networking/sdl_net/handlers/uploadfilehandler.h | 11 |
2 files changed, 14 insertions, 135 deletions
diff --git a/backends/networking/sdl_net/handlers/uploadfilehandler.cpp b/backends/networking/sdl_net/handlers/uploadfilehandler.cpp index 1eabf1d926..eeb4fad1ac 100644 --- a/backends/networking/sdl_net/handlers/uploadfilehandler.cpp +++ b/backends/networking/sdl_net/handlers/uploadfilehandler.cpp @@ -21,161 +21,49 @@ */ #include "backends/networking/sdl_net/handlers/uploadfilehandler.h" +#include "backends/networking/sdl_net/handlerutils.h" #include "backends/networking/sdl_net/localwebserver.h" +#include "backends/networking/sdl_net/uploadfileclienthandler.h" #include "backends/fs/fs-factory.h" #include "common/file.h" #include "common/translation.h" namespace Networking { -#define INDEX_PAGE_NAME ".index.html" - UploadFileHandler::UploadFileHandler() {} UploadFileHandler::~UploadFileHandler() {} void UploadFileHandler::handle(Client &client) { - Common::String errorMessage = ""; - - // show an error message if failed to upload the file - if (!uploadFile(client, errorMessage)) { - handleErrorMessage( - client, - Common::String::format( - "%s<br/><a href=\"files?path=%s\">%s</a>", - errorMessage.c_str(), - "%2F", //that's encoded "/" - _("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>", - _("Uploaded successfully!"), - client.queryParameter("path").c_str(), - _("Back to parent directory") - ) - ); - LocalWebserver::setClientRedirectHandler( - client, response, - "/files?path=" + LocalWebserver::urlEncodeQueryParameterValue(client.queryParameter("path")) - ); -} - -void UploadFileHandler::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); -} - -namespace { -bool copyStream(Common::ReadStream *from, Common::WriteStream *into) { - assert(from); - assert(into); - const uint32 BUFFER_SIZE = 1 * 1024 * 1024; - void *buffer = malloc(BUFFER_SIZE); - bool success = true; - assert(buffer); - - while (!from->eos()) { - uint32 readBytes = from->read(buffer, BUFFER_SIZE); - - if (from->err()) { - warning("copyStream: failed to read bytes from the stream"); - success = false; - break; - } - - if (readBytes != 0) - if (into->write(buffer, readBytes) != readBytes || into->err()) { - warning("copyStream: failed to write all bytes into the file"); - success = false; - break; - } - } - - free(buffer); - return success; -} -} - -bool UploadFileHandler::uploadFile(Client &client, Common::String &errorMessage) { Common::String path = client.queryParameter("path"); - Common::String originalFilename = client.queryParameter("upload_file"); - Common::String tempFilename = client.attachedFile(originalFilename); debug("path = <%s>", path.c_str()); - debug("filename = <%s>", originalFilename.c_str()); - debug("tempfile = <%s>", tempFilename.c_str()); // check that <path> is not an absolute root if (path == "" || path == "/" || path == "\\") { - errorMessage = _("Invalid path!"); - return false; + 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()) { - errorMessage = _("Invalid path!"); - return false; + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Invalid path!")); + return; } // check that <path> exists and is directory AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(path); if (!node->exists()) { - errorMessage = _("The parent directory doesn't exist!"); - return false; + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("The parent directory doesn't exist!")); + return; } if (!node->isDirectory()) { - errorMessage = _("Can't upload into a file!"); - return false; - } - - // check that <path>/<originalFilename> doesn't exist - if (path.lastChar() != '/' && path.lastChar() != '\\') path += '/'; - AbstractFSNode *originalNode = g_system->getFilesystemFactory()->makeFileNodePath(path + originalFilename); - if (originalNode->exists()) { - errorMessage = _("There is a file with that name in the parent directory!"); - return false; - } - - // check that <tempFilename> exists - AbstractFSNode *tempNode = g_system->getFilesystemFactory()->makeFileNodePath(tempFilename); - if (!tempNode->exists() || tempNode->isDirectory()) { - errorMessage = _("Failed to upload the file!"); - return false; - } - - // copy <tempFilename> into <path>/<originalFilename> - // FIXME: I think we should move/rename file with some system call - // even though that might be less portable, that is much better than - // making an actual copy of data (because user might had enough place - // for one copy of the file, but not for two of them) - Common::ReadStream *tempStream = tempNode->createReadStream(); - Common::WriteStream *fileStream = originalNode->createWriteStream(); - if (tempStream == nullptr || fileStream == nullptr || !copyStream(tempStream, fileStream)) { - delete tempStream; - delete fileStream; - errorMessage = _("Failed to upload the file!"); - return false; + HandlerUtils::setFilesManagerErrorMessageHandler(client, _("Can't upload into a file!")); + return; } - - delete tempStream; - delete fileStream; - return true; + + // if all OK, set special handler + client.setHandler(new UploadFileClientHandler(path)); } /// public diff --git a/backends/networking/sdl_net/handlers/uploadfilehandler.h b/backends/networking/sdl_net/handlers/uploadfilehandler.h index 6300a13e8d..bba7fdfc02 100644 --- a/backends/networking/sdl_net/handlers/uploadfilehandler.h +++ b/backends/networking/sdl_net/handlers/uploadfilehandler.h @@ -29,16 +29,7 @@ namespace Networking { class UploadFileHandler: public FilesBaseHandler { void handle(Client &client); - void handleErrorMessage(Client &client, Common::String message); - - /** - * Uploads file. - * - * Fills <errorMessage> on failure. - * - * Returns true on success. - */ - bool uploadFile(Client &client, Common::String &errorMessage); + public: UploadFileHandler(); virtual ~UploadFileHandler(); |