aboutsummaryrefslogtreecommitdiff
path: root/backends/networking/sdl_net
diff options
context:
space:
mode:
authorAlexander Tkachev2016-07-07 18:04:48 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commitf91bb39192cd11a0cb30a39bfb630d2fd9fad89e (patch)
treeab07ff6532d41c97fc5f970eda219586bdaed02a /backends/networking/sdl_net
parent589b4cd45741ff73ba2d1260a14a14351cfba914 (diff)
downloadscummvm-rg350-f91bb39192cd11a0cb30a39bfb630d2fd9fad89e.tar.gz
scummvm-rg350-f91bb39192cd11a0cb30a39bfb630d2fd9fad89e.tar.bz2
scummvm-rg350-f91bb39192cd11a0cb30a39bfb630d2fd9fad89e.zip
CLOUD: Use Reader in Client
Instead of copy-pasting it I'm just "integrating" it in.
Diffstat (limited to 'backends/networking/sdl_net')
-rw-r--r--backends/networking/sdl_net/client.cpp86
-rw-r--r--backends/networking/sdl_net/client.h6
-rw-r--r--backends/networking/sdl_net/localwebserver.cpp4
-rw-r--r--backends/networking/sdl_net/reader.cpp119
-rw-r--r--backends/networking/sdl_net/reader.h31
5 files changed, 125 insertions, 121 deletions
diff --git a/backends/networking/sdl_net/client.cpp b/backends/networking/sdl_net/client.cpp
index f567891dd8..adcbafdb12 100644
--- a/backends/networking/sdl_net/client.cpp
+++ b/backends/networking/sdl_net/client.cpp
@@ -45,6 +45,7 @@ void Client::open(SDLNet_SocketSet set, TCPsocket socket) {
_socket = socket;
_set = set;
_headers = "";
+ _reader = Reader();
_method = "";
_path = "";
_query = "";
@@ -63,88 +64,25 @@ void Client::readHeaders() {
if (!SDLNet_SocketReady(_socket)) return;
const uint32 BUFFER_SIZE = 16 * 1024;
- char buffer[BUFFER_SIZE];
+ byte buffer[BUFFER_SIZE];
int bytes = SDLNet_TCP_Recv(_socket, buffer, BUFFER_SIZE);
if (bytes <= 0) {
warning("Client::readHeaders recv fail");
close();
return;
}
- _headers += Common::String(buffer, bytes);
- checkIfHeadersEnded();
- checkIfBadRequest();
-}
-
-void Client::checkIfHeadersEnded() {
- const char *cstr = _headers.c_str();
- const char *position = strstr(cstr, "\r\n\r\n");
- if (position) _state = READ_HEADERS;
-}
-
-void Client::checkIfBadRequest() {
- uint32 headersSize = _headers.size();
- bool bad = false;
-
- const uint32 SUSPICIOUS_HEADERS_SIZE = 128 * 1024;
- if (headersSize > SUSPICIOUS_HEADERS_SIZE) bad = true;
-
- if (!bad) {
- if (headersSize > 0) {
- const char *cstr = _headers.c_str();
- const char *position = strstr(cstr, "\r\n");
- if (position) { //we have at least one line - and we want the first one
- //"<METHOD> <path> HTTP/<VERSION>\r\n"
- Common::String method, path, http, buf;
- uint32 length = position - cstr;
- if (headersSize > length) headersSize = length;
- for (uint32 i = 0; i < headersSize; ++i) {
- if (_headers[i] != ' ') buf += _headers[i];
- if (_headers[i] == ' ' || i == headersSize - 1) {
- if (method == "") method = buf;
- else if (path == "") path = buf;
- else if (http == "") http = buf;
- else {
- bad = true;
- break;
- }
- buf = "";
- }
- }
-
- //check that method is supported
- if (method != "GET" && method != "PUT" && method != "POST") bad = true;
-
- //check that HTTP/<VERSION> is OK
- if (!http.hasPrefix("HTTP/")) bad = true;
-
- _method = method;
- parsePathQueryAndAnchor(path);
- }
+
+ _reader.setContent(buffer, bytes);
+ if (_reader.readResponse()) {
+ if (_reader.badRequest()) _state = BAD_REQUEST;
+ else {
+ _state = READ_HEADERS;
+ _method = _reader.method();
+ _path = _reader.path();
+ _query = _reader.query();
+ _anchor = _reader.anchor();
}
}
-
- if (bad) _state = BAD_REQUEST;
-}
-
-void Client::parsePathQueryAndAnchor(Common::String path) {
- //<path>[?query][#anchor]
- bool readingPath = true;
- bool readingQuery = false;
- _path = "";
- _query = "";
- _anchor = "";
- for (uint32 i = 0; i < path.size(); ++i) {
- if (readingPath) {
- if (path[i] == '?') {
- readingPath = false;
- readingQuery = true;
- } else _path += path[i];
- } else if(readingQuery) {
- if (path[i] == '#') {
- readingQuery = false;
- } else _query += path[i];
- } else _anchor += path[i];
- }
}
void Client::setHandler(ClientHandler *handler) {
diff --git a/backends/networking/sdl_net/client.h b/backends/networking/sdl_net/client.h
index eba5dabfba..a54f72ae2b 100644
--- a/backends/networking/sdl_net/client.h
+++ b/backends/networking/sdl_net/client.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/str.h"
+#include "reader.h"
typedef struct _SDLNet_SocketSet *SDLNet_SocketSet;
typedef struct _TCPsocket *TCPsocket;
@@ -51,14 +52,11 @@ class Client {
ClientState _state;
SDLNet_SocketSet _set;
TCPsocket _socket;
+ Reader _reader;
Common::String _headers;
Common::String _method, _path, _query, _anchor;
ClientHandler *_handler;
- void checkIfHeadersEnded();
- void checkIfBadRequest();
- void parsePathQueryAndAnchor(Common::String path);
-
public:
Client();
Client(SDLNet_SocketSet set, TCPsocket socket);
diff --git a/backends/networking/sdl_net/localwebserver.cpp b/backends/networking/sdl_net/localwebserver.cpp
index d8f12b8220..8f9c30d069 100644
--- a/backends/networking/sdl_net/localwebserver.cpp
+++ b/backends/networking/sdl_net/localwebserver.cpp
@@ -48,10 +48,6 @@ LocalWebserver::LocalWebserver(): _set(nullptr), _serverSocket(nullptr), _timerS
addPathHandler("/create", _createDirectoryHandler.getHandler());
addPathHandler("/download", _downloadFileHandler.getHandler());
_defaultHandler = _resourceHandler.getHandler();
-
- Reader reader;
- reader.setBytesLeft(128);
- while (!reader.readResponse()) reader.setBytesLeft(20);
}
LocalWebserver::~LocalWebserver() {
diff --git a/backends/networking/sdl_net/reader.cpp b/backends/networking/sdl_net/reader.cpp
index b6bf9e52ba..3f7983506a 100644
--- a/backends/networking/sdl_net/reader.cpp
+++ b/backends/networking/sdl_net/reader.cpp
@@ -29,11 +29,9 @@ namespace Networking {
Reader::Reader() {
_state = RS_NONE;
+ _content = nullptr;
_bytesLeft = 0;
- _contentLength = 0;
- _availableBytes = 0;
-
_window = nullptr;
_windowUsed = 0;
_windowSize = 0;
@@ -41,28 +39,9 @@ Reader::Reader() {
_headers = "";
_buffer = "";
- _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--";
+ _contentLength = 0;
+ _availableBytes = 0;
+ _isBadRequest = false;
}
Reader::~Reader() {}
@@ -77,6 +56,10 @@ bool Reader::readResponse() {
if (!readHeaders())
return false;
+ if (_boundary.empty()) return true; //not POST multipart
+
+ if (!bytesLeft()) return false;
+
if (_state == RS_READING_CONTENT)
if (!readContent())
return false;
@@ -133,7 +116,8 @@ 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()) {
- //TODO: parse method, path, query, fragment
+ //parse method, path, query, fragment
+ parseFirstLine(headers);
//find boundary
_boundary = "";
@@ -162,6 +146,72 @@ void Reader::handleHeaders(Common::String headers) {
}
}
+void Reader::parseFirstLine(const Common::String &headers) {
+ uint32 headersSize = headers.size();
+ bool bad = false;
+
+ const uint32 SUSPICIOUS_HEADERS_SIZE = 128 * 1024;
+ if (headersSize > SUSPICIOUS_HEADERS_SIZE) bad = true;
+
+ if (!bad) {
+ if (headersSize > 0) {
+ const char *cstr = headers.c_str();
+ const char *position = strstr(cstr, "\r\n");
+ if (position) { //we have at least one line - and we want the first one
+ //"<METHOD> <path> HTTP/<VERSION>\r\n"
+ Common::String method, path, http, buf;
+ uint32 length = position - cstr;
+ if (headersSize > length) headersSize = length;
+ for (uint32 i = 0; i < headersSize; ++i) {
+ if (headers[i] != ' ') buf += headers[i];
+ if (headers[i] == ' ' || i == headersSize - 1) {
+ if (method == "") method = buf;
+ else if (path == "") path = buf;
+ else if (http == "") http = buf;
+ else {
+ bad = true;
+ break;
+ }
+ buf = "";
+ }
+ }
+
+ //check that method is supported
+ if (method != "GET" && method != "PUT" && method != "POST") bad = true;
+
+ //check that HTTP/<VERSION> is OK
+ if (!http.hasPrefix("HTTP/")) bad = true;
+
+ _method = method;
+ parsePathQueryAndAnchor(path);
+ }
+ }
+ }
+
+ if (bad) _isBadRequest = true;
+}
+
+void Reader::parsePathQueryAndAnchor(Common::String path) {
+ //<path>[?query][#anchor]
+ bool readingPath = true;
+ bool readingQuery = false;
+ _path = "";
+ _query = "";
+ _anchor = "";
+ for (uint32 i = 0; i < path.size(); ++i) {
+ if (readingPath) {
+ if (path[i] == '?') {
+ readingPath = false;
+ readingQuery = true;
+ } else _path += path[i];
+ } else if (readingQuery) {
+ if (path[i] == '#') {
+ readingQuery = false;
+ } else _query += path[i];
+ } else _anchor += path[i];
+ }
+}
+
bool Reader::readContent() {
Common::String boundary = "--" + _boundary;
if (_window == nullptr) {
@@ -251,7 +301,7 @@ bool Reader::readOneByteInString(Common::String &buffer, const Common::String &b
byte Reader::readOne() {
byte b = _content[0];
- _content.deleteChar(0);
+ ++_content;
--_availableBytes;
--_bytesLeft;
return b;
@@ -259,6 +309,19 @@ byte Reader::readOne() {
uint32 Reader::bytesLeft() { return _bytesLeft; }
-void Reader::setBytesLeft(uint32 b) { _bytesLeft = b; }
+void Reader::setContent(byte *buffer, uint32 size) {
+ _content = buffer;
+ _bytesLeft = size;
+}
+
+bool Reader::badRequest() { return _isBadRequest; }
+
+Common::String Reader::method() const { return _method; }
+
+Common::String Reader::path() const { return _path; }
+
+Common::String Reader::query() const { return _query; }
+
+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 b91973ea22..245f63abd1 100644
--- a/backends/networking/sdl_net/reader.h
+++ b/backends/networking/sdl_net/reader.h
@@ -37,25 +37,25 @@ enum ReaderState {
};
class Reader {
- ///Common::String _headers;
- ///Common::String _method, _path, _query, _anchor;
ReaderState _state;
- Common::String _content;
+ byte *_content;
uint32 _bytesLeft;
- Common::String _boundary;
- uint32 _contentLength;
- uint32 _availableBytes;
+ byte *_window;
+ uint32 _windowUsed, _windowSize;
Common::String _headers;
Common::String _buffer;
- Common::String _currentFieldName;
+ ///Common::String _headers;
+ Common::String _method, _path, _query, _anchor;
Common::HashMap<Common::String, Common::String> _fields;
Common::HashMap<Common::String, Common::String> _attachedFiles;
-
- byte *_window;
- uint32 _windowUsed, _windowSize;
+ uint32 _contentLength;
+ Common::String _boundary;
+ uint32 _availableBytes;
+ Common::String _currentFieldName;
+ bool _isBadRequest;
bool readHeaders(); //true when ended reading
bool readContent(); //true when ended reading
@@ -63,6 +63,9 @@ class Reader {
void handleFileContent(Common::String filename);
void handleValueContent(Common::String value);
+ void parseFirstLine(const Common::String &headers);
+ void parsePathQueryAndAnchor(Common::String path);
+
void makeWindow(uint32 size);
void freeWindow();
///bool Reader::readOneByteInStream(stream);
@@ -76,7 +79,13 @@ public:
~Reader();
bool readResponse(); //true when ended reading
- void setBytesLeft(uint32 b);
+ void setContent(byte *buffer, uint32 size);
+ bool badRequest();
+
+ Common::String method() const;
+ Common::String path() const;
+ Common::String query() const;
+ Common::String anchor() const;
};
} // End of namespace Networking