aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorAlexander Tkachev2016-06-15 21:59:03 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commit99c51380fdc866ce393c52eb41803a9ec119a9ad (patch)
tree83511132a8a8a75cd75ca9d9a078aa4ca091ae55 /backends
parent6126435b64442ae838953e095191230737391dca (diff)
downloadscummvm-rg350-99c51380fdc866ce393c52eb41803a9ec119a9ad.tar.gz
scummvm-rg350-99c51380fdc866ce393c52eb41803a9ec119a9ad.tar.bz2
scummvm-rg350-99c51380fdc866ce393c52eb41803a9ec119a9ad.zip
CLOUD: Add ClientState::BAD_REQUEST
Diffstat (limited to 'backends')
-rw-r--r--backends/networking/sdl_net/client.cpp45
-rw-r--r--backends/networking/sdl_net/client.h4
-rw-r--r--backends/networking/sdl_net/localwebserver.cpp4
3 files changed, 50 insertions, 3 deletions
diff --git a/backends/networking/sdl_net/client.cpp b/backends/networking/sdl_net/client.cpp
index 2af940c232..8ab9ed385e 100644
--- a/backends/networking/sdl_net/client.cpp
+++ b/backends/networking/sdl_net/client.cpp
@@ -60,11 +60,12 @@ void Client::readHeaders() {
int bytes = SDLNet_TCP_Recv(_socket, buffer, BUFFER_SIZE);
if (bytes <= 0) {
warning("Client::readHeaders recv fail");
- _state = INVALID;
+ close();
return;
- }
+ }
_headers += Common::String(buffer, bytes);
checkIfHeadersEnded();
+ checkIfBadRequest();
}
void Client::checkIfHeadersEnded() {
@@ -73,6 +74,46 @@ void Client::checkIfHeadersEnded() {
if (position) _state = READ_HEADERS;
}
+void Client::checkIfBadRequest() {
+ if (_state != READING_HEADERS) return;
+ 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;
+ for (uint32 i = 0; i < headersSize; ++i) {
+ if (_headers[i] == ' ') {
+ if (method == "") method = buf;
+ else if (path == "") path = buf;
+ else if (http == "") http = buf;
+ else {
+ bad = true;
+ break;
+ }
+ buf = "";
+ } else buf += _headers[i];
+ }
+
+ //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;
+ }
+ }
+ }
+
+ if (bad) _state = BAD_REQUEST;
+}
+
void Client::close() {
if (_set) {
if (_socket) {
diff --git a/backends/networking/sdl_net/client.h b/backends/networking/sdl_net/client.h
index 74c700e447..7f78947223 100644
--- a/backends/networking/sdl_net/client.h
+++ b/backends/networking/sdl_net/client.h
@@ -34,7 +34,8 @@ namespace Networking {
enum ClientState {
INVALID,
READING_HEADERS,
- READ_HEADERS
+ READ_HEADERS,
+ BAD_REQUEST
};
class Client {
@@ -44,6 +45,7 @@ class Client {
Common::String _headers;
void checkIfHeadersEnded();
+ void checkIfBadRequest();
public:
Client();
diff --git a/backends/networking/sdl_net/localwebserver.cpp b/backends/networking/sdl_net/localwebserver.cpp
index 783814de14..ee67f787c3 100644
--- a/backends/networking/sdl_net/localwebserver.cpp
+++ b/backends/networking/sdl_net/localwebserver.cpp
@@ -128,6 +128,10 @@ void LocalWebserver::handleClient(uint32 i) {
warning("headers %s", _client[i].headers().c_str());
_client[i].close();
break;
+ case BAD_REQUEST:
+ //TODO: answer with BAD REQUEST
+ _client[i].close();
+ break;
}
}