diff options
Diffstat (limited to 'backends/networking')
-rw-r--r-- | backends/networking/curl/curlrequest.cpp | 18 | ||||
-rw-r--r-- | backends/networking/curl/curlrequest.h | 6 | ||||
-rw-r--r-- | backends/networking/curl/networkreadstream.cpp | 123 | ||||
-rw-r--r-- | backends/networking/curl/networkreadstream.h | 33 | ||||
-rw-r--r-- | backends/networking/curl/session.cpp | 77 | ||||
-rw-r--r-- | backends/networking/curl/session.h | 45 | ||||
-rw-r--r-- | backends/networking/curl/sessionrequest.cpp | 68 | ||||
-rw-r--r-- | backends/networking/curl/sessionrequest.h | 12 |
8 files changed, 302 insertions, 80 deletions
diff --git a/backends/networking/curl/curlrequest.cpp b/backends/networking/curl/curlrequest.cpp index 887ba86c6e..a3c836b7c4 100644 --- a/backends/networking/curl/curlrequest.cpp +++ b/backends/networking/curl/curlrequest.cpp @@ -32,7 +32,7 @@ namespace Networking { CurlRequest::CurlRequest(DataCallback cb, ErrorCallback ecb, Common::String url): Request(cb, ecb), _url(url), _stream(nullptr), _headersList(nullptr), _bytesBuffer(nullptr), - _bytesBufferSize(0), _uploading(false), _usingPatch(false) {} + _bytesBufferSize(0), _uploading(false), _usingPatch(false), _keepAlive(false), _keepAliveIdle(120), _keepAliveInterval(60) {} CurlRequest::~CurlRequest() { delete _stream; @@ -41,10 +41,10 @@ CurlRequest::~CurlRequest() { NetworkReadStream *CurlRequest::makeStream() { if (_bytesBuffer) - return new NetworkReadStream(_url.c_str(), _headersList, _bytesBuffer, _bytesBufferSize, _uploading, _usingPatch, true); + return new NetworkReadStream(_url.c_str(), _headersList, _bytesBuffer, _bytesBufferSize, _uploading, _usingPatch, true, _keepAlive, _keepAliveIdle, _keepAliveInterval); if (!_formFields.empty() || !_formFiles.empty()) - return new NetworkReadStream(_url.c_str(), _headersList, _formFields, _formFiles); - return new NetworkReadStream(_url.c_str(), _headersList, _postFields, _uploading, _usingPatch); + return new NetworkReadStream(_url.c_str(), _headersList, _formFields, _formFiles, _keepAlive, _keepAliveIdle, _keepAliveInterval); + return new NetworkReadStream(_url.c_str(), _headersList, _postFields, _uploading, _usingPatch, _keepAlive, _keepAliveIdle, _keepAliveInterval); } void CurlRequest::handle() { @@ -137,6 +137,16 @@ void CurlRequest::usePut() { _uploading = true; } void CurlRequest::usePatch() { _usingPatch = true; } +void CurlRequest::connectionKeepAlive(long idle, long interval) { + _keepAlive = true; + _keepAliveIdle = idle; + _keepAliveInterval = interval; +} + +void CurlRequest::connectionClose() { + _keepAlive = false; +} + NetworkReadStreamResponse CurlRequest::execute() { if (!_stream) { _stream = makeStream(); diff --git a/backends/networking/curl/curlrequest.h b/backends/networking/curl/curlrequest.h index f8d71c4828..9bca05c771 100644 --- a/backends/networking/curl/curlrequest.h +++ b/backends/networking/curl/curlrequest.h @@ -50,6 +50,8 @@ protected: uint32 _bytesBufferSize; bool _uploading; //using PUT method bool _usingPatch; //using PATCH method + bool _keepAlive; + long _keepAliveIdle, _keepAliveInterval; virtual NetworkReadStream *makeStream(); @@ -85,6 +87,10 @@ public: /** Remembers to use PATCH method when it would create NetworkReadStream. */ virtual void usePatch(); + /** Remembers to use Connection: keep-alive or close. */ + virtual void connectionKeepAlive(long idle = 120, long interval = 60); + virtual void connectionClose(); + /** * Starts this Request with ConnMan. * @return its NetworkReadStream in NetworkReadStreamResponse. diff --git a/backends/networking/curl/networkreadstream.cpp b/backends/networking/curl/networkreadstream.cpp index b8f06b728f..06f4dc52a8 100644 --- a/backends/networking/curl/networkreadstream.cpp +++ b/backends/networking/curl/networkreadstream.cpp @@ -63,13 +63,18 @@ int NetworkReadStream::curlProgressCallbackOlder(void *p, double dltotal, double return curlProgressCallback(p, (curl_off_t)dltotal, (curl_off_t)dlnow, (curl_off_t)ultotal, (curl_off_t)ulnow); } -void NetworkReadStream::init(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading, bool usingPatch, bool post) { +void NetworkReadStream::resetStream() { _eos = _requestComplete = false; - _errorBuffer = (char *)calloc(CURL_ERROR_SIZE, 1); + if (!_errorBuffer) + _errorBuffer = (char *)calloc(CURL_ERROR_SIZE, 1); _sendingContentsBuffer = nullptr; _sendingContentsSize = _sendingContentsPos = 0; _progressDownloaded = _progressTotal = 0; _bufferCopy = nullptr; +} + +void NetworkReadStream::initCurl(const char *url, curl_slist *headersList) { + resetStream(); _easy = curl_easy_init(); curl_easy_setopt(_easy, CURLOPT_WRITEFUNCTION, curlDataCallback); @@ -102,6 +107,30 @@ void NetworkReadStream::init(const char *url, curl_slist *headersList, const byt curl_easy_setopt(_easy, CURLOPT_XFERINFOFUNCTION, curlProgressCallback); curl_easy_setopt(_easy, CURLOPT_XFERINFODATA, this); #endif + + if (_keepAlive) { + curl_easy_setopt(_easy, CURLOPT_TCP_KEEPALIVE, 1L); + curl_easy_setopt(_easy, CURLOPT_TCP_KEEPIDLE, _keepAliveIdle); + curl_easy_setopt(_easy, CURLOPT_TCP_KEEPINTVL, _keepAliveInterval); + } +} + +bool NetworkReadStream::reuseCurl(const char *url, curl_slist *headersList) { + if (!_keepAlive) { + warning("NetworkReadStream: Can't reuse curl handle (was not setup as keep-alive)"); + return false; + } + + resetStream(); + + curl_easy_setopt(_easy, CURLOPT_URL, url); + curl_easy_setopt(_easy, CURLOPT_HTTPHEADER, headersList); + curl_easy_setopt(_easy, CURLOPT_USERAGENT, gScummVMFullVersion); // in case headersList rewrites it + + return true; +} + +void NetworkReadStream::setupBufferContents(const byte *buffer, uint32 bufferSize, bool uploading, bool usingPatch, bool post) { if (uploading) { curl_easy_setopt(_easy, CURLOPT_UPLOAD, 1L); curl_easy_setopt(_easy, CURLOPT_READDATA, this); @@ -126,46 +155,7 @@ void NetworkReadStream::init(const char *url, curl_slist *headersList, const byt ConnMan.registerEasyHandle(_easy); } -void NetworkReadStream::init(const char *url, curl_slist *headersList, Common::HashMap<Common::String, Common::String> formFields, Common::HashMap<Common::String, Common::String> formFiles) { - _eos = _requestComplete = false; - _errorBuffer = (char *)calloc(CURL_ERROR_SIZE, 1); - _sendingContentsBuffer = nullptr; - _sendingContentsSize = _sendingContentsPos = 0; - _progressDownloaded = _progressTotal = 0; - _bufferCopy = nullptr; - - _easy = curl_easy_init(); - curl_easy_setopt(_easy, CURLOPT_WRITEFUNCTION, curlDataCallback); - curl_easy_setopt(_easy, CURLOPT_WRITEDATA, this); //so callback can call us - curl_easy_setopt(_easy, CURLOPT_PRIVATE, this); //so ConnectionManager can call us when request is complete - curl_easy_setopt(_easy, CURLOPT_HEADER, 0L); - curl_easy_setopt(_easy, CURLOPT_HEADERDATA, this); - curl_easy_setopt(_easy, CURLOPT_HEADERFUNCTION, curlHeadersCallback); - curl_easy_setopt(_easy, CURLOPT_URL, url); - curl_easy_setopt(_easy, CURLOPT_ERRORBUFFER, _errorBuffer); - curl_easy_setopt(_easy, CURLOPT_VERBOSE, 0L); - curl_easy_setopt(_easy, CURLOPT_FOLLOWLOCATION, 1L); //probably it's OK to have it always on - curl_easy_setopt(_easy, CURLOPT_HTTPHEADER, headersList); - curl_easy_setopt(_easy, CURLOPT_USERAGENT, gScummVMFullVersion); - curl_easy_setopt(_easy, CURLOPT_NOPROGRESS, 0L); - curl_easy_setopt(_easy, CURLOPT_PROGRESSFUNCTION, curlProgressCallbackOlder); - curl_easy_setopt(_easy, CURLOPT_PROGRESSDATA, this); -#if defined NINTENDO_SWITCH || defined ANDROID_PLAIN_PORT - curl_easy_setopt(_easy, CURLOPT_SSL_VERIFYPEER, 0); -#endif - - const char *caCertPath = ConnMan.getCaCertPath(); - if (caCertPath) { - curl_easy_setopt(_easy, CURLOPT_CAINFO, caCertPath); - } - -#if LIBCURL_VERSION_NUM >= 0x072000 - // CURLOPT_XFERINFOFUNCTION introduced in libcurl 7.32.0 - // CURLOPT_PROGRESSFUNCTION is used as a backup plan in case older version is used - curl_easy_setopt(_easy, CURLOPT_XFERINFOFUNCTION, curlProgressCallback); - curl_easy_setopt(_easy, CURLOPT_XFERINFODATA, this); -#endif - +void NetworkReadStream::setupFormMultipart(Common::HashMap<Common::String, Common::String> formFields, Common::HashMap<Common::String, Common::String> formFiles) { // set POST multipart upload form fields/files struct curl_httppost *formpost = nullptr; struct curl_httppost *lastptr = nullptr; @@ -197,23 +187,52 @@ void NetworkReadStream::init(const char *url, curl_slist *headersList, Common::H } curl_easy_setopt(_easy, CURLOPT_HTTPPOST, formpost); - ConnMan.registerEasyHandle(_easy); } -NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, Common::String postFields, bool uploading, bool usingPatch) : - _backingStream(DisposeAfterUse::YES) { - init(url, headersList, (const byte *)postFields.c_str(), postFields.size(), uploading, usingPatch, false); +NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, Common::String postFields, bool uploading, bool usingPatch, bool keepAlive, long keepAliveIdle, long keepAliveInterval): + _backingStream(DisposeAfterUse::YES), _keepAlive(keepAlive), _keepAliveIdle(keepAliveIdle), _keepAliveInterval(keepAliveInterval), _errorBuffer(nullptr) { + initCurl(url, headersList); + setupBufferContents((const byte *)postFields.c_str(), postFields.size(), uploading, usingPatch, false); +} + +NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, Common::HashMap<Common::String, Common::String> formFields, Common::HashMap<Common::String, Common::String> formFiles, bool keepAlive, long keepAliveIdle, long keepAliveInterval): + _backingStream(DisposeAfterUse::YES), _keepAlive(keepAlive), _keepAliveIdle(keepAliveIdle), _keepAliveInterval(keepAliveInterval), _errorBuffer(nullptr) { + initCurl(url, headersList); + setupFormMultipart(formFields, formFiles); } -NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, Common::HashMap<Common::String, Common::String> formFields, Common::HashMap<Common::String, Common::String> formFiles) : - _backingStream(DisposeAfterUse::YES) { - init(url, headersList, formFields, formFiles); +NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading, bool usingPatch, bool post, bool keepAlive, long keepAliveIdle, long keepAliveInterval): + _backingStream(DisposeAfterUse::YES), _keepAlive(keepAlive), _keepAliveIdle(keepAliveIdle), _keepAliveInterval(keepAliveInterval), _errorBuffer(nullptr) { + initCurl(url, headersList); + setupBufferContents(buffer, bufferSize, uploading, usingPatch, post); } -NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading, bool usingPatch, bool post) : - _backingStream(DisposeAfterUse::YES) { - init(url, headersList, buffer, bufferSize, uploading, usingPatch, post); +bool NetworkReadStream::reuse(const char *url, curl_slist *headersList, Common::String postFields, bool uploading, bool usingPatch) { + if (!reuseCurl(url, headersList)) + return false; + + _backingStream = Common::MemoryReadWriteStream(DisposeAfterUse::YES); + setupBufferContents((const byte *)postFields.c_str(), postFields.size(), uploading, usingPatch, false); + return true; +} + +bool NetworkReadStream::reuse(const char *url, curl_slist *headersList, Common::HashMap<Common::String, Common::String> formFields, Common::HashMap<Common::String, Common::String> formFiles) { + if (!reuseCurl(url, headersList)) + return false; + + _backingStream = Common::MemoryReadWriteStream(DisposeAfterUse::YES); + setupFormMultipart(formFields, formFiles); + return true; +} + +bool NetworkReadStream::reuse(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading, bool usingPatch, bool post) { + if (!reuseCurl(url, headersList)) + return false; + + _backingStream = Common::MemoryReadWriteStream(DisposeAfterUse::YES); + setupBufferContents(buffer, bufferSize, uploading, usingPatch, post); + return true; } NetworkReadStream::~NetworkReadStream() { diff --git a/backends/networking/curl/networkreadstream.h b/backends/networking/curl/networkreadstream.h index 468fce70a4..f8a49ea18f 100644 --- a/backends/networking/curl/networkreadstream.h +++ b/backends/networking/curl/networkreadstream.h @@ -37,16 +37,22 @@ namespace Networking { class NetworkReadStream: public Common::ReadStream { CURL *_easy; Common::MemoryReadWriteStream _backingStream; + bool _keepAlive; + long _keepAliveIdle, _keepAliveInterval; bool _eos, _requestComplete; char *_errorBuffer; const byte *_sendingContentsBuffer; uint32 _sendingContentsSize; uint32 _sendingContentsPos; - byte* _bufferCopy; // To use with old curl version where CURLOPT_COPYPOSTFIELDS is not available + byte *_bufferCopy; // To use with old curl version where CURLOPT_COPYPOSTFIELDS is not available Common::String _responseHeaders; uint64 _progressDownloaded, _progressTotal; - void init(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading, bool usingPatch, bool post); - void init(const char *url, curl_slist *headersList, Common::HashMap<Common::String, Common::String> formFields, Common::HashMap<Common::String, Common::String> formFiles); + + void resetStream(); + void initCurl(const char *url, curl_slist *headersList); + bool reuseCurl(const char *url, curl_slist *headersList); + void setupBufferContents(const byte *buffer, uint32 bufferSize, bool uploading, bool usingPatch, bool post); + void setupFormMultipart(Common::HashMap<Common::String, Common::String> formFields, Common::HashMap<Common::String, Common::String> formFiles); /** * Fills the passed buffer with _sendingContentsBuffer contents. @@ -70,16 +76,27 @@ class NetworkReadStream: public Common::ReadStream { static int curlProgressCallbackOlder(void *p, double dltotal, double dlnow, double ultotal, double ulnow); public: /** Send <postFields>, using POST by default. */ - NetworkReadStream(const char *url, curl_slist *headersList, Common::String postFields, bool uploading = false, bool usingPatch = false); + NetworkReadStream(const char *url, curl_slist *headersList, Common::String postFields, bool uploading = false, bool usingPatch = false, bool keepAlive = false, long keepAliveIdle = 120, long keepAliveInterval = 60); /** Send <formFields>, <formFiles>, using POST multipart/form. */ NetworkReadStream( const char *url, curl_slist *headersList, Common::HashMap<Common::String, Common::String> formFields, - Common::HashMap<Common::String, Common::String> formFiles); - /** Send <buffer, using POST by default. */ - NetworkReadStream(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading = false, bool usingPatch = false, bool post = true); + Common::HashMap<Common::String, Common::String> formFiles, + bool keepAlive = false, long keepAliveIdle = 120, long keepAliveInterval = 60); + /** Send <buffer>, using POST by default. */ + NetworkReadStream(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading = false, bool usingPatch = false, bool post = true, bool keepAlive = false, long keepAliveIdle = 120, long keepAliveInterval = 60); virtual ~NetworkReadStream(); + /** Send <postFields>, using POST by default. */ + bool reuse(const char *url, curl_slist *headersList, Common::String postFields, bool uploading = false, bool usingPatch = false); + /** Send <formFields>, <formFiles>, using POST multipart/form. */ + bool reuse( + const char *url, curl_slist *headersList, + Common::HashMap<Common::String, Common::String> formFields, + Common::HashMap<Common::String, Common::String> formFiles); + /** Send <buffer>, using POST by default. */ + bool reuse(const char *url, curl_slist *headersList, const byte *buffer, uint32 bufferSize, bool uploading = false, bool usingPatch = false, bool post = true); + /** * Returns true if a read failed because the stream end has been reached. * This flag is cleared by clearErr(). @@ -150,6 +167,8 @@ public: /** Used in curl progress callback to pass current downloaded/total values. */ void setProgress(uint64 downloaded, uint64 total); + + bool keepAlive() const { return _keepAlive; } }; } // End of namespace Networking diff --git a/backends/networking/curl/session.cpp b/backends/networking/curl/session.cpp new file mode 100644 index 0000000000..260f6d85c8 --- /dev/null +++ b/backends/networking/curl/session.cpp @@ -0,0 +1,77 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "backends/networking/curl/session.h" + +namespace Networking { + +Session::Session(Common::String prefix): + _prefix(prefix), _request(nullptr) {} + +Session::~Session() { + close(); +} + +SessionRequest *Session::get(Common::String url, DataCallback cb, ErrorCallback ecb) { + // check url prefix + if (!_prefix.empty()) { + if (url.contains("://")) { + if (url.size() < _prefix.size() || url.find(_prefix) != 0) { + warning("Session: given URL does not match the prefix!\n\t%s\n\t%s", url.c_str(), _prefix.c_str()); + return nullptr; + } + } else { + // if no schema given, just append <url> to <_prefix> + Common::String newUrl = _prefix; + if (newUrl.lastChar() != '/' && (url.size() > 0 && url.firstChar() != '/')) + newUrl += "/"; + newUrl += url; + url = newUrl; + } + } + + // check if request has finished (ready to be replaced) + if (_request) { + if (!_request->complete()) { + warning("Session: can't reuse Request that is being processed"); + return nullptr; + } + } + + if (!_request) { + _request = new Networking::SessionRequest(url, cb, ecb); // automatically added to ConnMan + _request->connectionKeepAlive(); + } else { + _request->reuse(url, cb, ecb); + } + + return _request; +} + +void Session::close() { + if (_request) + _request->close(); +} + +} // End of namespace Networking diff --git a/backends/networking/curl/session.h b/backends/networking/curl/session.h new file mode 100644 index 0000000000..d3aa5807a7 --- /dev/null +++ b/backends/networking/curl/session.h @@ -0,0 +1,45 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BACKENDS_NETWORKING_CURL_SESSION_H +#define BACKENDS_NETWORKING_CURL_SESSION_H + +#include "backends/networking/curl/sessionrequest.h" + +namespace Networking { + +class Session { +protected: + Common::String _prefix; + SessionRequest *_request; + +public: + Session(Common::String prefix = ""); + ~Session(); + + SessionRequest *get(Common::String url, DataCallback cb = nullptr, ErrorCallback ecb = nullptr); + void close(); +}; + +} // End of namespace Networking + +#endif diff --git a/backends/networking/curl/sessionrequest.cpp b/backends/networking/curl/sessionrequest.cpp index 5fe0e64aa1..42afd6387b 100644 --- a/backends/networking/curl/sessionrequest.cpp +++ b/backends/networking/curl/sessionrequest.cpp @@ -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; } diff --git a/backends/networking/curl/sessionrequest.h b/backends/networking/curl/sessionrequest.h index 590eee4a5a..fd2757fcd2 100644 --- a/backends/networking/curl/sessionrequest.h +++ b/backends/networking/curl/sessionrequest.h @@ -38,6 +38,8 @@ protected: char *_text; bool _started, _complete, _success; + bool reuseStream(); + /** Prepares raw bytes from _contentsStream. */ char *getPreparedContents(); @@ -48,14 +50,16 @@ public: SessionRequest(Common::String url, DataCallback cb = nullptr, ErrorCallback ecb = nullptr); virtual ~SessionRequest(); - virtual void start(); + void start(); + void startAndWait(); + + void reuse(Common::String url, DataCallback cb = nullptr, ErrorCallback ecb = nullptr); + virtual void handle(); virtual void restart(); /** This request DOES NOT delete automatically after calling callbacks. It gets PAUSED, and in order to make it FINISHED (i.e. delete), this method MUST be called. */ - virtual void close(); - - void startAndWait(); + void close(); bool complete(); bool success(); |