Subversion Repositories Kolibri OS

Rev

Rev 6969 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. //===================================================//
  2. //                                                   //
  3. //                       HTTP                        //
  4. //                                                   //
  5. //===================================================//
  6.  
  7. struct _http
  8. {
  9.     dword url;
  10.     dword transfer;
  11.     dword content_length;
  12.     dword content_received;
  13.     dword status_code;
  14.     dword receive_result;
  15.     dword content_pointer;
  16.  
  17.     dword get();
  18.     void free();
  19.     void receive();
  20.     bool handle_redirect();
  21. };
  22.  
  23. dword _http::get(dword _url)
  24. {
  25.     url = _url;
  26.     http_get stdcall (url, 0, 0, #accept_language);
  27.     transfer = EAX;
  28.     return transfer;
  29. }
  30.  
  31. void _http::free()
  32. {
  33.     http_free stdcall (transfer);
  34.     transfer=0;
  35. }
  36.  
  37. void _http::receive()
  38. {
  39.     http_receive stdcall (transfer);
  40.     receive_result = EAX;
  41.  
  42.     ESI = transfer;
  43.     if (!EAX) status_code = ESI.http_msg.status;
  44.     content_length = ESI.http_msg.content_length;
  45.     content_received = ESI.http_msg.content_received;
  46.  
  47.  }
  48.  
  49. bool _http::handle_redirect()
  50. {
  51.         dword redirect, i;
  52.         char redirect_url[4096*3], finaladress[4096*3];
  53.     http_find_header_field stdcall (transfer, "location\0");
  54.     if (EAX!=0) {
  55.         ESI = EAX;
  56.         EDI = #redirect_url;
  57.         do {
  58.             $lodsb;
  59.             $stosb;
  60.         } while (AL != 0) && (AL != 13) && (AL != 10);
  61.         DSBYTE[EDI-1]='\0';
  62.         get_absolute_url(#finaladress, url, #redirect_url);
  63.         strcpy(url, #finaladress);
  64.         return true;
  65.     }
  66.     return false;
  67. }
  68.  
  69. //===================================================//
  70. //                                                   //
  71. //                    DOWNLOADER                     //
  72. //                                                   //
  73. //===================================================//
  74.  
  75.  
  76. enum {
  77.         STATE_NOT_STARTED,
  78.         STATE_IN_PROGRESS,
  79.         STATE_COMPLETED
  80. };
  81.  
  82. struct DOWNLOADER {
  83.         _http httpd;
  84.         unsigned data_downloaded_size, data_full_size;
  85.         dword bufpointer, bufsize, url;
  86.         int state;
  87.         dword Start();
  88.         void Stop();
  89.         void Completed();
  90.         int MonitorProgress();
  91. } downloader;
  92.  
  93. dword DOWNLOADER::Start(dword _url)
  94. {
  95.         url = _url;
  96.         state = STATE_IN_PROGRESS;
  97.         httpd.get(url);
  98.         return httpd.transfer;
  99. }
  100.  
  101. void DOWNLOADER::Stop()
  102. {
  103.         state = STATE_NOT_STARTED;
  104.         if (httpd.transfer!=0)
  105.         {
  106.                 EAX = httpd.transfer;
  107.                 EAX = EAX.http_msg.content_ptr;         // get pointer to data
  108.                 $push EAX                                                       // save it on the stack
  109.                 http_free stdcall (httpd.transfer);     // abort connection
  110.                 $pop  EAX                                                      
  111.                 free(EAX);                                              // free data
  112.                 httpd.transfer=0;
  113.                 bufsize = 0;
  114.                 bufpointer = free(bufpointer);
  115.         }
  116.         data_downloaded_size = data_full_size = 0;
  117. }
  118.  
  119. void DOWNLOADER::Completed()
  120. {
  121.         state = STATE_COMPLETED;
  122.         ESI = httpd.transfer;
  123.         bufpointer = ESI.http_msg.content_ptr;
  124.         bufsize = ESI.http_msg.content_received;
  125.         httpd.free();
  126. }
  127.  
  128. int DOWNLOADER::MonitorProgress()
  129. {
  130.         dword receive_result;
  131.         char redirect_url[4096*3], finaladress[4096*3];
  132.         if (httpd.transfer <= 0) return false;
  133.         http_receive stdcall (httpd.transfer);
  134.         receive_result = EAX;
  135.         EDI = httpd.transfer;
  136.         httpd.status_code = EDI.http_msg.status;
  137.         data_full_size = EDI.http_msg.content_length;
  138.         data_downloaded_size = EDI.http_msg.content_received;
  139.         if (!data_full_size) data_full_size = data_downloaded_size * 6 + 1;
  140.  
  141.         if (receive_result == 0) {
  142.                 if (httpd.status_code >= 300) && (httpd.status_code < 400)
  143.                 {
  144.                         httpd.handle_redirect();
  145.                         strcpy(url, httpd.url);
  146.                         get_absolute_url(#finaladress, url, #redirect_url);
  147.                         Stop();
  148.                         Start(#finaladress);
  149.                         url = #finaladress;
  150.                         return false;
  151.                 }
  152.                 Completed();
  153.         }
  154.         return true;
  155. }
  156.  
  157.  
  158. /*=====================================
  159. ==                                   ==
  160. ==         CHECK PATH TYPE           ==
  161. ==                                   ==
  162. =====================================*/
  163.  
  164.  
  165. int check_is_the_adress_local(dword _in)
  166. {
  167.         if (ESBYTE[_in]!='/') return false;
  168.         _in++;
  169.         if(!strncmp(_in,"rd/",3)) return true;
  170.         if(!strncmp(_in,"fd/",3)) return true;
  171.         if(!strncmp(_in,"hd",2)) return true;
  172.         if(!strncmp(_in,"bd",2)) return true;
  173.         if(!strncmp(_in,"cd",2)) return true;
  174.         if(!strncmp(_in,"sys/",4)) return true;
  175.         if(!strncmp(_in,"tmp/",4)) return true;
  176.         if(!strncmp(_in,"usbhd",5)) return true;
  177.         if(!strncmp(_in,"kolibrios",10)) return true;
  178.         return false;
  179. }
  180.  
  181. int check_is_the_url_absolute(dword _in)
  182. {
  183.         if(!strncmp(_in,"ftp:",4)) return true;
  184.         if(!strncmp(_in,"http:",5)) return true;
  185.         if(!strncmp(_in,"https:",6)) return true;
  186.         if(!strncmp(_in,"mailto:",7)) return true;
  187.         if(check_is_the_adress_local(_in)) return true;
  188.         return false;
  189. }
  190.  
  191. void get_absolute_url(dword _rez, _base, _new)
  192. {
  193.         int i;
  194.         debug("_base:");debugln(_base);
  195.         debug("_new:");debugln(_new);
  196.         //case: ./valera.html
  197.         if (!strncmp(_new,"./", 2)) _new+=2;
  198.         //case: http://site.name
  199.         if (check_is_the_url_absolute(_new)) {
  200.                 strcpy(_rez, _new);
  201.                 goto _GET_ABSOLUTE_URL_END;
  202.         }
  203.         //case: /valera.html
  204.         if (ESBYTE[_new] == '/') //remove everything after site domain name
  205.         {
  206.                 strcpy(_rez, _base);
  207.                 i = strchr(_rez+8,'/');
  208.                 if (i<1) i=strlen(_rez)+_rez;
  209.                 strcpy(i, _new);
  210.                 goto _GET_ABSOLUTE_URL_END;
  211.         }      
  212.         //case: ../../valera.html
  213.         strcpy(_rez, _base);
  214.         ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0'; //remove name
  215.         while (!strncmp(_new,"../",3))
  216.         {
  217.                 _new += 3;
  218.                 ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0';  
  219.         }
  220.         //case: valera.html
  221.         chrcat(_rez, '/');
  222.         strcat(_rez, _new);
  223.         _GET_ABSOLUTE_URL_END:
  224.         while (i=strstr(_rez, "&amp;")) strcpy(i+1, i+5);      
  225.         debug("_rez:");debugln(_rez);
  226. }
  227.