Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5539 → Rev 5540

/programs/network/downloader/downloader.asm
1,28 → 1,24
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2009-2013. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2014-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; downloader.asm - HTTP client for KolibriOS ;;
;; ;;
;; Based on HTTPC.asm for menuetos by ville turjanmaa ;;
;; hidnplayr@kolibrios.org ;;
;; ;;
;; Programmers: Barsuk, Clevermouse, Marat Zakiyanov, ;;
;; Kirill Lipatov, dunkaist, HidnPlayr ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
URLMAXLEN = 1024
BUFFERSIZE = 4096
URLMAXLEN = 65535
 
__DEBUG__ = 1
__DEBUG_LEVEL__ = 1
 
 
format binary as ""
 
use32
org 0x0
 
32,18 → 28,23
dd IM_END ; image size
dd I_END+0x1000 ; required memory
dd I_END+0x1000 ; esp
dd params ; I_PARAM
dd url
dd 0x0 ; I_Path
 
 
include '../../macros.inc'
include '../../proc32.inc'
include '../../network.inc'
include '../../develop/libraries/box_lib/trunk/box_lib.mac'
include '../../dll.inc'
include '../../debug-fdo.inc'
include '../../develop/libraries/box_lib/trunk/box_lib.mac'
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
51,1033 → 52,340
test eax, eax
jnz exit
 
; prepare webAddr area
mov al, ' '
mov edi, webAddr
mov ecx, URLMAXLEN
rep stosb
xor eax, eax
stosb
; wanted events
mcall 40, EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE + EVM_MOUSE_FILTER
 
; prepare document area
mov al, '/'
mov edi, document
; prepare filename buffers
mov edi, fname_buf
mov esi, download_file_path
@@:
lodsb
stosb
mov al, ' '
mov ecx, URLMAXLEN-1
rep stosb
 
; 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
 
; check parameters
cmp byte[params], 0 ; no parameters ?
je reset_events ; load the GUI
 
; we have an url, copy untill space or 0
mov esi, params
mov edi, document_user
mov ecx, 1024 ; max parameter size
mov [shared_name], 0
.copy_param:
lodsb
test al, al
jz .done
jnz @r
 
cmp al, ' '
jz .done_with_shared
; Initialise OpenDialog
invoke OpenDialog_Init, OpenDialog_data
 
stosb
dec ecx
jnz .copy_param
DEBUGF 2, "Invalid parameters\n"
jmp exit
; If user provided parameters, start download right away!
cmp byte[url], 0
jne download
 
.done_with_shared:
mov [shared_name], esi
.done:
xor al, al
stosb
mov [OpenDialog_data.draw_window], draw_window
 
 
download:
 
DEBUGF 1, "Starting download\n"
 
call parse_url
 
cmp [server_ip], 0
je dns_error
 
call open_socket
call send_request
 
mcall 68, 12, BUFFERSIZE ; create buffer, we'll resize it later if needed..
mov [buf_ptr], eax
mov [buf_size], 0
 
call read_incoming_data
 
mcall close, [socketnum]
 
call parse_result
call save
 
mcall 68, 13, [final_buffer] ; free buffer
 
dns_error:
cmp byte [params], 0
jne exit
 
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"
 
mainloop:
mcall 10 ; wait here for event
 
cmp eax, EV_REDRAW
je redraw
 
cmp eax, EV_KEY
je key
 
je .key
cmp eax, EV_BUTTON
je button
je .button
cmp eax, EV_MOUSE
je mouse
je .mouse
jmp mainloop
 
jmp still
 
key:
.key:
mcall 2 ; read key
 
stdcall [edit_box_key], dword edit1
 
invoke edit_box_key, edit1
cmp ax, 13 shl 8
je download
jmp mainloop
jmp still
button:
 
.button:
mcall 17 ; get id
 
cmp ah, 26
jne @f
call save_to_file
jmp still
@@:
cmp ah, 1 ; button id=1 ?
je exit
 
jmp download
cmp [btn_text], sz_download
je download
 
mouse:
stdcall [edit_box_mouse], edit1
jmp still
cmp [btn_text], sz_open
je open_file
 
exit:
DEBUGF 1, "Exiting\n"
or eax, -1 ; close this program
mcall
.mouse:
invoke edit_box_mouse, edit1
jmp mainloop
 
open_file:
; mcall 70, ...
jmp mainloop
 
save:
cmp [shared_name], 0
je .use_file
exit:
error:
mcall -1 ; exit
 
call save_in_shared
jmp .done
 
.use_file:
 
call save_to_file
 
download:
; int 3
; Extract the filename from URL
mov edi, url
xor al, al
mov ecx, URLMAXLEN
repne scasb
mov esi, edi
dec esi
dec esi
std
.loop:
lodsb
cmp al, '/'
je .done
test al, al
jnz .loop
.done:
 
; if called from command line, then exit
cmp byte[params], 0
jne exit
 
mov ecx, [sc.work_text]
or ecx, 0x80000000
mcall 4, <10, 93>, , download_complete
 
ret
 
save_in_shared:
 
; open the shared memory area
mov esi, 1
mcall 68, 22, [shared_name], , 1 ; SHM_OPEN+SHM_WRITE
test eax, eax
jz exit
 
mov ecx, [final_size]
; store the size
mov [eax], ecx
 
; now copy the data
lea edi, [eax+4]
mov esi, [final_buffer]
mov eax, ecx
shr ecx, 2
rep movsd
mov ecx, eax
and ecx, 3
rep movsb
 
ret
 
 
;****************************************************************************
; Function
; save_to_file
;
; Description
;
;
;****************************************************************************
 
save_to_file:
 
DEBUGF 2, "Saving to file\n"
mcall 70, fileinfo
 
ret
 
 
;****************************************************************************
; Function
; send_request
;
; Description
; Transmits the GET request to the server.
; This is done as GET then URL then HTTP/1.1', 13, 10, 13, 10 in 3 packets
;
;****************************************************************************
send_request:
 
DEBUGF 1, "Sending request\n"
 
mov esi, string0
mov edi, request
movsd
; If proxy is used, make absolute URI - prepend http://<host>
cmp byte[proxyAddr], 0
jz .noproxy
mov dword[edi], 'http'
mov byte[edi+4], ':'
mov word[edi+5], '//'
add edi, 7
mov esi, webAddr
 
.copy_host_loop:
lodsb
cmp al, ' '
jz .noproxy
stosb
jmp .copy_host_loop
 
.noproxy:
xor edx, edx ; 0
 
.next_edx:
; Determine the length of the url to send in the GET request
mov al, [edx+document]
cmp al, ' '
jbe .document_done
mov [edi], al
inc edi
inc edx
jmp .next_edx
 
.document_done:
mov esi, stringh
mov ecx, stringh_end-stringh
rep movsb
xor edx, edx ; 0
 
.webaddr_next:
mov al, [webAddr + edx]
cmp al, ' '
jbe .webaddr_done
mov [edi], al
inc edi
inc edx
jmp .webaddr_next
 
.webaddr_done:
cmp byte[proxyUser], 0
jz @f
call append_proxy_auth_header
@@:
mov esi, connclose
mov ecx, connclose_end-connclose
rep movsb
 
pusha
mov eax, 63
mov ebx, 1
mov edx, request
@@:
mov cl, [edx]
cmp edx, edi
jz @f
mcall
inc edx
jmp @b
@@:
popa
 
mov esi, edi
sub esi, request ; length
xor edi, edi ; flags
mcall send, [socketnum], request ;' HTTP/1.1 .. '
 
ret
 
;****************************************************************************
; Function
; read_incoming_data
;
; Description
; receive the web page from the server, storing it without processing
;
;****************************************************************************
read_incoming_data:
 
DEBUGF 1, "Reading incoming data\n"
 
mov eax, [buf_ptr]
mov [pos], eax
.read:
mcall recv, [socketnum], [pos], BUFFERSIZE, 0
inc eax ; -1 = error (socket closed?)
jz .error
dec eax ; 0 bytes means the remote end closed the connection
jz .no_more_data
 
DEBUGF 1, "Got chunk of %u bytes\n", eax
 
add [buf_size], eax
add [pos], eax
push eax
mov ecx, [buf_size]
add ecx, BUFFERSIZE
mcall 68, 20, , [buf_ptr] ; reallocate memory block (make bigger)
; TODO: parse header and resize buffer only once
pop eax
jmp .read
 
.error:
DEBUGF 1, "Socket error: %u\n", ebx
.no_more_data:
mov eax, [buf_ptr]
sub [pos], eax
 
DEBUGF 1, "No more data\n"
 
ret
 
; this function cuts header, and removes chunk sizes if doc is chunked
; in: buf_ptr, pos; out: buf_ptr, pos.
parse_result:
 
mov edi, [buf_ptr]
mov edx, [pos]
; mov [buf_size], edx
; mcall 70, fileinfo_tmp
DEBUGF 1, "Parsing result (%u bytes)\n", edx
 
; first, find end of headers
.next_byte:
cmp dword[edi], 0x0a0d0a0d
je .end_of_headers
inc edi
dec edx
ja .next_byte
DEBUGF 1, "Uh-oh, there's no end of header!\n"
; no end of headers. it's an error. let client see all those headers.
ret
 
.end_of_headers:
; here we look at headers and search content-length or transfer-encoding headers
DEBUGF 1, "Found end of header\n"
 
sub edi, [buf_ptr]
add edi, 4
mov [body_pos], edi ; store position where document body starts
mov [is_chunked], 0
; find content-length in headers
; not good method, but should work for 'Content-Length:'
mov esi, [buf_ptr]
mov edi, s_contentlength
mov ebx, [body_pos]
xor edx, edx ; 0
.cl_next:
mov al, [esi]
cmp al, [edi + edx]
jne .cl_fail
inc edx
cmp edx, len_contentlength
je .cl_found
jmp .cl_incr
.cl_fail:
xor edx, edx ; 0
.cl_incr:
cld
mov ecx, edi
sub ecx, esi
inc esi
dec ebx
je .cl_error
jmp .cl_next
.cl_error:
DEBUGF 1, "content-length not found\n"
 
; find 'chunked'
; äà, ÿ êîïèðóþ êîä, ýòî óæàñíî, íî ìíå õî÷åòñÿ, ÷òîáû ïîñêîðåå çàðàáîòàëî
; à òàì óæ îòðåôàêòîðþ
mov esi, [buf_ptr]
mov edi, s_chunked
mov ebx, [body_pos]
xor edx, edx ; 0
 
.ch_next:
mov al, [esi]
cmp al, [edi + edx]
jne .ch_fail
inc edx
cmp edx, len_chunked
je .ch_found
jmp .ch_incr
 
.ch_fail:
xor edx, edx ; 0
 
.ch_incr:
inc esi
dec ebx
je .ch_error
jmp .ch_next
 
.ch_error:
; if neither of the 2 headers is found, it's an error
; DEBUGF 1, "transfer-encoding: chunked not found\n"
mov eax, [pos]
sub eax, [body_pos]
jmp .write_final_size
 
.ch_found:
mov [is_chunked], 1
mov eax, [body_pos]
add eax, [buf_ptr]
sub eax, 2
mov [prev_chunk_end], eax
jmp parse_chunks
.cl_found:
call read_number ; eax = number from *esi
DEBUGF 1, "Content length: %u\n", eax
 
.write_final_size:
mov ebx, [buf_size]
sub ebx, [body_pos]
cmp eax, ebx
jbe .size_ok
sub eax, ebx
DEBUGF 2, "%u bytes of data are missing!\n", eax
mov eax, ebx
.size_ok:
mov [final_size], eax
 
mov ebx, [body_pos]
add ebx, [buf_ptr]
mov [final_buffer], ebx
 
ret
parse_chunks:
DEBUGF 1, "parse chunks\n"
; we have to look through the data and remove sizes of chunks we see
; 1. read size of next chunk
; 2. if 0, it's end. if not, continue.
; 3. make a good buffer and copy a chunk there
xor eax, eax
mov [final_buffer], eax ; 0
mov [final_size], eax ; 0
.read_size:
mov eax, [prev_chunk_end]
mov ebx, eax
sub ebx, [buf_ptr]
mov edx, eax
DEBUGF 1, "rs "
cmp ebx, [pos]
jae chunks_end ; not good
call read_hex ; in: eax=pointer to text. out:eax=hex number, ebx=end of text.
cmp eax, 0
jz chunks_end
 
add ebx, 1
mov edx, ebx ; edx = size of size of chunk
add ebx, eax
mov [prev_chunk_end], ebx
DEBUGF 1, "sz "
 
; do copying: from buf_ptr+edx to final_buffer+prev_final_size count eax
; realloc final buffer
push eax
push edx
push dword [final_size]
add [final_size], eax
mcall 68, 20, [final_size], [final_buffer]
mov [final_buffer], eax
DEBUGF 1, "re "
pop edi
pop esi
pop ecx
; add [pos], ecx
add edi, [final_buffer]
DEBUGF 1, "cp "
 
mov edi, filename_area
rep movsb
jmp .read_size
chunks_end:
DEBUGF 1, "chunks end\n"
mcall 68, 13, [buf_ptr] ; free old buffer
; invoke OpenDialog
invoke OpenDialog_Start, OpenDialog_data
mcall 40, EVM_REDRAW + EVM_BUTTON + EVM_STACK
call draw_window
 
ret
 
; reads content-length from [edi+ecx], result in eax
read_number:
push ebx
; Create the file
mov [fileinfo], 2 ; create/write to file
xor eax, eax
xor ebx, ebx
mov [fileinfo.offset], eax
mov [fileinfo.offset+4], eax
mov [fileinfo.size], eax
mcall 70, fileinfo
test eax, eax
jnz error ; TODO: print error message
 
.next:
mov bl, [esi]
; And start the download
invoke HTTP_get, url, 0, FLAG_STREAM or FLAG_REUSE_BUFFER, 0
test eax, eax
jz error ; TODO: print error message
mov [identifier], eax
mov [offset], 0
mov [btn_text], sz_cancel
 
cmp bl, '0'
jb .not_number
cmp bl, '9'
ja .not_number
sub bl, '0'
shl eax, 1
lea eax, [eax + eax * 4] ; eax *= 10
add eax, ebx
or [edit1.flags], ed_figure_only
call draw_window
 
.not_number:
cmp bl, 13
je .done
inc esi
jmp .next
download_loop:
mcall 10
cmp eax, EV_REDRAW
je .redraw
cmp eax, EV_BUTTON
je .button
 
.done:
pop ebx
ret
invoke HTTP_receive, [identifier]
test eax, eax
jz save_chunk
; reads hex from eax, result in eax, end of text in ebx
read_hex:
add eax, 2
mov ebx, eax
mov eax, [ebx]
mov [deba], eax
mov eax, [identifier]
push [eax + http_msg.content_length]
pop [pb.max]
push [eax + http_msg.content_received]
pop [pb.value]
 
xor eax, eax
xor ecx, ecx
.next:
mov cl, [ebx]
inc ebx
invoke progressbar_draw, pb
jmp download_loop
cmp cl, 0x0d
jz .done
.redraw:
call draw_window
jmp download_loop
 
or cl, 0x20
sub cl, '0'
jb .bad
.button:
jmp http_free
 
cmp cl, 0x9
jbe .adding
save_chunk:
mov ebp, [identifier]
test [ebp + http_msg.flags], 0xffff0000 ; error?
jnz http_free
 
sub cl, 'a'-'0'-10
cmp cl, 0x0a
jb .bad
cmp [fileinfo], 3
je @f
DEBUGF 1, "new file size=%u\n", [ebp + http_msg.content_length]
mov [fileinfo], 4 ; set end of file
mov eax, [ebp + http_msg.content_length]
mov [fileinfo.offset], eax ; new file size
mcall 70, fileinfo
 
cmp cl, 0x0f
ja .bad
mov [fileinfo], 3 ; write to existing file
@@:
mov ecx, [ebp + http_msg.content_received]
sub ecx, [offset]
mov [fileinfo.size], ecx
mov eax, [ebp + http_msg.content_ptr]
mov [fileinfo.buffer], eax
mov ebx, [offset]
mov [fileinfo.offset], ebx
DEBUGF 1, "Writing to disk: size=%u offset=%u\n", ecx, ebx
mcall 70, fileinfo
 
.adding:
shl eax, 4
or eax, ecx
.bad:
jmp .next
.done:
mov eax, [ebp + http_msg.content_received]
mov [offset], eax
 
ret
test [ebp + http_msg.flags], FLAG_GOT_ALL_DATA
jz download_loop
 
;****************************************************************************
; Function
; open_socket
;
; Description
; opens the socket
;
;****************************************************************************
open_socket:
mov [pb.progress_color], 0x0000c800 ; green
 
DEBUGF 1, "opening socket\n"
http_free:
mcall 40, EVM_REDRAW + EVM_BUTTON
push [ebp + http_msg.content_received]
pop [pb.value]
 
mov edx, 80
cmp byte [proxyAddr], 0
mov ecx, [ebp + http_msg.content_ptr]
test ecx, ecx
jz @f
mov eax, [proxyPort]
xchg al, ah
mov [server_port], ax
mcall 68, 13 ; free the buffer
@@:
 
mcall socket, AF_INET4, SOCK_STREAM, 0
mov [socketnum], eax
mcall connect, [socketnum], sockaddr1, 18
invoke HTTP_free, [identifier] ; free headers and connection
 
ret
mov [btn_text], sz_open
call draw_window
jmp mainloop
 
 
;****************************************************************************
; Function
; parse_url
;
; Description
; parses the full url typed in by the user into a web address ( that
; can be turned into an IP address by DNS ) and the page to display
; DNS will be used to translate the web address into an IP address, if
; needed.
; url is at document_user and will be space terminated.
; web address goes to webAddr and is space terminated.
; ip address goes to server_ip
; page goes to document and is space terminated.
;
; Supported formats:
; <protocol://>address<page>
; <protocol> is optional, removed and ignored - only http supported
; <address> is required. It can be an ip address or web address
; <page> is optional and must start with a leading / character
;
;****************************************************************************
parse_url:
; First, reset destination variables
mov al, ' '
mov edi, document
mov ecx, URLMAXLEN
rep stosb
mov edi, webAddr
mov ecx, URLMAXLEN
rep stosb
 
mov al, '/'
mov [document], al
 
mov esi, document_user
; remove any leading protocol text
mov ecx, URLMAXLEN
mov ax, '//'
 
pu_000:
cmp [esi], byte ' ' ; end of text?
je pu_002 ; yep, so not found
cmp [esi], ax
je pu_001 ; Found it, so esi+2 is start
inc esi
loop pu_000
 
pu_002:
; not found, so reset esi to start
mov esi, document_user-2
 
pu_001:
add esi, 2
mov ebx, esi ; save address of start of web address
mov edi, document_user + URLMAXLEN ; end of string
; look for page delimiter - it's a '/' character
pu_003:
cmp [esi], byte ' ' ; end of text?
je pu_004 ; yep, so none found
cmp esi, edi ; end of string?
je pu_004 ; yep, so none found
cmp [esi], byte '/' ; delimiter?
je pu_005 ; yep - process it
inc esi
jmp pu_003
 
pu_005:
; copy page to document address
; esi = delimiter
push esi
mov ecx, edi ; end of document_user
mov edi, document
 
pu_006:
movsb
cmp esi, ecx
je pu_007 ; end of string?
cmp [esi], byte ' ' ; end of text
; je pu_007 ; äçåí-àññåìáëåð
; jmp pu_006 ; íå íàäî ïëîäèòü ñóùíîñòè ïî íàïðàñíó
jne pu_006
 
pu_007:
pop esi ; point esi to '/' delimiter
 
pu_004:
; copy web address to webAddr
; start in ebx, end in esi-1
mov ecx, esi
mov esi, ebx
mov edi, webAddr
@@:
movsb
cmp esi, ecx
jne @r
mov byte [edi], 0
 
pu_009:
; For debugging, display resulting strings
DEBUGF 2, "Downloadng %s\n", document_user
 
; Look up the ip address, or was it specified?
mov al, [proxyAddr]
cmp al, 0
jnz pu_015
mov al, [webAddr]
pu_015:
cmp al, '0'
jb pu_010 ; Resolve address
cmp al, '9'
ja pu_010 ; Resolve address
 
DEBUGF 1, "GotIP\n"
 
; Convert address
; If proxy is given, get proxy address instead of server
mov esi, proxyAddr-1
cmp byte[esi+1], 0
jne pu_020
mov esi, webAddr-1
 
pu_020:
mov edi, server_ip
xor eax, eax
 
ip1:
inc esi
cmp [esi], byte '0'
jb ip2
cmp [esi], byte '9'
ja ip2
imul eax, 10
movzx ebx, byte [esi]
sub ebx, 48
add eax, ebx
jmp ip1
 
ip2:
mov [edi], al
xor eax, eax
inc edi
cmp edi, server_ip+3
jbe ip1
 
ret
 
pu_010:
DEBUGF 1, "Resolving %s\n", webAddr
 
; resolve name
push esp ; reserve stack place
push esp ; fourth parameter
push 0 ; third parameter
push 0 ; second parameter
push webAddr
call [getaddrinfo]
pop esi
test eax, eax
jnz .fail_dns
 
; fill in ip
mov eax, [esi + addrinfo.ai_addr]
mov eax, [eax + sockaddr_in.sin_addr]
mov [server_ip], eax
 
; free allocated memory
push esi
call [freeaddrinfo]
 
DEBUGF 1, "Resolved to %u.%u.%u.%u\n", [server_ip]:1, [server_ip + 1]:1, [server_ip + 2]:1, [server_ip + 3]:1
 
ret
 
.fail_dns:
DEBUGF 1, "DNS resolution failed\n"
mov [server_ip], 0
 
ret
 
;***************************************************************************
; Function
; append_proxy_auth_header
;
; Description
; Append header to HTTP request for proxy authentification
;
;***************************************************************************
append_proxy_auth_header:
mov esi, proxy_auth_basic
mov ecx, proxy_auth_basic_end - proxy_auth_basic
rep movsb
; base64-encode string <user>:<password>
mov esi, proxyUser
 
apah000:
lodsb
test al, al
jz apah001
call encode_base64_byte
jmp apah000
 
apah001:
mov al, ':'
call encode_base64_byte
mov esi, proxyPassword
 
apah002:
lodsb
test al, al
jz apah003
call encode_base64_byte
jmp apah002
 
apah003:
call encode_base64_final
ret
 
encode_base64_byte:
inc ecx
shl edx, 8
mov dl, al
cmp ecx, 3
je ebb001
ret
 
ebb001:
shl edx, 8
inc ecx
 
ebb002:
rol edx, 6
xor eax, eax
xchg al, dl
mov al, [base64_table+eax]
stosb
loop ebb002
ret
 
encode_base64_final:
mov al, 0
test ecx, ecx
jz ebf000
call encode_base64_byte
test ecx, ecx
jz ebf001
call encode_base64_byte
mov byte [edi-2], '='
 
ebf001:
mov byte [edi-1], '='
 
ebf000:
ret
 
; *********************************************
; ******* WINDOW DEFINITIONS AND DRAW ********
; *********************************************
 
draw_window:
mcall 12, 1 ; start window draw
 
mcall 12, 1
; get system colors
mcall 48, 3, sc, 40
 
mcall 48, 3, sc, 40 ;get system colors
 
; draw window
mov edx, [sc.work]
or edx, 0x34000000
mcall 0, <50, 370>, <350, 140>, , 0, title ;draw window
mcall 0, <50, 320>, <350, 110>, , 0, title
mov ecx, [sc.work_text]
; draw button
mcall 8, <229,75>, <60,16>, 22, [sc.work_button] ; download
 
; draw button text
mov ecx, [sc.work_button_text]
or ecx, 80000000h
mcall 4, <14, 14>, , type_pls ;"URL:"
mcall 4, <240,65>, , [btn_text]
 
; draw editbox
edit_boxes_set_sys_color edit1, editboxes_end, sc
stdcall [edit_box_draw], edit1
invoke edit_box_draw, edit1
 
; RELOAD
mcall 8, <90, 68>, <54, 16>, 22, [sc.work_button]
; STOP
mcall , <166, 50>, <54, 16>, 24
; SAVE
mcall , <224, 54>, , 26
; BUTTON TEXT
mov ecx, [sc.work_button_text]
or ecx, 80000000h
mcall 4, <102, 59>, , button_text
cmp [identifier], 0
je @f
; draw progressbar
invoke progressbar_draw, pb
@@:
mcall 12, 2 ; end window draw
ret
 
mcall 12, 2 ; end window redraw
 
dont_draw:
 
ret
 
 
;-----------------------------------------------------------------------------
;---------------------------------------------------------------------
; Data area
;-----------------------------------------------------------------------------
align 4
@IMPORT:
 
library libini, 'libini.obj', \
library lib_http, 'http.obj', \
box_lib, 'box_lib.obj', \
network, 'network.obj'
proc_lib, 'proc_lib.obj'
 
import libini, \
ini.get_str, 'ini_get_str', \
ini.get_int, 'ini_get_int'
import lib_http, \
HTTP_get, 'get', \
HTTP_receive, 'receive', \
HTTP_free, 'free'
 
import box_lib, \
edit_box_draw, 'edit_box', \
edit_box_key, 'edit_box_key', \
edit_box_mouse, 'edit_box_mouse'
edit_box_mouse, 'edit_box_mouse', \
progressbar_draw, 'progressbar_draw', \
progressbar_prog, 'progressbar_progress'
 
import network,\
getaddrinfo, 'getaddrinfo',\
freeaddrinfo, 'freeaddrinfo',\
inet_ntoa, 'inet_ntoa'
import proc_lib, \
OpenDialog_Init, 'OpenDialog_init', \
OpenDialog_Start, 'OpenDialog_start'
 
;---------------------------------------------------------------------
fileinfo dd 2, 0, 0
final_size dd 0
final_buffer dd 0
db '/rd/1/.download', 0
body_pos dd 0
buf_size dd 0
buf_ptr dd 0
 
deba dd 0
fileinfo dd 2
.offset dd 0, 0
.size dd 0
.buffer dd 0
db 0
dd fname_buf
 
;---------------------------------------------------------------------
 
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
edit1 edit_box 299, 5, 10, 0xffffff, 0x0000ff, 0x0080ff, 0x000000, 0x8000, URLMAXLEN, url, mouse_dd, ed_focus+ed_always_focus, 0, 0
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
identifier dd 0
btn_text dd sz_download
sz_download db 'Download', 0
sz_cancel db ' Cancel ', 0
sz_open db ' Open ', 0
title db 'HTTP Downloader', 0
 
;---------------------------------------------------------------------
s_contentlength db 'Content-Length:'
len_contentlength = 15
OpenDialog_data:
.type dd 1 ; Save
.procinfo dd procinfo
.com_area_name dd communication_area_name
.com_area dd 0
.opendir_path dd temp_dir_path
.dir_default_path dd communication_area_default_path
.start_path dd open_dialog_path
.draw_window dd dont_draw
.status dd 0
.openfile_patch dd fname_buf
.filename_area dd filename_area
.filter_area dd filter
.x:
.x_size dw 420 ; Window X size
.x_start dw 200 ; Window X position
.y:
.y_size dw 320 ; Window y size
.y_start dw 120 ; Window Y position
 
s_chunked db 'Transfer-Encoding: chunked'
len_chunked = $ - s_chunked
communication_area_name db 'FFFFFFFF_open_dialog',0
open_dialog_path db '/sys/File Managers/opendial',0
communication_area_default_path db '/sys',0
 
string0: db 'GET '
filter:
dd 0
db 0
 
stringh db ' HTTP/1.1', 13, 10, 'Host: '
stringh_end:
proxy_auth_basic db 13, 10, 'Proxy-Authorization: Basic '
proxy_auth_basic_end:
connclose db 13, 10, 'User-Agent: Kolibrios Downloader', 13, 10, 'Connection: Close', 13, 10, 13, 10
connclose_end:
pb:
.value dd 0
.left dd 5
.top dd 35
.width dd 300
.height dd 16
.style dd 1
.min dd 0
.max dd 0
.back_color dd 0xefefef
.progress_color dd 0xc8c8c8
.frame_color dd 0x94aece
.frame_color2 dd 0xffffff
 
base64_table db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
db '0123456789+/'
include_debug_strings
 
inifile db '/sys/settings/network.ini', 0
download_file_path db '/tmp0/1/', 0
 
sec_proxy:
key_proxy db 'proxy', 0
key_proxyport db 'port', 0
key_user db 'user', 0
key_password db 'password', 0
IM_END:
 
sockaddr1:
dw AF_INET4
server_port dw 0x5000 ; 80
server_ip dd 0
rb 10
 
proxyPort dd 80
 
shared_name dd 0
 
;---------------------------------------------------------------------
document_user db 'http://', 0
;---------------------------------------------------------------------
IM_END:
;---------------------------------------------------------------------
rb URLMAXLEN-(IM_END - document_user)
;---------------------------------------------------------------------
url rb URLMAXLEN
sc system_colors
;---------------------------------------------------------------------
align 4
document rb URLMAXLEN
;---------------------------------------------------------------------
align 4
webAddr rb URLMAXLEN+1
;---------------------------------------------------------------------
pos dd ?
socketnum dd ?
is_chunked dd ?
prev_chunk_end dd ?
cur_chunk_size dd ?
;---------------------------------------------------------------------
offset dd ?
mouse_dd dd ?
 
params rb 1024
filename_area rb 256
temp_dir_path rb 4096
procinfo rb 1024
fname_buf rb 4096
text_work_area rb 1024
 
request rb 256
 
proxyAddr rb 256
proxyUser rb 256
proxyPassword rb 256
 
I_END:
 
 
 
I_END: