libs/http.obj: fix content_received overcount on chunked transfers (#569)
Build system / Build (en_US) (push) Successful in 2m25s
Build system / Build (ru_RU) (push) Successful in 2m27s
Build system / Build (es_ES) (push) Successful in 2m30s
Build system / Publish Images (push) Successful in 2m46s

For chunked responses HTTP_receive added the whole buffer tail to
content_received every time it consumed a chunkline. When several
chunks arrived in one TCP segment, the same bytes were counted once
per chunkline (observed: content_received = 42 MB for an 83 KB page);
the value only became exact at got_all_data. A client trusting the
counter mid-transfer read far past the buffer and page-faulted.
In plain buffered mode recompute the exact value from the pointers
instead: min(chunk_ptr, write_ptr) - content_ptr, the same formula
.got_all_data_chunked uses. Data below chunk_ptr is decoded and
contiguous; bytes in [chunk_ptr, write_ptr) are still raw (unconsumed
chunkline + partial chunk). Stream/ring modes keep the running add:
there data is consumed as it arrives, so the incremental count is
correct.

---------

Co-authored-by: Burer <burer@kolibrios.org>
Reviewed-on: #569
Reviewed-by: hidnplayr <hidnplayr@gmail.com>
Reviewed-by: Burer <burer@kolibrios.org>
Co-authored-by: leency <lipatov.kiril@gmail.com>
This commit was merged in pull request #569.
This commit is contained in:
2026-07-21 10:02:50 +00:00
committed by Burer
co-authored by Burer
parent 14162d4139
commit 8a48f089d8
+17 -1
View File
@@ -921,6 +921,7 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
; Set chunk pointer where first chunk should begin.
mov eax, [ebp + http_msg.content_ptr]
mov [ebp + http_msg.chunk_ptr], eax
xor eax, eax
;--------------------------------------------------------------
;
@@ -990,8 +991,11 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
mov ecx, [ebp + http_msg.write_ptr]
sub ecx, [ebp + http_msg.chunk_ptr]
sub ecx, edx ; ecx is now number of received data bytes (without chunkline)
; Update content_received counter
; Update content_received counter.
test [ebp + http_msg.flags], FLAG_STREAM or FLAG_RING
jz .chunkline_counted
add [ebp + http_msg.content_received], ecx
.chunkline_counted:
; Calculate new write ptr
sub [ebp + http_msg.write_ptr], edx
test [ebp + http_msg.flags], FLAG_STREAM
@@ -1101,7 +1105,19 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
sub [ebp + http_msg.write_ptr], ebx
@@:
; We only got a partial chunk, or need more chunks, update content_received and request more data
test [ebp + http_msg.flags], FLAG_STREAM or FLAG_RING
jz .nmdc_exact
add [ebp + http_msg.content_received], eax
jmp .nmdc_ret
.nmdc_exact:
mov eax, [ebp + http_msg.chunk_ptr]
cmp eax, [ebp + http_msg.write_ptr]
jbe @f
mov eax, [ebp + http_msg.write_ptr]
@@:
sub eax, [ebp + http_msg.content_ptr]
mov [ebp + http_msg.content_received], eax
.nmdc_ret:
popa
xor eax, eax
dec eax