aboutsummaryrefslogtreecommitdiff
path: root/backends/networking/sdl_net/handlers
diff options
context:
space:
mode:
authorAlexander Tkachev2016-07-09 15:49:18 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commite4bb7c4e750d53434140a8d1a401e7fa6ee221ab (patch)
tree4b6d555163353d71b51e64308e5a4dccc85f2216 /backends/networking/sdl_net/handlers
parenta424ebbc28549c0e06b9a8ca4985bf799179c404 (diff)
downloadscummvm-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.cpp138
-rw-r--r--backends/networking/sdl_net/handlers/uploadfilehandler.h11
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();