httprequest.mm 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include "httprequest.h"
  2. #include "../../std/async/native/async.h"
  3. struct bbHttpRequest::Rep{
  4. NSMutableURLRequest *_req;
  5. NSString *_response;
  6. int _status;
  7. };
  8. namespace{
  9. struct ReadyStateChangedEvent : public bbAsync::Event{
  10. bbHttpRequest *req;
  11. int state;
  12. ReadyStateChangedEvent( bbHttpRequest *req,int state ):req( req ),state( state ){
  13. }
  14. void dispatch(){
  15. if( state==req->_readyState ){
  16. if( req->_readyState==4 ){
  17. req->_response=bbString( req->_rep->_response );
  18. req->_status=req->_rep->_status;
  19. }
  20. req->readyStateChanged();
  21. }
  22. bbGC::release( req );
  23. delete this;
  24. }
  25. };
  26. }
  27. bbHttpRequest::bbHttpRequest(){
  28. _rep=new Rep;
  29. }
  30. bbHttpRequest::bbHttpRequest( bbString req,bbString url,bbFunction<void()> readyStateChanged ):bbHttpRequest(){
  31. this->readyStateChanged=readyStateChanged;
  32. open( req,url );
  33. }
  34. bbReadyState bbHttpRequest::readyState(){
  35. return (bbReadyState)_readyState;
  36. }
  37. bbString bbHttpRequest::responseText(){
  38. return _response;
  39. }
  40. int bbHttpRequest::status(){
  41. return _status;
  42. }
  43. void bbHttpRequest::open( bbString req,bbString url ){
  44. if( _readyState!=0 ) return;
  45. NSMutableURLRequest *nsreq=[[NSMutableURLRequest alloc] init];
  46. [nsreq setHTTPMethod:req.ToNSString()];
  47. [nsreq setURL:[NSURL URLWithString:url.ToNSString()]];
  48. if( [nsreq respondsToSelector:@selector(setAllowsCellularAccess:)] ){
  49. [nsreq setAllowsCellularAccess:YES];
  50. }
  51. _rep->_req=nsreq;
  52. _readyState=1;
  53. }
  54. void bbHttpRequest::setHeader( bbString name,bbString value ){
  55. if( _readyState!=1 ) return;
  56. [_rep->_req setValue:value.ToNSString() forHTTPHeaderField:name.ToNSString()];
  57. }
  58. void bbHttpRequest::send(){
  59. send( "" );
  60. }
  61. void bbHttpRequest::send( bbString text ){
  62. if( _readyState!=1 ) return;
  63. bbGC::retain( this );
  64. _readyState=3; //loading
  65. std::thread( [=](){
  66. NSURLResponse *response=0;
  67. NSData *data=[NSURLConnection sendSynchronousRequest:_rep->_req returningResponse:&response error:0];
  68. if( data && response ){
  69. _rep->_response=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  70. _rep->_status=[(NSHTTPURLResponse*)response statusCode];
  71. //_recv=[data length];
  72. }
  73. _readyState=4; //loaded
  74. ReadyStateChangedEvent *ev=new ReadyStateChangedEvent( this,_readyState );
  75. ev->post();
  76. } ).detach();
  77. }
  78. void bbHttpRequest::gcMark(){
  79. bbGCMark( readyStateChanged );
  80. }