aboutsummaryrefslogtreecommitdiff
path: root/backends/networking/sdl_net/reader.cpp
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/reader.cpp
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/reader.cpp')
-rw-r--r--backends/networking/sdl_net/reader.cpp119
1 files changed, 91 insertions, 28 deletions
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