;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                 ;;
;; Copyright (C) KolibriOS team 2009-2013. 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             ;;
;;                                                                 ;;
;;  Programmers: Barsuk, Clevermouse, Marat Zakiyanov,             ;;
;;      Kirill Lipatov, dunkaist, HidnPlayr                        ;;
;;                                                                 ;;
;;          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 '../../network.inc'
include '../../develop/libraries/box_lib/trunk/box_lib.mac'
include '../../dll.inc'
include '../../debug-fdo.inc'

START:

        mcall   68, 11                  ; init heap so we can allocate memory dynamically

; load libraries
        stdcall dll.Load, @IMPORT
        test    eax, eax
        jnz     exit

; prepare webAddr area
        mov     al, ' '
        mov     edi, webAddr
        mov     ecx, URLMAXLEN
        rep     stosb
        xor     eax, eax
        stosb

; prepare document area 
        mov     al, '/'
        mov     edi, document
        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

        cmp     al, ' '
        jz      .done_with_shared

        stosb
        dec     ecx
        jnz     .copy_param
        DEBUGF  2, "Invalid parameters\n"
        jmp     exit

  .done_with_shared:
        mov     [shared_name], esi
  .done:
        xor     al, al
        stosb


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"

        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_to_file
        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"
        or      eax, -1 ; close this program
        mcall


save:
        cmp     [shared_name], 0
        je      .use_file

        call    save_in_shared
        jmp     .done

  .use_file:

        call    save_to_file

  .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:
        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 "

        rep     movsb
        jmp     .read_size
        
chunks_end:
        DEBUGF  1, "chunks end\n"
        mcall   68, 13, [buf_ptr]       ; free old buffer

        ret

; reads content-length from [edi+ecx], result in eax
read_number:
        push    ebx
        xor     eax, eax
        xor     ebx, ebx

  .next:
        mov     bl, [esi]

        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

  .not_number:
        cmp     bl, 13
        je      .done
        inc     esi
        jmp     .next

  .done:
        pop     ebx
        ret
        
; 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

        xor     eax, eax
        xor     ecx, ecx
  .next:
        mov     cl, [ebx]
        inc     ebx
        
        cmp     cl, 0x0d
        jz      .done

        or      cl, 0x20
        sub     cl, '0'
        jb      .bad

        cmp     cl, 0x9
        jbe     .adding

        sub     cl, 'a'-'0'-10
        cmp     cl, 0x0a
        jb      .bad

        cmp     cl, 0x0f
        ja      .bad

  .adding:
        shl     eax, 4
        or      eax, ecx
  .bad:
        jmp     .next
  .done:

        ret

;****************************************************************************
;    Function
;       open_socket
;
;   Description
;       opens the socket
;
;****************************************************************************
open_socket:

        DEBUGF  1, "opening socket\n"

        mov     edx, 80
        cmp     byte [proxyAddr], 0
        jz      @f
        mov     eax, [proxyPort]
        xchg    al, ah
        mov     [server_port], ax
    @@:

        mcall   socket, AF_INET4, SOCK_STREAM, 0
        mov     [socketnum], eax
        mcall   connect, [socketnum], sockaddr1, 18

        ret


;****************************************************************************
;    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

        mcall   48, 3, sc, 40 ;get system colors

        mov     edx, [sc.work]
        or      edx, 0x34000000
        mcall   0, <50, 370>, <350, 140>, , 0, title   ;draw window
        
        mov     ecx, [sc.work_text]
        or      ecx, 80000000h
        mcall   4, <14, 14>, , type_pls ;"URL:"

        edit_boxes_set_sys_color edit1, editboxes_end, sc
        stdcall [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

        mcall   12, 2 ; end window redraw

        ret


;-----------------------------------------------------------------------------
; Data area
;-----------------------------------------------------------------------------
align   4
@IMPORT:

library libini, 'libini.obj', \
        box_lib, 'box_lib.obj', \
        network, 'network.obj'

import  libini, \
        ini.get_str, 'ini_get_str', \
        ini.get_int, 'ini_get_int'

import  box_lib, \
        edit_box_draw, 'edit_box', \
        edit_box_key, 'edit_box_key', \
        edit_box_mouse, 'edit_box_mouse'

import  network,\
        getaddrinfo,    'getaddrinfo',\
        freeaddrinfo,   'freeaddrinfo',\
        inet_ntoa,      'inet_ntoa'

;---------------------------------------------------------------------
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
                db 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

;---------------------------------------------------------------------
s_contentlength db 'Content-Length:'
len_contentlength = 15

s_chunked       db 'Transfer-Encoding: chunked'
len_chunked     = $ - s_chunked

string0:        db 'GET '

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:

base64_table    db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
                db '0123456789+/'

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

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)
;---------------------------------------------------------------------
                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 ?
;---------------------------------------------------------------------

params          rb 1024

request         rb 256

proxyAddr       rb 256
proxyUser       rb 256
proxyPassword   rb 256

I_END: