NETWORKING: Enter Session

Session allows to reuse SessionRequests to the same host by making them
keeping alive connection. Turns out, though, that libcurl already does
that for us, and we didn't gain any speedup we thought we'd get.

Usage:
```
Networking::Session s;
Networking::SessionRequest *request = s.get(url);
request->startAndWait();
warning("HTTP GET: %s", request->text());
s.close();
```

You can still use SessionRequest without Session (but you can't put them
on stack!):
```
Networking::SessionRequest *request = new
Networking::SessionRequest(url);
request->startAndWait();
warning("HTTP GET: %s", request->text());
request->close();
```
This commit is contained in:
Alexander Tkachev 2019-11-03 02:16:00 +07:00 committed by Eugene Sandulenko
parent f7d9156967
commit 99e21f4320
8 changed files with 302 additions and 80 deletions

View file

@ -34,12 +34,32 @@ namespace Networking {
SessionRequest::SessionRequest(Common::String url, DataCallback cb, ErrorCallback ecb):
CurlRequest(cb, ecb, url), _contentsStream(DisposeAfterUse::YES),
_buffer(new byte[CURL_SESSION_REQUEST_BUFFER_SIZE]), _text(nullptr),
_started(false), _complete(false), _success(false) {}
_started(false), _complete(false), _success(false) {
// automatically go under ConnMan control so nobody would be able to leak the memory
// but, we don't need it to be working just yet
_state = PAUSED;
ConnMan.addRequest(this);
}
SessionRequest::~SessionRequest() {
delete[] _buffer;
}
bool SessionRequest::reuseStream() {
if (!_stream) {
return false;
}
if (_bytesBuffer)
return _stream->reuse(_url.c_str(), _headersList, _bytesBuffer, _bytesBufferSize, _uploading, _usingPatch, true);
if (!_formFields.empty() || !_formFiles.empty())
return _stream->reuse(_url.c_str(), _headersList, _formFields, _formFiles);
return _stream->reuse(_url.c_str(), _headersList, _postFields, _uploading, _usingPatch);
}
char *SessionRequest::getPreparedContents() {
//write one more byte in the end
byte zero[1] = {0};
@ -71,12 +91,29 @@ void SessionRequest::finishSuccess() {
}
void SessionRequest::start() {
if (_started) {
if (_state != PAUSED || _started) {
warning("Can't start() SessionRequest as it is already started");
} else {
_started = true;
ConnMan.addRequest(this);
return;
}
_state = PROCESSING;
_started = true;
}
void SessionRequest::startAndWait() {
start();
wait();
}
void SessionRequest::reuse(Common::String url, DataCallback cb, ErrorCallback ecb) {
_url = url;
delete _callback;
delete _errorCallback;
_callback = cb;
_errorCallback = ecb;
restart();
}
void SessionRequest::handle() {
@ -95,13 +132,23 @@ void SessionRequest::handle() {
}
void SessionRequest::restart() {
if (_stream)
delete _stream;
_stream = nullptr;
if (_stream) {
bool deleteStream = true;
if (_keepAlive && reuseStream()) {
deleteStream = false;
}
if (deleteStream) {
delete _stream;
_stream = nullptr;
}
}
_contentsStream = Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
_text = nullptr;
_complete = false;
_success = false;
_started = false;
//with no stream available next handle() will create another one
}
@ -109,11 +156,6 @@ void SessionRequest::close() {
_state = FINISHED;
}
void SessionRequest::startAndWait() {
start();
wait();
}
bool SessionRequest::complete() {
return _complete;
}