Added HTTP library + example

git-svn-id: svn://kolibrios.org@4158 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2013-11-04 13:07:21 +00:00
parent a92e5cb862
commit 501706cdc8
3 changed files with 1078 additions and 0 deletions

View File

@ -0,0 +1,253 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2009-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; downloader.asm - HTTP client for KolibriOS ;;
;; ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
URLMAXLEN = 1024
BUFFERSIZE = 4096
__DEBUG__ = 1
__DEBUG_LEVEL__ = 1
format binary as ""
use32
org 0x0
db 'MENUET01' ; header
dd 0x01 ; header version
dd START ; entry point
dd IM_END ; image size
dd I_END+0x1000 ; required memory
dd I_END+0x1000 ; esp
dd params ; I_PARAM
dd 0x0 ; I_Path
include '../../macros.inc'
include '../../proc32.inc'
include '../../develop/libraries/box_lib/trunk/box_lib.mac'
include '../../dll.inc'
include '../../debug-fdo.inc'
include '../../develop/libraries/http/http.inc'
virtual at 0
http_msg http_msg
end virtual
START:
mcall 68, 11 ; init heap so we can allocate memory dynamically
; load libraries
stdcall dll.Load, @IMPORT
test eax, eax
jnz exit
; check parameters
cmp byte[params], 0 ; no parameters ?
je reset_events ; load the GUI
download:
DEBUGF 1, "Starting download\n"
invoke HTTP_get, params
test eax, eax
jz fail
mov [identifier], eax
.loop:
invoke HTTP_process, [identifier]
test eax, eax
jnz .loop
reset_events:
DEBUGF 1, "resetting events\n"
; Report events
; defaults + mouse
mcall 40,EVM_REDRAW+EVM_KEY+EVM_BUTTON+EVM_MOUSE+EVM_MOUSE_FILTER
redraw:
call draw_window
still:
;; DEBUGF 1, "waiting for events\n"
mcall 10 ; wait here for event
cmp eax, EV_REDRAW
je redraw
cmp eax, EV_KEY
je key
cmp eax, EV_BUTTON
je button
cmp eax, EV_MOUSE
je mouse
jmp still
key:
mcall 2 ; read key
stdcall [edit_box_key], dword edit1
cmp ax, 13 shl 8
je download
jmp still
button:
mcall 17 ; get id
cmp ah, 26
jne @f
call save
jmp still
@@:
cmp ah, 1 ; button id=1 ?
je exit
jmp download
mouse:
stdcall [edit_box_mouse], edit1
jmp still
exit:
DEBUGF 1, "Exiting\n"
mcall 68, 13, [identifier] ; free buffer
fail:
or eax, -1 ; close this program
mcall
save:
mov ebp, [identifier]
mov eax, [ebp + http_msg.content_length]
mov [final_size], eax
lea ebx, [ebp + http_msg.data]
add ebx, [ebp + http_msg.header_length]
mov [final_buffer], ebx
mcall 70, fileinfo
.done:
; TODO: if called from command line, then exit
mov ecx, [sc.work_text]
or ecx, 0x80000000
mcall 4, <10, 93>, , download_complete
ret
; *********************************************
; ******* WINDOW DEFINITIONS AND DRAW ********
; *********************************************
draw_window:
mcall 12, 1 ; start window draw
; get system colors
mcall 48, 3, sc, 40
; draw window
mov edx, [sc.work]
or edx, 0x34000000
mcall 0, <50, 370>, <350, 140>, , 0, title
; draw "url:" text
mov ecx, [sc.work_text]
or ecx, 80000000h
mcall 4, <14, 14>, , type_pls
; draw editbox
edit_boxes_set_sys_color edit1, editboxes_end, sc
stdcall [edit_box_draw], edit1
; draw buttons
mcall 8, <90, 68>, <54, 16>, 22, [sc.work_button] ; reload
mcall , <166, 50>, <54, 16>, 24 ; stop
mcall , <224, 54>, , 26 ; save
; draw buttons text
mov ecx, [sc.work_button_text]
or ecx, 80000000h
mcall 4, <102, 59>, , button_text
mcall 12, 2 ; end window redraw
ret
;-----------------------------------------------------------------------------
; Data area
;-----------------------------------------------------------------------------
align 4
@IMPORT:
library lib_http, 'http.obj', \
box_lib, 'box_lib.obj'
import lib_http, \
HTTP_get , 'get' , \
find_header_field , 'find_header_field' , \
HTTP_process , 'process'
import box_lib, \
edit_box_draw, 'edit_box', \
edit_box_key, 'edit_box_key', \
edit_box_mouse, 'edit_box_mouse'
;---------------------------------------------------------------------
fileinfo dd 2, 0, 0
final_size dd 0
final_buffer dd 0
db '/rd/1/.download', 0
;---------------------------------------------------------------------
mouse_dd dd 0
edit1 edit_box 295, 48, 10, 0xffffff, 0xff, 0x80ff, 0, 0x8000, URLMAXLEN, document_user, mouse_dd, ed_focus+ed_always_focus, 7, 7
editboxes_end:
;---------------------------------------------------------------------
include_debug_strings
;---------------------------------------------------------------------
type_pls db 'URL:', 0
button_text db 'DOWNLOAD STOP RESAVE', 0
download_complete db 'File saved as /rd/1/.download', 0
title db 'HTTP Downloader', 0
;---------------------------------------------------------------------
document_user db 'http://'
;---------------------------------------------------------------------
IM_END:
;---------------------------------------------------------------------
params rb URLMAXLEN
;---------------------------------------------------------------------
sc system_colors
;---------------------------------------------------------------------
identifier dd ?
;---------------------------------------------------------------------
I_END:

View File

@ -0,0 +1,787 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; HTTP library for KolibriOS ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; references:
; "HTTP made really easy", http://www.jmarshall.com/easy/http/
; "Hypertext Transfer Protocol -- HTTP/1.1", http://tools.ietf.org/html/rfc2616
URLMAXLEN = 65535
BUFFERSIZE = 4096
__DEBUG__ = 1
__DEBUG_LEVEL__ = 1
format MS COFF
public @EXPORT as 'EXPORTS'
include '../../../struct.inc'
include '../../../proc32.inc'
include '../../../macros.inc'
purge section,mov,add,sub
include '../../../debug-fdo.inc'
include '../../../network.inc'
include 'http.inc'
virtual at 0
http_msg http_msg
end virtual
macro copy_till_zero {
@@:
lodsb
test al, al
jz @f
stosb
jmp @r
@@:
}
section '.flat' code readable align 16
;;===========================================================================;;
lib_init: ;//////////////////////////////////////////////////////////////////;;
;;---------------------------------------------------------------------------;;
;? Library entry point (called after library load) ;;
;;---------------------------------------------------------------------------;;
;> eax = pointer to memory allocation routine ;;
;> ebx = pointer to memory freeing routine ;;
;> ecx = pointer to memory reallocation routine ;;
;> edx = pointer to library loading routine ;;
;;---------------------------------------------------------------------------;;
;< eax = 1 (fail) / 0 (ok) (library initialization result) ;;
;;===========================================================================;;
mov [mem.alloc], eax
mov [mem.free], ebx
mov [mem.realloc], ecx
mov [dll.load], edx
invoke dll.load, @IMPORT
or eax, eax
jz .ok
; load proxy settings
invoke ini.get_str, inifile, sec_proxy, key_proxy, proxyAddr, 256, proxyAddr
invoke ini.get_int, inifile, sec_proxy, key_proxyport, 80
mov [proxyPort], eax
invoke ini.get_str, inifile, sec_proxy, key_user, proxyUser, 256, proxyUser
invoke ini.get_str, inifile, sec_proxy, key_password, proxyPassword, 256, proxyPassword
xor eax, eax
inc eax
ret
.ok:
xor eax, eax
ret
;;================================================================================================;;
proc HTTP_get URL ;///////////////////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? ;;
;;------------------------------------------------------------------------------------------------;;
;> _ ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 (error) / buffer ptr ;;
;;================================================================================================;;
locals
hostname dd ?
pageaddr dd ?
sockaddr dd ?
socketnum dd ?
buffer dd ?
endl
; split the URL into hostname and pageaddr
stdcall parse_url, [URL]
test eax, eax
jz .error
mov [hostname], eax
mov [pageaddr], ebx
; Do we need to use a proxy?
cmp [proxyAddr], 0
jne .proxy_done
; TODO
.proxy_done:
; Resolve the hostname
DEBUGF 1, "Resolving hostname\n"
push esp ; reserve stack place
push esp ; fourth parameter
push 0 ; third parameter
push 0 ; second parameter
push [hostname]
call [getaddrinfo]
pop esi
test eax, eax
jnz .error
; getaddrinfo returns addrinfo struct, make the pointer to sockaddr struct
mov esi, [esi + addrinfo.ai_addr]
mov [sockaddr], esi
mov eax, [esi + sockaddr_in.sin_addr]
test eax, eax
jz .error
DEBUGF 1, "Server ip=%u.%u.%u.%u\n", \
[esi + sockaddr_in.sin_addr]:1, [esi + sockaddr_in.sin_addr + 1]:1, \
[esi + sockaddr_in.sin_addr + 2]:1, [esi + sockaddr_in.sin_addr + 3]:1
mov [esi + sockaddr_in.sin_family], AF_INET4
mov [esi + sockaddr_in.sin_port], 80 shl 8 ;;; FIXME
; Connect to the server.
mcall socket, AF_INET4, SOCK_STREAM, 0
test eax, eax
jz .error
mov [socketnum], eax
DEBUGF 1, "Socket: 0x%x\n", eax
mcall connect, [socketnum], [sockaddr], 18
test eax, eax
jnz .error
DEBUGF 1, "Socket is now connected.\n"
; TODO: free address buffer(s)
; Create the HTTP request.
invoke mem.alloc, BUFFERSIZE
test eax, eax
jz .error
mov [buffer], eax
DEBUGF 1, "Buffer has been allocated.\n"
mov dword[eax], 'GET '
lea edi, [eax + 4]
mov esi, [pageaddr] ; TODO: for proxy use http:// and then full URL
copy_till_zero
mov esi, str_http11
mov ecx, str_http11.length
rep movsb
mov esi, [hostname]
copy_till_zero
mov esi, str_close
mov ecx, str_close.length
rep movsb
mov byte[edi], 0
DEBUGF 1, "Request:\n%s", [buffer]
; now send the request
mov esi, edi
sub esi, [buffer] ; length
xor edi, edi ; flags
mcall send, [socketnum], [buffer]
test eax, eax
jz .error
DEBUGF 1, "Request has been sent to server.\n"
; Now that we have sent the request, re-purpose buffer as receive buffer
mov eax, [buffer]
push [socketnum]
popd [eax + http_msg.socket]
lea esi, [eax + http_msg.data]
mov [eax + http_msg.flags], 0
mov [eax + http_msg.write_ptr], esi
mov [eax + http_msg.buffer_length], BUFFERSIZE - http_msg.data
mov [eax + http_msg.chunk_ptr], 0
mov [eax + http_msg.status], 0
mov [eax + http_msg.header_length], 0
mov [eax + http_msg.content_length], 0
ret ; return buffer ptr
.error:
DEBUGF 1, "Error!\n"
xor eax, eax ; return 0 = error
ret
endp
;;================================================================================================;;
proc HTTP_process identifier ;////////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? ;;
;;------------------------------------------------------------------------------------------------;;
;> _ ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = -1 (not finished) / 0 finished ;;
;;================================================================================================;;
pusha
mov ebp, [identifier]
mcall recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \
[ebp + http_msg.buffer_length], MSG_DONTWAIT
cmp eax, 0xffffffff
je .check_socket
DEBUGF 1, "Received %u bytes\n", eax
mov edi, [ebp + http_msg.write_ptr]
add [ebp + http_msg.write_ptr], eax
sub [ebp + http_msg.buffer_length], eax
jz .got_all_data
test [ebp + http_msg.flags], FLAG_GOT_HEADER
jnz .header_parsed
sub eax, 4
jl .no_header
.scan:
; scan for end of header (empty line)
cmp dword[edi], 0x0a0d0a0d ; end of header
je .end_of_header
cmp word[edi+2], 0x0a0a
je .end_of_header
inc edi
dec eax
jnz .scan
.no_header:
popa
xor eax, eax
dec eax
ret
.end_of_header:
add edi, 4 - http_msg.data
sub edi, ebp
mov [ebp + http_msg.header_length], edi
or [ebp + http_msg.flags], FLAG_GOT_HEADER
DEBUGF 1, "Header length: %u\n", edi
; Ok, we have found header:
cmp dword[ebp + http_msg.data], 'HTTP'
jne .invalid_header
cmp dword[ebp + http_msg.data+4], '/1.0'
je .http_1.0
cmp dword[ebp + http_msg.data+4], '/1.1'
jne .invalid_header
or [ebp + http_msg.flags], FLAG_HTTP11
.http_1.0:
cmp byte[ebp + http_msg.data+8], ' '
jne .invalid_header
DEBUGF 1, "Header seems valid.\n"
lea esi, [ebp + http_msg.data+9]
xor eax, eax
xor ebx, ebx
mov ecx, 3
.statusloop:
lodsb
sub al, '0'
jb .invalid_header
cmp al, 9
ja .invalid_header
lea ebx, [ebx + 4*ebx]
shl ebx, 1
add ebx, eax
dec ecx
jnz .statusloop
mov [ebp + http_msg.status], ebx
DEBUGF 1, "Status: %u\n", ebx
; Now, convert all header names to lowercase.
; This way, it will be much easier to find certain header fields, later on.
lea esi, [ebp + http_msg.data]
mov ecx, [ebp + http_msg.header_length]
.need_newline:
inc esi
dec ecx
jz .convert_done
cmp byte[esi], 10
jne .need_newline
; Ok, we have a newline, a line beginning with space or tabs has no header fields.
inc esi
dec ecx
jz .convert_done
cmp byte[esi], ' '
je .need_newline
cmp byte[esi], 9 ; horizontal tab
je .need_newline
jmp .convert_loop
.next_char:
inc esi
dec ecx
jz .convert_done
.convert_loop:
cmp byte[esi], ':'
je .need_newline
cmp byte[esi], 'A'
jb .next_char
cmp byte[esi], 'Z'
ja .next_char
or byte[esi], 0x20 ; convert to lowercase
jmp .next_char
.convert_done:
mov byte[esi-1], 0
lea esi, [ebp + http_msg.data]
DEBUGF 1, "Header names converted to lowercase:\n%s\n", esi
; Check for content-length header field.
stdcall find_header_field, ebp, str_cl
test eax, eax
jz .no_content
or [ebp + http_msg.flags], FLAG_CONTENT_LENGTH
xor edx, edx
.cl_loop:
movzx ebx, byte[eax]
inc eax
cmp bl, 10
je .cl_ok
cmp bl, 13
je .cl_ok
cmp bl, ' '
je .cl_ok
sub bl, '0'
jb .invalid_header
cmp bl, 9
ja .invalid_header
lea edx, [edx + edx*4] ; edx = edx*10
shl edx, 1 ;
add edx, ebx
jmp .cl_loop
.cl_ok:
mov [ebp + http_msg.content_length], edx
DEBUGF 1, "Content-length: %u\n", edx
; Resize buffer according to content-length.
mov eax, [ebp + http_msg.header_length]
add eax, [ebp + http_msg.content_length]
add eax, http_msg.data
mov ecx, eax
sub ecx, [ebp + http_msg.write_ptr]
mov [ebp + http_msg.buffer_length], ecx
invoke mem.realloc, ebp, eax
or eax, eax
jz .no_ram
jmp .header_parsed ; hooray!
.no_content:
DEBUGF 1, "Content-length not found.\n"
; We didnt find 'content-length', maybe server is using chunked transfer encoding?
; Try to find 'transfer-encoding' header.
stdcall find_header_field, ebp, str_te
test eax, eax
jz .invalid_header
mov ebx, dword[eax]
or eax, 0x20202020
cmp ebx, 'chun'
jne .invalid_header
mov ebx, dword[eax+4]
or eax, 0x00202020
and eax, 0x00ffffff
cmp ebx, 'ked'
jne .invalid_header
or [ebp + http_msg.flags], FLAG_CHUNKED
DEBUGF 1, "Transfer type is: chunked\n"
; Set chunk pointer where first chunk should begin.
mov eax, [ebp + http_msg.header_length]
add eax, http_msg.data
mov [ebp + http_msg.chunk_ptr], eax
.header_parsed:
; If data is chunked, combine chunks into contiguous data if so.
test [ebp + http_msg.flags], FLAG_CHUNKED
jz .not_chunked
.chunkloop:
mov ecx, [ebp + http_msg.write_ptr]
sub ecx, [ebp + http_msg.chunk_ptr]
jb .not_finished
mov esi, [ebp + http_msg.chunk_ptr]
xor ebx, ebx
.chunk_hexloop:
lodsb
sub al, '0'
jb .chunk_
cmp al, 9
jbe .chunk_hex
sub al, 'A' - '0'
jb .chunk_
cmp al, 5
jbe .chunk_hex
sub al, 'a' - 'A'
cmp al, 5
ja .chunk_
.chunk_hex:
shl ebx, 4
add bl, al
jmp .chunk_hexloop
.chunk_:
DEBUGF 1, "got chunk of %u bytes\n", ebx
; If chunk size is 0, all chunks have been received.
test ebx, ebx
jz .got_all_data ; last chunk, hooray! FIXME: what if it wasnt a valid hex number???
add [ebp + http_msg.chunk_ptr], ebx
; Chunkline ends with a CR, LF or simply LF
.end_of_chunkline?: ; FIXME: buffer overflow possible!
cmp al, 10
je .end_of_chunkline
lodsb
jmp .end_of_chunkline?
.end_of_chunkline:
; Now move all received data to the left (remove chunk header).
; Meanwhile, update write_ptr and content_length accordingly.
mov edi, [ebp + http_msg.chunk_ptr]
mov ecx, [ebp + http_msg.write_ptr]
sub ecx, esi
mov eax, esi
sub eax, edi
sub [ebp + http_msg.write_ptr], eax
add [ebp + http_msg.content_length], ecx
rep movsb
jmp .chunkloop
.not_chunked:
; Check if we got all the data.
mov eax, [ebp + http_msg.header_length]
add eax, [ebp + http_msg.content_length]
cmp eax, [ebp + http_msg.buffer_length]
je .got_all_data
.not_finished:
; DEBUGF 1, "Needs more processing...\n"
popa
xor eax, eax
dec eax
ret
.got_all_data:
DEBUGF 1, "We got all the data!\n"
or [ebp + http_msg.flags], FLAG_GOT_DATA
mcall close, [ebp + http_msg.socket]
popa
xor eax, eax
ret
.check_socket:
cmp ebx, EWOULDBLOCK
je .not_finished
DEBUGF 1, "ERROR: socket error %u\n", ebx
or [ebp + http_msg.flags], FLAG_SOCKET_ERROR
popa
xor eax, eax
ret
.invalid_header:
DEBUGF 1, "ERROR: invalid header\n"
or [ebp + http_msg.flags], FLAG_INVALID_HEADER
popa
xor eax, eax
ret
.no_ram:
DEBUGF 1, "ERROR: out of RAM\n"
or [ebp + http_msg.flags], FLAG_NO_RAM
popa
xor eax, eax
ret
endp
;;================================================================================================;;
proc find_header_field identifier, headername ;///////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? ;;
;;------------------------------------------------------------------------------------------------;;
;> _ ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = -1 (error) / 0 ;;
;;================================================================================================;;
push ebx ecx edx esi edi
DEBUGF 1, "Find header field: %s\n", [headername]
mov ebx, [identifier]
lea edx, [ebx + http_msg.data]
mov ecx, edx
add ecx, [ebx + http_msg.header_length]
.restart:
mov esi, [headername]
mov edi, edx
.loop:
cmp edi, ecx
jae .fail
lodsb
scasb
je .loop
test al, al
jz .done?
.next:
inc edx
jmp .restart
.not_done:
inc edi
.done?:
cmp byte[edi-1], ':'
je .almost_done
cmp byte[edi-1], ' '
je .not_done
cmp byte[edi-1], 9 ; tab
je .not_done
jmp .next
.almost_done: ; FIXME: buffer overflow?
dec edi
DEBUGF 1, "Found header field\n"
.spaceloop:
inc edi
cmp byte[edi], ' '
je .spaceloop
cmp byte[edi], 9 ; tab
je .spaceloop
mov eax, edi
pop edi esi edx ecx ebx
ret
.fail:
pop edi esi edx ecx ebx
xor eax, eax
ret
endp
; internal procedures start here:
;;================================================================================================;;
proc parse_url URL ;//////////////////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? ;;
;;------------------------------------------------------------------------------------------------;;
;> _ ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = -1 (error) / 0 ;;
;;================================================================================================;;
locals
urlsize dd ?
hostname dd ?
pageaddr dd ?
endl
DEBUGF 1, "URL: %s\n", [URL]
; remove any leading protocol text
mov esi, [URL]
mov ecx, URLMAXLEN
mov ax, '//'
.loop1:
cmp byte[esi], 0 ; end of URL?
je .url_ok ; yep, so not found
cmp [esi], ax
je .skip_proto
inc esi
dec ecx
jnz .loop1
; URL invalid !
xor eax, eax
ret
.skip_proto:
inc esi ; skip the two '/'
inc esi
mov [URL], esi ; update pointer so it skips protocol
jmp .loop1 ; we still need to find the length of the URL
.url_ok:
sub esi, [URL] ; calculate total length of URL
mov [urlsize], esi
;;; FIXME: urls with no pageaddr are not parsed correctly!!
; now look for page delimiter - it's a '/' character
mov ecx, esi ; URL length
mov edi, [URL]
mov al, '/'
repne scasb
dec edi ; return one char, '/' must be part of the pageaddr
inc ecx ;
push ecx edi ; remember the pointer and length of pageaddr
mov ecx, edi
sub ecx, [URL]
inc ecx ; we will add a 0 byte at the end
invoke mem.alloc, ecx
or eax, eax
jz .no_mem
mov [hostname], eax ; copy hostname to buffer
mov edi, eax
mov esi, [URL]
dec ecx
rep movsb
xor al, al
stosb
mov [pageaddr], null_str ; assume there is no pageaddr
pop esi ecx
test ecx, ecx
jz .no_page
inc ecx ; we will add a 0 byte at the end
invoke mem.alloc, ecx
or eax, eax
jz .no_mem
mov [pageaddr], eax ; copy pageaddr to buffer
mov edi, eax
dec ecx
rep movsb
xor al, al
stosb
.no_page:
mov eax, [hostname]
mov ebx, [pageaddr]
DEBUGF 1, "hostname: %s\n", eax
DEBUGF 1, "pageaddr: %s\n", ebx
ret
.no_mem:
xor eax, eax
ret
endp
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
;! Imported functions section ;;
;;================================================================================================;;
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
;;================================================================================================;;
align 16
@IMPORT:
library \
libini, 'libini.obj', \
network, 'network.obj'
import libini, \
ini.get_str, 'ini_get_str', \
ini.get_int, 'ini_get_int'
import network,\
getaddrinfo, 'getaddrinfo',\
freeaddrinfo, 'freeaddrinfo',\
inet_ntoa, 'inet_ntoa'
;;===========================================================================;;
;;///////////////////////////////////////////////////////////////////////////;;
;;===========================================================================;;
;! Exported functions section ;;
;;===========================================================================;;
;;///////////////////////////////////////////////////////////////////////////;;
;;===========================================================================;;
align 4
@EXPORT:
export \
lib_init , 'lib_init' , \
0x00010001 , 'version' , \
HTTP_get , 'get' , \
find_header_field , 'find_header_field' , \
HTTP_process , 'process'
; HTTP_head , 'head' , \
; HTTP_post , 'post' , \
; HTTP_put , 'put' , \
; HTTP_delete , 'delete' , \
; HTTP_trace , 'trace' , \
; HTTP_connect , 'connect' , \
section '.data' data readable writable align 16
inifile db '/sys/settings/network.ini', 0
sec_proxy:
key_proxy db 'proxy', 0
key_proxyport db 'port', 0
key_user db 'user', 0
key_password db 'password', 0
str_http11 db ' HTTP/1.1', 13, 10, 'Host: '
.length = $ - str_http11
str_close db 13, 10, 'User-Agent: KolibriOS libHTTP/1.0', 13, 10, 'Connection: Close', 13, 10, 13, 10
.length = $ - str_close
str_proxy_auth db 13, 10, 'Proxy-Authorization: Basic '
.length = $ - str_proxy_auth
base64_table db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
db '0123456789+/'
str_cl db 'content-length', 0
null_str db 0
str_te db 'transfer-encoding', 0
include_debug_strings
; uninitialized data
mem.alloc dd ?
mem.free dd ?
mem.realloc dd ?
dll.load dd ?
proxyAddr rb 256
proxyUser rb 256
proxyPassword rb 256
proxyPort dd ?

View File

@ -0,0 +1,38 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; HTTP library for KolibriOS ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FLAG_HTTP11 = 1 shl 0
FLAG_GOT_HEADER = 1 shl 1
FLAG_GOT_DATA = 1 shl 2
FLAG_CONTENT_LENGTH = 1 shl 3
FLAG_CHUNKED = 1 shl 4
; error flags go into the upper word
FLAG_INVALID_HEADER = 1 shl 16
FLAG_NO_RAM = 1 shl 17
FLAG_SOCKET_ERROR = 1 shl 18
struc http_msg {
.socket dd ?
.flags dd ?
.write_ptr dd ?
.buffer_length dd ?
.chunk_ptr dd ?
.status dd ?
.header_length dd ?
.content_length dd ?
.data:
}