Subversion Repositories Kolibri OS

Rev

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