Subversion Repositories Kolibri OS

Rev

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