Updates and bugfixes for HTTP lib.

git-svn-id: svn://kolibrios.org@4168 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2013-11-05 17:02:59 +00:00
parent 44992ba6df
commit fc383603e2
4 changed files with 69 additions and 19 deletions

View File

@ -33,5 +33,6 @@ struct http_msg{
dword status; dword status;
dword header_length; dword header_length;
dword content_length; dword content_length;
dword content_received;
char data; char data;
}; };

View File

@ -65,6 +65,7 @@ macro HTTP_init_buffer buffer, socketnum {
mov [eax + http_msg.status], 0 mov [eax + http_msg.status], 0
mov [eax + http_msg.header_length], 0 mov [eax + http_msg.header_length], 0
mov [eax + http_msg.content_length], 0 mov [eax + http_msg.content_length], 0
mov [eax + http_msg.content_received], 0
} }
section '.flat' code readable align 16 section '.flat' code readable align 16
@ -292,7 +293,7 @@ endp
;;================================================================================================;; ;;================================================================================================;;
proc HTTP_post URL, content, content_type, content_length ;///////////////////////////////////////;; proc HTTP_post URL, content_type, content_length ;////////////////////////////////////////////////;;
;;------------------------------------------------------------------------------------------------;; ;;------------------------------------------------------------------------------------------------;;
;? ;; ;? ;;
;;------------------------------------------------------------------------------------------------;; ;;------------------------------------------------------------------------------------------------;;
@ -383,11 +384,6 @@ endl
jz .error jz .error
DEBUGF 1, "Request has been sent to server.\n" DEBUGF 1, "Request has been sent to server.\n"
mcall send, [socketnum], [content], [content_length]
test eax, eax
jz .error
DEBUGF 1, "Data has been sent to server.\n"
HTTP_init_buffer [buffer], [socketnum] HTTP_init_buffer [buffer], [socketnum]
; mov eax, [buffer] ; mov eax, [buffer]
@ -411,6 +407,10 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
;;------------------------------------------------------------------------------------------------;; ;;------------------------------------------------------------------------------------------------;;
;< eax = -1 (not finished) / 0 finished ;; ;< eax = -1 (not finished) / 0 finished ;;
;;================================================================================================;; ;;================================================================================================;;
locals
received dd ?
endl
pusha pusha
mov ebp, [identifier] mov ebp, [identifier]
@ -427,6 +427,8 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
sub [ebp + http_msg.buffer_length], eax sub [ebp + http_msg.buffer_length], eax
jz .got_all_data jz .got_all_data
mov [received], eax
; 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
jnz .chunk_loop jnz .chunk_loop
@ -555,17 +557,18 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
DEBUGF 1, "Content-length: %u\n", edx DEBUGF 1, "Content-length: %u\n", edx
; Resize buffer according to content-length. ; Resize buffer according to content-length.
mov eax, [ebp + http_msg.header_length] add edx, [ebp + http_msg.header_length]
add eax, [ebp + http_msg.content_length] add edx, http_msg.data
add eax, http_msg.data
mov ecx, eax mov ecx, edx
sub ecx, [ebp + http_msg.write_ptr] sub ecx, [ebp + http_msg.write_ptr]
mov [ebp + http_msg.buffer_length], ecx mov [ebp + http_msg.buffer_length], ecx
invoke mem.realloc, ebp, eax invoke mem.realloc, ebp, edx
or eax, eax or eax, eax
jz .no_ram jz .no_ram
mov eax, [received]
sub eax, [ebp + http_msg.header_length]
jmp .header_parsed ; hooray! jmp .header_parsed ; hooray!
.no_content: .no_content:
@ -653,16 +656,16 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
; Update content_length accordingly. ; Update content_length accordingly.
mov ecx, [ebp + http_msg.write_ptr] mov ecx, [ebp + http_msg.write_ptr]
sub ecx, esi sub ecx, esi
add [ebp + http_msg.content_length], ecx add [ebp + http_msg.content_received], ecx
rep movsb rep movsb
jmp .chunk_loop jmp .chunk_loop
; Check if we got all the data. ; Check if we got all the data.
.header_parsed: .header_parsed:
mov eax, [ebp + http_msg.header_length] add [ebp + http_msg.content_received], eax
add eax, [ebp + http_msg.content_length] mov eax, [ebp + http_msg.content_length]
cmp eax, [ebp + http_msg.buffer_length] cmp eax, [ebp + http_msg.content_received]
je .got_all_data jae .got_all_data
.need_more_data: .need_more_data:
popa popa
xor eax, eax xor eax, eax
@ -670,7 +673,7 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
ret ret
.need_more_data_chunked: .need_more_data_chunked:
add [ebp + http_msg.content_length], eax add [ebp + http_msg.content_received], eax
popa popa
xor eax, eax xor eax, eax
dec eax dec eax
@ -682,6 +685,7 @@ proc HTTP_process identifier ;//////////////////////////////////////////////////
sub eax, http_msg.data sub eax, http_msg.data
sub eax, ebp sub eax, ebp
mov [ebp + http_msg.content_length], eax mov [ebp + http_msg.content_length], eax
mov [ebp + http_msg.content_received], eax
.got_all_data: .got_all_data:
DEBUGF 1, "We got all the data! (%u bytes)\n", [ebp + http_msg.content_length] DEBUGF 1, "We got all the data! (%u bytes)\n", [ebp + http_msg.content_length]
or [ebp + http_msg.flags], FLAG_GOT_DATA or [ebp + http_msg.flags], FLAG_GOT_DATA
@ -970,16 +974,24 @@ endp
; edi = ptr where to store ascii ; edi = ptr where to store ascii
ascii_dec: ascii_dec:
push -'0'
mov ecx, 10 mov ecx, 10
.loop: .loop:
xor edx, edx xor edx, edx
div ecx div ecx
add dl, '0' add dl, '0'
mov byte[edi], dl push edx
inc edi
test eax, eax test eax, eax
jnz .loop jnz .loop
.loop2:
pop eax
add al, '0'
jz .done
stosb
jmp .loop2
.done:
ret ret

View File

@ -34,5 +34,6 @@ struc http_msg {
.status dd ? .status dd ?
.header_length dd ? .header_length dd ?
.content_length dd ? .content_length dd ?
.content_received dd ?
.data: .data:
} }

View File

@ -0,0 +1,36 @@
get(*url);
*url = pointer to ASCIIZ URL
Initiates a HTTP connection, using 'GET' method.
- returns 0 on error, identifier otherwise.
head(*url);
*url = pointer to ASCIIZ URL
Initiate a HTTP connection, using 'HEAD' method.
- returns 0 on error, identifier otherwise
post(*url, *content-type, content-length);
*url = pointer to ASCIIZ URL
*content-type = pointer to ASCIIZ string containing content type.
content-length = length of the content (in bytes).
Initiate a HTTP connection, using 'POST' method.
The content itself must be send to the socket (which you can find in the structure),
using system function 75, 6.
- returns 0 on error, identifier otherwise
process(identifier);
identifier = identifier which one of the previous functions returned
This procedure will handle all incoming data for a connection and place it in the buffer.
As long as the procedure expects more data, -1 is returned and the procedure must be called again.
- When transfer is done, the procedure will return 0.
All data is placed together with some flags and other attributes in the http_msg structure.
This structure is defined in http.inc (and not copied here because it might still change.)
The identifier used by the functions is actually a pointer to this structure.
In the dword named .flags, the library will set various bit-flags indicating the status of the process.
(When a transfer is done, one should check these bit-flags to find out if the transfer was error-free.)
All received data is placed at the end of this structure, including HTTP headers.
The dword .status contains the status code received from the server (e.g. 200 for OK).
In header_length you'll find the length of the header as soon as it has been received.
In content_length you'll find the length of the content (not counting headers).
In content_received, you'll find the number of bytes already received (not counting headers).