diff options
author | Alexander Tkachev | 2016-07-07 16:57:14 +0600 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | 79b39bf0d080d43dc1c5569272b8091017dfa3e3 (patch) | |
tree | 9bc1fe737bfa03eafd043f5909d13ef0343dd8d2 /backends/networking/sdl_net | |
parent | 4d88f51de9583d9fcdebe8fc5e90fed61416fe96 (diff) | |
download | scummvm-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.cpp | 4 | ||||
-rw-r--r-- | backends/networking/sdl_net/reader.cpp | 220 | ||||
-rw-r--r-- | backends/networking/sdl_net/reader.h | 70 |
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 |