164 lines
4.0 KiB
C
164 lines
4.0 KiB
C
|
|
||
|
enum {
|
||
|
STATE_NOT_STARTED,
|
||
|
STATE_IN_PROGRESS,
|
||
|
STATE_COMPLETED
|
||
|
};
|
||
|
|
||
|
struct DOWNLOADER {
|
||
|
unsigned data_downloaded_size, data_full_size;
|
||
|
dword bufpointer, bufsize, url;
|
||
|
byte state;
|
||
|
dword http_transfer;
|
||
|
int http_status_code;
|
||
|
dword Start();
|
||
|
void Stop();
|
||
|
void Completed();
|
||
|
int MonitorProgress();
|
||
|
} downloader;
|
||
|
|
||
|
dword DOWNLOADER::Start(dword _url)
|
||
|
{
|
||
|
url = _url;
|
||
|
state = STATE_IN_PROGRESS;
|
||
|
http_get stdcall (url, 0, 0, #accept_language);
|
||
|
http_transfer = EAX;
|
||
|
return http_transfer;
|
||
|
}
|
||
|
|
||
|
void DOWNLOADER::Stop()
|
||
|
{
|
||
|
state = STATE_NOT_STARTED;
|
||
|
if (http_transfer!=0)
|
||
|
{
|
||
|
EAX = http_transfer;
|
||
|
EAX = EAX.http_msg.content_ptr; // get pointer to data
|
||
|
$push EAX // save it on the stack
|
||
|
http_free stdcall (http_transfer); // abort connection
|
||
|
$pop EAX
|
||
|
mem_Free(EAX); // free data
|
||
|
http_transfer=0;
|
||
|
bufsize = 0;
|
||
|
bufpointer = mem_Free(bufpointer);
|
||
|
}
|
||
|
data_downloaded_size = data_full_size = 0;
|
||
|
}
|
||
|
|
||
|
void DOWNLOADER::Completed()
|
||
|
{
|
||
|
state = STATE_COMPLETED;
|
||
|
ESI = http_transfer;
|
||
|
bufpointer = ESI.http_msg.content_ptr;
|
||
|
bufsize = ESI.http_msg.content_received;
|
||
|
http_free stdcall (http_transfer);
|
||
|
http_transfer=0;
|
||
|
}
|
||
|
|
||
|
int DOWNLOADER::MonitorProgress()
|
||
|
{
|
||
|
dword receive_result;
|
||
|
char redirect_url[4096*3], finaladress[4096*3];
|
||
|
if (http_transfer <= 0) return false;
|
||
|
http_receive stdcall (http_transfer);
|
||
|
receive_result = EAX;
|
||
|
EDI = http_transfer;
|
||
|
http_status_code = EDI.http_msg.status;
|
||
|
data_full_size = EDI.http_msg.content_length;
|
||
|
data_downloaded_size = EDI.http_msg.content_received;
|
||
|
if (!data_full_size) data_full_size = data_downloaded_size * 6 + 1;
|
||
|
|
||
|
if (receive_result == 0) {
|
||
|
if (http_status_code >= 300) && (http_status_code < 400)
|
||
|
{
|
||
|
http_find_header_field stdcall (http_transfer, "location\0");
|
||
|
if (EAX!=0) {
|
||
|
ESI = EAX;
|
||
|
EDI = #redirect_url;
|
||
|
do {
|
||
|
$lodsb;
|
||
|
$stosb;
|
||
|
} while (AL != 0) && (AL != 13) && (AL != 10));
|
||
|
DSBYTE[EDI-1]='\0';
|
||
|
}
|
||
|
get_absolute_url(#finaladress, url, #redirect_url);
|
||
|
Stop();
|
||
|
Start(#finaladress);
|
||
|
url = #finaladress;
|
||
|
return false;
|
||
|
}
|
||
|
Completed();
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*=====================================
|
||
|
== ==
|
||
|
== CHECK URL TYPE ==
|
||
|
== ==
|
||
|
=====================================*/
|
||
|
|
||
|
|
||
|
int check_is_the_adress_local(dword _in)
|
||
|
{
|
||
|
if (ESBYTE[_in]!='/') return false;
|
||
|
_in++;
|
||
|
if(!strncmp(_in,"rd/",3)) return true;
|
||
|
if(!strncmp(_in,"fd/",3)) return true;
|
||
|
if(!strncmp(_in,"hd/",3)) return true;
|
||
|
if(!strncmp(_in,"bd/",3)) return true;
|
||
|
if(!strncmp(_in,"cd/",3)) return true;
|
||
|
if(!strncmp(_in,"sys/",4)) return true;
|
||
|
if(!strncmp(_in,"tmp/",4)) return true;
|
||
|
if(!strncmp(_in,"usbhd",6)) return true;
|
||
|
if(!strncmp(_in,"kolibrios",10)) return true;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
int check_is_the_url_absolute(dword _in)
|
||
|
{
|
||
|
if(!strncmp(_in,"ftp:",4)) return true;
|
||
|
if(!strncmp(_in,"http:",5)) return true;
|
||
|
if(!strncmp(_in,"https:",6)) return true;
|
||
|
if(!strncmp(_in,"mailto:",7)) return true;
|
||
|
if(check_is_the_adress_local(_in)) return true;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void get_absolute_url(dword _rez, _base, _new)
|
||
|
{
|
||
|
int i;
|
||
|
debug("_base:");debugln(_base);
|
||
|
debug("_new:");debugln(_new);
|
||
|
//case: ./valera.html
|
||
|
if (!strncmp(_new,"./", 2)) _new+=2;
|
||
|
//case: http://site.name
|
||
|
if (check_is_the_url_absolute(_new)) {
|
||
|
strcpy(_rez, _new);
|
||
|
goto _GET_ABSOLUTE_URL_END;
|
||
|
}
|
||
|
//case: /valera.html
|
||
|
if (ESBYTE[_new] == '/') //remove everything after site domain name
|
||
|
{
|
||
|
strcpy(_rez, _base);
|
||
|
i = strchr(_rez+8,'/');
|
||
|
if (i<1) i=strlen(_rez)+_rez;
|
||
|
strcpy(i, _new);
|
||
|
goto _GET_ABSOLUTE_URL_END;
|
||
|
}
|
||
|
//case: ../../valera.html
|
||
|
strcpy(_rez, _base);
|
||
|
ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0'; //remove name
|
||
|
while (!strncmp(_new,"../",3))
|
||
|
{
|
||
|
_new += 3;
|
||
|
ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0';
|
||
|
}
|
||
|
//case: valera.html
|
||
|
chrcat(_rez, '/');
|
||
|
strcat(_rez, _new);
|
||
|
_GET_ABSOLUTE_URL_END:
|
||
|
while (i=strstr(_rez, "&")) strcpy(i+1, i+5);
|
||
|
debug("_rez:");debugln(_rez);
|
||
|
}
|