aboutsummaryrefslogtreecommitdiff
path: root/backends/networking/sdl_net
diff options
context:
space:
mode:
authorAlexander Tkachev2016-07-07 16:57:14 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commit79b39bf0d080d43dc1c5569272b8091017dfa3e3 (patch)
tree9bc1fe737bfa03eafd043f5909d13ef0343dd8d2 /backends/networking/sdl_net
parent4d88f51de9583d9fcdebe8fc5e90fed61416fe96 (diff)
downloadscummvm-rg350-79b39bf0d080d43dc1c5569272b8091017dfa3e3.tar.gz
scummvm-rg350-79b39bf0d080d43dc1c5569272b8091017dfa3e3.tar.bz2
scummvm-rg350-79b39bf0d080d43dc1c5569272b8091017dfa3e3.zip
CLOUD: Add Reader sketch
That should be part of the Client, I guess. Reader is not ready to continue reading from place it stopped, but it already works as it should for the case when whole content is available.
Diffstat (limited to 'backends/networking/sdl_net')
-rw-r--r--backends/networking/sdl_net/localwebserver.cpp4
-rw-r--r--backends/networking/sdl_net/reader.cpp220
-rw-r--r--backends/networking/sdl_net/reader.h70
3 files changed, 294 insertions, 0 deletions
diff --git a/backends/networking/sdl_net/localwebserver.cpp b/backends/networking/sdl_net/localwebserver.cpp
index 2880c67d2b..cac7dab8ac 100644
--- a/backends/networking/sdl_net/localwebserver.cpp
+++ b/backends/networking/sdl_net/localwebserver.cpp
@@ -30,6 +30,7 @@
#include "common/timer.h"
#include "common/textconsole.h"
#include <SDL/SDL_net.h>
+#include "reader.h"
namespace Common {
class MemoryReadWriteStream;
@@ -47,6 +48,9 @@ LocalWebserver::LocalWebserver(): _set(nullptr), _serverSocket(nullptr), _timerS
addPathHandler("/create", _createDirectoryHandler.getHandler());
addPathHandler("/download", _downloadFileHandler.getHandler());
_defaultHandler = _resourceHandler.getHandler();
+
+ Reader reader;
+ reader.readResponse();
}
LocalWebserver::~LocalWebserver() {
diff --git a/backends/networking/sdl_net/reader.cpp b/backends/networking/sdl_net/reader.cpp
new file mode 100644
index 0000000000..edfaf81874
--- /dev/null
+++ b/backends/networking/sdl_net/reader.cpp
@@ -0,0 +1,220 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "backends/networking/sdl_net/reader.h"
+#include <common/debug.h>
+
+namespace Networking {
+
+Reader::Reader() {
+ _contentLength = 0;
+ _availableBytes = 0;
+
+ _window = nullptr;
+ _windowUsed = 0;
+ _windowSize = 0;
+
+ _content =
+ "POST /upload HTTP/1.1\r\n" \
+ "Host: 127.0.0.1:12345\r\n" \
+ "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0\r\n" \
+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" \
+ "Accept-Language: ru,en-US;q=0.7,en;q=0.3\r\n" \
+ "Accept-Encoding: gzip, deflate\r\n" \
+ "Referer: http://127.0.0.1:12345/files\r\n" \
+ "Connection: keep-alive\r\n" \
+ "Content-Type: multipart/form-data; boundary=---------------------------93411339527546\r\n" \
+ "Content-Length: 319\r\n" \
+ "\r\n" \
+ "-----------------------------93411339527546\r\n" \
+ "Content-Disposition: form-data; name=\"path\"\r\n" \
+ "\r\n" \
+ "/root\r\n" \
+ "-----------------------------93411339527546\r\n" \
+ "Content-Disposition: form-data; name=\"upload_file\"; filename=\"irc.txt\"\r\n" \
+ "Content-Type: text/plain\r\n" \
+ "\r\n" \
+ "shells.fnordserver.eu/1400\r\n" \
+ "-----------------------------93411339527546--";
+}
+
+Reader::~Reader() {}
+
+void Reader::readResponse() {
+ while (true) {
+ readHeaders(); //til "\r\n\r\n"
+ readContent(); //til "--" + _boundary
+ if (_availableBytes >= 2) {
+ Common::String bts;
+ bts += readOne();
+ bts += readOne();
+ if (bts == "--") break;
+ if (bts == "\r\n") continue;
+ warning("strange bytes: \"%s\"", bts);
+ } else {
+ warning("strange ending");
+ break;
+ }
+ }
+ if (_availableBytes > 0) debug("STRANGE END: %llu bytes left", _availableBytes);
+ else debug("END");
+}
+
+void Reader::readHeaders() {
+ Common::String boundary = "\r\n\r\n";
+ makeWindow(boundary.size());
+
+ Common::String headers = "";
+ while (readOneByteInString(headers, boundary));
+ handleHeaders(headers);
+}
+
+namespace {
+void readFromThatUntilLineEnd(const char *cstr, Common::String needle, Common::String &result) {
+ const char *position = strstr(cstr, needle.c_str());
+
+ if (position) {
+ char c;
+ for (const char *i = position + needle.size(); c = *i, c != 0; ++i) {
+ if (c == '\n' || c == '\r') break;
+ result += c;
+ }
+ }
+}
+}
+
+void Reader::handleHeaders(Common::String headers) {
+ debug("\nHANDLE HEADERS:\n>>%s<<", headers.c_str());
+ if (_boundary.empty()) {
+ //TODO: parse method, path, query, fragment
+
+ //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
+ //_fieldIsFile = true;
+ }
+}
+
+void Reader::readContent() {
+ Common::String boundary = "--" + _boundary;
+ makeWindow(boundary.size());
+
+ /*
+ if (_fieldIsFile) {
+ //create temporary file
+ tempFileName = generateTempFileName();
+ stream = openFileStream(tempFileName);
+ //read till "--" + _boundary
+ while (readOneByteInStream(stream));
+ handleFileContent(tempFileName);
+ } else {
+ */
+ Common::String buffer = "";
+ while (readOneByteInString(buffer, boundary)) ;
+ handleValueContent(buffer);
+ //}
+}
+
+void Reader::handleFileContent(Common::String filename) {
+ _attachedFiles[_currentFieldName] = filename;
+}
+
+void Reader::handleValueContent(Common::String value) {
+ debug("\nHANDLE CONTENT:\n>>%s<<", value.c_str());
+ _fields[_currentFieldName] = value;
+}
+
+void Reader::makeWindow(uint32 size) {
+ delete[] _window;
+ _window = nullptr;
+
+ _window = new byte[size];
+ _windowUsed = 0;
+ _windowSize = size;
+}
+
+/*
+bool Reader::readOneByteInStream(stream) {
+ b = read(1);
+ _window[_windowUsed++] = b;
+ if (_windowUsed < _windowSize) return true;
+
+ //when window is filled, check whether that's the boundary
+ if (_window == "--" + _boundary)
+ return false;
+
+ //if not, write the first byte of the window to the stream
+ stream.write(_window[0]);
+ for (uint32 i = 1; i < _windowSize; ++i)
+ _window[i - 1] = _window[i];
+ --_windowUsed;
+ return true;
+}
+*/
+
+bool Reader::readOneByteInString(Common::String &buffer, const Common::String &boundary) {
+ byte b = readOne();
+ _window[_windowUsed++] = b;
+ if (_windowUsed < _windowSize) return true;
+
+ //when window is filled, check whether that's the boundary
+ if (Common::String((char *)_window, _windowSize) == boundary)
+ return false;
+
+ //if not, add the first byte of the window to the string
+ buffer += _window[0];
+ for (uint32 i = 1; i < _windowSize; ++i)
+ _window[i - 1] = _window[i];
+ --_windowUsed;
+ return true;
+}
+
+byte Reader::readOne() {
+ byte b = _content[0];
+ _content.deleteChar(0);
+ --_availableBytes;
+ return b;
+}
+
+} // End of namespace Networking
diff --git a/backends/networking/sdl_net/reader.h b/backends/networking/sdl_net/reader.h
new file mode 100644
index 0000000000..d4f9e11f0b
--- /dev/null
+++ b/backends/networking/sdl_net/reader.h
@@ -0,0 +1,70 @@
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#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"
+
+namespace Networking {
+
+class Reader {
+ ///Common::String _headers;
+ ///Common::String _method, _path, _query, _anchor;
+ Common::String _content;
+
+ Common::String _boundary;
+ uint32 _contentLength;
+ uint32 _availableBytes;
+
+ Common::String _currentFieldName;
+ Common::HashMap<Common::String, Common::String> _fields;
+ Common::HashMap<Common::String, Common::String> _attachedFiles;
+
+ byte *_window;
+ uint32 _windowUsed, _windowSize;
+
+ void readHeaders();
+ void readContent();
+ void handleHeaders(Common::String headers);
+ void handleFileContent(Common::String filename);
+ void handleValueContent(Common::String value);
+
+ void makeWindow(uint32 size);
+ ///bool Reader::readOneByteInStream(stream);
+ bool Reader::readOneByteInString(Common::String &buffer, const Common::String &boundary);
+
+ byte readOne();
+
+public:
+ Reader();
+ ~Reader();
+
+ void readResponse();
+};
+
+} // End of namespace Networking
+
+#endif