HTTP lib: experimental support for ring buffers

git-svn-id: svn://kolibrios.org@7969 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2020-05-22 15:49:00 +00:00
parent 5a633309ff
commit ed82b4c1bb
2 changed files with 58 additions and 10 deletions

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2018. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; HTTP library for KolibriOS ;; ;; HTTP library for KolibriOS ;;
@ -23,7 +23,7 @@
TIMEOUT = 500 ; in 1/100 s TIMEOUT = 500 ; in 1/100 s
__DEBUG__ = 1 __DEBUG__ = 1
__DEBUG_LEVEL__ = 1 __DEBUG_LEVEL__ = 2
format MS COFF format MS COFF
@ -134,7 +134,7 @@ proc HTTP_buffersize_get ;//////////////////////////////////////////////////////
;< eax = buffer size in bytes ;; ;< eax = buffer size in bytes ;;
;;================================================================================================;; ;;================================================================================================;;
mov eax, [BUFFERSIZE] mov eax, BUFFERSIZE
ret ret
endp endp
@ -147,7 +147,7 @@ proc HTTP_buffersize_set ;//////////////////////////////////////////////////////
;> eax = buffer size in bytes ;; ;> eax = buffer size in bytes ;;
;;================================================================================================;; ;;================================================================================================;;
mov [BUFFERSIZE], eax ; mov [BUFFERSIZE], eax
ret ret
endp endp
@ -664,10 +664,13 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
test [ebp + http_msg.flags], FLAG_CONNECTED test [ebp + http_msg.flags], FLAG_CONNECTED
jz .connection_closed jz .connection_closed
; If the buffer is full, allocate a new one ; Check if our receive buffer still has space
cmp [ebp + http_msg.buffer_length], 0 cmp [ebp + http_msg.buffer_length], 0
jne .receive jne .receive
test [ebp + http_msg.flags], FLAG_RING
jz .need_more_space
test [ebp + http_msg.flags], FLAG_STREAM test [ebp + http_msg.flags], FLAG_STREAM
jz .err_header jz .err_header
@ -704,7 +707,7 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
test eax, eax test eax, eax
jz .server_closed jz .server_closed
DEBUGF 1, "Received %u bytes\n", eax DEBUGF 1, "Received %u bytes ", eax
; Update timestamp ; Update timestamp
push eax push eax
@ -716,6 +719,7 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
mov edi, [ebp + http_msg.write_ptr] mov edi, [ebp + http_msg.write_ptr]
add [ebp + http_msg.write_ptr], eax add [ebp + http_msg.write_ptr], eax
sub [ebp + http_msg.buffer_length], eax sub [ebp + http_msg.buffer_length], eax
DEBUGF 1, "buffer length = %d\n", [ebp + http_msg.buffer_length]
; If data is chunked, combine chunks into contiguous data. ; If data is chunked, combine chunks into contiguous data.
test [ebp + http_msg.flags], FLAG_CHUNKED test [ebp + http_msg.flags], FLAG_CHUNKED
@ -1017,6 +1021,16 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
; ;
.header_parsed: .header_parsed:
; If we're using ring buffer, check we crossed the boundary
test [ebp + http_msg.flags], FLAG_RING
jz @f
mov ebx, [ebp + http_msg.content_ptr]
add ebx, BUFFERSIZE
cmp [ebp + http_msg.write_ptr], ebx
jb @f
DEBUGF 1, "Restarting at beginning of ring buffer\n"
sub [ebp + http_msg.write_ptr], BUFFERSIZE
@@:
; Header was already parsed and connection isnt chunked. ; Header was already parsed and connection isnt chunked.
; Update content_received ; Update content_received
add [ebp + http_msg.content_received], eax add [ebp + http_msg.content_received], eax
@ -1069,6 +1083,16 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
ret ret
.need_more_data_chunked: .need_more_data_chunked:
; If we're using ring buffer, check we crossed the boundary
test [ebp + http_msg.flags], FLAG_RING
jz @f
mov ebx, [ebp + http_msg.content_ptr]
add ebx, BUFFERSIZE
cmp [ebp + http_msg.write_ptr], ebx
jb @f
DEBUGF 1, "Restarting at beginning of ring buffer\n"
sub [ebp + http_msg.write_ptr], BUFFERSIZE
@@:
; We only got a partial chunk, or need more chunks, update content_received and request more data ; We only got a partial chunk, or need more chunks, update content_received and request more data
add [ebp + http_msg.content_received], eax add [ebp + http_msg.content_received], eax
popa popa
@ -1133,7 +1157,7 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
.err_no_ram: .err_no_ram:
DEBUGF 2, "ERROR: out of RAM\n" DEBUGF 2, "ERROR: out of RAM\n"
or [ebp + http_msg.flags], FLAG_NO_RAM or [ebp + http_msg.flags], FLAG_NO_RAM
jmp .abort jmp .abort ; TODO: dont abort connection (requires rechecking all codepaths..)
.err_timeout: .err_timeout:
DEBUGF 2, "ERROR: timeout\n" DEBUGF 2, "ERROR: timeout\n"
@ -1147,6 +1171,14 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
and [ebp + http_msg.flags], not FLAG_CONNECTED and [ebp + http_msg.flags], not FLAG_CONNECTED
mcall close, [ebp + http_msg.socket] mcall close, [ebp + http_msg.socket]
.connection_closed: .connection_closed:
.continue:
popa
xor eax, eax
ret
.need_more_space:
DEBUGF 1, "Buffer is full!\n"
and [ebp + http_msg.flags], not FLAG_NEED_MORE_SPACE
popa popa
xor eax, eax xor eax, eax
ret ret
@ -1156,6 +1188,16 @@ endp
alloc_contentbuff: alloc_contentbuff:
test [ebp + http_msg.flags], FLAG_RING
jz @f
DEBUGF 1, "Allocating ring buffer\n"
mcall 68, 29, [buffersize]
or eax, eax
jz .no_ram
jmp .allocated
@@:
test [ebp + http_msg.flags], FLAG_STREAM test [ebp + http_msg.flags], FLAG_STREAM
jz @f jz @f
mov edx, [buffersize] mov edx, [buffersize]
@ -1166,6 +1208,7 @@ alloc_contentbuff:
or eax, eax or eax, eax
jz .no_ram jz .no_ram
.allocated:
DEBUGF 1, "Content buffer allocated: 0x%x\n", eax DEBUGF 1, "Content buffer allocated: 0x%x\n", eax
; Copy already received content into content buffer ; Copy already received content into content buffer
@ -1190,8 +1233,11 @@ alloc_contentbuff:
add eax, [ebp + http_msg.header_length] add eax, [ebp + http_msg.header_length]
invoke mem.realloc, ebp, eax invoke mem.realloc, ebp, eax
or eax, eax or eax, eax
.no_ram: ret
.no_ram:
DEBUGF 2, "Error allocating content buffer!\n"
mov [ebp + http_msg.buffer_length], 0 ;;;
ret ret

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; HTTP library for KolibriOS ;; ;; HTTP library for KolibriOS ;;
@ -28,13 +28,15 @@ FLAG_KEEPALIVE = 1 shl 8
FLAG_STREAM = 1 shl 9 FLAG_STREAM = 1 shl 9
FLAG_REUSE_BUFFER = 1 shl 10 FLAG_REUSE_BUFFER = 1 shl 10
FLAG_BLOCK = 1 shl 11 FLAG_BLOCK = 1 shl 11
FLAG_RING = 1 shl 12
; error ; error
FLAG_INVALID_HEADER = 1 shl 16 FLAG_INVALID_HEADER = 1 shl 16
FLAG_NO_RAM = 1 shl 17 FLAG_NO_RAM = 1 shl 17 ; alloc failed
FLAG_SOCKET_ERROR = 1 shl 18 FLAG_SOCKET_ERROR = 1 shl 18
FLAG_TIMEOUT_ERROR = 1 shl 19 FLAG_TIMEOUT_ERROR = 1 shl 19
FLAG_TRANSFER_FAILED = 1 shl 20 FLAG_TRANSFER_FAILED = 1 shl 20
FLAG_NEED_MORE_SPACE = 1 shl 21 ; need more space in existing buffer
struc http_msg { struc http_msg {