| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- #include "HttpRequestTask.h"
- #include "core/file.h"
- #include "core/oxygine.h"
- #include "utils/stringUtils.h"
- namespace oxygine
- {
- HttpRequestTask* createNullHttpTask()
- {
- return 0;
- }
- HttpRequestTask::createHttpRequestCallback _createRequestsCallback = createNullHttpTask;
- spHttpRequestTask HttpRequestTask::create()
- {
- return _createRequestsCallback();
- }
- #if OX_NO_HTTP
- void HttpRequestTask::init() {}
- void HttpRequestTask::release() {}
- #endif
- static HttpRequestTask::responseCodeChecker _defaultCheckerAny = [](int code)
- {
- return true;
- };
- static HttpRequestTask::responseCodeChecker _defaultChecker200 = [](int code)
- {
- return code == 200 || code == 206;
- };
- HttpRequestTask::HttpRequestTask() :
- _cacheEnabled(true),
- _continueDownload(false),
- _expectedContentSize(0),
- _receivedContentSize(0),
- _fhandle(0),
- _suitableResponse(false),
- _responseCodeChecker(_defaultChecker200)
- {
- setName("HttpRequestTask");
- _mainThreadSync = true;
- }
- HttpRequestTask::~HttpRequestTask()
- {
- if (_fhandle)
- file::close(_fhandle);
- }
- void HttpRequestTask::setCustomRequests(createHttpRequestCallback cb)
- {
- _createRequestsCallback = cb;
- }
- void HttpRequestTask::setPostData(const std::vector<unsigned char>& data)
- {
- _postData = data;
- _setPostData(data);
- }
- void HttpRequestTask::setUrl(const std::string& url)
- {
- _url = url;
- _setUrl(url);
- }
- void HttpRequestTask::setFileName(const std::string& name, bool continueDownload)
- {
- _continueDownload = continueDownload;
- _fname = name;
- _setFileName(name);
- }
- void HttpRequestTask::setCacheEnabled(bool enabled)
- {
- _cacheEnabled = enabled;
- _setCacheEnabled(enabled);
- }
- void HttpRequestTask::setSuccessOnAnyResponseCode(bool any)
- {
- _responseCodeChecker = any ? _defaultCheckerAny : _defaultChecker200;
- }
- void HttpRequestTask::addHeader(const std::string& key, const std::string& value)
- {
- OX_ASSERT(!key.empty());
- _headers.push_back(std::make_pair(key, value));
- _addHeader(key, value);
- }
- const std::vector<unsigned char>& HttpRequestTask::getPostData() const
- {
- return _postData;
- }
- const std::vector<unsigned char>& HttpRequestTask::getResponse() const
- {
- return _response;
- }
- void HttpRequestTask::getResponseSwap(std::vector<unsigned char>& r)
- {
- std::swap(r, _response);
- }
- const std::string& HttpRequestTask::getFileName() const
- {
- return _fname;
- }
- bool HttpRequestTask::_prerun()
- {
- _progressDeltaDelayed = 0;
- _progressDispatched = false;
- _suitableResponse = false;
- _receivedContentSize = 0;
- _expectedContentSize = 0;
- _responseCode = 0;
- _response.clear();
- _writeFileError = false;
- if (_fhandle)
- file::close(_fhandle);
- _fhandle = 0;
- if (!_fname.empty())
- {
- const char* mode = _continueDownload ? "ab" : "wb";
- _fhandle = file::open(_fname, mode);
- OX_ASSERT(_fhandle);
- if (!_fhandle)
- {
- return false;
- }
- if (_continueDownload)
- {
- file::seek(_fhandle, 0, SEEK_END);
- unsigned int size = file::tell(_fhandle);
- char str[255];
- safe_sprintf(str, "bytes=%d-", size);
- addHeader("Range", str);
- _receivedContentSize = size;
- }
- }
- return true;
- }
- void HttpRequestTask::dispatchProgress(size_t delta, size_t loaded, size_t total)
- {
- ProgressEvent event(delta, loaded, total);
- dispatchEvent(&event);
- }
- void HttpRequestTask::asyncProgress(size_t delta, size_t loaded, size_t total)
- {
- if (_progressDispatched && loaded != total)//dispatch progress only once per frame
- {
- _progressDeltaDelayed += delta;
- return;
- }
- _progressDispatched = true;
- sync([ = ]()
- {
- _progressDispatched = false;
- dispatchProgress(delta + _progressDeltaDelayed, loaded, total);
- _progressDeltaDelayed = 0;
- }, false);
- }
- void HttpRequestTask::_onError()
- {
- log::warning("http request error (%d): %s", _responseCode , _url.c_str());
- }
- void HttpRequestTask::_onComplete()
- {
- log::messageln("http request done (%d): %s", _responseCode, _url.c_str());
- }
- void HttpRequestTask::_dispatchComplete()
- {
- unsigned int id = _suitableResponse ? COMPLETE : ERROR;
- if (_writeFileError)
- id = ERROR;
- Event ev(id);
- dispatchEvent(&ev);
- }
- void HttpRequestTask::_finalize(bool error)
- {
- if (_fhandle)
- {
- file::close(_fhandle);
- _fhandle = 0;
- if (error && !_continueDownload)
- file::deleteFile(_fname);
- }
- _fhandle = 0;
- }
- void HttpRequestTask::gotHeaders()
- {
- _suitableResponse = _responseCodeChecker(_responseCode);
- if (_continueDownload)
- asyncProgress(_receivedContentSize, _receivedContentSize, _expectedContentSize);
- }
- void HttpRequestTask::write(const void* data, size_t size)
- {
- if (!_suitableResponse)
- return;
- if (_fhandle)
- {
- unsigned int written = file::write(_fhandle, data, (unsigned int)size);
- if (written != size)
- {
- log::messageln("WRITE FILE ERROR %d %d", written, size);
- _writeFileError = true;
- return;
- }
- }
- else
- {
- const char* p = (const char*)data;
- _response.insert(_response.end(), p, p + size);
- }
- _receivedContentSize += size;
- asyncProgress(size, _receivedContentSize, _expectedContentSize);
- }
- }
|