MyHttp.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. #include "MyHttp.h"
  2. //#include "net/downloader.h"
  3. //#include "shared.h"
  4. //#include "utils/debug_tools.h"
  5. //#include "utils/net_utils.h"
  6. #define NETWORK_AVAILABLE() OX_ASSERT(s3eSocketGetInt(S3E_SOCKET_NETWORK_AVAILABLE) == 1)
  7. using namespace std;
  8. using namespace oxygine;
  9. const int httpTimeout = 20000;
  10. const int bufSize = 1024 * 64;
  11. MyHttp::MyHttp() : _http(0), _status(status_none), _handle(0), _method(GETFILE)
  12. {
  13. }
  14. MyHttp::~MyHttp()
  15. {
  16. destroy();
  17. }
  18. void MyHttp::destroy()
  19. {
  20. if (_http)
  21. _http->Cancel();
  22. delete _http;
  23. _http = 0;
  24. if (_handle)
  25. file::close(_handle);
  26. _handle = 0;
  27. _status = status_none;
  28. _data.clear();
  29. _tempBuffer.clear();
  30. }
  31. unsigned int MyHttp::getTotalSize() const
  32. {
  33. return _http->ContentLength();
  34. }
  35. unsigned int MyHttp::getReceivedSize() const
  36. {
  37. return _http->ContentReceived();
  38. }
  39. int MyHttp::_delayedError(void* systemData, void* userData)
  40. {
  41. MyHttp* http = (MyHttp*)userData;
  42. http->onError();
  43. return 0;
  44. }
  45. void MyHttp::getFile(const string& url, const string& name)
  46. {
  47. destroy();
  48. _method = GETFILE;
  49. _url = url;
  50. log::messageln("getfile:");
  51. puts(url.c_str());
  52. _status = status_inprogress;
  53. _http = new CIwHTTP;
  54. if (!name.empty())
  55. _handle = file::open(name.c_str(), "wb");
  56. _http->Get(url.c_str(), _gotHeaders, this);
  57. }
  58. void MyHttp::get(const string& url)
  59. {
  60. destroy();
  61. _method = GET;
  62. _url = url;
  63. log::messageln("post: %s", url.c_str());
  64. _status = status_inprogress;
  65. _http = new CIwHTTP;
  66. //_http->SetRequestHeader("Content-type", "application/x-www-form-urlencoded");
  67. if (!isNetworkAvailable())
  68. {
  69. //it is too dangerous call onError from there
  70. //do it at next update
  71. #ifdef __S3E__
  72. s3eThreadEnqueueCallback(s3eThreadGetCurrent(), _delayedError, this);
  73. #endif
  74. return;
  75. }
  76. _http->Get(url.c_str(), _gotHeaders, this);
  77. }
  78. void MyHttp::post(const string& url, const char* data, int size)
  79. {
  80. destroy();
  81. _post = data;
  82. _postSize = size;
  83. _method = POST;
  84. _url = url;
  85. log::messageln("post: %s", url.c_str());
  86. _status = status_inprogress;
  87. _http = new CIwHTTP;
  88. _http->SetRequestHeader("Content-type", "application/x-www-form-urlencoded");
  89. if (!isNetworkAvailable())
  90. {
  91. //it is too dangerous call onError from there
  92. //do it at next update
  93. #ifdef __S3E__
  94. s3eThreadEnqueueCallback(s3eThreadGetCurrent(), _delayedError, this);
  95. #endif
  96. return;
  97. }
  98. _http->Post(url.c_str(), data, size, _gotHeaders, this);
  99. }
  100. int MyHttp::getResponseCode() const
  101. {
  102. return _http->GetResponseCode();
  103. }
  104. void MyHttp::gotHeaders()
  105. {
  106. //log::messageln("gotHeaders");
  107. if (_http->GetStatus() == S3E_RESULT_ERROR)
  108. {
  109. onError();
  110. }
  111. else
  112. {
  113. if (_cbProgress)
  114. _cbProgress(this, 0);
  115. int resp = _http->GetResponseCode();
  116. if (resp != 200)
  117. {
  118. if (resp == 302)
  119. {
  120. string res;
  121. _http->GetHeader("Location", res);
  122. if (!res.empty())
  123. {
  124. switch (_method)
  125. {
  126. case MyHttp::GETFILE:
  127. get(res);
  128. break;
  129. case MyHttp::GET:
  130. getFile(res, "");
  131. break;
  132. case MyHttp::POST:
  133. post(res, _post, _postSize);
  134. break;
  135. default:
  136. break;
  137. }
  138. getFile(res, "");
  139. return;
  140. }
  141. }
  142. _status = status_error;
  143. if (_cbError)
  144. _cbError(this);
  145. return;
  146. }
  147. int len = _http->ContentExpected();
  148. if (!len)
  149. len = 1024;
  150. if (!_handle)
  151. _data.reserve(len);
  152. len = min(bufSize, len);
  153. _tempBuffer.resize(len);
  154. _http->ReadDataAsync((char*)&_tempBuffer.front(), len, httpTimeout, _gotData, this);
  155. }
  156. }
  157. void MyHttp::progress(int size)
  158. {
  159. if (_cbProgress)
  160. _cbProgress(this, size);
  161. if (_handle)
  162. file::write(_handle, &_tempBuffer.front(), size);
  163. else
  164. _data.insert(_data.end(), _tempBuffer.begin(), _tempBuffer.begin() + size);
  165. int rec = _http->ContentReceived();
  166. /*
  167. int32 v = 0;
  168. _http->GetHeader("Content-Length", v);
  169. string r;
  170. _http->GetHeader("Content-Range", r);
  171. */
  172. int ln = _http->ContentLength();
  173. if (!ln)
  174. {
  175. //something is wrong
  176. ln = rec + _http->ContentExpected();
  177. }
  178. //if (rec != ln)
  179. if (!_http->ContentFinished())
  180. {
  181. int len = ln - rec;
  182. len = min(bufSize, len);
  183. _tempBuffer.resize(len);
  184. _http->ReadDataAsync((char*)&_tempBuffer.front(), len, httpTimeout, _gotData, this);
  185. return;
  186. }
  187. if (_handle)
  188. file::close(_handle);
  189. _handle = 0;
  190. _status = status_done;
  191. if (_cbDone)
  192. _cbDone(this);
  193. }
  194. void MyHttp::onError()
  195. {
  196. log::messageln("http error: %s", _url.c_str());
  197. if (_handle)
  198. file::close(_handle);
  199. _handle = 0;
  200. _status = status_error;
  201. if (_cbError)
  202. _cbError(this);
  203. }
  204. void MyHttp::gotData(int size)
  205. {
  206. progress(size);
  207. }
  208. int MyHttp::_gotData(void* systemData, void* userData)
  209. {
  210. MyHttp* http = (MyHttp*)userData;
  211. http->gotData((size_t)systemData);
  212. return 0;
  213. }
  214. int MyHttp::_gotHeaders(void* systemData, void* userData)
  215. {
  216. MyHttp* http = (MyHttp*)userData;
  217. http->gotHeaders();
  218. return 0;
  219. }
  220. class SingleHttpAsyncRequest: public Object
  221. {
  222. public:
  223. void get(const char* url)
  224. {
  225. _http.getFile(url, "");
  226. _http._cbDone = CLOSURE(this, &SingleHttpAsyncRequest::_delete);
  227. _http._cbError = CLOSURE(this, &SingleHttpAsyncRequest::_delete);
  228. }
  229. void post(const char* url, const char* data, int size)
  230. {
  231. _http.post(url, data, size);
  232. _http._cbDone = CLOSURE(this, &SingleHttpAsyncRequest::_delete);
  233. _http._cbError = CLOSURE(this, &SingleHttpAsyncRequest::_delete);
  234. }
  235. void _delete(MyHttp*)
  236. {
  237. delete this;
  238. }
  239. MyHttp _http;
  240. };
  241. void makeSingleHttpAsyncGetRequest(const char* url)
  242. {
  243. if (!isNetworkAvailable())
  244. return;
  245. SingleHttpAsyncRequest* r = new SingleHttpAsyncRequest;
  246. r->get(url);
  247. }
  248. void makeSingleHttpAsyncPostRequest(const char* url, const char* data, int size)
  249. {
  250. if (!isNetworkAvailable())
  251. return;
  252. SingleHttpAsyncRequest* r = new SingleHttpAsyncRequest;
  253. r->post(url, data, size);
  254. }