Subversion Repositories Kolibri OS

Rev

Rev 4241 | Rev 4561 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4241 Rev 4541
Line 1... Line 1...
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  HTTP library for KolibriOS                                     ;;
6
;;  HTTP library for KolibriOS                                     ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;   Written by hidnplayr@kolibrios.org                            ;;
8
;;   Written by hidnplayr@kolibrios.org                            ;;
Line 17... Line 17...
17
; "HTTP made really easy", http://www.jmarshall.com/easy/http/
17
; "HTTP made really easy", http://www.jmarshall.com/easy/http/
18
; "Hypertext Transfer Protocol -- HTTP/1.1", http://tools.ietf.org/html/rfc2616
18
; "Hypertext Transfer Protocol -- HTTP/1.1", http://tools.ietf.org/html/rfc2616
Line 19... Line 19...
19
 
19
 
20
 
20
 
21
        URLMAXLEN       = 65535
21
        URLMAXLEN       = 65535
Line 22... Line 22...
22
        BUFFERSIZE      = 4096
22
        BUFFERSIZE      = 8192
23
        TIMEOUT         = 1000  ; in 1/100 s
23
        TIMEOUT         = 1000  ; in 1/100 s
Line 57... Line 57...
57
macro HTTP_init_buffer buffer, socketnum {
57
macro HTTP_init_buffer buffer, socketnum {
Line 58... Line 58...
58
 
58
 
59
        mov     eax, buffer
59
        mov     eax, buffer
60
        push    socketnum
60
        push    socketnum
61
        popd    [eax + http_msg.socket]
61
        popd    [eax + http_msg.socket]
62
        lea     esi, [eax + http_msg.data]
62
        lea     esi, [eax + http_msg.http_header]
63
        mov     [eax + http_msg.flags], FLAG_CONNECTED
63
        mov     [eax + http_msg.flags], FLAG_CONNECTED
64
        mov     [eax + http_msg.write_ptr], esi
64
        mov     [eax + http_msg.write_ptr], esi
65
        mov     [eax + http_msg.buffer_length], BUFFERSIZE -  http_msg.data
65
        mov     [eax + http_msg.buffer_length], BUFFERSIZE -  http_msg.http_header
Line 66... Line 66...
66
        mov     [eax + http_msg.chunk_ptr], 0
66
        mov     [eax + http_msg.chunk_ptr], 0
67
 
67
 
-
 
68
        mov     [eax + http_msg.status], 0
68
        mov     [eax + http_msg.status], 0
69
        mov     [eax + http_msg.header_length], 0
69
        mov     [eax + http_msg.header_length], 0
70
        mov     [eax + http_msg.content_ptr], 0
Line 70... Line 71...
70
        mov     [eax + http_msg.content_length], 0
71
        mov     [eax + http_msg.content_length], 0
71
        mov     [eax + http_msg.content_received], 0
72
        mov     [eax + http_msg.content_received], 0
Line 108... Line 109...
108
        invoke  ini.get_str, inifile, sec_proxy, key_user, proxyUser, 256, proxyUser
109
        invoke  ini.get_str, inifile, sec_proxy, key_user, proxyUser, 256, proxyUser
109
        invoke  ini.get_str, inifile, sec_proxy, key_password, proxyPassword, 256, proxyPassword
110
        invoke  ini.get_str, inifile, sec_proxy, key_password, proxyPassword, 256, proxyPassword
110
        popa
111
        popa
Line 111... Line 112...
111
 
112
 
112
        DEBUGF  1, "HTTP library: init OK\n"
-
 
113
 
113
        DEBUGF  1, "HTTP library: init OK\n"
114
        xor     eax, eax
114
        xor     eax, eax
Line 115... Line 115...
115
        ret
115
        ret
116
 
116
 
117
  .error:
-
 
118
        DEBUGF  1, "ERROR loading libraries\n"
117
  .error:
119
 
118
        DEBUGF  1, "ERROR loading libraries\n"
120
        xor     eax, eax
-
 
121
        inc     eax
119
        xor     eax, eax
Line 164... Line 162...
164
        invoke  mem.alloc, BUFFERSIZE
162
        invoke  mem.alloc, BUFFERSIZE
165
        test    eax, eax
163
        test    eax, eax
166
        jz      .error
164
        jz      .error
167
        mov     [buffer], eax
165
        mov     [buffer], eax
168
        mov     edi, eax
166
        mov     edi, eax
169
        DEBUGF  1, "Buffer has been allocated.\n"
167
        DEBUGF  1, "Buffer allocated: 0x%x\n", eax
Line 170... Line 168...
170
 
168
 
171
        mov     esi, str_get
169
        mov     esi, str_get
Line 172... Line 170...
172
        copy_till_zero
170
        copy_till_zero
Line 242... Line 240...
242
 
240
 
243
;;================================================================================================;;
241
;;================================================================================================;;
244
proc HTTP_head URL, add_header ;//////////////////////////////////////////////////////////////////;;
242
proc HTTP_head URL, add_header ;//////////////////////////////////////////////////////////////////;;
245
;;------------------------------------------------------------------------------------------------;;
243
;;------------------------------------------------------------------------------------------------;;
-
 
244
;? Initiates a HTTP connection, using 'HEAD' method.                                              ;;
246
;? Initiates a HTTP connection, using 'HEAD' method.                                              ;;
245
;? This will only return HTTP header and status, no content                                       ;;
247
;;------------------------------------------------------------------------------------------------;;
246
;;------------------------------------------------------------------------------------------------;;
248
;> URL          = pointer to ASCIIZ URL                                                           ;;
247
;> URL          = pointer to ASCIIZ URL                                                           ;;
249
;> add_header   = pointer to additional header parameters (ASCIIZ), or null for none.             ;;
248
;> add_header   = pointer to additional header parameters (ASCIIZ), or null for none.             ;;
250
;;------------------------------------------------------------------------------------------------;;
249
;;------------------------------------------------------------------------------------------------;;
Line 355... Line 354...
355
 
354
 
356
 
355
 
357
;;================================================================================================;;
356
;;================================================================================================;;
358
proc HTTP_post URL, add_header, content_type, content_length ;////////////////////////////////////;;
357
proc HTTP_post URL, add_header, content_type, content_length ;////////////////////////////////////;;
-
 
358
;;------------------------------------------------------------------------------------------------;;
359
;;------------------------------------------------------------------------------------------------;;
359
;? Initiates a HTTP connection, using 'POST' method.                                              ;;
360
;? Initiates a HTTP connection, using 'GET' method.                                               ;;
360
;? This method is used to send data to the HTTP server                                            ;;
361
;;------------------------------------------------------------------------------------------------;;
361
;;------------------------------------------------------------------------------------------------;;
362
;> URL                  = pointer to ASCIIZ URL                                                   ;;
362
;> URL                  = pointer to ASCIIZ URL                                                   ;;
363
;> add_header           = pointer to additional header parameters (ASCIIZ), or null for none.     ;;
363
;> add_header           = pointer to additional header parameters (ASCIIZ), or null for none.     ;;
Line 533... Line 533...
533
 
533
 
534
; We havent found the (final) header yet, search for it..
534
; We havent found the (final) header yet, search for it..
535
  .scan_again:
535
  .scan_again:
536
        ; eax = total number of bytes received so far
536
        ; eax = total number of bytes received so far
537
        mov     eax, [ebp + http_msg.write_ptr]
537
        mov     eax, [ebp + http_msg.write_ptr]
538
        sub     eax, http_msg.data
538
        sub     eax, http_msg.http_header
539
        sub     eax, ebp
539
        sub     eax, ebp
540
        sub     eax, [ebp + http_msg.header_length]
540
        sub     eax, [ebp + http_msg.header_length]
541
        ; edi is ptr to begin of header
541
        ; edi is ptr to begin of header
542
        lea     edi, [ebp + http_msg.data]
542
        lea     edi, [ebp + http_msg.http_header]
543
        add     edi, [ebp + http_msg.header_length]
543
        add     edi, [ebp + http_msg.header_length]
544
        ; put it in esi for next proc too
544
        ; put it in esi for next proc too
545
        mov     esi, edi
545
        mov     esi, edi
546
        sub     eax, 3
546
        sub     eax, 3
Line 555... Line 555...
555
        dec     eax
555
        dec     eax
556
        jnz     .scan_loop
556
        jnz     .scan_loop
557
        jmp     .need_more_data
557
        jmp     .need_more_data
Line 558... Line 558...
558
 
558
 
559
  .end_of_header:
559
  .end_of_header:
560
        add     edi, 4 - http_msg.data
560
        add     edi, 4 - http_msg.http_header
561
        sub     edi, ebp
561
        sub     edi, ebp
562
        mov     [ebp + http_msg.header_length], edi     ; If this isnt the final header, we'll use this as an offset to find real header.
562
        mov     [ebp + http_msg.header_length], edi     ; If this isnt the final header, we'll use this as an offset to find real header.
Line 563... Line 563...
563
        DEBUGF  1, "Header length: %u\n", edi
563
        DEBUGF  1, "Header length: %u\n", edi
Line 599... Line 599...
599
        or      [ebp + http_msg.flags], FLAG_GOT_HEADER
599
        or      [ebp + http_msg.flags], FLAG_GOT_HEADER
Line 600... Line 600...
600
 
600
 
601
; Now, convert all header names to lowercase.
601
; Now, convert all header names to lowercase.
Line 602... Line 602...
602
; This way, it will be much easier to find certain header fields, later on.
602
; This way, it will be much easier to find certain header fields, later on.
603
 
603
 
604
        lea     esi, [ebp + http_msg.data]
604
        lea     esi, [ebp + http_msg.http_header]
605
        mov     ecx, [ebp + http_msg.header_length]
605
        mov     ecx, [ebp + http_msg.header_length]
606
  .need_newline:
606
  .need_newline:
607
        inc     esi
607
        inc     esi
Line 632... Line 632...
632
        ja      .next_char
632
        ja      .next_char
633
        or      byte[esi], 0x20 ; convert to lowercase
633
        or      byte[esi], 0x20 ; convert to lowercase
634
        jmp     .next_char
634
        jmp     .next_char
635
  .convert_done:
635
  .convert_done:
636
        mov     byte[esi-1], 0
636
        mov     byte[esi-1], 0
637
        lea     esi, [ebp + http_msg.data]
637
        lea     esi, [ebp + http_msg.http_header]
638
        DEBUGF  1, "Header names converted to lowercase:\n%s\n", esi
638
        DEBUGF  1, "Header names converted to lowercase:\n%s\n", esi
Line 639... Line 639...
639
 
639
 
640
; Check for content-length header field.
640
; Check for content-length header field.
641
        stdcall HTTP_find_header_field, ebp, str_cl
641
        stdcall HTTP_find_header_field, ebp, str_cl
Line 664... Line 664...
664
 
664
 
665
  .cl_ok:
665
  .cl_ok:
666
        mov     [ebp + http_msg.content_length], edx
666
        mov     [ebp + http_msg.content_length], edx
Line 667... Line -...
667
        DEBUGF  1, "Content-length: %u\n", edx
-
 
668
 
-
 
669
; Resize buffer according to content-length.
-
 
670
        add     edx, [ebp + http_msg.header_length]
-
 
671
        add     edx, http_msg.data
667
        DEBUGF  1, "Content-length: %u\n", edx
672
 
668
 
673
        mov     ecx, edx
-
 
Line 674... Line 669...
674
        sub     ecx, [ebp + http_msg.write_ptr]
669
        test    edx, edx
675
        mov     [ebp + http_msg.buffer_length], ecx
670
        jz      .got_all_data
676
 
671
 
677
        invoke  mem.realloc, ebp, edx
-
 
678
        or      eax, eax
-
 
679
        jz      .no_ram
-
 
680
 
-
 
681
  .not_chunked:
-
 
682
        mov     eax, [ebp + http_msg.write_ptr]
672
        call    alloc_contentbuff
683
        sub     eax, [ebp + http_msg.header_length]
673
        test    eax, eax
Line 684... Line 674...
684
        sub     eax, http_msg.data
674
        jz      .no_ram
685
        sub     eax, ebp
675
        xor     eax, eax
Line 686... Line 676...
686
        jmp     .header_parsed  ; hooray!
676
        jmp     .header_parsed
687
 
677
 
688
  .no_content:
678
  .no_content:
689
        DEBUGF  1, "Content-length not found.\n"
679
        DEBUGF  1, "Content-length not found.\n"
-
 
680
 
-
 
681
; We didnt find 'content-length', maybe server is using chunked transfer encoding?
-
 
682
; Try to find 'transfer-encoding' header.
-
 
683
        stdcall HTTP_find_header_field, ebp, str_te
-
 
684
        test    eax, eax
-
 
685
        jnz     .ct_hdr_found
690
 
686
 
-
 
687
  .not_chunked:
-
 
688
        mov     edx, BUFFERSIZE
Line -... Line 689...
-
 
689
        call    alloc_contentbuff
691
; We didnt find 'content-length', maybe server is using chunked transfer encoding?
690
        test    eax, eax
692
; Try to find 'transfer-encoding' header.
691
        jz      .no_ram
693
        stdcall HTTP_find_header_field, ebp, str_te
692
        xor     eax, eax
694
        test    eax, eax
693
        jmp     .header_parsed
695
        jz      .not_chunked
694
 
Line 705... Line 704...
705
        jne     .not_chunked
704
        jne     .not_chunked
Line 706... Line 705...
706
 
705
 
707
        or      [ebp + http_msg.flags], FLAG_CHUNKED
706
        or      [ebp + http_msg.flags], FLAG_CHUNKED
Line -... Line 707...
-
 
707
        DEBUGF  1, "Transfer type is: chunked\n"
-
 
708
 
-
 
709
        mov     edx, BUFFERSIZE
-
 
710
        call    alloc_contentbuff
-
 
711
        test    eax, eax
708
        DEBUGF  1, "Transfer type is: chunked\n"
712
        jz      .no_ram
709
 
-
 
710
; Set chunk pointer where first chunk should begin.
713
 
711
        lea     eax, [ebp + http_msg.data]
714
; Set chunk pointer where first chunk should begin.
Line 712... Line 715...
712
        add     eax, [ebp + http_msg.header_length]
715
        mov     eax, [ebp + http_msg.content_ptr]
713
        mov     [ebp + http_msg.chunk_ptr], eax
716
        mov     [ebp + http_msg.chunk_ptr], eax
714
 
717
 
715
  .chunk_loop:
718
  .chunk_loop:
716
        mov     ecx, [ebp + http_msg.write_ptr]
-