Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5533 → Rev 5534

/programs/develop/libraries/http/examples/downloader.asm
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2009-2013. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2009-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; downloader.asm - HTTP client for KolibriOS ;;
168,13 → 168,13
download_1:
DEBUGF 1, "Starting download\n"
 
invoke HTTP_get, params, 0
invoke HTTP_get, 0, 0, params, 0
test eax, eax
jz fail
mov [identifier], eax
 
.loop:
invoke HTTP_process, [identifier]
invoke HTTP_receive, [identifier]
test eax, eax
jnz .loop
ret
284,7 → 284,7
 
import lib_http, \
HTTP_get , 'get' , \
HTTP_process , 'process' ,\
HTTP_receive , 'receive', \
HTTP_free , 'free'
 
import box_lib, \
/programs/develop/libraries/http/examples/pasta.asm
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2014-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; pasta.asm - Paste something to paste.kolibrios.org using POST ;;
42,13 → 42,13
test eax, eax
jnz exit
 
invoke HTTP_get, sz_url, 0
invoke HTTP_get, sz_url, 0, 0, 0
test eax, eax
jz error
mov [identifier], eax
 
.again:
invoke HTTP_process, [identifier]
invoke HTTP_receive, [identifier]
test eax, eax
jnz .again
 
78,7 → 78,7
 
invoke HTTP_free, [identifier]
 
invoke HTTP_post, sz_url, sz_cookie, sz_ctype, sz_paste.length
invoke HTTP_post, sz_url, 0, 0, sz_cookie, sz_ctype, sz_paste.length
test eax, eax
jz error
mov [identifier], eax
87,7 → 87,7
mcall 75, 6, , sz_paste, sz_paste.length, 0
 
.again2:
invoke HTTP_process, [identifier]
invoke HTTP_receive, [identifier]
test eax, eax
jnz .again2
 
142,11 → 142,10
 
import lib_http, \
HTTP_get, 'get', \
HTTP_process, 'process', \
HTTP_free, 'free', \
HTTP_stop, 'stop', \
HTTP_post, 'post', \
HTTP_find_header_field, 'find_header_field'
HTTP_receive, 'receive', \
HTTP_find_header_field, 'find_header_field', \
HTTP_free, 'free'
 
 
identifier dd 0
/programs/develop/libraries/http/http.asm
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; HTTP library for KolibriOS ;;
54,13 → 54,15
.copydone:
}
 
macro HTTP_init_buffer buffer, socketnum {
macro HTTP_init_buffer buffer, socketnum, flags {
 
mov eax, buffer
push socketnum
popd [eax + http_msg.socket]
lea esi, [eax + http_msg.http_header]
mov [eax + http_msg.flags], FLAG_CONNECTED
push flags
pop [eax + http_msg.flags]
or [eax + http_msg.flags], FLAG_CONNECTED
mov [eax + http_msg.write_ptr], esi
mov [eax + http_msg.buffer_length], BUFFERSIZE - http_msg.http_header
mov [eax + http_msg.chunk_ptr], 0
176,13 → 178,17
 
endp
 
 
 
;;================================================================================================;;
proc HTTP_get URL, add_header ;///////////////////////////////////////////////////////////////////;;
proc HTTP_get URL, identifier, flags, add_header ;////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Initiates a HTTP connection, using 'GET' method. ;;
;;------------------------------------------------------------------------------------------------;;
;> URL = pointer to ASCIIZ URL ;;
;> add_header = pointer to additional header parameters (ASCIIZ), or null for none. ;;
;> identifier = Identifier of an already open connection, or NULL to create a new one. ;;
;> flags = Flags indicating how to threat the connection. ;;
;> add_header = pointer to additional header parameters (ASCIIZ), or NULL for none. ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 (error) / buffer ptr ;;
;;================================================================================================;;
189,12 → 195,13
locals
hostname dd ?
pageaddr dd ?
sockaddr dd ?
socketnum dd ?
buffer dd ?
port dd ?
endl
 
and [flags], FLAG_KEEPALIVE or FLAG_MULTIBUFF ; filter out invalid flags
 
pusha
 
; split the URL into hostname and pageaddr
205,7 → 212,17
mov [pageaddr], ebx
mov [port], ecx
 
mov eax, [identifier]
test eax, eax
jz .open_new
test [eax + http_msg.flags], FLAG_CONNECTED
jz .error
mov eax, [eax + http_msg.socket]
mov [socketnum], eax
jmp .send_request
 
; Connect to the other side.
.open_new:
stdcall open_connection, [hostname], [port]
test eax, eax
jz .error
212,6 → 229,7
mov [socketnum], eax
 
; Create the HTTP request.
.send_request:
invoke mem.alloc, BUFFERSIZE
test eax, eax
jz .error
256,6 → 274,11
 
mov esi, str_close
mov ecx, str_close.length
test [flags], FLAG_KEEPALIVE
jz @f
mov esi, str_keep
mov ecx, str_keep.length
@@:
rep movsb
 
mov byte[edi], 0
275,12 → 298,20
jz .error
DEBUGF 1, "Request has been sent to server.\n"
 
HTTP_init_buffer [buffer], [socketnum]
cmp [identifier], 0
jne .old_connection
HTTP_init_buffer [buffer], [socketnum], [flags]
 
popa
mov eax, [buffer] ; return buffer ptr
ret
 
.old_connection:
invoke mem.free, [buffer]
popa
mov eax, [identifier]
ret
 
.error:
DEBUGF 1, "Error!\n"
popa
292,13 → 323,15
 
 
;;================================================================================================;;
proc HTTP_head URL, add_header ;//////////////////////////////////////////////////////////////////;;
proc HTTP_head URL, identifier, flags, add_header ;///////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Initiates a HTTP connection, using 'HEAD' method. ;;
;? This will only return HTTP header and status, no content ;;
;;------------------------------------------------------------------------------------------------;;
;> URL = pointer to ASCIIZ URL ;;
;> add_header = pointer to additional header parameters (ASCIIZ), or null for none. ;;
;> identifier = Identifier of an already open connection, or NULL to create a new one. ;;
;> flags = Flags indicating how to threat the connection. ;;
;> add_header = pointer to additional header parameters (ASCIIZ), or NULL for none. ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 (error) / buffer ptr ;;
;;================================================================================================;;
305,12 → 338,13
locals
hostname dd ?
pageaddr dd ?
sockaddr dd ?
socketnum dd ?
buffer dd ?
port dd ?
endl
 
and [flags], FLAG_KEEPALIVE or FLAG_MULTIBUFF ; filter out invalid flags
 
pusha
; split the URL into hostname and pageaddr
stdcall parse_url, [URL]
320,7 → 354,17
mov [pageaddr], ebx
mov [port], ecx
 
mov eax, [identifier]
test eax, eax
jz .open_new
test [eax + http_msg.flags], FLAG_CONNECTED
jz .error
mov eax, [eax + http_msg.socket]
mov [socketnum], eax
jmp .send_request
 
; Connect to the other side.
.open_new:
stdcall open_connection, [hostname], [port]
test eax, eax
jz .error
327,6 → 371,7
mov [socketnum], eax
 
; Create the HTTP request.
.send_request:
invoke mem.alloc, BUFFERSIZE
test eax, eax
jz .error
371,12 → 416,16
 
mov esi, str_close
mov ecx, str_close.length
test [flags], FLAG_KEEPALIVE
jz @f
mov esi, str_keep
mov ecx, str_keep.length
@@:
rep movsb
 
mov byte[edi], 0
DEBUGF 1, "Request:\n%s", [buffer]
 
 
; Free unused memory
push edi
invoke mem.free, [pageaddr]
391,12 → 440,20
jz .error
DEBUGF 1, "Request has been sent to server.\n"
 
HTTP_init_buffer [buffer], [socketnum]
cmp [identifier], 0
jne .old_connection
HTTP_init_buffer [buffer], [socketnum], [flags]
 
popa
mov eax, [buffer]
ret ; return buffer ptr
mov eax, [buffer] ; return buffer ptr
ret
 
.old_connection:
invoke mem.free, [buffer]
popa
mov eax, [identifier]
ret
 
.error:
DEBUGF 1, "Error!\n"
popa
407,27 → 464,30
 
 
;;================================================================================================;;
proc HTTP_post URL, add_header, content_type, content_length ;////////////////////////////////////;;
proc HTTP_post URL, identifier, flags, add_header, content_type, content_length ;/////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? Initiates a HTTP connection, using 'POST' method. ;;
;? This method is used to send data to the HTTP server ;;
;;------------------------------------------------------------------------------------------------;;
;> URL = pointer to ASCIIZ URL ;;
;> add_header = pointer to additional header parameters (ASCIIZ), or null for none. ;;
;> identifier = Identifier of an already open connection, or NULL to create a new one. ;;
;> flags = Flags indicating how to threat the connection. ;;
;> add_header = pointer to additional header parameters (ASCIIZ), or NULL for none. ;;
;> content_type = pointer to ASCIIZ string containing content type ;;
;> content_length = length of content (in bytes) ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 (error) / buffer ptr ;;
;< eax = 0 (error) / buffer ptr (aka Identifier) ;;
;;================================================================================================;;
locals
hostname dd ?
pageaddr dd ?
sockaddr dd ?
socketnum dd ?
buffer dd ?
port dd ?
endl
 
and [flags], FLAG_KEEPALIVE or FLAG_MULTIBUFF ; filter out invalid flags
 
pusha
; split the URL into hostname and pageaddr
stdcall parse_url, [URL]
437,7 → 497,17
mov [pageaddr], ebx
mov [port], ecx
 
mov eax, [identifier]
test eax, eax
jz .open_new
test [eax + http_msg.flags], FLAG_CONNECTED
jz .error
mov eax, [eax + http_msg.socket]
mov [socketnum], eax
jmp .send_request
 
; Connect to the other side.
.open_new:
stdcall open_connection, [hostname], [port]
test eax, eax
jz .error
444,6 → 514,7
mov [socketnum], eax
 
; Create the HTTP request.
.send_request:
invoke mem.alloc, BUFFERSIZE
test eax, eax
jz .error
502,6 → 573,11
 
mov esi, str_close
mov ecx, str_close.length
test [flags], FLAG_KEEPALIVE
jz @f
mov esi, str_keep
mov ecx, str_keep.length
@@:
rep movsb
 
mov byte[edi], 0
521,12 → 597,23
jz .error
DEBUGF 1, "Request has been sent to server.\n"
 
HTTP_init_buffer [buffer], [socketnum]
cmp [identifier], 0
jne .old_connection
HTTP_init_buffer [buffer], [socketnum], [flags]
 
popa
mov eax, [buffer]
ret ; return buffer ptr
mov eax, [buffer] ; return buffer ptr
ret
 
.old_connection:
invoke mem.free, [buffer]
mov ebx, [flags]
mov eax, [identifier]
or [eax + http_msg.flags], ebx
popa
mov eax, [identifier]
ret
 
.error:
DEBUGF 1, "Error!\n"
popa
555,7 → 642,22
test [ebp + http_msg.flags], FLAG_CONNECTED
jz .connection_closed
 
; If the buffer is full, allocate a new one
cmp [ebp + http_msg.buffer_length], 0
jne .receive
 
test [ebp + http_msg.flags], FLAG_MULTIBUFF
jz .err_header
 
invoke mem.alloc, BUFFERSIZE
test eax, eax
jz .err_no_ram
mov [ebp + http_msg.content_ptr], eax
mov [ebp + http_msg.write_ptr], eax
mov [ebp + http_msg.buffer_length], BUFFERSIZE
 
; Receive some data
.receive:
mcall recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \
[ebp + http_msg.buffer_length], MSG_DONTWAIT
cmp eax, 0xffffffff
841,6 → 943,8
mov edx, esi
sub edx, [ebp + http_msg.chunk_ptr] ; edx is now length of chunkline
sub [ebp + http_msg.write_ptr], edx
test [ebp + http_msg.flags], FLAG_MULTIBUFF
jnz .dont_resize
; Realloc buffer, make it 'chunksize' bigger.
lea edx, [ebx + BUFFERSIZE]
mov [ebp + http_msg.buffer_length], edx ; remaining space in new buffer
853,6 → 957,7
jz .err_no_ram
call recalculate_pointers ; Because it's possible that buffer begins on another address now
add esi, eax ; recalculate esi too!
.dont_resize:
; Remove chunk header (aka chunkline) from the buffer by shifting all received data after chunkt_ptr to the left
mov edi, [ebp + http_msg.chunk_ptr]
rep movsb
887,7 → 992,8
ret
 
.buffer_full:
; Lets make it bigger..
test [ebp + http_msg.flags], FLAG_MULTIBUFF
jnz .multibuff
mov eax, [ebp + http_msg.write_ptr]
add eax, BUFFERSIZE
sub eax, [ebp + http_msg.content_ptr]
902,6 → 1008,12
dec eax
ret
 
.multibuff:
; This buffer is full
popa
xor eax, eax
ret
 
.need_more_data_for_header:
cmp [ebp + http_msg.buffer_length], 0
je .err_header ; It's just too damn long!
1151,24 → 1263,22
 
 
;;================================================================================================;;
proc HTTP_escape URI ;////////////////////////////////////////////////////////////////////////////;;
proc HTTP_escape URI, length ;////////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? ;;
;;------------------------------------------------------------------------------------------------;;
;> URI = ptr to ASCIIZ URI ;;
;> URI = ptr to ASCIIZ URI/data ;;
;> length = length of URI/data ;;
;;------------------------------------------------------------------------------------------------;;
;< eax = 0 (error) / ptr to ASCIIZ URI/data ;;
;< ebx = length of escaped URI/data ;;
;;================================================================================================;;
 
 
; TODO: instead of static buffer allocation, make it 4096 bytes and larger only if needed
 
DEBUGF 1, "HTTP_escape: %s\n", [URI]
 
pusha
 
invoke mem.alloc, URLMAXLEN
invoke mem.alloc, URLMAXLEN ; FIXME: use length provided by caller to guess final size.
test eax, eax
jz .error
mov [esp + 7 * 4], eax ; return ptr in eax
1227,7 → 1337,7
 
 
;;================================================================================================;;
proc HTTP_unescape URI ;//////////////////////////////////////////////////////////////////////////;;
proc HTTP_unescape URI, length ;//////////////////////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;;
;? ;;
;;------------------------------------------------------------------------------------------------;;
1239,7 → 1349,7
DEBUGF 1, "HTTP_unescape: %s\n", [URI]
pusha
 
invoke mem.alloc, URLMAXLEN
invoke mem.alloc, URLMAXLEN ; FIXME: use length provided by caller
test eax, eax
jz .error
mov [esp + 7 * 4], eax ; return ptr in eax
1768,8 → 1878,10
.length = $ - str_post_ct
str_proxy_auth db 13, 10, 'Proxy-Authorization: Basic '
.length = $ - str_proxy_auth
str_close db 'User-Agent: KolibriOS libHTTP/1.0', 13, 10, 'Connection: Close', 13, 10, 13, 10
str_close db 'User-Agent: KolibriOS libHTTP/1.1', 13, 10, 'Connection: Close', 13, 10, 13, 10
.length = $ - str_close
str_keep db 'User-Agent: KolibriOS libHTTP/1.1', 13, 10, 'Connection: Keepalive', 13, 10, 13, 10
.length = $ - str_close
 
str_http db 'http://', 0
 
/programs/develop/libraries/http/http.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; HTTP library for KolibriOS ;;
14,6 → 14,8
 
 
; Bitflags for http_msg.flags
 
; status
FLAG_HTTP11 = 1 shl 0
FLAG_GOT_HEADER = 1 shl 1
FLAG_GOT_ALL_DATA = 1 shl 2
20,7 → 22,12
FLAG_CONTENT_LENGTH = 1 shl 3
FLAG_CHUNKED = 1 shl 4
FLAG_CONNECTED = 1 shl 5
; ERROR flags go into the upper word
 
; user options
FLAG_KEEPALIVE = 1 shl 8
FLAG_MULTIBUFF = 1 shl 9
 
; error
FLAG_INVALID_HEADER = 1 shl 16
FLAG_NO_RAM = 1 shl 17
FLAG_SOCKET_ERROR = 1 shl 18
/programs/develop/libraries/http/http_en.txt
1,20 → 1,26
 
get(*url, *add_header);
get(*url, identifier, flags, *add_header);
*url = pointer to ASCIIZ URL
identifier = identified of previously opened connection, or 0 to open a new one
flags = bit flags (see http.inc user flags)
*add_header = pointer to ASCIIZ additional header parameters, or null for none.
Every additional parameter must end with CR LF bytes, including the last line.
Initiates a HTTP connection, using 'GET' method.
- returns 0 on error, identifier otherwise.
 
head(*url, *add_header);
head(*url, identifier, flags, *add_header);
*url = pointer to ASCIIZ URL
identifier = identified of previously opened connection, or 0 to open a new one
flags = bit flags (see http.inc user flags)
*add_header = pointer to ASCIIZ additional header parameters, or null for none.
Every additional parameter must end with CR LF bytes, including the last line.
Initiate a HTTP connection, using 'HEAD' method.
- returns 0 on error, identifier otherwise
 
post(*url, *add_header, *content-type, content-length);
post(*url, identifier, flags, *add_header, *content-type, content-length);
*url = pointer to ASCIIZ URL
identifier = identified of previously opened connection, or 0 to open a new one
flags = bit flags (see http.inc user flags)
*add_header = pointer to ASCIIZ additional header parameters, or null for none.
Every additional parameter must end with CR LF bytes, including the last line.
*content-type = pointer to ASCIIZ string containing content type.