diff options
author | Alexander Tkachev | 2016-06-16 14:19:18 +0600 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | 3946f23d172f55411748171af9822d2be3863701 (patch) | |
tree | cc4eba5d489c153b5d364f9c82ff34d225a82109 /backends/networking/sdl_net/client.cpp | |
parent | ceb86a0dd8421047fc3d067da2a4c7faccc2f782 (diff) | |
download | scummvm-rg350-3946f23d172f55411748171af9822d2be3863701.tar.gz scummvm-rg350-3946f23d172f55411748171af9822d2be3863701.tar.bz2 scummvm-rg350-3946f23d172f55411748171af9822d2be3863701.zip |
CLOUD: Prepare code for path handlers
LocalWebserver would storage the handlers.
Client now has methods like path() or query() to access different parts
of the request.
Diffstat (limited to 'backends/networking/sdl_net/client.cpp')
-rw-r--r-- | backends/networking/sdl_net/client.cpp | 79 |
1 files changed, 67 insertions, 12 deletions
diff --git a/backends/networking/sdl_net/client.cpp b/backends/networking/sdl_net/client.cpp index 0e86610e54..60f6be2adc 100644 --- a/backends/networking/sdl_net/client.cpp +++ b/backends/networking/sdl_net/client.cpp @@ -28,9 +28,9 @@ namespace Networking { -Client::Client(): _state(INVALID), _set(nullptr), _socket(nullptr), _handler(nullptr) {} +Client::Client() : _state(INVALID), _set(nullptr), _socket(nullptr), _handler(nullptr) {} -Client::Client(SDLNet_SocketSet set, TCPsocket socket): _state(INVALID), _set(nullptr), _socket(nullptr), _handler(nullptr) { +Client::Client(SDLNet_SocketSet set, TCPsocket socket) : _state(INVALID), _set(nullptr), _socket(nullptr), _handler(nullptr) { open(set, socket); } @@ -38,7 +38,7 @@ Client::~Client() { close(); } -void Client::open(SDLNet_SocketSet set, TCPsocket socket) { +void Client::open(SDLNet_SocketSet set, TCPsocket socket) { if (_state != INVALID) close(); _state = READING_HEADERS; _socket = socket; @@ -56,14 +56,14 @@ void Client::readHeaders() { if (!SDLNet_SocketReady(_socket)) return; const uint32 BUFFER_SIZE = 16 * 1024; - char buffer[BUFFER_SIZE]; - int bytes = SDLNet_TCP_Recv(_socket, buffer, BUFFER_SIZE); + char buffer[BUFFER_SIZE]; + int bytes = SDLNet_TCP_Recv(_socket, buffer, BUFFER_SIZE); if (bytes <= 0) { - warning("Client::readHeaders recv fail"); + warning("Client::readHeaders recv fail"); close(); return; } - _headers += Common::String(buffer, bytes); + _headers += Common::String(buffer, bytes); checkIfHeadersEnded(); checkIfBadRequest(); } @@ -74,7 +74,7 @@ void Client::checkIfHeadersEnded() { if (position) _state = READ_HEADERS; } -void Client::checkIfBadRequest() { +void Client::checkIfBadRequest() { uint32 headersSize = _headers.size(); bool bad = false; @@ -92,7 +92,7 @@ void Client::checkIfBadRequest() { 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 (_headers[i] == ' ' || i == headersSize - 1) { if (method == "") method = buf; else if (path == "") path = buf; else if (http == "") http = buf; @@ -109,11 +109,35 @@ void Client::checkIfBadRequest() { //check that HTTP/<VERSION> is OK if (!http.hasPrefix("HTTP/")) bad = true; + + _method = method; + parsePathQueryAndAnchor(path); } } } - if (bad) _state = BAD_REQUEST; + 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) { @@ -147,9 +171,40 @@ void Client::close() { } -ClientState Client::state() { return _state; } +ClientState Client::state() const { return _state; } + +Common::String Client::headers() const { return _headers; } + +Common::String Client::method() const { return _method; } + +Common::String Client::path() const { return _path; } + +Common::String Client::query() const { return _query; } + +Common::String Client::queryParameter(Common::String name) const { + // this approach is a bit slower than searching for the <name> + // yet I believe it to be the right one, because we probably can have "<name>=" in the value of other key + Common::String key = ""; + Common::String value = ""; + bool readingKey = true; + for (uint32 i = 0; i < _query.size(); ++i) { + if (readingKey) { + if (_query[i] == '=') { + readingKey = false; + value = ""; + } else key += _query[i]; + } else { + if (_query[i] == '&') { + if (key == name) return value; + readingKey = true; + key = ""; + } else value += _query[i]; + } + } + return ""; +} -Common::String Client::headers() { return _headers; } +Common::String Client::anchor() const { return _anchor; } bool Client::socketIsReady() { return SDLNet_SocketReady(_socket); } |