diff options
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(); |