Rev 7282 | 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; |
||
7282 | leency | 16 | char redirect_url[4096*3]; |
17 | char finaladress[4096*3]; |
||
7281 | leency | 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 | |||
7282 | leency | 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; |
||
7281 | leency | 51 | |
52 | } |
||
53 | |||
54 | bool _http::handle_redirect() |
||
55 | { |
||
7282 | leency | 56 | dword redirect; |
7281 | leency | 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 | |||
6058 | leency | 80 | enum { |
81 | STATE_NOT_STARTED, |
||
82 | STATE_IN_PROGRESS, |
||
83 | STATE_COMPLETED |
||
84 | }; |
||
85 | |||
86 | struct DOWNLOADER { |
||
7281 | leency | 87 | _http httpd; |
6058 | leency | 88 | dword bufpointer, bufsize, url; |
7281 | leency | 89 | int state; |
6058 | leency | 90 | dword Start(); |
91 | void Stop(); |
||
7282 | leency | 92 | bool MonitorProgress(); |
7283 | leency | 93 | }; |
6058 | leency | 94 | |
95 | dword DOWNLOADER::Start(dword _url) |
||
96 | { |
||
97 | url = _url; |
||
98 | state = STATE_IN_PROGRESS; |
||
7281 | leency | 99 | httpd.get(url); |
100 | return httpd.transfer; |
||
6058 | leency | 101 | } |
102 | |||
103 | void DOWNLOADER::Stop() |
||
104 | { |
||
105 | state = STATE_NOT_STARTED; |
||
7281 | leency | 106 | if (httpd.transfer!=0) |
6058 | leency | 107 | { |
7281 | leency | 108 | EAX = httpd.transfer; |
6058 | leency | 109 | EAX = EAX.http_msg.content_ptr; // get pointer to data |
110 | $push EAX // save it on the stack |
||
7281 | leency | 111 | http_free stdcall (httpd.transfer); // abort connection |
6058 | leency | 112 | $pop EAX |
7281 | leency | 113 | free(EAX); // free data |
114 | httpd.transfer=0; |
||
6058 | leency | 115 | bufsize = 0; |
7281 | leency | 116 | bufpointer = free(bufpointer); |
6058 | leency | 117 | } |
7282 | leency | 118 | httpd.content_received = httpd.content_length = 0; |
6058 | leency | 119 | } |
120 | |||
7282 | leency | 121 | bool DOWNLOADER::MonitorProgress() |
6058 | leency | 122 | { |
7281 | leency | 123 | if (httpd.transfer <= 0) return false; |
7282 | leency | 124 | httpd.receive(); |
125 | if (!httpd.content_length) httpd.content_length = httpd.content_received * 20; |
||
6058 | leency | 126 | |
7282 | leency | 127 | if (httpd.receive_result == 0) { |
7281 | leency | 128 | if (httpd.status_code >= 300) && (httpd.status_code < 400) |
6058 | leency | 129 | { |
7281 | leency | 130 | httpd.handle_redirect(); |
131 | strcpy(url, httpd.url); |
||
7282 | leency | 132 | get_absolute_url(#httpd.finaladress, url, #httpd.redirect_url); |
6058 | leency | 133 | Stop(); |
7282 | leency | 134 | Start(#httpd.finaladress); |
135 | url = #httpd.finaladress; |
||
6058 | leency | 136 | return false; |
137 | } |
||
7282 | leency | 138 | state = STATE_COMPLETED; |
139 | bufpointer = httpd.content_pointer; |
||
140 | bufsize = httpd.content_received; |
||
141 | httpd.free(); |
||
6058 | leency | 142 | } |
143 | return true; |
||
144 | } |
||
145 | |||
146 | |||
147 | /*===================================== |
||
148 | == == |
||
7281 | leency | 149 | == CHECK PATH TYPE == |
6058 | leency | 150 | == == |
151 | =====================================*/ |
||
152 | |||
153 | |||
154 | int check_is_the_adress_local(dword _in) |
||
155 | { |
||
156 | if (ESBYTE[_in]!='/') return false; |
||
157 | _in++; |
||
158 | if(!strncmp(_in,"rd/",3)) return true; |
||
159 | if(!strncmp(_in,"fd/",3)) return true; |
||
6216 | leency | 160 | if(!strncmp(_in,"hd",2)) return true; |
161 | if(!strncmp(_in,"bd",2)) return true; |
||
162 | if(!strncmp(_in,"cd",2)) return true; |
||
6058 | leency | 163 | if(!strncmp(_in,"sys/",4)) return true; |
164 | if(!strncmp(_in,"tmp/",4)) return true; |
||
6216 | leency | 165 | if(!strncmp(_in,"usbhd",5)) return true; |
6058 | leency | 166 | if(!strncmp(_in,"kolibrios",10)) return true; |
167 | return false; |
||
168 | } |
||
169 | |||
170 | int check_is_the_url_absolute(dword _in) |
||
171 | { |
||
172 | if(!strncmp(_in,"ftp:",4)) return true; |
||
173 | if(!strncmp(_in,"http:",5)) return true; |
||
174 | if(!strncmp(_in,"https:",6)) return true; |
||
175 | if(!strncmp(_in,"mailto:",7)) return true; |
||
176 | if(check_is_the_adress_local(_in)) return true; |
||
177 | return false; |
||
178 | } |
||
179 | |||
180 | void get_absolute_url(dword _rez, _base, _new) |
||
181 | { |
||
182 | int i; |
||
183 | //case: ./valera.html |
||
184 | if (!strncmp(_new,"./", 2)) _new+=2; |
||
185 | //case: http://site.name |
||
186 | if (check_is_the_url_absolute(_new)) { |
||
187 | strcpy(_rez, _new); |
||
188 | goto _GET_ABSOLUTE_URL_END; |
||
189 | } |
||
190 | //case: /valera.html |
||
191 | if (ESBYTE[_new] == '/') //remove everything after site domain name |
||
192 | { |
||
193 | strcpy(_rez, _base); |
||
194 | i = strchr(_rez+8,'/'); |
||
195 | if (i<1) i=strlen(_rez)+_rez; |
||
196 | strcpy(i, _new); |
||
197 | goto _GET_ABSOLUTE_URL_END; |
||
198 | } |
||
199 | //case: ../../valera.html |
||
200 | strcpy(_rez, _base); |
||
201 | ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0'; //remove name |
||
202 | while (!strncmp(_new,"../",3)) |
||
203 | { |
||
204 | _new += 3; |
||
205 | ESBYTE[ strrchr(_rez,'/') + _rez -1 ] = '\0'; |
||
206 | } |
||
207 | //case: valera.html |
||
208 | chrcat(_rez, '/'); |
||
209 | strcat(_rez, _new); |
||
210 | _GET_ABSOLUTE_URL_END: |
||
211 | while (i=strstr(_rez, "&")) strcpy(i+1, i+5); |
||
212 | }1)>>=> |