From ed82b4c1bb4cd232f5e5eb46b3a3fa0dec80222f Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Fri, 22 May 2020 15:49:00 +0000 Subject: [PATCH] HTTP lib: experimental support for ring buffers git-svn-id: svn://kolibrios.org@7969 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/develop/libraries/http/http.asm | 62 +++++++++++++++++++++--- programs/develop/libraries/http/http.inc | 6 ++- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/programs/develop/libraries/http/http.asm b/programs/develop/libraries/http/http.asm index efaaebf7f9..707f5ccfa0 100644 --- a/programs/develop/libraries/http/http.asm +++ b/programs/develop/libraries/http/http.asm @@ -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 ;; ;; ;; ;; HTTP library for KolibriOS ;; @@ -23,7 +23,7 @@ TIMEOUT = 500 ; in 1/100 s __DEBUG__ = 1 - __DEBUG_LEVEL__ = 1 + __DEBUG_LEVEL__ = 2 format MS COFF @@ -134,7 +134,7 @@ proc HTTP_buffersize_get ;////////////////////////////////////////////////////// ;< eax = buffer size in bytes ;; ;;================================================================================================;; - mov eax, [BUFFERSIZE] + mov eax, BUFFERSIZE ret endp @@ -147,7 +147,7 @@ proc HTTP_buffersize_set ;////////////////////////////////////////////////////// ;> eax = buffer size in bytes ;; ;;================================================================================================;; - mov [BUFFERSIZE], eax +; mov [BUFFERSIZE], eax ret endp @@ -664,10 +664,13 @@ proc HTTP_receive identifier ;////////////////////////////////////////////////// test [ebp + http_msg.flags], FLAG_CONNECTED 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 jne .receive + test [ebp + http_msg.flags], FLAG_RING + jz .need_more_space + test [ebp + http_msg.flags], FLAG_STREAM jz .err_header @@ -704,7 +707,7 @@ proc HTTP_receive identifier ;////////////////////////////////////////////////// test eax, eax jz .server_closed - DEBUGF 1, "Received %u bytes\n", eax + DEBUGF 1, "Received %u bytes ", eax ; Update timestamp push eax @@ -716,6 +719,7 @@ proc HTTP_receive identifier ;////////////////////////////////////////////////// mov edi, [ebp + http_msg.write_ptr] add [ebp + http_msg.write_ptr], 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. test [ebp + http_msg.flags], FLAG_CHUNKED @@ -1017,6 +1021,16 @@ proc HTTP_receive identifier ;////////////////////////////////////////////////// ; .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. ; Update content_received add [ebp + http_msg.content_received], eax @@ -1069,6 +1083,16 @@ proc HTTP_receive identifier ;////////////////////////////////////////////////// ret .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 add [ebp + http_msg.content_received], eax popa @@ -1133,7 +1157,7 @@ proc HTTP_receive identifier ;////////////////////////////////////////////////// .err_no_ram: DEBUGF 2, "ERROR: out of RAM\n" or [ebp + http_msg.flags], FLAG_NO_RAM - jmp .abort + jmp .abort ; TODO: dont abort connection (requires rechecking all codepaths..) .err_timeout: DEBUGF 2, "ERROR: timeout\n" @@ -1147,6 +1171,14 @@ proc HTTP_receive identifier ;////////////////////////////////////////////////// and [ebp + http_msg.flags], not FLAG_CONNECTED mcall close, [ebp + http_msg.socket] .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 xor eax, eax ret @@ -1156,6 +1188,16 @@ endp 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 jz @f mov edx, [buffersize] @@ -1166,6 +1208,7 @@ alloc_contentbuff: or eax, eax jz .no_ram + .allocated: DEBUGF 1, "Content buffer allocated: 0x%x\n", eax ; Copy already received content into content buffer @@ -1190,8 +1233,11 @@ alloc_contentbuff: add eax, [ebp + http_msg.header_length] invoke mem.realloc, ebp, eax or eax, eax - .no_ram: + ret + .no_ram: + DEBUGF 2, "Error allocating content buffer!\n" + mov [ebp + http_msg.buffer_length], 0 ;;; ret diff --git a/programs/develop/libraries/http/http.inc b/programs/develop/libraries/http/http.inc index b406eced84..7107bda925 100644 --- a/programs/develop/libraries/http/http.inc +++ b/programs/develop/libraries/http/http.inc @@ -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 ;; ;; ;; ;; HTTP library for KolibriOS ;; @@ -28,13 +28,15 @@ FLAG_KEEPALIVE = 1 shl 8 FLAG_STREAM = 1 shl 9 FLAG_REUSE_BUFFER = 1 shl 10 FLAG_BLOCK = 1 shl 11 +FLAG_RING = 1 shl 12 ; error 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_TIMEOUT_ERROR = 1 shl 19 FLAG_TRANSFER_FAILED = 1 shl 20 +FLAG_NEED_MORE_SPACE = 1 shl 21 ; need more space in existing buffer struc http_msg {