HTTP lib now also supports chunked content encoding.

git-svn-id: svn://kolibrios.org@4162 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2013-11-04 18:41:15 +00:00
parent cb3c960361
commit 5da434be1e

View File

@ -236,21 +236,31 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
;;================================================================================================;;
pusha
mov ebp, [identifier]
; Receive some data
mcall recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \
[ebp + http_msg.buffer_length], MSG_DONTWAIT
cmp eax, 0xffffffff
je .check_socket
DEBUGF 1, "Received %u bytes\n", eax
; Update pointers
mov edi, [ebp + http_msg.write_ptr]
add [ebp + http_msg.write_ptr], eax
sub [ebp + http_msg.buffer_length], eax
jz .got_all_data
; If data is chunked, combine chunks into contiguous data.
test [ebp + http_msg.flags], FLAG_CHUNKED
jnz .chunk_loop
; Did we detect the header yet?
test [ebp + http_msg.flags], FLAG_GOT_HEADER
jnz .header_parsed
; We havent found the header yet, search for it..
sub eax, 4
jl .no_header
jl .need_more_data
.scan:
; scan for end of header (empty line)
cmp dword[edi], 0x0a0d0a0d ; end of header
@ -261,12 +271,6 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
dec eax
jnz .scan
.no_header:
popa
xor eax, eax
dec eax
ret
.end_of_header:
add edi, 4 - http_msg.data
sub edi, ebp
@ -397,34 +401,29 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
jz .invalid_header
mov ebx, dword[eax]
or eax, 0x20202020
or ebx, 0x20202020
cmp ebx, 'chun'
jne .invalid_header
mov ebx, dword[eax+4]
or eax, 0x00202020
and eax, 0x00ffffff
or ebx, 0x00202020
and ebx, 0x00ffffff
cmp ebx, 'ked'
jne .invalid_header
or [ebp + http_msg.flags], FLAG_CHUNKED
DEBUGF 1, "Transfer type is: chunked\n"
; Set chunk pointer where first chunk should begin.
mov eax, [ebp + http_msg.header_length]
add eax, http_msg.data
lea eax, [ebp + http_msg.data]
add eax, [ebp + http_msg.header_length]
mov [ebp + http_msg.chunk_ptr], eax
.header_parsed:
; If data is chunked, combine chunks into contiguous data if so.
test [ebp + http_msg.flags], FLAG_CHUNKED
jz .not_chunked
.chunkloop:
.chunk_loop:
mov ecx, [ebp + http_msg.write_ptr]
sub ecx, [ebp + http_msg.chunk_ptr]
jb .not_finished
jb .need_more_data_chunked
; TODO: make sure we have the complete chunkline header
mov esi, [ebp + http_msg.chunk_ptr]
xor ebx, ebx
.chunk_hexloop:
@ -433,12 +432,12 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
jb .chunk_
cmp al, 9
jbe .chunk_hex
sub al, 'A' - '0'
sub al, 'A' - '0' - 10
jb .chunk_
cmp al, 5
cmp al, 15
jbe .chunk_hex
sub al, 'a' - 'A'
cmp al, 5
cmp al, 15
ja .chunk_
.chunk_hex:
shl ebx, 4
@ -448,7 +447,8 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
DEBUGF 1, "got chunk of %u bytes\n", ebx
; If chunk size is 0, all chunks have been received.
test ebx, ebx
jz .got_all_data ; last chunk, hooray! FIXME: what if it wasnt a valid hex number???
jz .got_all_data_chunked ; last chunk, hooray! FIXME: what if it wasnt a valid hex number???
mov edi, [ebp + http_msg.chunk_ptr] ; we'll need this in about 25 lines...
add [ebp + http_msg.chunk_ptr], ebx
; Chunkline ends with a CR, LF or simply LF
@ -459,34 +459,55 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
jmp .end_of_chunkline?
.end_of_chunkline:
; Now move all received data to the left (remove chunk header).
; Meanwhile, update write_ptr and content_length accordingly.
mov edi, [ebp + http_msg.chunk_ptr]
mov ecx, [ebp + http_msg.write_ptr]
sub ecx, esi
; Realloc buffer, make it 'chunksize' bigger.
mov eax, [ebp + http_msg.buffer_length]
add eax, ebx
invoke mem.realloc, ebp, eax
or eax, eax
jz .no_ram
add [ebp + http_msg.buffer_length], ebx
; Update write ptr
mov eax, esi
sub eax, edi
sub [ebp + http_msg.write_ptr], eax
; Now move all received data to the left (remove chunk header).
; Update content_length accordingly.
mov ecx, [ebp + http_msg.write_ptr]
sub ecx, esi
add [ebp + http_msg.content_length], ecx
rep movsb
jmp .chunkloop
jmp .chunk_loop
.not_chunked:
; Check if we got all the data.
.header_parsed:
mov eax, [ebp + http_msg.header_length]
add eax, [ebp + http_msg.content_length]
cmp eax, [ebp + http_msg.buffer_length]
je .got_all_data
.not_finished:
; DEBUGF 1, "Needs more processing...\n"
.need_more_data:
popa
xor eax, eax
dec eax
ret
.need_more_data_chunked:
add [ebp + http_msg.content_length], eax
popa
xor eax, eax
dec eax
ret
.got_all_data_chunked:
mov eax, [ebp + http_msg.chunk_ptr]
sub eax, [ebp + http_msg.header_length]
sub eax, http_msg.data
sub eax, ebp
mov [ebp + http_msg.content_length], eax
.got_all_data:
DEBUGF 1, "We got all the data!\n"
DEBUGF 1, "We got all the data! (%u bytes)\n", [ebp + http_msg.content_length]
or [ebp + http_msg.flags], FLAG_GOT_DATA
mcall close, [ebp + http_msg.socket]
popa
@ -495,7 +516,7 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
.check_socket:
cmp ebx, EWOULDBLOCK
je .not_finished
je .need_more_data
DEBUGF 1, "ERROR: socket error %u\n", ebx
or [ebp + http_msg.flags], FLAG_SOCKET_ERROR