diff options
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 | 
