From bca05b2720298b17f9078465cd0896cc5d627819 Mon Sep 17 00:00:00 2001 From: Alexander Tkachev Date: Fri, 8 Jul 2016 12:28:33 +0600 Subject: CLOUD: Save files fields into temp files Instead of keeping them in memory. Temp file name is generated to point into ScummVM's working directory. That means that if user wanted to upload file to the place with sufficient size, it would instead be uploaded to ScummVM's working directory. Yet it's too early to parse the target directory, so there is no way to generate temp file name within that directory. --- backends/networking/sdl_net/reader.cpp | 82 +++++++++++++++++++++++++++------- backends/networking/sdl_net/reader.h | 3 +- 2 files changed, 67 insertions(+), 18 deletions(-) (limited to 'backends/networking') diff --git a/backends/networking/sdl_net/reader.cpp b/backends/networking/sdl_net/reader.cpp index 19c5b0a088..2037ef747e 100644 --- a/backends/networking/sdl_net/reader.cpp +++ b/backends/networking/sdl_net/reader.cpp @@ -27,6 +27,7 @@ #include "common/debug.h" #include "common/stream.h" #include "common/memstream.h" +#include "backends/fs/fs-factory.h" namespace Networking { @@ -40,7 +41,6 @@ Reader::Reader() { _windowSize = 0; _headers = ""; - _buffer = ""; _stream = nullptr; _contentLength = 0; @@ -263,29 +263,78 @@ void Reader::parseQueryParameters() { } } +namespace { +char generateRandomChar() { + int r = rand() % 36; + char c = '0' + r; + if (r > 9) c = 'a' + r - 10; + return c; +} + +Common::String generateTempFileName(Common::String originalFilename) { + //generates "./-.scummtmp" + //normalize + Common::String prefix = "./"; + for (uint32 i = 0; i < originalFilename.size(); ++i) { + char c = originalFilename[i]; + if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '.' || c == '_' || c == '-') { + prefix += c; + } else { + prefix += '_'; + } + } + prefix += '-'; + + //generate initial sequence + Common::String uniqueSequence; + for (uint32 i = 0; i < 5; ++i) + uniqueSequence += generateRandomChar(); + + //update sequence while generate path exists + AbstractFSNode *node; + Common::String path; + do { + uniqueSequence += generateRandomChar(); + path = prefix + uniqueSequence + ".scummtmp"; + node = g_system->getFilesystemFactory()->makeFileNodePath(path); + } while (node->exists()); + + return path; +} +} + bool Reader::readContent() { Common::String boundary = "--" + _boundary; if (_window == nullptr) { makeWindow(boundary.size()); - _buffer = ""; if (_stream) delete _stream; - _stream = new Common::MemoryReadWriteStream(DisposeAfterUse::YES); + if (_isFileField) { + //create temporary file + _currentTempFileName = generateTempFileName(_currentFileName); + AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(_currentTempFileName); + _stream = node->createWriteStream(); + if (_stream == nullptr) + error("Unable to open temp file to write into!"); + } else { + _stream = new Common::MemoryReadWriteStream(DisposeAfterUse::YES); + } } - /* - if (_fieldIsFile) { - //create temporary file - tempFileName = generateTempFileName(); - stream = openFileStream(tempFileName); - //read till "--" + _boundary - while (readOneByteInStream(stream)); - handleFileContent(tempFileName); - } else { - */ - while (readOneByteInStream(_stream, boundary)) { - if (!bytesLeft()) return false; + while (readOneByteInStream(_stream, boundary)) { + if (!bytesLeft()) return false; + } + + if (_isFileField) { + if (_stream != nullptr) { + _stream->flush(); + delete _stream; + _stream = nullptr; + } else { + warning("No stream was created!"); } + handleFileContent(_currentTempFileName); + } else { Common::MemoryReadWriteStream *dynamicStream = dynamic_cast(_stream); if (dynamicStream != nullptr) if (dynamicStream->size() == 0) @@ -297,7 +346,7 @@ bool Reader::readContent() { warning("Stream somehow changed its type from MemoryReadWriteStream!"); else warning("No stream was created!"); - //} + } freeWindow(); _state = RS_READING_HEADERS; @@ -305,6 +354,7 @@ bool Reader::readContent() { } void Reader::handleFileContent(Common::String filename) { + debug("\nHANDLE FILE CONTENT:\nFILE >>%s<< SAVED INTO >>%s<<", _currentFileName.c_str(), filename.c_str()); _attachedFiles[_currentFileName] = filename; } diff --git a/backends/networking/sdl_net/reader.h b/backends/networking/sdl_net/reader.h index 5f5770149b..20b2a6148f 100644 --- a/backends/networking/sdl_net/reader.h +++ b/backends/networking/sdl_net/reader.h @@ -49,7 +49,6 @@ class Reader { uint32 _windowUsed, _windowSize; Common::String _headers; - Common::String _buffer; Common::WriteStream *_stream; ///Common::String _headers; @@ -59,7 +58,7 @@ class Reader { uint32 _contentLength; Common::String _boundary; uint32 _availableBytes; - Common::String _currentFieldName, _currentFileName; + Common::String _currentFieldName, _currentFileName, _currentTempFileName; bool _isFileField; bool _isBadRequest; -- cgit v1.2.3