Rev 4222 | Rev 4241 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4158 | hidnplayr | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
3 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
||
4 | ;; Distributed under terms of the GNU General Public License ;; |
||
5 | ;; ;; |
||
6 | ;; HTTP library for KolibriOS ;; |
||
7 | ;; ;; |
||
8 | ;; Written by hidnplayr@kolibrios.org ;; |
||
4233 | hidnplayr | 9 | ;; Proxy code written by CleverMouse ;; |
4158 | hidnplayr | 10 | ;; ;; |
11 | ;; GNU GENERAL PUBLIC LICENSE ;; |
||
12 | ;; Version 2, June 1991 ;; |
||
13 | ;; ;; |
||
14 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
15 | |||
16 | ; references: |
||
17 | ; "HTTP made really easy", http://www.jmarshall.com/easy/http/ |
||
18 | ; "Hypertext Transfer Protocol -- HTTP/1.1", http://tools.ietf.org/html/rfc2616 |
||
19 | |||
20 | |||
21 | URLMAXLEN = 65535 |
||
22 | BUFFERSIZE = 4096 |
||
4206 | hidnplayr | 23 | TIMEOUT = 1000 ; in 1/100 s |
4158 | hidnplayr | 24 | |
25 | __DEBUG__ = 1 |
||
26 | __DEBUG_LEVEL__ = 1 |
||
27 | |||
28 | |||
29 | format MS COFF |
||
30 | |||
31 | public @EXPORT as 'EXPORTS' |
||
32 | |||
33 | include '../../../struct.inc' |
||
34 | include '../../../proc32.inc' |
||
35 | include '../../../macros.inc' |
||
36 | purge section,mov,add,sub |
||
37 | include '../../../debug-fdo.inc' |
||
38 | |||
39 | include '../../../network.inc' |
||
40 | include 'http.inc' |
||
41 | |||
42 | virtual at 0 |
||
43 | http_msg http_msg |
||
44 | end virtual |
||
45 | |||
46 | macro copy_till_zero { |
||
47 | @@: |
||
48 | lodsb |
||
49 | test al, al |
||
50 | jz @f |
||
51 | stosb |
||
52 | jmp @r |
||
53 | @@: |
||
54 | } |
||
55 | |||
4167 | hidnplayr | 56 | macro HTTP_init_buffer buffer, socketnum { |
57 | |||
58 | mov eax, buffer |
||
59 | push socketnum |
||
60 | popd [eax + http_msg.socket] |
||
61 | lea esi, [eax + http_msg.data] |
||
4205 | hidnplayr | 62 | mov [eax + http_msg.flags], FLAG_CONNECTED |
4167 | hidnplayr | 63 | mov [eax + http_msg.write_ptr], esi |
64 | mov [eax + http_msg.buffer_length], BUFFERSIZE - http_msg.data |
||
65 | mov [eax + http_msg.chunk_ptr], 0 |
||
66 | |||
67 | mov [eax + http_msg.status], 0 |
||
68 | mov [eax + http_msg.header_length], 0 |
||
69 | mov [eax + http_msg.content_length], 0 |
||
4168 | hidnplayr | 70 | mov [eax + http_msg.content_received], 0 |
4206 | hidnplayr | 71 | |
72 | push eax ebp |
||
73 | mov ebp, eax |
||
74 | mcall 29, 9 |
||
75 | mov [ebp + http_msg.timestamp], eax |
||
76 | pop ebp eax |
||
4167 | hidnplayr | 77 | } |
78 | |||
4158 | hidnplayr | 79 | section '.flat' code readable align 16 |
80 | |||
81 | ;;===========================================================================;; |
||
82 | lib_init: ;//////////////////////////////////////////////////////////////////;; |
||
83 | ;;---------------------------------------------------------------------------;; |
||
84 | ;? Library entry point (called after library load) ;; |
||
85 | ;;---------------------------------------------------------------------------;; |
||
86 | ;> eax = pointer to memory allocation routine ;; |
||
87 | ;> ebx = pointer to memory freeing routine ;; |
||
88 | ;> ecx = pointer to memory reallocation routine ;; |
||
89 | ;> edx = pointer to library loading routine ;; |
||
90 | ;;---------------------------------------------------------------------------;; |
||
4209 | hidnplayr | 91 | ;< eax = 1 (fail) / 0 (ok) ;; |
4158 | hidnplayr | 92 | ;;===========================================================================;; |
93 | mov [mem.alloc], eax |
||
94 | mov [mem.free], ebx |
||
95 | mov [mem.realloc], ecx |
||
96 | mov [dll.load], edx |
||
97 | |||
98 | invoke dll.load, @IMPORT |
||
4209 | hidnplayr | 99 | test eax, eax |
100 | jnz .error |
||
4158 | hidnplayr | 101 | |
102 | ; load proxy settings |
||
4216 | hidnplayr | 103 | pusha |
4158 | hidnplayr | 104 | invoke ini.get_str, inifile, sec_proxy, key_proxy, proxyAddr, 256, proxyAddr |
105 | invoke ini.get_int, inifile, sec_proxy, key_proxyport, 80 |
||
106 | mov [proxyPort], eax |
||
107 | invoke ini.get_str, inifile, sec_proxy, key_user, proxyUser, 256, proxyUser |
||
108 | invoke ini.get_str, inifile, sec_proxy, key_password, proxyPassword, 256, proxyPassword |
||
4216 | hidnplayr | 109 | popa |
4158 | hidnplayr | 110 | |
4212 | hidnplayr | 111 | DEBUGF 1, "HTTP library: init OK\n" |
4211 | hidnplayr | 112 | |
4158 | hidnplayr | 113 | xor eax, eax |
114 | ret |
||
115 | |||
4209 | hidnplayr | 116 | .error: |
4212 | hidnplayr | 117 | DEBUGF 1, "ERROR loading libraries\n" |
4211 | hidnplayr | 118 | |
4158 | hidnplayr | 119 | xor eax, eax |
4209 | hidnplayr | 120 | inc eax |
121 | |||
4158 | hidnplayr | 122 | ret |
123 | |||
124 | |||
125 | |||
126 | |||
127 | ;;================================================================================================;; |
||
4221 | hidnplayr | 128 | proc HTTP_get URL, add_header ;///////////////////////////////////////////////////////////////////;; |
4158 | hidnplayr | 129 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 130 | ;? Initiates a HTTP connection, using 'GET' method. ;; |
4158 | hidnplayr | 131 | ;;------------------------------------------------------------------------------------------------;; |
4221 | hidnplayr | 132 | ;> URL = pointer to ASCIIZ URL ;; |
133 | ;> add_header = pointer to additional header parameters (ASCIIZ), or null for none. ;; |
||
4158 | hidnplayr | 134 | ;;------------------------------------------------------------------------------------------------;; |
135 | ;< eax = 0 (error) / buffer ptr ;; |
||
136 | ;;================================================================================================;; |
||
137 | locals |
||
138 | hostname dd ? |
||
139 | pageaddr dd ? |
||
140 | sockaddr dd ? |
||
141 | socketnum dd ? |
||
142 | buffer dd ? |
||
4167 | hidnplayr | 143 | port dd ? |
4158 | hidnplayr | 144 | endl |
145 | |||
4216 | hidnplayr | 146 | pusha |
147 | |||
4158 | hidnplayr | 148 | ; split the URL into hostname and pageaddr |
149 | stdcall parse_url, [URL] |
||
150 | test eax, eax |
||
151 | jz .error |
||
152 | mov [hostname], eax |
||
153 | mov [pageaddr], ebx |
||
4221 | hidnplayr | 154 | mov [port], ecx |
4158 | hidnplayr | 155 | |
4167 | hidnplayr | 156 | ; Connect to the other side. |
157 | stdcall open_connection, [hostname], [port] |
||
4158 | hidnplayr | 158 | test eax, eax |
4167 | hidnplayr | 159 | jz .error |
160 | mov [socketnum], eax |
||
4158 | hidnplayr | 161 | |
4167 | hidnplayr | 162 | ; Create the HTTP request. |
163 | invoke mem.alloc, BUFFERSIZE |
||
4158 | hidnplayr | 164 | test eax, eax |
165 | jz .error |
||
4167 | hidnplayr | 166 | mov [buffer], eax |
167 | mov edi, eax |
||
168 | DEBUGF 1, "Buffer has been allocated.\n" |
||
4158 | hidnplayr | 169 | |
4167 | hidnplayr | 170 | mov esi, str_get |
171 | copy_till_zero |
||
4158 | hidnplayr | 172 | |
4233 | hidnplayr | 173 | ; If we are using a proxy, send complete URL, otherwise send only page address. |
174 | cmp [proxyAddr], 0 |
||
175 | je .no_proxy |
||
176 | mov esi, str_http ; prepend 'http://' |
||
177 | copy_till_zero |
||
178 | mov esi, [hostname] |
||
179 | copy_till_zero |
||
180 | .no_proxy: |
||
4167 | hidnplayr | 181 | mov esi, [pageaddr] |
182 | copy_till_zero |
||
4158 | hidnplayr | 183 | |
4167 | hidnplayr | 184 | mov esi, str_http11 |
185 | mov ecx, str_http11.length |
||
186 | rep movsb |
||
187 | |||
188 | mov esi, [hostname] |
||
189 | copy_till_zero |
||
190 | |||
4221 | hidnplayr | 191 | mov esi, [add_header] |
192 | test esi, esi |
||
193 | jz @f |
||
194 | copy_till_zero |
||
195 | @@: |
||
196 | |||
4233 | hidnplayr | 197 | cmp byte[proxyUser], 0 |
198 | je @f |
||
199 | call append_proxy_auth_header |
||
200 | @@: |
||
201 | |||
4167 | hidnplayr | 202 | mov esi, str_close |
203 | mov ecx, str_close.length |
||
204 | rep movsb |
||
205 | |||
206 | mov byte[edi], 0 |
||
207 | DEBUGF 1, "Request:\n%s", [buffer] |
||
208 | |||
4222 | hidnplayr | 209 | ; Free unused memory |
210 | push edi |
||
211 | invoke mem.free, [pageaddr] |
||
212 | invoke mem.free, [hostname] |
||
213 | pop esi |
||
214 | |||
4167 | hidnplayr | 215 | ; Send the request |
216 | sub esi, [buffer] ; length |
||
217 | xor edi, edi ; flags |
||
218 | mcall send, [socketnum], [buffer] |
||
4158 | hidnplayr | 219 | test eax, eax |
220 | jz .error |
||
4167 | hidnplayr | 221 | DEBUGF 1, "Request has been sent to server.\n" |
4158 | hidnplayr | 222 | |
4167 | hidnplayr | 223 | HTTP_init_buffer [buffer], [socketnum] |
224 | |||
4216 | hidnplayr | 225 | popa |
226 | mov eax, [buffer] ; return buffer ptr |
||
227 | ret |
||
4167 | hidnplayr | 228 | |
229 | .error: |
||
230 | DEBUGF 1, "Error!\n" |
||
4216 | hidnplayr | 231 | popa |
4167 | hidnplayr | 232 | xor eax, eax ; return 0 = error |
233 | ret |
||
234 | |||
235 | endp |
||
236 | |||
237 | |||
238 | |||
239 | ;;================================================================================================;; |
||
4221 | hidnplayr | 240 | proc HTTP_head URL, add_header ;//////////////////////////////////////////////////////////////////;; |
4167 | hidnplayr | 241 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 242 | ;? Initiates a HTTP connection, using 'HEAD' method. ;; |
4167 | hidnplayr | 243 | ;;------------------------------------------------------------------------------------------------;; |
4221 | hidnplayr | 244 | ;> URL = pointer to ASCIIZ URL ;; |
245 | ;> add_header = pointer to additional header parameters (ASCIIZ), or null for none. ;; |
||
4167 | hidnplayr | 246 | ;;------------------------------------------------------------------------------------------------;; |
247 | ;< eax = 0 (error) / buffer ptr ;; |
||
248 | ;;================================================================================================;; |
||
249 | locals |
||
250 | hostname dd ? |
||
251 | pageaddr dd ? |
||
252 | sockaddr dd ? |
||
253 | socketnum dd ? |
||
254 | buffer dd ? |
||
255 | port dd ? |
||
256 | endl |
||
257 | |||
4216 | hidnplayr | 258 | pusha |
4167 | hidnplayr | 259 | ; split the URL into hostname and pageaddr |
260 | stdcall parse_url, [URL] |
||
4158 | hidnplayr | 261 | test eax, eax |
4167 | hidnplayr | 262 | jz .error |
263 | mov [hostname], eax |
||
264 | mov [pageaddr], ebx |
||
4221 | hidnplayr | 265 | mov [port], ecx |
4158 | hidnplayr | 266 | |
4167 | hidnplayr | 267 | ; Connect to the other side. |
268 | stdcall open_connection, [hostname], [port] |
||
269 | test eax, eax |
||
270 | jz .error |
||
271 | mov [socketnum], eax |
||
272 | |||
4158 | hidnplayr | 273 | ; Create the HTTP request. |
274 | invoke mem.alloc, BUFFERSIZE |
||
275 | test eax, eax |
||
276 | jz .error |
||
277 | mov [buffer], eax |
||
4167 | hidnplayr | 278 | mov edi, eax |
4158 | hidnplayr | 279 | DEBUGF 1, "Buffer has been allocated.\n" |
280 | |||
4167 | hidnplayr | 281 | mov esi, str_head |
4158 | hidnplayr | 282 | copy_till_zero |
283 | |||
4233 | hidnplayr | 284 | ; If we are using a proxy, send complete URL, otherwise send only page address. |
285 | cmp [proxyAddr], 0 |
||
286 | je .no_proxy |
||
287 | mov esi, str_http ; prepend 'http://' |
||
288 | copy_till_zero |
||
289 | mov esi, [hostname] |
||
290 | copy_till_zero |
||
291 | .no_proxy: |
||
4167 | hidnplayr | 292 | mov esi, [pageaddr] |
293 | copy_till_zero |
||
294 | |||
4158 | hidnplayr | 295 | mov esi, str_http11 |
296 | mov ecx, str_http11.length |
||
297 | rep movsb |
||
298 | |||
299 | mov esi, [hostname] |
||
300 | copy_till_zero |
||
301 | |||
4221 | hidnplayr | 302 | mov esi, [add_header] |
303 | test esi, esi |
||
304 | jz @f |
||
305 | copy_till_zero |
||
306 | @@: |
||
307 | |||
4233 | hidnplayr | 308 | cmp byte[proxyUser], 0 |
309 | je @f |
||
310 | call append_proxy_auth_header |
||
311 | @@: |
||
312 | |||
4158 | hidnplayr | 313 | mov esi, str_close |
314 | mov ecx, str_close.length |
||
315 | rep movsb |
||
316 | |||
317 | mov byte[edi], 0 |
||
318 | DEBUGF 1, "Request:\n%s", [buffer] |
||
319 | |||
4222 | hidnplayr | 320 | |
321 | ; Free unused memory |
||
322 | push edi |
||
323 | invoke mem.free, [pageaddr] |
||
324 | invoke mem.free, [hostname] |
||
325 | pop esi |
||
326 | |||
4167 | hidnplayr | 327 | ; Send the request |
4158 | hidnplayr | 328 | sub esi, [buffer] ; length |
329 | xor edi, edi ; flags |
||
330 | mcall send, [socketnum], [buffer] |
||
331 | test eax, eax |
||
332 | jz .error |
||
333 | DEBUGF 1, "Request has been sent to server.\n" |
||
334 | |||
4167 | hidnplayr | 335 | HTTP_init_buffer [buffer], [socketnum] |
4158 | hidnplayr | 336 | |
4216 | hidnplayr | 337 | popa |
338 | mov eax, [buffer] |
||
4167 | hidnplayr | 339 | ret ; return buffer ptr |
4158 | hidnplayr | 340 | |
4167 | hidnplayr | 341 | .error: |
342 | DEBUGF 1, "Error!\n" |
||
4216 | hidnplayr | 343 | popa |
4167 | hidnplayr | 344 | xor eax, eax ; return 0 = error |
345 | ret |
||
346 | |||
347 | endp |
||
348 | |||
349 | |||
350 | ;;================================================================================================;; |
||
4221 | hidnplayr | 351 | proc HTTP_post URL, add_header, content_type, content_length ;////////////////////////////////////;; |
4167 | hidnplayr | 352 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 353 | ;? Initiates a HTTP connection, using 'GET' method. ;; |
4167 | hidnplayr | 354 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 355 | ;> URL = pointer to ASCIIZ URL ;; |
4221 | hidnplayr | 356 | ;> add_header = pointer to additional header parameters (ASCIIZ), or null for none. ;; |
4202 | hidnplayr | 357 | ;> content_type = pointer to ASCIIZ string containing content type ;; |
358 | ;> content_length = length of content (in bytes) ;; |
||
4167 | hidnplayr | 359 | ;;------------------------------------------------------------------------------------------------;; |
360 | ;< eax = 0 (error) / buffer ptr ;; |
||
361 | ;;================================================================================================;; |
||
362 | locals |
||
363 | hostname dd ? |
||
364 | pageaddr dd ? |
||
365 | sockaddr dd ? |
||
366 | socketnum dd ? |
||
367 | buffer dd ? |
||
368 | port dd ? |
||
369 | endl |
||
370 | |||
4216 | hidnplayr | 371 | pusha |
4167 | hidnplayr | 372 | ; split the URL into hostname and pageaddr |
373 | stdcall parse_url, [URL] |
||
374 | test eax, eax |
||
375 | jz .error |
||
376 | mov [hostname], eax |
||
377 | mov [pageaddr], ebx |
||
4221 | hidnplayr | 378 | mov [port], ecx |
4167 | hidnplayr | 379 | |
380 | ; Connect to the other side. |
||
381 | stdcall open_connection, [hostname], [port] |
||
382 | test eax, eax |
||
383 | jz .error |
||
384 | mov [socketnum], eax |
||
385 | |||
386 | ; Create the HTTP request. |
||
387 | invoke mem.alloc, BUFFERSIZE |
||
388 | test eax, eax |
||
389 | jz .error |
||
390 | mov [buffer], eax |
||
391 | mov edi, eax |
||
392 | DEBUGF 1, "Buffer has been allocated.\n" |
||
393 | |||
394 | mov esi, str_post |
||
395 | copy_till_zero |
||
396 | |||
4233 | hidnplayr | 397 | ; If we are using a proxy, send complete URL, otherwise send only page address. |
398 | cmp [proxyAddr], 0 |
||
399 | je .no_proxy |
||
400 | mov esi, str_http ; prepend 'http://' |
||
401 | copy_till_zero |
||
402 | mov esi, [hostname] |
||
403 | copy_till_zero |
||
404 | .no_proxy: |
||
4167 | hidnplayr | 405 | mov esi, [pageaddr] |
406 | copy_till_zero |
||
407 | |||
408 | mov esi, str_http11 |
||
409 | mov ecx, str_http11.length |
||
410 | rep movsb |
||
411 | |||
412 | mov esi, [hostname] |
||
413 | copy_till_zero |
||
414 | |||
415 | mov esi, str_post_cl |
||
416 | mov ecx, str_post_cl.length |
||
417 | rep movsb |
||
418 | |||
419 | mov eax, [content_length] |
||
4233 | hidnplayr | 420 | call eax_ascii_dec |
4167 | hidnplayr | 421 | |
422 | mov esi, str_post_ct |
||
423 | mov ecx, str_post_ct.length |
||
424 | rep movsb |
||
425 | |||
426 | mov esi, [content_type] |
||
4221 | hidnplayr | 427 | copy_till_zero |
4167 | hidnplayr | 428 | |
4221 | hidnplayr | 429 | mov esi, [add_header] |
430 | test esi, esi |
||
431 | jz @f |
||
432 | copy_till_zero |
||
433 | @@: |
||
434 | |||
4233 | hidnplayr | 435 | cmp byte[proxyUser], 0 |
436 | je @f |
||
437 | call append_proxy_auth_header |
||
438 | @@: |
||
439 | |||
4167 | hidnplayr | 440 | mov esi, str_close |
441 | mov ecx, str_close.length |
||
442 | rep movsb |
||
443 | |||
444 | mov byte[edi], 0 |
||
445 | DEBUGF 1, "Request:\n%s", [buffer] |
||
446 | |||
4222 | hidnplayr | 447 | ; Free unused memory |
448 | push edi |
||
449 | invoke mem.free, [pageaddr] |
||
450 | invoke mem.free, [hostname] |
||
451 | pop esi |
||
452 | |||
4167 | hidnplayr | 453 | ; Send the request |
454 | sub esi, [buffer] ; length |
||
455 | xor edi, edi ; flags |
||
456 | mcall send, [socketnum], [buffer] |
||
457 | test eax, eax |
||
458 | jz .error |
||
459 | DEBUGF 1, "Request has been sent to server.\n" |
||
460 | |||
461 | HTTP_init_buffer [buffer], [socketnum] |
||
4206 | hidnplayr | 462 | |
4216 | hidnplayr | 463 | popa |
464 | mov eax, [buffer] |
||
4158 | hidnplayr | 465 | ret ; return buffer ptr |
466 | |||
467 | .error: |
||
468 | DEBUGF 1, "Error!\n" |
||
4216 | hidnplayr | 469 | popa |
4158 | hidnplayr | 470 | xor eax, eax ; return 0 = error |
471 | ret |
||
472 | |||
473 | endp |
||
474 | |||
475 | |||
476 | |||
477 | ;;================================================================================================;; |
||
478 | proc HTTP_process identifier ;////////////////////////////////////////////////////////////////////;; |
||
479 | ;;------------------------------------------------------------------------------------------------;; |
||
4202 | hidnplayr | 480 | ;? Receive data from the server, parse headers and put data in receive buffer. ;; |
481 | ;? To complete a transfer, this procedure must be called over and over again untill it returns 0. ;; |
||
4158 | hidnplayr | 482 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 483 | ;> identifier = pointer to buffer containing http_msg struct. ;; |
4158 | hidnplayr | 484 | ;;------------------------------------------------------------------------------------------------;; |
485 | ;< eax = -1 (not finished) / 0 finished ;; |
||
486 | ;;================================================================================================;; |
||
487 | pusha |
||
488 | mov ebp, [identifier] |
||
4162 | hidnplayr | 489 | |
4209 | hidnplayr | 490 | ; If the connection is closed, return immediately |
4205 | hidnplayr | 491 | test [ebp + http_msg.flags], FLAG_CONNECTED |
492 | jz .connection_closed |
||
493 | |||
4162 | hidnplayr | 494 | ; Receive some data |
4158 | hidnplayr | 495 | mcall recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \ |
496 | [ebp + http_msg.buffer_length], MSG_DONTWAIT |
||
497 | cmp eax, 0xffffffff |
||
498 | je .check_socket |
||
4220 | hidnplayr | 499 | |
500 | test eax, eax |
||
501 | jz .server_closed |
||
4158 | hidnplayr | 502 | DEBUGF 1, "Received %u bytes\n", eax |
503 | |||
4209 | hidnplayr | 504 | ; Update timestamp |
4206 | hidnplayr | 505 | push eax |
506 | mcall 29, 9 |
||
507 | mov [ebp + http_msg.timestamp], eax |
||
508 | pop eax |
||
509 | |||
4162 | hidnplayr | 510 | ; Update pointers |
4158 | hidnplayr | 511 | mov edi, [ebp + http_msg.write_ptr] |
512 | add [ebp + http_msg.write_ptr], eax |
||
513 | sub [ebp + http_msg.buffer_length], eax |
||
514 | jz .got_all_data |
||
4162 | hidnplayr | 515 | |
516 | ; If data is chunked, combine chunks into contiguous data. |
||
517 | test [ebp + http_msg.flags], FLAG_CHUNKED |
||
518 | jnz .chunk_loop |
||
519 | |||
4212 | hidnplayr | 520 | ; Did we detect the (final) header yet? |
4158 | hidnplayr | 521 | test [ebp + http_msg.flags], FLAG_GOT_HEADER |
522 | jnz .header_parsed |
||
523 | |||
4212 | hidnplayr | 524 | ; We havent found the (final) header yet, search for it.. |
525 | .scan_again: |
||
526 | ; eax = total number of bytes received so far |
||
527 | mov eax, [ebp + http_msg.write_ptr] |
||
528 | sub eax, http_msg.data |
||
529 | sub eax, ebp |
||
530 | sub eax, [ebp + http_msg.header_length] |
||
531 | ; edi is ptr to begin of header |
||
532 | lea edi, [ebp + http_msg.data] |
||
533 | add edi, [ebp + http_msg.header_length] |
||
534 | ; put it in esi for next proc too |
||
535 | mov esi, edi |
||
536 | sub eax, 3 |
||
537 | jle .need_more_data |
||
538 | .scan_loop: |
||
4158 | hidnplayr | 539 | ; scan for end of header (empty line) |
540 | cmp dword[edi], 0x0a0d0a0d ; end of header |
||
541 | je .end_of_header |
||
4212 | hidnplayr | 542 | cmp word[edi+2], 0x0a0a ; notice the use of offset + 2, to calculate header length correctly :) |
4158 | hidnplayr | 543 | je .end_of_header |
544 | inc edi |
||
545 | dec eax |
||
4212 | hidnplayr | 546 | jnz .scan_loop |
547 | jmp .need_more_data |
||
4158 | hidnplayr | 548 | |
549 | .end_of_header: |
||
550 | add edi, 4 - http_msg.data |
||
551 | sub edi, ebp |
||
4212 | hidnplayr | 552 | mov [ebp + http_msg.header_length], edi ; If this isnt the final header, we'll use this as an offset to find real header. |
4158 | hidnplayr | 553 | DEBUGF 1, "Header length: %u\n", edi |
554 | |||
555 | ; Ok, we have found header: |
||
4212 | hidnplayr | 556 | cmp dword[esi], 'HTTP' |
4158 | hidnplayr | 557 | jne .invalid_header |
4212 | hidnplayr | 558 | cmp dword[esi+4], '/1.0' |
4158 | hidnplayr | 559 | je .http_1.0 |
4212 | hidnplayr | 560 | cmp dword[esi+4], '/1.1' |
4158 | hidnplayr | 561 | jne .invalid_header |
562 | or [ebp + http_msg.flags], FLAG_HTTP11 |
||
563 | .http_1.0: |
||
4212 | hidnplayr | 564 | cmp byte[esi+8], ' ' |
4158 | hidnplayr | 565 | jne .invalid_header |
566 | |||
4212 | hidnplayr | 567 | add esi, 9 |
4158 | hidnplayr | 568 | xor eax, eax |
569 | xor ebx, ebx |
||
570 | mov ecx, 3 |
||
571 | .statusloop: |
||
572 | lodsb |
||
573 | sub al, '0' |
||
574 | jb .invalid_header |
||
575 | cmp al, 9 |
||
576 | ja .invalid_header |
||
577 | lea ebx, [ebx + 4*ebx] |
||
578 | shl ebx, 1 |
||
579 | add ebx, eax |
||
580 | dec ecx |
||
581 | jnz .statusloop |
||
4212 | hidnplayr | 582 | |
583 | ; Ignore "100 - Continue" headers |
||
584 | cmp ebx, 100 |
||
585 | je .scan_again |
||
586 | |||
587 | DEBUGF 1, "Status: %u\n", ebx |
||
4158 | hidnplayr | 588 | mov [ebp + http_msg.status], ebx |
4212 | hidnplayr | 589 | or [ebp + http_msg.flags], FLAG_GOT_HEADER |
4158 | hidnplayr | 590 | |
591 | ; Now, convert all header names to lowercase. |
||
592 | ; This way, it will be much easier to find certain header fields, later on. |
||
593 | |||
594 | lea esi, [ebp + http_msg.data] |
||
595 | mov ecx, [ebp + http_msg.header_length] |
||
596 | .need_newline: |
||
597 | inc esi |
||
598 | dec ecx |
||
599 | jz .convert_done |
||
600 | cmp byte[esi], 10 |
||
601 | jne .need_newline |
||
602 | ; Ok, we have a newline, a line beginning with space or tabs has no header fields. |
||
603 | |||
604 | inc esi |
||
605 | dec ecx |
||
606 | jz .convert_done |
||
607 | cmp byte[esi], ' ' |
||
608 | je .need_newline |
||
609 | cmp byte[esi], 9 ; horizontal tab |
||
610 | je .need_newline |
||
611 | jmp .convert_loop |
||
612 | .next_char: |
||
613 | inc esi |
||
614 | dec ecx |
||
615 | jz .convert_done |
||
616 | .convert_loop: |
||
617 | cmp byte[esi], ':' |
||
618 | je .need_newline |
||
619 | cmp byte[esi], 'A' |
||
620 | jb .next_char |
||
621 | cmp byte[esi], 'Z' |
||
622 | ja .next_char |
||
623 | or byte[esi], 0x20 ; convert to lowercase |
||
624 | jmp .next_char |
||
625 | .convert_done: |
||
626 | mov byte[esi-1], 0 |
||
627 | lea esi, [ebp + http_msg.data] |
||
628 | DEBUGF 1, "Header names converted to lowercase:\n%s\n", esi |
||
629 | |||
630 | ; Check for content-length header field. |
||
4222 | hidnplayr | 631 | stdcall HTTP_find_header_field, ebp, str_cl |
4158 | hidnplayr | 632 | test eax, eax |
633 | jz .no_content |
||
634 | or [ebp + http_msg.flags], FLAG_CONTENT_LENGTH |
||
635 | |||
636 | xor edx, edx |
||
637 | .cl_loop: |
||
638 | movzx ebx, byte[eax] |
||
639 | inc eax |
||
640 | cmp bl, 10 |
||
641 | je .cl_ok |
||
642 | cmp bl, 13 |
||
643 | je .cl_ok |
||
644 | cmp bl, ' ' |
||
645 | je .cl_ok |
||
646 | sub bl, '0' |
||
647 | jb .invalid_header |
||
648 | cmp bl, 9 |
||
649 | ja .invalid_header |
||
650 | lea edx, [edx + edx*4] ; edx = edx*10 |
||
651 | shl edx, 1 ; |
||
652 | add edx, ebx |
||
653 | jmp .cl_loop |
||
654 | |||
655 | .cl_ok: |
||
656 | mov [ebp + http_msg.content_length], edx |
||
657 | DEBUGF 1, "Content-length: %u\n", edx |
||
658 | |||
659 | ; Resize buffer according to content-length. |
||
4168 | hidnplayr | 660 | add edx, [ebp + http_msg.header_length] |
661 | add edx, http_msg.data |
||
4158 | hidnplayr | 662 | |
4168 | hidnplayr | 663 | mov ecx, edx |
4158 | hidnplayr | 664 | sub ecx, [ebp + http_msg.write_ptr] |
665 | mov [ebp + http_msg.buffer_length], ecx |
||
666 | |||
4168 | hidnplayr | 667 | invoke mem.realloc, ebp, edx |
4158 | hidnplayr | 668 | or eax, eax |
4212 | hidnplayr | 669 | jz .no_ram |
4203 | hidnplayr | 670 | |
4220 | hidnplayr | 671 | .not_chunked: |
4212 | hidnplayr | 672 | mov eax, [ebp + http_msg.write_ptr] |
4168 | hidnplayr | 673 | sub eax, [ebp + http_msg.header_length] |
4212 | hidnplayr | 674 | sub eax, http_msg.data |
675 | sub eax, ebp |
||
4158 | hidnplayr | 676 | jmp .header_parsed ; hooray! |
677 | |||
678 | .no_content: |
||
679 | DEBUGF 1, "Content-length not found.\n" |
||
680 | |||
681 | ; We didnt find 'content-length', maybe server is using chunked transfer encoding? |
||
682 | ; Try to find 'transfer-encoding' header. |
||
4222 | hidnplayr | 683 | stdcall HTTP_find_header_field, ebp, str_te |
4158 | hidnplayr | 684 | test eax, eax |
4220 | hidnplayr | 685 | jz .not_chunked |
4158 | hidnplayr | 686 | |
687 | mov ebx, dword[eax] |
||
4162 | hidnplayr | 688 | or ebx, 0x20202020 |
4158 | hidnplayr | 689 | cmp ebx, 'chun' |
4220 | hidnplayr | 690 | jne .not_chunked |
4158 | hidnplayr | 691 | mov ebx, dword[eax+4] |
4162 | hidnplayr | 692 | or ebx, 0x00202020 |
693 | and ebx, 0x00ffffff |
||
4158 | hidnplayr | 694 | cmp ebx, 'ked' |
4220 | hidnplayr | 695 | jne .not_chunked |
4158 | hidnplayr | 696 | |
697 | or [ebp + http_msg.flags], FLAG_CHUNKED |
||
698 | DEBUGF 1, "Transfer type is: chunked\n" |
||
699 | |||
700 | ; Set chunk pointer where first chunk should begin. |
||
4162 | hidnplayr | 701 | lea eax, [ebp + http_msg.data] |
702 | add eax, [ebp + http_msg.header_length] |
||
4158 | hidnplayr | 703 | mov [ebp + http_msg.chunk_ptr], eax |
704 | |||
4162 | hidnplayr | 705 | .chunk_loop: |
4158 | hidnplayr | 706 | mov ecx, [ebp + http_msg.write_ptr] |
707 | sub ecx, [ebp + http_msg.chunk_ptr] |
||
4202 | hidnplayr | 708 | jb .need_more_data_chunked ; TODO: use this ecx !!! |
4158 | hidnplayr | 709 | |
4202 | hidnplayr | 710 | ; Chunkline starts here, convert the ASCII hex number into ebx |
4158 | hidnplayr | 711 | mov esi, [ebp + http_msg.chunk_ptr] |
712 | xor ebx, ebx |
||
713 | .chunk_hexloop: |
||
714 | lodsb |
||
715 | sub al, '0' |
||
716 | jb .chunk_ |
||
717 | cmp al, 9 |
||
718 | jbe .chunk_hex |
||
4162 | hidnplayr | 719 | sub al, 'A' - '0' - 10 |
4158 | hidnplayr | 720 | jb .chunk_ |
4162 | hidnplayr | 721 | cmp al, 15 |
4158 | hidnplayr | 722 | jbe .chunk_hex |
723 | sub al, 'a' - 'A' |
||
4162 | hidnplayr | 724 | cmp al, 15 |
4158 | hidnplayr | 725 | ja .chunk_ |
726 | .chunk_hex: |
||
727 | shl ebx, 4 |
||
728 | add bl, al |
||
729 | jmp .chunk_hexloop |
||
730 | .chunk_: |
||
731 | DEBUGF 1, "got chunk of %u bytes\n", ebx |
||
4202 | hidnplayr | 732 | ;; cmp esi, [ebp + http_msg.chunk_ptr] |
733 | ;; je |
||
4158 | hidnplayr | 734 | ; If chunk size is 0, all chunks have been received. |
735 | test ebx, ebx |
||
4162 | hidnplayr | 736 | jz .got_all_data_chunked ; last chunk, hooray! FIXME: what if it wasnt a valid hex number??? |
4158 | hidnplayr | 737 | |
738 | ; Chunkline ends with a CR, LF or simply LF |
||
4202 | hidnplayr | 739 | .end_of_chunkline?: |
4158 | hidnplayr | 740 | cmp al, 10 |
741 | je .end_of_chunkline |
||
742 | lodsb |
||
4202 | hidnplayr | 743 | cmp edi, [ebp + http_msg.write_ptr] |
744 | jb .end_of_chunkline? |
||
745 | jmp .need_more_data |
||
4158 | hidnplayr | 746 | |
747 | .end_of_chunkline: |
||
4202 | hidnplayr | 748 | ; Update chunk ptr, and remember old one |
749 | mov edi, [ebp + http_msg.chunk_ptr] |
||
750 | add [ebp + http_msg.chunk_ptr], ebx |
||
4162 | hidnplayr | 751 | ; Realloc buffer, make it 'chunksize' bigger. |
752 | mov eax, [ebp + http_msg.buffer_length] |
||
753 | add eax, ebx |
||
754 | invoke mem.realloc, ebp, eax |
||
755 | or eax, eax |
||
756 | jz .no_ram |
||
757 | add [ebp + http_msg.buffer_length], ebx |
||
758 | |||
759 | ; Update write ptr |
||
760 | mov eax, esi |
||
761 | sub eax, edi |
||
762 | sub [ebp + http_msg.write_ptr], eax |
||
763 | |||
4158 | hidnplayr | 764 | ; Now move all received data to the left (remove chunk header). |
4162 | hidnplayr | 765 | ; Update content_length accordingly. |
4158 | hidnplayr | 766 | mov ecx, [ebp + http_msg.write_ptr] |
767 | sub ecx, esi |
||
4168 | hidnplayr | 768 | add [ebp + http_msg.content_received], ecx |
4158 | hidnplayr | 769 | rep movsb |
4162 | hidnplayr | 770 | jmp .chunk_loop |
4158 | hidnplayr | 771 | |
772 | ; Check if we got all the data. |
||
4162 | hidnplayr | 773 | .header_parsed: |
4168 | hidnplayr | 774 | add [ebp + http_msg.content_received], eax |
4220 | hidnplayr | 775 | test [ebp + http_msg.flags], FLAG_CONTENT_LENGTH |
776 | jz .need_more_data_and_space |
||
4217 | hidnplayr | 777 | mov eax, [ebp + http_msg.content_received] |
778 | cmp eax, [ebp + http_msg.content_length] |
||
4168 | hidnplayr | 779 | jae .got_all_data |
4220 | hidnplayr | 780 | jmp .need_more_data |
4212 | hidnplayr | 781 | |
4220 | hidnplayr | 782 | .need_more_data_and_space: |
783 | mov eax, [ebp + http_msg.write_ptr] |
||
784 | add eax, BUFFERSIZE |
||
785 | sub eax, ebp |
||
786 | invoke mem.realloc, ebp, eax |
||
787 | or eax, eax |
||
788 | jz .no_ram |
||
789 | mov [ebp + http_msg.buffer_length], BUFFERSIZE |
||
790 | |||
4162 | hidnplayr | 791 | .need_more_data: |
792 | popa |
||
793 | xor eax, eax |
||
794 | dec eax |
||
795 | ret |
||
4158 | hidnplayr | 796 | |
4162 | hidnplayr | 797 | .need_more_data_chunked: |
4168 | hidnplayr | 798 | add [ebp + http_msg.content_received], eax |
4158 | hidnplayr | 799 | popa |
800 | xor eax, eax |
||
801 | dec eax |
||
802 | ret |
||
803 | |||
4162 | hidnplayr | 804 | .got_all_data_chunked: |
805 | mov eax, [ebp + http_msg.chunk_ptr] |
||
806 | sub eax, [ebp + http_msg.header_length] |
||
807 | sub eax, http_msg.data |
||
808 | sub eax, ebp |
||
809 | mov [ebp + http_msg.content_length], eax |
||
4168 | hidnplayr | 810 | mov [ebp + http_msg.content_received], eax |
4158 | hidnplayr | 811 | .got_all_data: |
4217 | hidnplayr | 812 | DEBUGF 1, "We got all the data! (%u bytes)\n", [ebp + http_msg.content_received] |
4205 | hidnplayr | 813 | or [ebp + http_msg.flags], FLAG_GOT_ALL_DATA |
814 | and [ebp + http_msg.flags], not FLAG_CONNECTED |
||
4158 | hidnplayr | 815 | mcall close, [ebp + http_msg.socket] |
816 | popa |
||
817 | xor eax, eax |
||
818 | ret |
||
819 | |||
820 | .check_socket: |
||
821 | cmp ebx, EWOULDBLOCK |
||
4206 | hidnplayr | 822 | jne .socket_error |
4158 | hidnplayr | 823 | |
4206 | hidnplayr | 824 | mcall 29, 9 |
825 | sub eax, TIMEOUT |
||
826 | cmp eax, [ebp + http_msg.timestamp] |
||
4207 | hidnplayr | 827 | jb .need_more_data |
4206 | hidnplayr | 828 | DEBUGF 1, "ERROR: timeout\n" |
829 | or [ebp + http_msg.flags], FLAG_TIMEOUT_ERROR |
||
830 | jmp .disconnect |
||
4158 | hidnplayr | 831 | |
4220 | hidnplayr | 832 | .server_closed: |
833 | DEBUGF 1, "server closed connection, transfer complete?\n" |
||
834 | test [ebp + http_msg.flags], FLAG_GOT_HEADER |
||
835 | jz .server_error |
||
836 | test [ebp + http_msg.flags], FLAG_CONTENT_LENGTH |
||
837 | jz .got_all_data |
||
838 | |||
839 | .server_error: |
||
840 | pop eax |
||
841 | DEBUGF 1, "ERROR: server closed connection unexpectedly\n" |
||
842 | or [ebp + http_msg.flags], FLAG_TRANSFER_FAILED |
||
843 | jmp .disconnect |
||
844 | |||
4158 | hidnplayr | 845 | .invalid_header: |
4203 | hidnplayr | 846 | pop eax |
4158 | hidnplayr | 847 | DEBUGF 1, "ERROR: invalid header\n" |
848 | or [ebp + http_msg.flags], FLAG_INVALID_HEADER |
||
4206 | hidnplayr | 849 | jmp .disconnect |
4158 | hidnplayr | 850 | |
851 | .no_ram: |
||
852 | DEBUGF 1, "ERROR: out of RAM\n" |
||
853 | or [ebp + http_msg.flags], FLAG_NO_RAM |
||
4206 | hidnplayr | 854 | jmp .disconnect |
855 | |||
856 | .socket_error: |
||
857 | DEBUGF 1, "ERROR: socket error %u\n", ebx |
||
858 | or [ebp + http_msg.flags], FLAG_SOCKET_ERROR |
||
859 | .disconnect: |
||
4205 | hidnplayr | 860 | and [ebp + http_msg.flags], not FLAG_CONNECTED |
861 | mcall close, [ebp + http_msg.socket] |
||
4206 | hidnplayr | 862 | .connection_closed: |
4158 | hidnplayr | 863 | popa |
864 | xor eax, eax |
||
865 | ret |
||
866 | |||
867 | endp |
||
868 | |||
869 | |||
870 | |||
4205 | hidnplayr | 871 | |
4158 | hidnplayr | 872 | ;;================================================================================================;; |
4205 | hidnplayr | 873 | proc HTTP_free identifier ;///////////////////////////////////////////////////////////////////////;; |
874 | ;;------------------------------------------------------------------------------------------------;; |
||
875 | ;? Free the http_msg structure ;; |
||
876 | ;;------------------------------------------------------------------------------------------------;; |
||
877 | ;> identifier = pointer to buffer containing http_msg struct. ;; |
||
878 | ;;------------------------------------------------------------------------------------------------;; |
||
879 | ;< none ;; |
||
880 | ;;================================================================================================;; |
||
881 | |||
882 | pusha |
||
883 | mov ebp, [identifier] |
||
884 | |||
885 | test [ebp + http_msg.flags], FLAG_CONNECTED |
||
886 | jz .not_connected |
||
887 | |||
888 | and [ebp + http_msg.flags], not FLAG_CONNECTED |
||
889 | mcall close, [ebp + http_msg.socket] |
||
890 | |||
891 | .not_connected: |
||
892 | invoke mem.free, ebp |
||
893 | |||
894 | popa |
||
895 | ret |
||
896 | |||
897 | endp |
||
898 | |||
899 | |||
900 | |||
901 | ;;================================================================================================;; |
||
902 | proc HTTP_stop identifier ;///////////////////////////////////////////////////////////////////////;; |
||
903 | ;;------------------------------------------------------------------------------------------------;; |
||
904 | ;? Stops the open connection ;; |
||
905 | ;;------------------------------------------------------------------------------------------------;; |
||
906 | ;> identifier = pointer to buffer containing http_msg struct. ;; |
||
907 | ;;------------------------------------------------------------------------------------------------;; |
||
908 | ;< none ;; |
||
909 | ;;================================================================================================;; |
||
910 | |||
911 | pusha |
||
912 | mov ebp, [identifier] |
||
913 | |||
914 | and [ebp + http_msg.flags], not FLAG_CONNECTED |
||
915 | mcall close, [ebp + http_msg.socket] |
||
916 | |||
917 | popa |
||
918 | ret |
||
919 | |||
920 | endp |
||
921 | |||
922 | |||
923 | |||
924 | ;;================================================================================================;; |
||
4222 | hidnplayr | 925 | proc HTTP_find_header_field identifier, headername ;//////////////////////////////////////////////;; |
4158 | hidnplayr | 926 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 927 | ;? Find a header field in the received HTTP header ;; |
4158 | hidnplayr | 928 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 929 | ;> identifier = ptr to http_msg struct ;; |
930 | ;> headername = ptr to ASCIIZ string containg field you want to find (must be in lowercase) ;; |
||
4158 | hidnplayr | 931 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 932 | ;< eax = 0 (error) / ptr to content of the HTTP header field ;; |
4158 | hidnplayr | 933 | ;;================================================================================================;; |
934 | push ebx ecx edx esi edi |
||
935 | |||
936 | DEBUGF 1, "Find header field: %s\n", [headername] |
||
937 | |||
938 | mov ebx, [identifier] |
||
4202 | hidnplayr | 939 | test [ebx + http_msg.flags], FLAG_GOT_HEADER |
940 | jz .fail |
||
941 | |||
4158 | hidnplayr | 942 | lea edx, [ebx + http_msg.data] |
943 | mov ecx, edx |
||
944 | add ecx, [ebx + http_msg.header_length] |
||
945 | |||
946 | .restart: |
||
947 | mov esi, [headername] |
||
948 | mov edi, edx |
||
949 | .loop: |
||
950 | cmp edi, ecx |
||
951 | jae .fail |
||
952 | lodsb |
||
953 | scasb |
||
954 | je .loop |
||
955 | test al, al |
||
956 | jz .done? |
||
957 | .next: |
||
958 | inc edx |
||
959 | jmp .restart |
||
960 | |||
961 | .not_done: |
||
962 | inc edi |
||
963 | .done?: |
||
964 | cmp byte[edi-1], ':' |
||
965 | je .almost_done |
||
966 | cmp byte[edi-1], ' ' |
||
967 | je .not_done |
||
968 | cmp byte[edi-1], 9 ; tab |
||
969 | je .not_done |
||
970 | |||
971 | jmp .next |
||
972 | |||
973 | .almost_done: ; FIXME: buffer overflow? |
||
974 | dec edi |
||
975 | DEBUGF 1, "Found header field\n" |
||
976 | .spaceloop: |
||
977 | inc edi |
||
978 | cmp byte[edi], ' ' |
||
979 | je .spaceloop |
||
980 | cmp byte[edi], 9 ; tab |
||
981 | je .spaceloop |
||
982 | |||
983 | mov eax, edi |
||
984 | pop edi esi edx ecx ebx |
||
985 | ret |
||
986 | |||
987 | .fail: |
||
988 | pop edi esi edx ecx ebx |
||
989 | xor eax, eax |
||
990 | ret |
||
991 | |||
992 | endp |
||
993 | |||
994 | |||
995 | |||
4209 | hidnplayr | 996 | ;;================================================================================================;; |
997 | proc URI_escape URI ;/////////////////////////////////////////////////////////////////////////////;; |
||
998 | ;;------------------------------------------------------------------------------------------------;; |
||
999 | ;? ;; |
||
1000 | ;;------------------------------------------------------------------------------------------------;; |
||
1001 | ;> URI = ptr to ASCIIZ URI ;; |
||
1002 | ;;------------------------------------------------------------------------------------------------;; |
||
1003 | ;< eax = 0 (error) / ptr to ASCIIZ URI ;; |
||
1004 | ;;================================================================================================;; |
||
4202 | hidnplayr | 1005 | |
4209 | hidnplayr | 1006 | pusha |
4205 | hidnplayr | 1007 | |
4209 | hidnplayr | 1008 | invoke mem.alloc, URLMAXLEN |
1009 | test eax, eax |
||
1010 | jz .error |
||
1011 | mov [esp + 7 * 4], eax ; return ptr in eax |
||
1012 | mov esi, [URI] |
||
1013 | mov edi, eax |
||
1014 | xor ebx, ebx |
||
1015 | xor ecx, ecx |
||
1016 | .loop: |
||
1017 | lodsb |
||
1018 | test al, al |
||
1019 | jz .done |
||
1020 | |||
1021 | mov cl, al |
||
1022 | and cl, 0x1f |
||
1023 | mov bl, al |
||
1024 | shr bl, 5 |
||
1025 | bt dword[bits_must_escape + ebx], ecx |
||
1026 | jc .escape |
||
1027 | |||
1028 | stosb |
||
1029 | jmp .loop |
||
1030 | |||
1031 | .escape: |
||
1032 | mov al, '%' |
||
1033 | stosb |
||
1034 | mov bl, byte[esi-1] |
||
1035 | shr bl, 4 |
||
1036 | mov al, byte[str_hex + ebx] |
||
1037 | stosb |
||
1038 | mov bl, byte[esi-1] |
||
1039 | and bl, 0x0f |
||
1040 | mov al, byte[str_hex + ebx] |
||
1041 | stosb |
||
1042 | jmp .loop |
||
1043 | |||
1044 | |||
1045 | .done: |
||
1046 | stosb |
||
1047 | |||
1048 | popa |
||
1049 | ret |
||
1050 | |||
1051 | .error: |
||
1052 | popa |
||
1053 | xor eax, eax |
||
1054 | ret |
||
1055 | |||
1056 | endp |
||
1057 | |||
1058 | |||
1059 | |||
4167 | hidnplayr | 1060 | ;;================================================================================================;; |
4209 | hidnplayr | 1061 | proc URI_unescape URI ;///////////////////////////////////////////////////////////////////////////;; |
1062 | ;;------------------------------------------------------------------------------------------------;; |
||
1063 | ;? ;; |
||
1064 | ;;------------------------------------------------------------------------------------------------;; |
||
1065 | ;> URI = ptr to ASCIIZ URI ;; |
||
1066 | ;;------------------------------------------------------------------------------------------------;; |
||
1067 | ;< eax = 0 (error) / ptr to ASCIIZ URI ;; |
||
1068 | ;;================================================================================================;; |
||
1069 | |||
1070 | pusha |
||
1071 | |||
1072 | invoke mem.alloc, URLMAXLEN |
||
1073 | test eax, eax |
||
1074 | jz .error |
||
1075 | mov [esp + 7 * 4], eax ; return ptr in eax |
||
1076 | mov esi, [URI] |
||
1077 | mov edi, eax |
||
1078 | .loop: |
||
1079 | lodsb |
||
1080 | test al, al |
||
1081 | jz .done |
||
1082 | |||
1083 | cmp al, '%' |
||
1084 | je .unescape |
||
1085 | |||
1086 | stosb |
||
1087 | jmp .loop |
||
1088 | |||
1089 | .unescape: |
||
1090 | xor ebx, ebx |
||
1091 | xor ecx, ecx |
||
1092 | .unescape_nibble: |
||
1093 | lodsb |
||
1094 | sub al, '0' |
||
1095 | jb .fail |
||
1096 | cmp al, 9 |
||
1097 | jbe .nibble_ok |
||
1098 | sub al, 'A' - '0' - 10 |
||
1099 | jb .fail |
||
1100 | cmp al, 15 |
||
1101 | jbe .nibble_ok |
||
1102 | sub al, 'a' - 'A' |
||
1103 | cmp al, 15 |
||
1104 | ja .fail |
||
1105 | .nibble_ok: |
||
1106 | shl bl, 8 |
||
1107 | or bl, al |
||
1108 | dec ecx |
||
1109 | jc .unescape_nibble |
||
1110 | mov al, bl |
||
1111 | stosb |
||
1112 | jmp .loop |
||
1113 | |||
1114 | .fail: |
||
1115 | DEBUGF 1, "ERROR: invalid URI!\n" |
||
1116 | jmp .loop |
||
1117 | |||
1118 | .done: |
||
1119 | stosb |
||
1120 | |||
1121 | popa |
||
1122 | ret |
||
1123 | |||
1124 | .error: |
||
1125 | popa |
||
1126 | xor eax, eax |
||
1127 | ret |
||
1128 | |||
1129 | endp |
||
1130 | |||
1131 | |||
1132 | |||
1133 | |||
1134 | |||
1135 | ;;================================================================================================;; |
||
4202 | hidnplayr | 1136 | ;;////////////////////////////////////////////////////////////////////////////////////////////////;; |
1137 | ;;================================================================================================;; |
||
1138 | ;! Internal procedures section ;; |
||
4220 | hidnplayr | 1139 | ;; ;; |
1140 | ;; NOTICE: These procedures do not follow stdcall conventions and thus may destroy any register. ;; |
||
4202 | hidnplayr | 1141 | ;;================================================================================================;; |
1142 | ;;////////////////////////////////////////////////////////////////////////////////////////////////;; |
||
1143 | ;;================================================================================================;; |
||
1144 | |||
1145 | |||
1146 | |||
1147 | |||
1148 | ;;================================================================================================;; |
||
4167 | hidnplayr | 1149 | proc open_connection hostname, port ;/////////////////////////////////////////////////////////////;; |
1150 | ;;------------------------------------------------------------------------------------------------;; |
||
4202 | hidnplayr | 1151 | ;? Connects to a HTTP server ;; |
4167 | hidnplayr | 1152 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 1153 | ;> hostname = ptr to ASCIIZ hostname ;; |
1154 | ;> port = port (x86 byte order) ;; |
||
4167 | hidnplayr | 1155 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 1156 | ;< eax = 0 (error) / socketnum ;; |
4167 | hidnplayr | 1157 | ;;================================================================================================;; |
4158 | hidnplayr | 1158 | |
4167 | hidnplayr | 1159 | locals |
1160 | sockaddr dd ? |
||
1161 | socketnum dd ? |
||
1162 | endl |
||
1163 | |||
4233 | hidnplayr | 1164 | cmp [proxyAddr], 0 |
1165 | je .no_proxy |
||
1166 | |||
1167 | mov [hostname], proxyAddr |
||
1168 | |||
1169 | push [proxyPort] |
||
1170 | pop [port] |
||
1171 | .no_proxy: |
||
1172 | |||
4167 | hidnplayr | 1173 | ; Resolve the hostname |
1174 | DEBUGF 1, "Resolving hostname\n" |
||
1175 | push esp ; reserve stack place |
||
1176 | push esp ; fourth parameter |
||
1177 | push 0 ; third parameter |
||
1178 | push 0 ; second parameter |
||
1179 | push [hostname] |
||
1180 | call [getaddrinfo] |
||
1181 | pop esi |
||
1182 | test eax, eax |
||
1183 | jnz .error1 |
||
1184 | |||
1185 | ; getaddrinfo returns addrinfo struct, make the pointer to sockaddr struct |
||
1186 | mov esi, [esi + addrinfo.ai_addr] |
||
1187 | mov [sockaddr], esi |
||
1188 | mov eax, [esi + sockaddr_in.sin_addr] |
||
1189 | test eax, eax |
||
1190 | jz .error2 |
||
1191 | |||
1192 | DEBUGF 1, "Server ip=%u.%u.%u.%u\n", \ |
||
1193 | [esi + sockaddr_in.sin_addr]:1, [esi + sockaddr_in.sin_addr + 1]:1, \ |
||
1194 | [esi + sockaddr_in.sin_addr + 2]:1, [esi + sockaddr_in.sin_addr + 3]:1 |
||
1195 | |||
1196 | mov [esi + sockaddr_in.sin_family], AF_INET4 |
||
1197 | mov eax, [port] |
||
1198 | xchg al, ah |
||
1199 | mov [esi + sockaddr_in.sin_port], ax |
||
1200 | |||
1201 | ; Connect to the server. |
||
1202 | mcall socket, AF_INET4, SOCK_STREAM, 0 |
||
1203 | test eax, eax |
||
1204 | jz .error2 |
||
1205 | mov [socketnum], eax |
||
1206 | DEBUGF 1, "Socket: 0x%x\n", eax |
||
1207 | |||
1208 | mcall connect, [socketnum], [sockaddr], 18 |
||
1209 | test eax, eax |
||
1210 | jnz .error2 |
||
1211 | DEBUGF 1, "Socket is now connected.\n" |
||
1212 | |||
1213 | ; free allocated memory |
||
1214 | push [sockaddr] |
||
1215 | call [freeaddrinfo] |
||
1216 | |||
1217 | mov eax, [socketnum] |
||
1218 | ret |
||
1219 | |||
1220 | .error2: |
||
1221 | |||
1222 | ; free allocated memory |
||
1223 | push [sockaddr] |
||
1224 | call [freeaddrinfo] |
||
1225 | |||
1226 | .error1: |
||
1227 | xor eax, eax |
||
1228 | ret |
||
1229 | |||
1230 | endp |
||
1231 | |||
1232 | |||
4158 | hidnplayr | 1233 | ;;================================================================================================;; |
1234 | proc parse_url URL ;//////////////////////////////////////////////////////////////////////////////;; |
||
1235 | ;;------------------------------------------------------------------------------------------------;; |
||
4202 | hidnplayr | 1236 | ;? Split a given URL into hostname and pageaddr ;; |
4158 | hidnplayr | 1237 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 1238 | ;> URL = ptr to ASCIIZ URL ;; |
4158 | hidnplayr | 1239 | ;;------------------------------------------------------------------------------------------------;; |
4202 | hidnplayr | 1240 | ;< eax = 0 (error) / ptr to ASCIIZ hostname ;; |
1241 | ;< ebx = ptr to ASCIIZ pageaddr ;; |
||
4233 | hidnplayr | 1242 | ;< ecx = port number ;; |
4158 | hidnplayr | 1243 | ;;================================================================================================;; |
1244 | |||
1245 | locals |
||
1246 | urlsize dd ? |
||
1247 | hostname dd ? |
||
1248 | pageaddr dd ? |
||
4233 | hidnplayr | 1249 | port dd ? |
4158 | hidnplayr | 1250 | endl |
1251 | |||
4161 | hidnplayr | 1252 | DEBUGF 1, "parsing URL: %s\n", [URL] |
4158 | hidnplayr | 1253 | |
1254 | ; remove any leading protocol text |
||
1255 | mov esi, [URL] |
||
1256 | mov ecx, URLMAXLEN |
||
1257 | mov ax, '//' |
||
1258 | .loop1: |
||
1259 | cmp byte[esi], 0 ; end of URL? |
||
1260 | je .url_ok ; yep, so not found |
||
1261 | cmp [esi], ax |
||
1262 | je .skip_proto |
||
1263 | inc esi |
||
1264 | dec ecx |
||
1265 | jnz .loop1 |
||
4233 | hidnplayr | 1266 | jmp .invalid |
4158 | hidnplayr | 1267 | |
1268 | .skip_proto: |
||
1269 | inc esi ; skip the two '/' |
||
1270 | inc esi |
||
1271 | mov [URL], esi ; update pointer so it skips protocol |
||
1272 | jmp .loop1 ; we still need to find the length of the URL |
||
1273 | |||
1274 | .url_ok: |
||
1275 | sub esi, [URL] ; calculate total length of URL |
||
1276 | mov [urlsize], esi |
||
1277 | |||
1278 | |||
1279 | ; now look for page delimiter - it's a '/' character |
||
1280 | mov ecx, esi ; URL length |
||
1281 | mov edi, [URL] |
||
1282 | mov al, '/' |
||
1283 | repne scasb |
||
4161 | hidnplayr | 1284 | jne @f |
4158 | hidnplayr | 1285 | dec edi ; return one char, '/' must be part of the pageaddr |
1286 | inc ecx ; |
||
4161 | hidnplayr | 1287 | @@: |
4158 | hidnplayr | 1288 | push ecx edi ; remember the pointer and length of pageaddr |
1289 | |||
4222 | hidnplayr | 1290 | |
4233 | hidnplayr | 1291 | ; Create new buffer and put hostname in it. |
4158 | hidnplayr | 1292 | mov ecx, edi |
1293 | sub ecx, [URL] |
||
1294 | inc ecx ; we will add a 0 byte at the end |
||
1295 | invoke mem.alloc, ecx |
||
1296 | or eax, eax |
||
1297 | jz .no_mem |
||
1298 | |||
1299 | mov [hostname], eax ; copy hostname to buffer |
||
1300 | mov edi, eax |
||
1301 | mov esi, [URL] |
||
1302 | dec ecx |
||
1303 | rep movsb |
||
1304 | xor al, al |
||
1305 | stosb |
||
1306 | |||
4233 | hidnplayr | 1307 | ; Check if user provided a port, and convert it if so. |
1308 | mov esi, [hostname] |
||
1309 | mov [port], 80 ; default port if user didnt provide one |
||
1310 | .portloop: |
||
1311 | lodsb |
||
1312 | test al, al |
||
1313 | jz .no_port |
||
1314 | cmp al, ':' |
||
1315 | jne .portloop |
||
1316 | |||
1317 | push esi |
||
1318 | call ascii_dec_ebx |
||
1319 | pop edi |
||
1320 | cmp byte[esi-1], 0 |
||
1321 | jne .invalid |
||
1322 | cmp [proxyAddr], 0 ; remove port number from hostname |
||
1323 | jne @f ; unless when we are using proxy |
||
1324 | mov byte[edi-1], 0 |
||
1325 | @@: |
||
1326 | test ebx, ebx |
||
1327 | je .invalid |
||
1328 | cmp ebx, 0xffff |
||
1329 | ja .invalid |
||
1330 | mov [port], ebx |
||
1331 | .no_port: |
||
1332 | |||
1333 | |||
1334 | ; Did user provide a pageaddr? |
||
4161 | hidnplayr | 1335 | mov [pageaddr], str_slash ; assume there is no pageaddr |
4158 | hidnplayr | 1336 | pop esi ecx |
1337 | test ecx, ecx |
||
1338 | jz .no_page |
||
4233 | hidnplayr | 1339 | |
1340 | ; Create new buffer and put pageaddr into it. |
||
4158 | hidnplayr | 1341 | inc ecx ; we will add a 0 byte at the end |
1342 | invoke mem.alloc, ecx |
||
1343 | or eax, eax |
||
1344 | jz .no_mem |
||
1345 | |||
1346 | mov [pageaddr], eax ; copy pageaddr to buffer |
||
1347 | mov edi, eax |
||
1348 | dec ecx |
||
1349 | rep movsb |
||
1350 | xor al, al |
||
1351 | stosb |
||
4233 | hidnplayr | 1352 | |
4158 | hidnplayr | 1353 | .no_page: |
1354 | mov eax, [hostname] |
||
1355 | mov ebx, [pageaddr] |
||
4233 | hidnplayr | 1356 | mov ecx, [port] |
4158 | hidnplayr | 1357 | |
1358 | DEBUGF 1, "hostname: %s\n", eax |
||
1359 | DEBUGF 1, "pageaddr: %s\n", ebx |
||
4221 | hidnplayr | 1360 | DEBUGF 1, "port: %u\n", ecx |
4158 | hidnplayr | 1361 | |
1362 | ret |
||
1363 | |||
1364 | .no_mem: |
||
4233 | hidnplayr | 1365 | DEBUGF 1, "Out of memory!\n" |
4158 | hidnplayr | 1366 | xor eax, eax |
1367 | ret |
||
1368 | |||
4233 | hidnplayr | 1369 | .invalid: |
1370 | DEBUGF 1, "Invalid URL!\n" |
||
1371 | xor eax, eax |
||
1372 | ret |
||
1373 | |||
4158 | hidnplayr | 1374 | endp |
1375 | |||
1376 | |||
4233 | hidnplayr | 1377 | |
1378 | |||
1379 | |||
4202 | hidnplayr | 1380 | ;;================================================================================================;; |
4233 | hidnplayr | 1381 | proc append_proxy_auth_header ;///////////////////////////////////////////////////////////////////;; |
4202 | hidnplayr | 1382 | ;;------------------------------------------------------------------------------------------------;; |
4233 | hidnplayr | 1383 | ;? Appends the proxy authentication header ;; |
1384 | ;;------------------------------------------------------------------------------------------------;; |
||
1385 | ;> / ;; |
||
1386 | ;;------------------------------------------------------------------------------------------------;; |
||
1387 | ;< / ;; |
||
1388 | ;;================================================================================================;; |
||
1389 | mov esi, str_proxy_auth |
||
1390 | mov ecx, str_proxy_auth.length |
||
1391 | rep movsb |
||
1392 | ; base64-encode string |
||
1393 | mov esi, proxyUser |
||
1394 | |||
1395 | apah000: |
||
1396 | lodsb |
||
1397 | test al, al |
||
1398 | jz apah001 |
||
1399 | call encode_base64_byte |
||
1400 | jmp apah000 |
||
1401 | |||
1402 | apah001: |
||
1403 | mov al, ':' |
||
1404 | call encode_base64_byte |
||
1405 | mov esi, proxyPassword |
||
1406 | |||
1407 | apah002: |
||
1408 | lodsb |
||
1409 | test al, al |
||
1410 | jz apah003 |
||
1411 | call encode_base64_byte |
||
1412 | jmp apah002 |
||
1413 | |||
1414 | apah003: |
||
1415 | call encode_base64_final |
||
1416 | ret |
||
1417 | |||
1418 | encode_base64_byte: |
||
1419 | inc ecx |
||
1420 | shl edx, 8 |
||
1421 | mov dl, al |
||
1422 | cmp ecx, 3 |
||
1423 | je ebb001 |
||
1424 | ret |
||
1425 | |||
1426 | ebb001: |
||
1427 | shl edx, 8 |
||
1428 | inc ecx |
||
1429 | |||
1430 | ebb002: |
||
1431 | rol edx, 6 |
||
1432 | xor eax, eax |
||
1433 | xchg al, dl |
||
1434 | mov al, [base64_table+eax] |
||
1435 | stosb |
||
1436 | loop ebb002 |
||
1437 | ret |
||
1438 | |||
1439 | encode_base64_final: |
||
1440 | mov al, 0 |
||
1441 | test ecx, ecx |
||
1442 | jz ebf000 |
||
1443 | call encode_base64_byte |
||
1444 | test ecx, ecx |
||
1445 | jz ebf001 |
||
1446 | call encode_base64_byte |
||
1447 | mov byte [edi-2], '=' |
||
1448 | |||
1449 | ebf001: |
||
1450 | mov byte [edi-1], '=' |
||
1451 | |||
1452 | ebf000: |
||
1453 | ret |
||
1454 | |||
1455 | endp |
||
1456 | |||
1457 | |||
1458 | ;;================================================================================================;; |
||
1459 | proc eax_ascii_dec ;//////////////////////////////////////////////////////////////////////////////;; |
||
1460 | ;;------------------------------------------------------------------------------------------------;; |
||
4202 | hidnplayr | 1461 | ;? Convert eax to ASCII decimal number ;; |
1462 | ;;------------------------------------------------------------------------------------------------;; |
||
1463 | ;> eax = number ;; |
||
1464 | ;> edi = ptr where to write ASCII decimal number ;; |
||
1465 | ;;------------------------------------------------------------------------------------------------;; |
||
1466 | ;< / ;; |
||
1467 | ;;================================================================================================;; |
||
4158 | hidnplayr | 1468 | |
4168 | hidnplayr | 1469 | push -'0' |
4167 | hidnplayr | 1470 | mov ecx, 10 |
1471 | .loop: |
||
1472 | xor edx, edx |
||
1473 | div ecx |
||
1474 | add dl, '0' |
||
4168 | hidnplayr | 1475 | push edx |
4167 | hidnplayr | 1476 | test eax, eax |
1477 | jnz .loop |
||
4158 | hidnplayr | 1478 | |
4168 | hidnplayr | 1479 | .loop2: |
1480 | pop eax |
||
1481 | add al, '0' |
||
1482 | jz .done |
||
1483 | stosb |
||
1484 | jmp .loop2 |
||
1485 | .done: |
||
1486 | |||
4167 | hidnplayr | 1487 | ret |
4158 | hidnplayr | 1488 | |
4202 | hidnplayr | 1489 | endp |
4167 | hidnplayr | 1490 | |
4202 | hidnplayr | 1491 | |
4158 | hidnplayr | 1492 | ;;================================================================================================;; |
4233 | hidnplayr | 1493 | proc ascii_dec_ebx ;//////////////////////////////////////////////////////////////////////////////;; |
1494 | ;;------------------------------------------------------------------------------------------------;; |
||
1495 | ;? Convert ASCII decimal number to ebx ;; |
||
1496 | ;;------------------------------------------------------------------------------------------------;; |
||
1497 | ;> esi = ptr where to read ASCII decimal number ;; |
||
1498 | ;;------------------------------------------------------------------------------------------------;; |
||
1499 | ;> ebx = number ;; |
||
1500 | ;;================================================================================================;; |
||
1501 | |||
1502 | xor eax, eax |
||
1503 | xor ebx, ebx |
||
1504 | .loop: |
||
1505 | lodsb |
||
1506 | sub al, '0' |
||
1507 | jb .done |
||
1508 | cmp al, 9 |
||
1509 | ja .done |
||
1510 | lea ebx, [ebx + 4*ebx] |
||
1511 | shl ebx, 1 |
||
1512 | add ebx, eax |
||
1513 | jmp .loop |
||
1514 | .done: |
||
1515 | |||
1516 | ret |
||
1517 | |||
1518 | endp |
||
1519 | |||
1520 | |||
1521 | ;;================================================================================================;; |
||
4158 | hidnplayr | 1522 | ;;////////////////////////////////////////////////////////////////////////////////////////////////;; |
1523 | ;;================================================================================================;; |
||
1524 | ;! Imported functions section ;; |
||
1525 | ;;================================================================================================;; |
||
1526 | ;;////////////////////////////////////////////////////////////////////////////////////////////////;; |
||
1527 | ;;================================================================================================;; |
||
1528 | |||
1529 | |||
1530 | align 16 |
||
1531 | @IMPORT: |
||
1532 | |||
1533 | library \ |
||
1534 | libini, 'libini.obj', \ |
||
1535 | network, 'network.obj' |
||
1536 | |||
1537 | import libini, \ |
||
1538 | ini.get_str, 'ini_get_str', \ |
||
1539 | ini.get_int, 'ini_get_int' |
||
1540 | |||
1541 | import network,\ |
||
1542 | getaddrinfo, 'getaddrinfo',\ |
||
1543 | freeaddrinfo, 'freeaddrinfo',\ |
||
1544 | inet_ntoa, 'inet_ntoa' |
||
1545 | |||
1546 | ;;===========================================================================;; |
||
1547 | ;;///////////////////////////////////////////////////////////////////////////;; |
||
1548 | ;;===========================================================================;; |
||
1549 | ;! Exported functions section ;; |
||
1550 | ;;===========================================================================;; |
||
1551 | ;;///////////////////////////////////////////////////////////////////////////;; |
||
1552 | ;;===========================================================================;; |
||
1553 | |||
1554 | |||
1555 | align 4 |
||
1556 | @EXPORT: |
||
1557 | export \ |
||
1558 | lib_init , 'lib_init' , \ |
||
1559 | 0x00010001 , 'version' , \ |
||
1560 | HTTP_get , 'get' , \ |
||
4167 | hidnplayr | 1561 | HTTP_head , 'head' , \ |
1562 | HTTP_post , 'post' , \ |
||
4222 | hidnplayr | 1563 | HTTP_find_header_field , 'find_header_field' , \ |
4205 | hidnplayr | 1564 | HTTP_process , 'process' , \ |
1565 | HTTP_free , 'free' , \ |
||
4209 | hidnplayr | 1566 | HTTP_stop , 'stop' , \ |
1567 | URI_escape , 'escape' , \ |
||
1568 | URI_unescape , 'unescape' |
||
4158 | hidnplayr | 1569 | |
1570 | ; HTTP_put , 'put' , \ |
||
1571 | ; HTTP_delete , 'delete' , \ |
||
1572 | ; HTTP_trace , 'trace' , \ |
||
1573 | ; HTTP_connect , 'connect' , \ |
||
1574 | |||
1575 | |||
1576 | |||
1577 | section '.data' data readable writable align 16 |
||
1578 | |||
1579 | inifile db '/sys/settings/network.ini', 0 |
||
1580 | |||
1581 | sec_proxy: |
||
1582 | key_proxy db 'proxy', 0 |
||
1583 | key_proxyport db 'port', 0 |
||
1584 | key_user db 'user', 0 |
||
1585 | key_password db 'password', 0 |
||
1586 | |||
1587 | str_http11 db ' HTTP/1.1', 13, 10, 'Host: ' |
||
1588 | .length = $ - str_http11 |
||
4167 | hidnplayr | 1589 | str_post_cl db 13, 10, 'Content-Length: ' |
1590 | .length = $ - str_post_cl |
||
1591 | str_post_ct db 13, 10, 'Content-Type: ' |
||
1592 | .length = $ - str_post_ct |
||
4158 | hidnplayr | 1593 | str_close db 13, 10, 'User-Agent: KolibriOS libHTTP/1.0', 13, 10, 'Connection: Close', 13, 10, 13, 10 |
1594 | .length = $ - str_close |
||
1595 | str_proxy_auth db 13, 10, 'Proxy-Authorization: Basic ' |
||
1596 | .length = $ - str_proxy_auth |
||
1597 | |||
4233 | hidnplayr | 1598 | str_http db 'http://', 0 |
1599 | |||
4158 | hidnplayr | 1600 | base64_table db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' |
1601 | db '0123456789+/' |
||
1602 | |||
1603 | str_cl db 'content-length', 0 |
||
4161 | hidnplayr | 1604 | str_slash db '/', 0 |
4158 | hidnplayr | 1605 | str_te db 'transfer-encoding', 0 |
4167 | hidnplayr | 1606 | str_get db 'GET ', 0 |
1607 | str_head db 'HEAD ', 0 |
||
1608 | str_post db 'POST ', 0 |
||
4158 | hidnplayr | 1609 | |
4209 | hidnplayr | 1610 | bits_must_escape: |
1611 | dd 0xffffffff ; 00-1F |
||
1612 | dd 1 shl 0 + 1 shl 2 + 1 shl 3 + 1 shl 5 + 1 shl 28 + 1 shl 30 ; "#%<> |
||
1613 | dd 1 shl 27 + 1 shl 28 + 1 shl 29 + 1 shl 30 ;[\]^ |
||
1614 | dd 1 shl 0 + 1 shl 27 + 1 shl 28 + 1 shl 29 + 1 shl 31 ;`{|} DEL |
||
1615 | |||
1616 | dd 0xffffffff |
||
1617 | dd 0xffffffff |
||
1618 | dd 0xffffffff |
||
1619 | dd 0xffffffff |
||
1620 | |||
1621 | str_hex: |
||
1622 | db '0123456789ABCDEF' |
||
1623 | |||
4158 | hidnplayr | 1624 | include_debug_strings |
1625 | |||
1626 | ; uninitialized data |
||
1627 | mem.alloc dd ? |
||
1628 | mem.free dd ? |
||
1629 | mem.realloc dd ? |
||
1630 | dll.load dd ? |
||
1631 | |||
1632 | proxyAddr rb 256 |
||
1633 | proxyUser rb 256 |
||
1634 | proxyPassword rb 256 |
||
1635 | proxyPort dd ?>>>>>>>>>>>>>>>>> |