Rev 6969 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
7281 | leency | 1 | //===================================================// |
2 | // // |
||
3 | // HTTP // |
||
4 | // // |
||
5 | //===================================================// |
||
6058 | leency | 6 | |
7281 | leency | 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 | |||
6058 | leency | 76 | enum { |
77 | STATE_NOT_STARTED, |
||
78 | STATE_IN_PROGRESS, |
||
79 | STATE_COMPLETED |
||
80 | }; |
||
81 | |||
82 | struct DOWNLOADER { |
||
7281 | leency | 83 | _http httpd; |
6058 | leency | 84 | unsigned data_downloaded_size, data_full_size; |
85 | dword bufpointer, bufsize, url; |
||
7281 | leency | 86 | int state; |
6058 | leency | 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; |
||
7281 | leency | 97 | httpd.get(url); |
98 | return httpd.transfer; |
||
6058 | leency | 99 | } |
100 | |||
101 | void DOWNLOADER::Stop() |
||
102 | { |
||
103 | state = STATE_NOT_STARTED; |
||
7281 | leency | 104 | if (httpd.transfer!=0) |
6058 | leency | 105 | { |
7281 | leency | 106 | EAX = httpd.transfer; |
6058 | leency | 107 | EAX = EAX.http_msg.content_ptr; // get pointer to data |
108 | $push EAX // save it on the stack |
||
7281 | leency | 109 | http_free stdcall (httpd.transfer); // abort connection |
6058 | leency | 110 | $pop EAX |
7281 | leency | 111 | free(EAX); // free data |
112 | httpd.transfer=0; |
||
6058 | leency | 113 | bufsize = 0; |
7281 | leency | 114 | bufpointer = free(bufpointer); |
6058 | leency | 115 | } |
116 | data_downloaded_size = data_full_size = 0; |
||
117 | } |
||
118 | |||
119 | void DOWNLOADER::Completed() |
||
120 | { |
||
121 | state = STATE_COMPLETED; |
||
7281 | leency | 122 | ESI = httpd.transfer; |
6058 | leency | 123 | bufpointer = ESI.http_msg.content_ptr; |
124 | bufsize = ESI.http_msg.content_received; |
||
7281 | leency | 125 | httpd.free(); |
6058 | leency | 126 | } |
127 | |||
128 | int DOWNLOADER::MonitorProgress() |
||
129 | { |
||
130 | dword receive_result; |
||
131 | char redirect_url[4096*3], finaladress[4096*3]; |
||
7281 | leency | 132 | if (httpd.transfer <= 0) return false; |
133 | http_receive stdcall (httpd.transfer); |
||
6058 | leency | 134 | receive_result = EAX; |
7281 | leency | 135 | EDI = httpd.transfer; |
136 | httpd.status_code = EDI.http_msg.status; |
||
6058 | leency | 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) { |
||
7281 | leency | 142 | if (httpd.status_code >= 300) && (httpd.status_code < 400) |
6058 | leency | 143 | { |
7281 | leency | 144 | httpd.handle_redirect(); |
145 | strcpy(url, httpd.url); |
||
6058 | leency | 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 | == == |
||
7281 | leency | 160 | == CHECK PATH TYPE == |
6058 | leency | 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; |
||
6216 | leency | 171 | if(!strncmp(_in,"hd",2)) return true; |
172 | if(!strncmp(_in,"bd",2)) return true; |
||
173 | if(!strncmp(_in,"cd",2)) return true; |
||
6058 | leency | 174 | if(!strncmp(_in,"sys/",4)) return true; |
175 | if(!strncmp(_in,"tmp/",4)) return true; |
||
6216 | leency | 176 | if(!strncmp(_in,"usbhd",5)) return true; |
6058 | leency | 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, "&")) strcpy(i+1, i+5); |
||
225 | debug("_rez:");debugln(_rez); |
||
226 | }1)>>=> |