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] |
- |