aboutsummaryrefslogtreecommitdiff
path: root/backends/networking/sdl_net
diff options
context:
space:
mode:
authorAlexander Tkachev2016-07-09 16:37:56 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commitd1b5a640205af29af9785846d2e6153e67241f2c (patch)
tree69f4899494ae97d6ae1b94e9eb1aaee3d0d49767 /backends/networking/sdl_net
parent7fcdcc10cb8f6dad370e942ef917ff00e888e2ec (diff)
downloadscummvm-rg350-d1b5a640205af29af9785846d2e6153e67241f2c.tar.gz
scummvm-rg350-d1b5a640205af29af9785846d2e6153e67241f2c.tar.bz2
scummvm-rg350-d1b5a640205af29af9785846d2e6153e67241f2c.zip
CLOUD: Cleanup in Reader and Client
Diffstat (limited to 'backends/networking/sdl_net')
-rw-r--r--backends/networking/sdl_net/client.cpp4
-rw-r--r--backends/networking/sdl_net/client.h6
-rw-r--r--backends/networking/sdl_net/reader.cpp392
-rw-r--r--backends/networking/sdl_net/reader.h28
4 files changed, 100 insertions, 330 deletions
diff --git a/backends/networking/sdl_net/client.cpp b/backends/networking/sdl_net/client.cpp
index ef46e81815..a486e3c66f 100644
--- a/backends/networking/sdl_net/client.cpp
+++ b/backends/networking/sdl_net/client.cpp
@@ -150,7 +150,7 @@ void Client::close() {
ClientState Client::state() const { return _state; }
-//Common::String Client::headers() const { return _headers; }
+Common::String Client::headers() const { return _reader.headers(); }
Common::String Client::method() const { return _reader.method(); }
@@ -160,8 +160,6 @@ Common::String Client::query() const { return _reader.query(); }
Common::String Client::queryParameter(Common::String name) const { return _reader.queryParameter(name); }
-Common::String Client::attachedFile(Common::String name) const { return _reader.attachedFile(name); }
-
Common::String Client::anchor() const { return _reader.anchor(); }
bool Client::noMoreContent() const { return _reader.noMoreContent(); }
diff --git a/backends/networking/sdl_net/client.h b/backends/networking/sdl_net/client.h
index a60545e2c6..eab3bcff2a 100644
--- a/backends/networking/sdl_net/client.h
+++ b/backends/networking/sdl_net/client.h
@@ -23,7 +23,6 @@
#ifndef BACKENDS_NETWORKING_SDL_NET_CLIENT_H
#define BACKENDS_NETWORKING_SDL_NET_CLIENT_H
-#include "common/scummsys.h"
#include "common/str.h"
#include "reader.h"
@@ -73,18 +72,17 @@ public:
bool readBlockHeaders(Common::WriteStream *stream);
bool readBlockContent(Common::WriteStream *stream);
void setHandler(ClientHandler *handler);
- void dropHandler();
void handle();
void close();
ClientState state() const;
- //Common::String headers() const;
+ Common::String headers() const;
Common::String method() const;
Common::String path() const;
Common::String query() const;
Common::String queryParameter(Common::String name) const;
- Common::String attachedFile(Common::String name) const;
Common::String anchor() const;
+
bool noMoreContent() const;
/**
diff --git a/backends/networking/sdl_net/reader.cpp b/backends/networking/sdl_net/reader.cpp
index 143ab93816..1e5693c22f 100644
--- a/backends/networking/sdl_net/reader.cpp
+++ b/backends/networking/sdl_net/reader.cpp
@@ -20,27 +20,15 @@
*
*/
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
-
#include "backends/networking/sdl_net/reader.h"
+#include "backends/fs/fs-factory.h"
#include "backends/networking/sdl_net/localwebserver.h"
-#include "common/debug.h"
-#include "common/stream.h"
#include "common/memstream.h"
-#include "backends/fs/fs-factory.h"
-
-// This define lets us use the system function remove() on Symbian, which
-// is disabled by default due to a macro conflict.
-// See backends/platform/symbian/src/portdefs.h .
-#define SYMBIAN_USE_SYSTEM_REMOVE
-
-#ifndef _WIN32_WCE
-#include <errno.h> // for removeFile()
-#endif
+#include "common/stream.h"
namespace Networking {
-Reader::Reader(): _randomSource("Networking::Reader") {
+Reader::Reader() {
_state = RS_NONE;
_content = nullptr;
_bytesLeft = 0;
@@ -50,36 +38,14 @@ Reader::Reader(): _randomSource("Networking::Reader") {
_windowSize = 0;
_headers = "";
- _stream = nullptr;
_firstBlock = true;
_contentLength = 0;
_availableBytes = 0;
- _isFileField = false;
_isBadRequest = false;
_allContentRead = false;
}
-namespace {
-bool removeFile(const char *filename) {
- // FIXME: remove does not exist on all systems. If your port fails to
- // compile because of this, please let us know (scummvm-devel).
- // There is a nicely portable workaround, too: Make this method overloadable.
- if (remove(filename) != 0) {
-#ifndef _WIN32_WCE
- if (errno == EACCES)
- error("Reader: removeFile(): Search or write permission denied: %s", filename);
-
- if (errno == ENOENT)
- error("Reader: removeFile(): '%s' does not exist or path is invalid", filename);
-#endif
- return false;
- } else {
- return true;
- }
-}
-}
-
Reader::~Reader() {
cleanup();
}
@@ -99,25 +65,15 @@ Reader &Reader::operator=(Reader &r) {
r._window = nullptr;
_headers = r._headers;
- _stream = r._stream;
- _firstBlock = r._firstBlock;
- r._stream = nullptr;
-
- _headers = r._headers;
_method = r._method;
_path = r._path;
_query = r._query;
_anchor = r._anchor;
_queryParameters = r._queryParameters;
- _attachedFiles = r._attachedFiles;
- r._attachedFiles.clear();
_contentLength = r._contentLength;
_boundary = r._boundary;
_availableBytes = r._availableBytes;
- _currentFieldName = r._currentFieldName;
- _currentFileName = r._currentFileName;
- _currentTempFileName = r._currentTempFileName;
- _isFileField = r._isFileField;
+ _firstBlock = r._firstBlock;
_isBadRequest = r._isBadRequest;
_allContentRead = r._allContentRead;
@@ -128,112 +84,9 @@ void Reader::cleanup() {
//_content is not to be freed, it's not owned by Reader
if (_window != nullptr) freeWindow();
- delete _stream;
-
- //delete temp files (by the time Reader is destucted those must be renamed or read)
- for (Common::HashMap<Common::String, Common::String>::iterator i = _attachedFiles.begin(); i != _attachedFiles.end(); ++i) {
- AbstractFSNode *node = g_system->getFilesystemFactory()->makeFileNodePath(i->_value);
- if (node->exists()) removeFile(node->getPath().c_str());
- }
}
-bool Reader::readWholeRequest() {
- if (_state == RS_NONE) _state = RS_READING_HEADERS;
-
- while (true) {
- if (!bytesLeft()) return false;
-
- if (_state == RS_READING_HEADERS)
- if (!readWholeHeaders())
- return false;
-
- if (_boundary.empty()) return true; //not POST multipart
-
- if (!bytesLeft()) return false;
-
- if (_state == RS_READING_CONTENT)
- if (!readWholeContent())
- return false;
-
- if (_availableBytes >= 2) {
- Common::String bts;
- bts += readOne();
- bts += readOne();
- if (bts == "--") break;
- if (bts == "\r\n") continue;
- warning("strange bytes: \"%s\"", bts.c_str());
- } else {
- warning("strange ending");
- break;
- }
- }
- if (_availableBytes > 0) debug("STRANGE END: %llu bytes left", _availableBytes);
- else debug("END");
-
- return true;
-}
-
-bool Reader::readFirstHeaders() {
- if (_state == RS_NONE) _state = RS_READING_HEADERS;
-
- if (!bytesLeft()) return false;
-
- if (_state == RS_READING_HEADERS)
- return readWholeHeaders();
-
- warning("Reader::readFirstHeaders(): bad state");
- return false;
-}
-
-bool Reader::readFirstContent(Common::WriteStream *stream) {
- if (_state != RS_READING_CONTENT) {
- warning("Reader::readFirstContent(): bad state");
- return false;
- }
-
- if (!bytesLeft()) return false;
-
- return readWholeContentIntoStream(stream);
-}
-
-bool Reader::readBlockHeaders(Common::WriteStream *stream) {
- if (_state != RS_READING_HEADERS) {
- warning("Reader::readBlockHeaders(): bad state");
- return false;
- }
-
- if (!bytesLeft()) return false;
-
- return readWholeHeadersIntoStream(stream);
-}
-
-bool Reader::readBlockContent(Common::WriteStream *stream) {
- if (_state != RS_READING_CONTENT) {
- warning("Reader::readBlockContent(): bad state");
- return false;
- }
-
- if (!bytesLeft()) return false;
-
- if (!readWholeContentIntoStream(stream))
- return false;
-
- if (_availableBytes >= 2) {
- Common::String bts;
- bts += readOne();
- bts += readOne();
- if (bts == "--") _allContentRead = true;
- else if (bts != "\r\n")
- warning("strange bytes: \"%s\"", bts.c_str());
- } else {
- warning("strange ending");
- _allContentRead = true;
- }
-
- return true;
-}
-
-bool Reader::readWholeHeaders() {
+bool Reader::readAndHandleFirstHeaders() {
Common::String boundary = "\r\n\r\n";
if (_window == nullptr) {
makeWindow(boundary.size());
@@ -243,14 +96,14 @@ bool Reader::readWholeHeaders() {
while (readOneByteInString(_headers, boundary)) {
if (!bytesLeft()) return false;
}
- handleHeaders(_headers);
+ handleFirstHeaders(_headers);
freeWindow();
_state = RS_READING_CONTENT;
return true;
}
-bool Reader::readWholeHeadersIntoStream(Common::WriteStream *stream) {
+bool Reader::readBlockHeadersIntoStream(Common::WriteStream *stream) {
Common::String boundary = "\r\n\r\n";
if (_window == nullptr) makeWindow(boundary.size());
@@ -278,51 +131,24 @@ void readFromThatUntilLineEnd(const char *cstr, Common::String needle, Common::S
}
}
-void Reader::handleHeaders(Common::String headers) {
- debug("\nHANDLE HEADERS:\n>>%s<<", headers.c_str());
- if (_boundary.empty()) {
- //parse method, path, query, fragment
- parseFirstLine(headers);
-
- //find boundary
- _boundary = "";
- readFromThatUntilLineEnd(headers.c_str(), "boundary=", _boundary);
-
- //find content length
- Common::String contentLength = "";
- readFromThatUntilLineEnd(headers.c_str(), "Content-Length: ", contentLength);
- _contentLength = contentLength.asUint64();
- _availableBytes = _contentLength;
- debug("BOUNDARY: %s", _boundary.c_str());
- debug("LENGTH: %llu", _contentLength);
- } else {
- //find field name
- _currentFieldName = "";
- readFromThatUntilLineEnd(headers.c_str(), "name=\"", _currentFieldName);
- for (uint32 i = 0; i < _currentFieldName.size(); ++i)
- if (_currentFieldName[i] == '\"') {
- _currentFieldName.erase(i);
- break;
- }
- debug("FIELD NAME: >>%s<<", _currentFieldName.c_str());
-
- //find out field type
- _currentFileName = "";
- readFromThatUntilLineEnd(headers.c_str(), "filename=\"", _currentFileName);
- for (uint32 i = 0; i < _currentFileName.size(); ++i)
- if (_currentFileName[i] == '\"') {
- _currentFileName.erase(i);
- break;
- }
-
- if (!_currentFileName.empty()) {
- _isFileField = true;
- _queryParameters[_currentFieldName] = _currentFileName;
- debug("FILE NAME: >>%s<<", _currentFileName.c_str());
- } else {
- _isFileField = false;
- }
+void Reader::handleFirstHeaders(Common::String headers) {
+ if (!_boundary.empty()) {
+ warning("handleFirstHeaders() called when first headers were already handled");
+ return;
}
+
+ //parse method, path, query, fragment
+ parseFirstLine(headers);
+
+ //find boundary
+ _boundary = "";
+ readFromThatUntilLineEnd(headers.c_str(), "boundary=", _boundary);
+
+ //find content length
+ Common::String contentLength = "";
+ readFromThatUntilLineEnd(headers.c_str(), "Content-Length: ", contentLength);
+ _contentLength = contentLength.asUint64();
+ _availableBytes = _contentLength;
}
void Reader::parseFirstLine(const Common::String &headers) {
@@ -419,101 +245,10 @@ void Reader::parseQueryParameters() {
}
}
-namespace {
-char generateRandomChar(Common::RandomSource &random) {
- int r = random.getRandomNumber(36);
- char c = '0' + r;
- if (r > 9) c = 'a' + r - 10;
- return c;
-}
-
-Common::String generateTempFileName(Common::String originalFilename, Common::RandomSource &random) {
- //generates "./<originalFilename>-<uniqueSequence>.scummtmp"
- //normalize <originalFilename>
- 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(random);
-
- //update sequence while generate path exists
- AbstractFSNode *node;
- Common::String path;
- do {
- uniqueSequence += generateRandomChar(random);
- path = prefix + uniqueSequence + ".scummtmp";
- node = g_system->getFilesystemFactory()->makeFileNodePath(path);
- } while (node->exists());
-
- return path;
-}
-}
-
-bool Reader::readWholeContent() {
- Common::String boundary = "--" + _boundary;
- if (!_firstBlock) boundary = "\r\n" + boundary;
- if (_window == nullptr) {
- makeWindow(boundary.size());
-
- if (_stream) delete _stream;
- if (_isFileField) {
- //create temporary file
- _currentTempFileName = generateTempFileName(_currentFileName, _randomSource);
- 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);
- }
- }
-
- while (readOneByteInStream(_stream, boundary)) {
- if (!bytesLeft()) return false;
- }
-
- _firstBlock = 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<Common::MemoryReadWriteStream *>(_stream);
- if (dynamicStream != nullptr)
- if (dynamicStream->size() == 0)
- handleValueContent("");
- else
- handleValueContent(Common::String((char *)dynamicStream->getData(), dynamicStream->size()));
- else
- if (_stream != nullptr)
- warning("Stream somehow changed its type from MemoryReadWriteStream!");
- else
- warning("No stream was created!");
- }
-
- freeWindow();
- _state = RS_READING_HEADERS;
- return true;
-}
-
-bool Reader::readWholeContentIntoStream(Common::WriteStream *stream) {
+bool Reader::readContentIntoStream(Common::WriteStream *stream) {
Common::String boundary = "--" + _boundary;
if (!_firstBlock) boundary = "\r\n" + boundary;
+ if (_boundary.empty()) boundary = "\r\n";
if (_window == nullptr) makeWindow(boundary.size());
while (readOneByteInStream(stream, boundary)) {
@@ -528,16 +263,6 @@ bool Reader::readWholeContentIntoStream(Common::WriteStream *stream) {
return true;
}
-void Reader::handleFileContent(Common::String filename) {
- debug("\nHANDLE FILE CONTENT:\nFILE >>%s<< SAVED INTO >>%s<<", _currentFileName.c_str(), filename.c_str());
- _attachedFiles[_currentFileName] = filename;
-}
-
-void Reader::handleValueContent(Common::String value) {
- debug("\nHANDLE CONTENT:\n>>%s<<", value.c_str());
- _queryParameters[_currentFieldName] = value;
-}
-
void Reader::makeWindow(uint32 size) {
freeWindow();
@@ -594,6 +319,67 @@ byte Reader::readOne() {
return b;
}
+/// public
+
+bool Reader::readFirstHeaders() {
+ if (_state == RS_NONE) _state = RS_READING_HEADERS;
+
+ if (!bytesLeft()) return false;
+
+ if (_state == RS_READING_HEADERS)
+ return readAndHandleFirstHeaders();
+
+ warning("Reader::readFirstHeaders(): bad state");
+ return false;
+}
+
+bool Reader::readFirstContent(Common::WriteStream *stream) {
+ if (_state != RS_READING_CONTENT) {
+ warning("Reader::readFirstContent(): bad state");
+ return false;
+ }
+
+ // no difference, actually
+ return readBlockContent(stream);
+}
+
+bool Reader::readBlockHeaders(Common::WriteStream *stream) {
+ if (_state != RS_READING_HEADERS) {
+ warning("Reader::readBlockHeaders(): bad state");
+ return false;
+ }
+
+ if (!bytesLeft()) return false;
+
+ return readBlockHeadersIntoStream(stream);
+}
+
+bool Reader::readBlockContent(Common::WriteStream *stream) {
+ if (_state != RS_READING_CONTENT) {
+ warning("Reader::readBlockContent(): bad state");
+ return false;
+ }
+
+ if (!bytesLeft()) return false;
+
+ if (!readContentIntoStream(stream))
+ return false;
+
+ if (_availableBytes >= 2) {
+ Common::String bts;
+ bts += readOne();
+ bts += readOne();
+ if (bts == "--") _allContentRead = true;
+ else if (bts != "\r\n")
+ warning("strange bytes: \"%s\"", bts.c_str());
+ } else {
+ warning("strange ending");
+ _allContentRead = true;
+ }
+
+ return true;
+}
+
uint32 Reader::bytesLeft() { return _bytesLeft; }
void Reader::setContent(Common::MemoryReadWriteStream *stream) {
@@ -605,6 +391,8 @@ bool Reader::badRequest() const { return _isBadRequest; }
bool Reader::noMoreContent() const { return _allContentRead; }
+Common::String Reader::headers() const { return _headers; }
+
Common::String Reader::method() const { return _method; }
Common::String Reader::path() const { return _path; }
@@ -613,8 +401,6 @@ Common::String Reader::query() const { return _query; }
Common::String Reader::queryParameter(Common::String name) const { return _queryParameters[name]; }
-Common::String Reader::attachedFile(Common::String name) const { return _attachedFiles[name]; }
-
Common::String Reader::anchor() const { return _anchor; }
} // End of namespace Networking
diff --git a/backends/networking/sdl_net/reader.h b/backends/networking/sdl_net/reader.h
index 0ed0d8c91e..d234a82782 100644
--- a/backends/networking/sdl_net/reader.h
+++ b/backends/networking/sdl_net/reader.h
@@ -23,11 +23,9 @@
#ifndef BACKENDS_NETWORKING_SDL_NET_READER_H
#define BACKENDS_NETWORKING_SDL_NET_READER_H
-#include "common/scummsys.h"
#include "common/str.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
-#include "common/random.h"
namespace Common {
class MemoryReadWriteStream;
@@ -43,8 +41,6 @@ enum ReaderState {
};
class Reader {
- Common::RandomSource _randomSource; //for temp file names
-
ReaderState _state;
Common::MemoryReadWriteStream *_content;
uint32 _bytesLeft;
@@ -53,31 +49,22 @@ class Reader {
uint32 _windowUsed, _windowSize;
Common::String _headers;
- Common::WriteStream *_stream;
- bool _firstBlock;
-
- ///Common::String _headers;
Common::String _method, _path, _query, _anchor;
Common::HashMap<Common::String, Common::String> _queryParameters;
- Common::HashMap<Common::String, Common::String> _attachedFiles;
uint32 _contentLength;
Common::String _boundary;
uint32 _availableBytes;
- Common::String _currentFieldName, _currentFileName, _currentTempFileName;
- bool _isFileField;
+ bool _firstBlock;
bool _isBadRequest;
bool _allContentRead;
void cleanup();
- bool readWholeHeaders(); //true when ended reading
- bool readWholeContent(); //true when ended reading
- bool readWholeHeadersIntoStream(Common::WriteStream *stream); //true when ended reading
- bool readWholeContentIntoStream(Common::WriteStream *stream); //true when ended reading
- void handleHeaders(Common::String headers);
- void handleFileContent(Common::String filename);
- void handleValueContent(Common::String value);
+ bool readAndHandleFirstHeaders(); //true when ended reading
+ bool readBlockHeadersIntoStream(Common::WriteStream *stream); //true when ended reading
+ bool readContentIntoStream(Common::WriteStream *stream); //true when ended reading
+ void handleFirstHeaders(Common::String headers);
void parseFirstLine(const Common::String &headers);
void parsePathQueryAndAnchor(Common::String path);
void parseQueryParameters();
@@ -96,20 +83,21 @@ public:
Reader &operator=(Reader &r);
- bool readWholeRequest(); //true when ended reading
bool readFirstHeaders(); //true when ended reading
bool readFirstContent(Common::WriteStream *stream); //true when ended reading
bool readBlockHeaders(Common::WriteStream *stream); //true when ended reading
bool readBlockContent(Common::WriteStream *stream); //true when ended reading
+
void setContent(Common::MemoryReadWriteStream *stream);
+
bool badRequest() const;
bool noMoreContent() const;
+ Common::String headers() const;
Common::String method() const;
Common::String path() const;
Common::String query() const;
Common::String queryParameter(Common::String name) const;
- Common::String attachedFile(Common::String name) const;
Common::String anchor() const;
};