Subversion Repositories Kolibri OS

Rev

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

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