Subversion Repositories Kolibri OS

Rev

Rev 4158 | Rev 4162 | 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
22
 
23
        __DEBUG__       = 1
24
        __DEBUG_LEVEL__ = 1
25
 
26
 
27
format MS COFF
28
 
29
public @EXPORT as 'EXPORTS'
30
 
31
include '../../../struct.inc'
32
include '../../../proc32.inc'
33
include '../../../macros.inc'
34
purge section,mov,add,sub
35
include '../../../debug-fdo.inc'
36
 
37
include '../../../network.inc'
38
include 'http.inc'
39
 
40
virtual at 0
41
        http_msg http_msg
42
end virtual
43
 
44
macro copy_till_zero {
45
  @@:
46
        lodsb
47
        test    al, al
48
        jz      @f
49
        stosb
50
        jmp     @r
51
  @@:
52
}
53
 
54
section '.flat' code readable align 16
55
 
56
;;===========================================================================;;
57
lib_init: ;//////////////////////////////////////////////////////////////////;;
58
;;---------------------------------------------------------------------------;;
59
;? Library entry point (called after library load)                           ;;
60
;;---------------------------------------------------------------------------;;
61
;> eax = pointer to memory allocation routine                                ;;
62
;> ebx = pointer to memory freeing routine                                   ;;
63
;> ecx = pointer to memory reallocation routine                              ;;
64
;> edx = pointer to library loading routine                                  ;;
65
;;---------------------------------------------------------------------------;;
66
;< eax = 1 (fail) / 0 (ok) (library initialization result)                   ;;
67
;;===========================================================================;;
68
        mov     [mem.alloc], eax
69
        mov     [mem.free], ebx
70
        mov     [mem.realloc], ecx
71
        mov     [dll.load], edx
72
 
73
        invoke  dll.load, @IMPORT
74
        or      eax, eax
75
        jz      .ok
76
 
77
; load proxy settings
78
        invoke  ini.get_str, inifile, sec_proxy, key_proxy, proxyAddr, 256, proxyAddr
79
        invoke  ini.get_int, inifile, sec_proxy, key_proxyport, 80
80
        mov     [proxyPort], eax
81
        invoke  ini.get_str, inifile, sec_proxy, key_user, proxyUser, 256, proxyUser
82
        invoke  ini.get_str, inifile, sec_proxy, key_password, proxyPassword, 256, proxyPassword
83
 
84
        xor     eax, eax
85
        inc     eax
86
        ret
87
 
88
  .ok:
89
        xor     eax, eax
90
        ret
91
 
92
 
93
 
94
 
95
 
96
;;================================================================================================;;
97
proc HTTP_get URL ;///////////////////////////////////////////////////////////////////////////////;;
98
;;------------------------------------------------------------------------------------------------;;
99
;?                                                                                                ;;
100
;;------------------------------------------------------------------------------------------------;;
101
;> _                                                                                              ;;
102
;;------------------------------------------------------------------------------------------------;;
103
;< eax = 0 (error) / buffer ptr                                                                   ;;
104
;;================================================================================================;;
105
locals
106
        hostname        dd ?
107
        pageaddr        dd ?
108
        sockaddr        dd ?
109
        socketnum       dd ?
110
        buffer          dd ?
111
endl
112
 
113
; split the URL into hostname and pageaddr
114
        stdcall parse_url, [URL]
115
        test    eax, eax
116
        jz      .error
117
        mov     [hostname], eax
118
        mov     [pageaddr], ebx
119
 
120
; Do we need to use a proxy?
121
        cmp     [proxyAddr], 0
122
        jne     .proxy_done
123
 
124
        ; TODO
125
  .proxy_done:
126
 
127
; Resolve the hostname
128
        DEBUGF  1, "Resolving hostname\n"
129
        push    esp     ; reserve stack place
130
        push    esp     ; fourth parameter
131
        push    0       ; third parameter
132
        push    0       ; second parameter
133
        push    [hostname]
134
        call    [getaddrinfo]
135
        pop     esi
136
        test    eax, eax
137
        jnz     .error
138
 
139
; getaddrinfo returns addrinfo struct, make the pointer to sockaddr struct
140
        mov     esi, [esi + addrinfo.ai_addr]
141
        mov     [sockaddr], esi
142
        mov     eax, [esi + sockaddr_in.sin_addr]
143
        test    eax, eax
144
        jz      .error
145
 
146
        DEBUGF  1, "Server ip=%u.%u.%u.%u\n", \
147
        [esi + sockaddr_in.sin_addr]:1, [esi + sockaddr_in.sin_addr + 1]:1, \
148
        [esi + sockaddr_in.sin_addr + 2]:1, [esi + sockaddr_in.sin_addr + 3]:1
149
 
150
        mov     [esi + sockaddr_in.sin_family], AF_INET4
151
        mov     [esi + sockaddr_in.sin_port], 80 shl 8  ;;; FIXME
152
 
153
; Connect to the server.
154
        mcall   socket, AF_INET4, SOCK_STREAM, 0
155
        test    eax, eax
156
        jz      .error
157
        mov     [socketnum], eax
158
        DEBUGF  1, "Socket: 0x%x\n", eax
159
 
160
        mcall   connect, [socketnum], [sockaddr], 18
161
        test    eax, eax
162
        jnz     .error
163
        DEBUGF  1, "Socket is now connected.\n"
164
 
165
        ; TODO: free address buffer(s)
166
 
167
; Create the HTTP request.
168
        invoke  mem.alloc, BUFFERSIZE
169
        test    eax, eax
170
        jz      .error
171
        mov     [buffer], eax
172
        DEBUGF  1, "Buffer has been allocated.\n"
173
 
174
        mov     dword[eax], 'GET '
175
        lea     edi, [eax + 4]
176
        mov     esi, [pageaddr] ; TODO: for proxy use http:// and then full URL
177
        copy_till_zero
178
 
179
        mov     esi, str_http11
180
        mov     ecx, str_http11.length
181
        rep     movsb
182
 
183
        mov     esi, [hostname]
184
        copy_till_zero
185
 
186
        mov     esi, str_close
187
        mov     ecx, str_close.length
188
        rep     movsb
189
 
190
        mov     byte[edi], 0
191
        DEBUGF  1, "Request:\n%s", [buffer]
192
 
193
; now send the request
194
        mov     esi, edi
195
        sub     esi, [buffer]   ; length
196
        xor     edi, edi        ; flags
197
 
198
        mcall   send, [socketnum], [buffer]
199
        test    eax, eax
200
        jz      .error
201
        DEBUGF  1, "Request has been sent to server.\n"
202
 
203
; Now that we have sent the request, re-purpose buffer as receive buffer
204
        mov     eax, [buffer]
205
        push    [socketnum]
206
        popd    [eax + http_msg.socket]
207
        lea     esi, [eax + http_msg.data]
208
        mov     [eax + http_msg.flags], 0
209
        mov     [eax + http_msg.write_ptr], esi
210
        mov     [eax + http_msg.buffer_length], BUFFERSIZE -  http_msg.data
211
        mov     [eax + http_msg.chunk_ptr], 0
212
 
213
        mov     [eax + http_msg.status], 0
214
        mov     [eax + http_msg.header_length], 0
215
        mov     [eax + http_msg.content_length], 0
216
 
217
        ret                     ; return buffer ptr
218
 
219
  .error:
220
        DEBUGF  1, "Error!\n"
221
        xor     eax, eax        ; return 0 = error
222
        ret
223
 
224
endp
225
 
226
 
227
 
228
;;================================================================================================;;
229
proc HTTP_process identifier ;////////////////////////////////////////////////////////////////////;;
230
;;------------------------------------------------------------------------------------------------;;
231
;?                                                                                                ;;
232
;;------------------------------------------------------------------------------------------------;;
233
;> _                                                                                              ;;
234
;;------------------------------------------------------------------------------------------------;;
235
;< eax = -1 (not finished) / 0 finished                                                           ;;
236
;;================================================================================================;;
237
        pusha
238
        mov     ebp, [identifier]
239
        mcall   recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \
240
                      [ebp + http_msg.buffer_length], MSG_DONTWAIT
241
        cmp     eax, 0xffffffff
242
        je      .check_socket
243
        DEBUGF  1, "Received %u bytes\n", eax
244
 
245
        mov     edi, [ebp + http_msg.write_ptr]
246
        add     [ebp + http_msg.write_ptr], eax
247
        sub     [ebp + http_msg.buffer_length], eax
248
        jz      .got_all_data
249
        test    [ebp + http_msg.flags], FLAG_GOT_HEADER
250
        jnz     .header_parsed
251
 
252
        sub     eax, 4
253
        jl      .no_header
254
  .scan:
255
        ; scan for end of header (empty line)
256
        cmp     dword[edi], 0x0a0d0a0d                  ; end of header
257
        je      .end_of_header
258
        cmp     word[edi+2], 0x0a0a
259
        je      .end_of_header
260
        inc     edi
261
        dec     eax
262
        jnz     .scan
263
 
264
  .no_header:
265
        popa
266
        xor     eax, eax
267
        dec     eax
268
        ret
269
 
270
  .end_of_header:
271
        add     edi, 4 - http_msg.data
272
        sub     edi, ebp
273
        mov     [ebp + http_msg.header_length], edi
274
        or      [ebp + http_msg.flags], FLAG_GOT_HEADER
275
        DEBUGF  1, "Header length: %u\n", edi
276
 
277
; Ok, we have found header:
278
        cmp     dword[ebp + http_msg.data], 'HTTP'
279
        jne     .invalid_header
280
        cmp     dword[ebp + http_msg.data+4], '/1.0'
281
        je      .http_1.0
282
        cmp     dword[ebp + http_msg.data+4], '/1.1'
283
        jne     .invalid_header
284
        or      [ebp + http_msg.flags], FLAG_HTTP11
285
  .http_1.0:
286
        cmp     byte[ebp + http_msg.data+8], ' '
287
        jne     .invalid_header
288
        DEBUGF  1, "Header seems valid.\n"
289
 
290
        lea     esi, [ebp + http_msg.data+9]
291
        xor     eax, eax
292
        xor     ebx, ebx
293
        mov     ecx, 3
294
  .statusloop:
295
        lodsb
296
        sub     al, '0'
297
        jb      .invalid_header
298
        cmp     al, 9
299
        ja      .invalid_header
300
        lea     ebx, [ebx + 4*ebx]
301
        shl     ebx, 1
302
        add     ebx, eax
303
        dec     ecx
304
        jnz     .statusloop
305
        mov     [ebp + http_msg.status], ebx
306
        DEBUGF  1, "Status: %u\n", ebx
307
 
308
; Now, convert all header names to lowercase.
309
; This way, it will be much easier to find certain header fields, later on.
310
 
311
        lea     esi, [ebp + http_msg.data]
312
        mov     ecx, [ebp + http_msg.header_length]
313
  .need_newline:
314
        inc     esi
315
        dec     ecx
316
        jz      .convert_done
317
        cmp     byte[esi], 10
318
        jne     .need_newline
319
; Ok, we have a newline, a line beginning with space or tabs has no header fields.
320
 
321
        inc     esi
322
        dec     ecx
323
        jz      .convert_done
324
        cmp     byte[esi], ' '
325
        je      .need_newline
326
        cmp     byte[esi], 9    ; horizontal tab
327
        je      .need_newline
328
        jmp     .convert_loop
329
  .next_char:
330
        inc     esi
331
        dec     ecx
332
        jz      .convert_done
333
  .convert_loop:
334
        cmp     byte[esi], ':'
335
        je      .need_newline
336
        cmp     byte[esi], 'A'
337
        jb      .next_char
338
        cmp     byte[esi], 'Z'
339
        ja      .next_char
340
        or      byte[esi], 0x20 ; convert to lowercase
341
        jmp     .next_char
342
  .convert_done:
343
        mov     byte[esi-1], 0
344
        lea     esi, [ebp + http_msg.data]
345
        DEBUGF  1, "Header names converted to lowercase:\n%s\n", esi
346
 
347
; Check for content-length header field.
348
        stdcall find_header_field, ebp, str_cl
349
        test    eax, eax
350
        jz      .no_content
351
        or      [ebp + http_msg.flags], FLAG_CONTENT_LENGTH
352
 
353
        xor     edx, edx
354
  .cl_loop:
355
        movzx   ebx, byte[eax]
356
        inc     eax
357
        cmp     bl, 10
358
        je      .cl_ok
359
        cmp     bl, 13
360
        je      .cl_ok
361
        cmp     bl, ' '
362
        je      .cl_ok
363
        sub     bl, '0'
364
        jb      .invalid_header
365
        cmp     bl, 9
366
        ja      .invalid_header
367
        lea     edx, [edx + edx*4]      ; edx = edx*10
368
        shl     edx, 1                  ;
369
        add     edx, ebx
370
        jmp     .cl_loop
371
 
372
  .cl_ok:
373
        mov     [ebp + http_msg.content_length], edx
374
        DEBUGF  1, "Content-length: %u\n", edx
375
 
376
; Resize buffer according to content-length.
377
        mov     eax, [ebp + http_msg.header_length]
378
        add     eax, [ebp + http_msg.content_length]
379
        add     eax, http_msg.data
380
 
381
        mov     ecx, eax
382
        sub     ecx, [ebp + http_msg.write_ptr]
383
        mov     [ebp + http_msg.buffer_length], ecx
384
 
385
        invoke  mem.realloc, ebp, eax
386
        or      eax, eax
387
        jz      .no_ram
388
        jmp     .header_parsed  ; hooray!
389
 
390
  .no_content:
391
        DEBUGF  1, "Content-length not found.\n"
392
 
393
; We didnt find 'content-length', maybe server is using chunked transfer encoding?
394
; Try to find 'transfer-encoding' header.
395
        stdcall find_header_field, ebp, str_te
396
        test    eax, eax
397
        jz      .invalid_header
398
 
399
        mov     ebx, dword[eax]
400
        or      eax, 0x20202020
401
        cmp     ebx, 'chun'
402
        jne     .invalid_header
403
        mov     ebx, dword[eax+4]
404
        or      eax, 0x00202020
405
        and     eax, 0x00ffffff
406
        cmp     ebx, 'ked'
407
        jne     .invalid_header
408
 
409
        or      [ebp + http_msg.flags], FLAG_CHUNKED
410
 
411
        DEBUGF  1, "Transfer type is: chunked\n"
412
 
413
; Set chunk pointer where first chunk should begin.
414
        mov     eax, [ebp + http_msg.header_length]
415
        add     eax, http_msg.data
416
        mov     [ebp + http_msg.chunk_ptr], eax
417
 
418
  .header_parsed:
419
; If data is chunked, combine chunks into contiguous data if so.
420
        test    [ebp + http_msg.flags], FLAG_CHUNKED
421
        jz      .not_chunked
422
 
423
  .chunkloop:
424
        mov     ecx, [ebp + http_msg.write_ptr]
425
        sub     ecx, [ebp + http_msg.chunk_ptr]
426
        jb      .not_finished
427
 
428
        mov     esi, [ebp + http_msg.chunk_ptr]
429
        xor     ebx, ebx
430
  .chunk_hexloop:
431
        lodsb
432
        sub     al, '0'
433
        jb      .chunk_
434
        cmp     al, 9
435
        jbe     .chunk_hex
436
        sub     al, 'A' - '0'
437
        jb      .chunk_
438
        cmp     al, 5
439
        jbe     .chunk_hex
440
        sub     al, 'a' - 'A'
441
        cmp     al, 5
442
        ja      .chunk_
443
  .chunk_hex:
444
        shl     ebx, 4
445
        add     bl, al
446
        jmp     .chunk_hexloop
447
  .chunk_:
448
        DEBUGF  1, "got chunk of %u bytes\n", ebx
449
; If chunk size is 0, all chunks have been received.
450
        test    ebx, ebx
451
        jz      .got_all_data   ; last chunk, hooray! FIXME: what if it wasnt a valid hex number???
452
        add     [ebp + http_msg.chunk_ptr], ebx
453
 
454
; Chunkline ends with a CR, LF or simply LF
455
  .end_of_chunkline?:           ; FIXME: buffer overflow possible!
456
        cmp     al, 10
457
        je      .end_of_chunkline
458
        lodsb
459
        jmp     .end_of_chunkline?
460
 
461
  .end_of_chunkline:
462
; Now move all received data to the left (remove chunk header).
463
; Meanwhile, update write_ptr and content_length accordingly.
464
        mov     edi, [ebp + http_msg.chunk_ptr]
465
        mov     ecx, [ebp + http_msg.write_ptr]
466
        sub     ecx, esi
467
        mov     eax, esi
468
        sub     eax, edi
469
        sub     [ebp + http_msg.write_ptr], eax
470
        add     [ebp + http_msg.content_length], ecx
471
        rep     movsb
472
        jmp     .chunkloop
473
 
474
  .not_chunked:
475
; Check if we got all the data.
476
        mov     eax, [ebp + http_msg.header_length]
477
        add     eax, [ebp + http_msg.content_length]
478
        cmp     eax, [ebp + http_msg.buffer_length]
479
        je      .got_all_data
480
 
481
  .not_finished:
482
;        DEBUGF  1, "Needs more processing...\n"
483
        popa
484
        xor     eax, eax
485
        dec     eax
486
        ret
487
 
488
  .got_all_data:
489
        DEBUGF  1, "We got all the data!\n"
490
        or      [ebp + http_msg.flags], FLAG_GOT_DATA
491
        mcall   close, [ebp + http_msg.socket]
492
        popa
493
        xor     eax, eax
494
        ret
495
 
496
  .check_socket:
497
        cmp     ebx, EWOULDBLOCK
498
        je      .not_finished
499
        DEBUGF  1, "ERROR: socket error %u\n", ebx
500
 
501
        or      [ebp + http_msg.flags], FLAG_SOCKET_ERROR
502
        popa
503
        xor     eax, eax
504
        ret
505
 
506
  .invalid_header:
507
        DEBUGF  1, "ERROR: invalid header\n"
508
        or      [ebp + http_msg.flags], FLAG_INVALID_HEADER
509
        popa
510
        xor     eax, eax
511
        ret
512
 
513
  .no_ram:
514
        DEBUGF  1, "ERROR: out of RAM\n"
515
        or      [ebp + http_msg.flags], FLAG_NO_RAM
516
        popa
517
        xor     eax, eax
518
        ret
519
 
520
endp
521
 
522
 
523
 
524
;;================================================================================================;;
525
proc find_header_field identifier, headername ;///////////////////////////////////////////////////;;
526
;;------------------------------------------------------------------------------------------------;;
527
;?                                                                                                ;;
528
;;------------------------------------------------------------------------------------------------;;
529
;> _                                                                                              ;;
530
;;------------------------------------------------------------------------------------------------;;
531
;< eax = -1 (error) / 0                                                                           ;;
532
;;================================================================================================;;
533
        push    ebx ecx edx esi edi
534
 
535
        DEBUGF  1, "Find header field: %s\n", [headername]
536
 
537
        mov     ebx, [identifier]
538
        lea     edx, [ebx + http_msg.data]
539
        mov     ecx, edx
540
        add     ecx, [ebx + http_msg.header_length]
541
 
542
  .restart:
543
        mov     esi, [headername]
544
        mov     edi, edx
545
  .loop:
546
        cmp     edi, ecx
547
        jae     .fail
548
        lodsb
549
        scasb
550
        je      .loop
551
        test    al, al
552
        jz      .done?
553
  .next:
554
        inc     edx
555
        jmp     .restart
556
 
557
  .not_done:
558
        inc     edi
559
  .done?:
560
        cmp     byte[edi-1], ':'
561
        je      .almost_done
562
        cmp     byte[edi-1], ' '
563
        je      .not_done
564
        cmp     byte[edi-1], 9  ; tab
565
        je      .not_done
566
 
567
        jmp     .next
568
 
569
  .almost_done:                 ; FIXME: buffer overflow?
570
        dec     edi
571
        DEBUGF  1, "Found header field\n"
572
  .spaceloop:
573
        inc     edi
574
        cmp     byte[edi], ' '
575
        je      .spaceloop
576
        cmp     byte[edi], 9    ; tab
577
        je      .spaceloop
578
 
579
        mov     eax, edi
580
        pop     edi esi edx ecx ebx
581
        ret
582
 
583
  .fail:
584
        pop     edi esi edx ecx ebx
585
        xor     eax, eax
586
        ret
587
 
588
endp
589
 
590
 
591
; internal procedures start here:
592
 
593
 
594
;;================================================================================================;;
595
proc parse_url URL ;//////////////////////////////////////////////////////////////////////////////;;
596
;;------------------------------------------------------------------------------------------------;;
597
;?                                                                                                ;;
598
;;------------------------------------------------------------------------------------------------;;
599
;> _                                                                                              ;;
600
;;------------------------------------------------------------------------------------------------;;
601
;< eax = -1 (error) / 0                                                                           ;;
602
;;================================================================================================;;
603
 
604
locals
605
        urlsize         dd ?
606
        hostname        dd ?
607
        pageaddr        dd ?
608
endl
609
 
4161 hidnplayr 610
        DEBUGF  1, "parsing URL: %s\n", [URL]
4158 hidnplayr 611
 
612
; remove any leading protocol text
613
        mov     esi, [URL]
614
        mov     ecx, URLMAXLEN
615
        mov     ax, '//'
616
  .loop1:
617
        cmp     byte[esi], 0            ; end of URL?
618
        je      .url_ok                 ; yep, so not found
619
        cmp     [esi], ax
620
        je      .skip_proto
621
        inc     esi
622
        dec     ecx
623
        jnz     .loop1
624
 
4161 hidnplayr 625
        DEBUGF  1, "Invalid URL\n"
4158 hidnplayr 626
        xor     eax, eax
627
        ret
628
 
629
  .skip_proto:
630
        inc     esi                     ; skip the two '/'
631
        inc     esi
632
        mov     [URL], esi              ; update pointer so it skips protocol
633
        jmp     .loop1                  ; we still need to find the length of the URL
634
 
635
  .url_ok:
636
        sub     esi, [URL]              ; calculate total length of URL
637
        mov     [urlsize], esi
638
 
639
 
640
; now look for page delimiter - it's a '/' character
641
        mov     ecx, esi                ; URL length
642
        mov     edi, [URL]
643
        mov     al, '/'
644
        repne   scasb
4161 hidnplayr 645
        jne     @f
4158 hidnplayr 646
        dec     edi                     ; return one char, '/' must be part of the pageaddr
647
        inc     ecx                     ;
4161 hidnplayr 648
  @@:
4158 hidnplayr 649
        push    ecx edi                 ; remember the pointer and length of pageaddr
650
 
651
        mov     ecx, edi
652
        sub     ecx, [URL]
653
        inc     ecx                     ; we will add a 0 byte at the end
654
        invoke  mem.alloc, ecx
655
        or      eax, eax
656
        jz      .no_mem
657
 
658
        mov     [hostname], eax         ; copy hostname to buffer
659
        mov     edi, eax
660
        mov     esi, [URL]
661
        dec     ecx
662
        rep     movsb
663
        xor     al, al
664
        stosb
665
 
4161 hidnplayr 666
        mov     [pageaddr], str_slash   ; assume there is no pageaddr
4158 hidnplayr 667
        pop     esi ecx
668
        test    ecx, ecx
669
        jz      .no_page
670
        inc     ecx                     ; we will add a 0 byte at the end
671
        invoke  mem.alloc, ecx
672
        or      eax, eax
673
        jz      .no_mem
674
 
675
        mov     [pageaddr], eax         ; copy pageaddr to buffer
676
        mov     edi, eax
677
        dec     ecx
678
        rep     movsb
679
        xor     al, al
680
        stosb
681
  .no_page:
682
 
683
        mov     eax, [hostname]
684
        mov     ebx, [pageaddr]
685
 
686
        DEBUGF  1, "hostname: %s\n", eax
687
        DEBUGF  1, "pageaddr: %s\n", ebx
688
 
689
        ret
690
 
691
  .no_mem:
692
        xor     eax, eax
693
        ret
694
 
695
endp
696
 
697
 
698
 
699
 
700
 
701
;;================================================================================================;;
702
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
703
;;================================================================================================;;
704
;! Imported functions section                                                                     ;;
705
;;================================================================================================;;
706
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
707
;;================================================================================================;;
708
 
709
 
710
align 16
711
@IMPORT:
712
 
713
library \
714
        libini, 'libini.obj', \
715
        network, 'network.obj'
716
 
717
import  libini, \
718
        ini.get_str, 'ini_get_str', \
719
        ini.get_int, 'ini_get_int'
720
 
721
import  network,\
722
        getaddrinfo, 'getaddrinfo',\
723
        freeaddrinfo,  'freeaddrinfo',\
724
        inet_ntoa, 'inet_ntoa'
725
 
726
;;===========================================================================;;
727
;;///////////////////////////////////////////////////////////////////////////;;
728
;;===========================================================================;;
729
;! Exported functions section                                                ;;
730
;;===========================================================================;;
731
;;///////////////////////////////////////////////////////////////////////////;;
732
;;===========================================================================;;
733
 
734
 
735
align 4
736
@EXPORT:
737
export  \
738
        lib_init                , 'lib_init'            , \
739
        0x00010001              , 'version'             , \
740
        HTTP_get                , 'get'                 , \
741
        find_header_field       , 'find_header_field'   , \
742
        HTTP_process            , 'process'
743
 
744
;        HTTP_head               , 'head'                , \
745
;        HTTP_post               , 'post'                , \
746
;        HTTP_put                , 'put'                 , \
747
;        HTTP_delete             , 'delete'              , \
748
;        HTTP_trace              , 'trace'               , \
749
;        HTTP_connect            , 'connect'             , \
750
 
751
 
752
 
753
section '.data' data readable writable align 16
754
 
755
inifile         db '/sys/settings/network.ini', 0
756
 
757
sec_proxy:
758
key_proxy       db 'proxy', 0
759
key_proxyport   db 'port', 0
760
key_user        db 'user', 0
761
key_password    db 'password', 0
762
 
763
str_http11      db ' HTTP/1.1', 13, 10, 'Host: '
764
  .length       = $ - str_http11
765
str_close       db 13, 10, 'User-Agent: KolibriOS libHTTP/1.0', 13, 10, 'Connection: Close', 13, 10, 13, 10
766
  .length       = $ - str_close
767
str_proxy_auth  db 13, 10, 'Proxy-Authorization: Basic '
768
  .length       = $ - str_proxy_auth
769
 
770
base64_table    db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
771
                db '0123456789+/'
772
 
773
str_cl          db 'content-length', 0
4161 hidnplayr 774
str_slash       db '/', 0
4158 hidnplayr 775
str_te          db 'transfer-encoding', 0
776
 
777
include_debug_strings
778
 
779
; uninitialized data
780
mem.alloc       dd ?
781
mem.free        dd ?
782
mem.realloc     dd ?
783
dll.load        dd ?
784
 
785
proxyAddr       rb 256
786
proxyUser       rb 256
787
proxyPassword   rb 256
788
proxyPort       dd ?