Subversion Repositories Kolibri OS

Rev

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