| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- #include "MyHttp.h"
- //#include "net/downloader.h"
- //#include "shared.h"
- //#include "utils/debug_tools.h"
- //#include "utils/net_utils.h"
- #define NETWORK_AVAILABLE() OX_ASSERT(s3eSocketGetInt(S3E_SOCKET_NETWORK_AVAILABLE) == 1)
- using namespace std;
- using namespace oxygine;
- const int httpTimeout = 20000;
- const int bufSize = 1024 * 64;
- MyHttp::MyHttp() : _http(0), _status(status_none), _handle(0), _method(GETFILE)
- {
- }
- MyHttp::~MyHttp()
- {
- destroy();
- }
- void MyHttp::destroy()
- {
- if (_http)
- _http->Cancel();
- delete _http;
- _http = 0;
- if (_handle)
- file::close(_handle);
- _handle = 0;
- _status = status_none;
- _data.clear();
- _tempBuffer.clear();
- }
- unsigned int MyHttp::getTotalSize() const
- {
- return _http->ContentLength();
- }
- unsigned int MyHttp::getReceivedSize() const
- {
- return _http->ContentReceived();
- }
- int MyHttp::_delayedError(void* systemData, void* userData)
- {
- MyHttp* http = (MyHttp*)userData;
- http->onError();
- return 0;
- }
- void MyHttp::getFile(const string& url, const string& name)
- {
- destroy();
- _method = GETFILE;
- _url = url;
- log::messageln("getfile:");
- puts(url.c_str());
- _status = status_inprogress;
- _http = new CIwHTTP;
- if (!name.empty())
- _handle = file::open(name.c_str(), "wb");
- _http->Get(url.c_str(), _gotHeaders, this);
- }
- void MyHttp::get(const string& url)
- {
- destroy();
- _method = GET;
- _url = url;
- log::messageln("post: %s", url.c_str());
- _status = status_inprogress;
- _http = new CIwHTTP;
- //_http->SetRequestHeader("Content-type", "application/x-www-form-urlencoded");
- if (!isNetworkAvailable())
- {
- //it is too dangerous call onError from there
- //do it at next update
- #ifdef __S3E__
- s3eThreadEnqueueCallback(s3eThreadGetCurrent(), _delayedError, this);
- #endif
- return;
- }
- _http->Get(url.c_str(), _gotHeaders, this);
- }
- void MyHttp::post(const string& url, const char* data, int size)
- {
- destroy();
- _post = data;
- _postSize = size;
- _method = POST;
- _url = url;
- log::messageln("post: %s", url.c_str());
- _status = status_inprogress;
- _http = new CIwHTTP;
- _http->SetRequestHeader("Content-type", "application/x-www-form-urlencoded");
- if (!isNetworkAvailable())
- {
- //it is too dangerous call onError from there
- //do it at next update
- #ifdef __S3E__
- s3eThreadEnqueueCallback(s3eThreadGetCurrent(), _delayedError, this);
- #endif
- return;
- }
- _http->Post(url.c_str(), data, size, _gotHeaders, this);
- }
- int MyHttp::getResponseCode() const
- {
- return _http->GetResponseCode();
- }
- void MyHttp::gotHeaders()
- {
- //log::messageln("gotHeaders");
- if (_http->GetStatus() == S3E_RESULT_ERROR)
- {
- onError();
- }
- else
- {
- if (_cbProgress)
- _cbProgress(this, 0);
- int resp = _http->GetResponseCode();
- if (resp != 200)
- {
- if (resp == 302)
- {
- string res;
- _http->GetHeader("Location", res);
- if (!res.empty())
- {
- switch (_method)
- {
- case MyHttp::GETFILE:
- get(res);
- break;
- case MyHttp::GET:
- getFile(res, "");
- break;
- case MyHttp::POST:
- post(res, _post, _postSize);
- break;
- default:
- break;
- }
- getFile(res, "");
- return;
- }
- }
- _status = status_error;
- if (_cbError)
- _cbError(this);
- return;
- }
- int len = _http->ContentExpected();
- if (!len)
- len = 1024;
- if (!_handle)
- _data.reserve(len);
- len = min(bufSize, len);
- _tempBuffer.resize(len);
- _http->ReadDataAsync((char*)&_tempBuffer.front(), len, httpTimeout, _gotData, this);
- }
- }
- void MyHttp::progress(int size)
- {
- if (_cbProgress)
- _cbProgress(this, size);
- if (_handle)
- file::write(_handle, &_tempBuffer.front(), size);
- else
- _data.insert(_data.end(), _tempBuffer.begin(), _tempBuffer.begin() + size);
- int rec = _http->ContentReceived();
- /*
- int32 v = 0;
- _http->GetHeader("Content-Length", v);
- string r;
- _http->GetHeader("Content-Range", r);
- */
- int ln = _http->ContentLength();
- if (!ln)
- {
- //something is wrong
- ln = rec + _http->ContentExpected();
- }
- //if (rec != ln)
- if (!_http->ContentFinished())
- {
- int len = ln - rec;
- len = min(bufSize, len);
- _tempBuffer.resize(len);
- _http->ReadDataAsync((char*)&_tempBuffer.front(), len, httpTimeout, _gotData, this);
- return;
- }
- if (_handle)
- file::close(_handle);
- _handle = 0;
- _status = status_done;
- if (_cbDone)
- _cbDone(this);
- }
- void MyHttp::onError()
- {
- log::messageln("http error: %s", _url.c_str());
- if (_handle)
- file::close(_handle);
- _handle = 0;
- _status = status_error;
- if (_cbError)
- _cbError(this);
- }
- void MyHttp::gotData(int size)
- {
- progress(size);
- }
- int MyHttp::_gotData(void* systemData, void* userData)
- {
- MyHttp* http = (MyHttp*)userData;
- http->gotData((size_t)systemData);
- return 0;
- }
- int MyHttp::_gotHeaders(void* systemData, void* userData)
- {
- MyHttp* http = (MyHttp*)userData;
- http->gotHeaders();
- return 0;
- }
- class SingleHttpAsyncRequest: public Object
- {
- public:
- void get(const char* url)
- {
- _http.getFile(url, "");
- _http._cbDone = CLOSURE(this, &SingleHttpAsyncRequest::_delete);
- _http._cbError = CLOSURE(this, &SingleHttpAsyncRequest::_delete);
- }
- void post(const char* url, const char* data, int size)
- {
- _http.post(url, data, size);
- _http._cbDone = CLOSURE(this, &SingleHttpAsyncRequest::_delete);
- _http._cbError = CLOSURE(this, &SingleHttpAsyncRequest::_delete);
- }
- void _delete(MyHttp*)
- {
- delete this;
- }
- MyHttp _http;
- };
- void makeSingleHttpAsyncGetRequest(const char* url)
- {
- if (!isNetworkAvailable())
- return;
- SingleHttpAsyncRequest* r = new SingleHttpAsyncRequest;
- r->get(url);
- }
- void makeSingleHttpAsyncPostRequest(const char* url, const char* data, int size)
- {
- if (!isNetworkAvailable())
- return;
- SingleHttpAsyncRequest* r = new SingleHttpAsyncRequest;
- r->post(url, data, size);
- }
|