mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-11-28 11:43:09 +03:00
Extended http library API to allow keepalive connections, streaming connections and transfer of large files.
git-svn-id: svn://kolibrios.org@5534 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
5080442b18
commit
d52d41e20d
@ -220,7 +220,7 @@ void main()
|
||||
|
||||
case evNetwork:
|
||||
if (http_transfer > 0) {
|
||||
http_process stdcall (http_transfer);
|
||||
http_receive stdcall (http_transfer);
|
||||
$push EAX
|
||||
ESI = http_transfer;
|
||||
wv_progress_bar.max = ESI.http_msg.content_length;
|
||||
@ -618,7 +618,7 @@ void OpenPage()
|
||||
if (strncmp(#URL,"http:",5)==0)
|
||||
{
|
||||
img_draw stdcall(skin.image, address_box.left+address_box.width+1, address_box.top-2, 17, skin.h, 131, 0);
|
||||
http_get stdcall (#URL, #accept_language);
|
||||
http_get stdcall (#URL, 0, 0, #accept_language);
|
||||
http_transfer = EAX;
|
||||
if (http_transfer == 0)
|
||||
{
|
||||
|
@ -88,7 +88,7 @@ void Downloader()
|
||||
|
||||
default:
|
||||
if (DL_Form.width==0) || (DL_http_transfer <= 0) break;
|
||||
http_process stdcall (DL_http_transfer);
|
||||
http_receive stdcall (DL_http_transfer);
|
||||
$push EAX
|
||||
ESI = DL_http_transfer;
|
||||
DL_progress_bar.max = ESI.http_msg.content_length;
|
||||
@ -220,7 +220,7 @@ void StartDownloading()
|
||||
{
|
||||
download_state = STATE_IN_PROGRESS;
|
||||
DL_address_box.color = DL_address_box.blur_border_color = DL_address_box.focus_border_color = 0xdddDDD;
|
||||
http_get stdcall (#DL_URL, #accept_language);
|
||||
http_get stdcall (#DL_URL, 0, 0, #accept_language);
|
||||
DL_http_transfer = EAX;
|
||||
DL_progress_bar.value = 0;
|
||||
DL_Draw_Window();
|
||||
|
@ -96,7 +96,7 @@ void main()
|
||||
default:
|
||||
if (Form.width==0) break;
|
||||
if (http_transfer <= 0) break;
|
||||
http_process stdcall (http_transfer);
|
||||
http_receive stdcall (http_transfer);
|
||||
if (EAX == 0) {
|
||||
ESI = http_transfer;
|
||||
bufpointer = ESI.http_msg.content_ptr;
|
||||
@ -222,7 +222,7 @@ void StartDownloading()
|
||||
if (strncmp(#URL,"http:",5)==0)
|
||||
{
|
||||
address_box.color = address_box.blur_border_color = address_box.focus_border_color = 0xededed;
|
||||
http_get stdcall (#URL, #accept_language);
|
||||
http_get stdcall (#URL, 0, 0, #accept_language);
|
||||
http_transfer = EAX;
|
||||
Draw_Window();
|
||||
if (http_transfer == 0)
|
||||
|
@ -8,9 +8,10 @@ dword http_get = #aHTTPget;
|
||||
dword http_head = #aHTTPhead;
|
||||
dword http_post = #aHTTPpost;
|
||||
dword http_find_header_field = #aFHF;
|
||||
dword http_process = #aHTTPprocess;
|
||||
dword http_send = #aHTTPsend;
|
||||
dword http_receive = #aHTTPreceive;
|
||||
dword http_disconnect = #aHTTPdisconnect;
|
||||
dword http_free = #aHTTPfree;
|
||||
dword http_stop = #aHTTPstop;
|
||||
dword uri_escape = #aURIescape;
|
||||
dword uri_unescape = #aURIunescape;
|
||||
$DD 2 dup 0
|
||||
@ -20,12 +21,14 @@ char aHTTPget[4] = "get\0";
|
||||
char aHTTPhead[5] = "head\0";
|
||||
char aHTTPpost[5] = "post\0";
|
||||
char aFHF[18] = "find_header_field\0";
|
||||
char aHTTPprocess[8] = "process\0";
|
||||
char aHTTPsend[5] = "send\0";
|
||||
char aHTTPreceive[8] = "receive\0";
|
||||
char aHTTPdisconnect[11] = "disconnect\0";
|
||||
char aHTTPfree[5] = "free\0";
|
||||
char aHTTPstop[5] = "stop\0";
|
||||
char aURIescape[7] = "escape\0";
|
||||
char aURIunescape[9] = "unescape\0";
|
||||
|
||||
// status flags
|
||||
#define FLAG_HTTP11 1 << 0
|
||||
#define FLAG_GOT_HEADER 1 << 1
|
||||
#define FLAG_GOT_ALL_DATA 1 << 2
|
||||
@ -33,7 +36,11 @@ char aURIunescape[9] = "unescape\0";
|
||||
#define FLAG_CHUNKED 1 << 4
|
||||
#define FLAG_CONNECTED 1 << 5
|
||||
|
||||
// error flags go into the upper word
|
||||
// user flags
|
||||
#define FLAG_KEEPALIVE 1 << 8
|
||||
#define FLAG_MULTIBUFF 1 << 9
|
||||
|
||||
// error flags
|
||||
#define FLAG_INVALID_HEADER 1 << 16
|
||||
#define FLAG_NO_RAM 1 << 17
|
||||
#define FLAG_SOCKET_ERROR 1 << 18
|
||||
|
@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2009-2013. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2009-2015. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; downloader.asm - HTTP client for KolibriOS ;;
|
||||
@ -63,13 +63,13 @@ START:
|
||||
test eax, eax
|
||||
jnz exit
|
||||
;---------------------------------------------------------------------
|
||||
mov edi,filename_area
|
||||
mov esi,start_temp_file_name
|
||||
call copy_file_name_path
|
||||
mov edi,filename_area
|
||||
mov esi,start_temp_file_name
|
||||
call copy_file_name_path
|
||||
|
||||
mov edi,fname_buf
|
||||
mov esi,start_file_path
|
||||
call copy_file_name_path
|
||||
mov edi,fname_buf
|
||||
mov esi,start_file_path
|
||||
call copy_file_name_path
|
||||
|
||||
;OpenDialog initialisation
|
||||
push dword OpenDialog_data
|
||||
@ -86,7 +86,7 @@ START:
|
||||
inc [silently]
|
||||
|
||||
download:
|
||||
call download_1
|
||||
call download_1
|
||||
|
||||
test [silently], 0xff
|
||||
jnz save
|
||||
@ -151,7 +151,7 @@ button:
|
||||
cmp ah, 1 ; button id=1 ?
|
||||
je exit
|
||||
|
||||
call download_1
|
||||
call download_1
|
||||
jmp save
|
||||
;---------------------------------------------------------------------
|
||||
mouse:
|
||||
@ -168,16 +168,16 @@ fail:
|
||||
download_1:
|
||||
DEBUGF 1, "Starting download\n"
|
||||
|
||||
invoke HTTP_get, params, 0
|
||||
invoke HTTP_get, 0, 0, params, 0
|
||||
test eax, eax
|
||||
jz fail
|
||||
mov [identifier], eax
|
||||
|
||||
.loop:
|
||||
invoke HTTP_process, [identifier]
|
||||
invoke HTTP_receive, [identifier]
|
||||
test eax, eax
|
||||
jnz .loop
|
||||
ret
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
save:
|
||||
mov ebp, [identifier]
|
||||
@ -199,14 +199,14 @@ save:
|
||||
jmp still
|
||||
;---------------------------------------------------------------------
|
||||
copy_file_name_path:
|
||||
xor eax,eax
|
||||
cld
|
||||
xor eax,eax
|
||||
cld
|
||||
@@:
|
||||
lodsb
|
||||
stosb
|
||||
test eax,eax
|
||||
jnz @r
|
||||
ret
|
||||
lodsb
|
||||
stosb
|
||||
test eax,eax
|
||||
jnz @r
|
||||
ret
|
||||
;---------------------------------------------------------------------
|
||||
; *********************************************
|
||||
; ******* WINDOW DEFINITIONS AND DRAW ********
|
||||
@ -225,23 +225,23 @@ draw_window:
|
||||
mcall 0, <50, 370>, <350, 170>, , 0, title
|
||||
;-----------------------------------
|
||||
; draw frames
|
||||
mov [frame_data.x],dword frame_1.x shl 16+frame_1.width
|
||||
mov [frame_data.y],dword frame_1.y shl 16+frame_1.height
|
||||
mov [frame_data.text_pointer],dword select_addr_text
|
||||
mov eax,[sc.work]
|
||||
mov [frame_data.font_backgr_color],eax
|
||||
mov eax,[sc.work_text]
|
||||
mov [frame_data.font_color],eax
|
||||
|
||||
push dword frame_data
|
||||
call [Frame_draw]
|
||||
mov [frame_data.x],dword frame_1.x shl 16+frame_1.width
|
||||
mov [frame_data.y],dword frame_1.y shl 16+frame_1.height
|
||||
mov [frame_data.text_pointer],dword select_addr_text
|
||||
mov eax,[sc.work]
|
||||
mov [frame_data.font_backgr_color],eax
|
||||
mov eax,[sc.work_text]
|
||||
mov [frame_data.font_color],eax
|
||||
|
||||
push dword frame_data
|
||||
call [Frame_draw]
|
||||
;-----------------------------------
|
||||
mov [frame_data.x],dword frame_2.x shl 16+frame_2.width
|
||||
mov [frame_data.y],dword frame_2.y shl 16+frame_2.height
|
||||
mov [frame_data.text_pointer],dword select_path_text
|
||||
mov [frame_data.x],dword frame_2.x shl 16+frame_2.width
|
||||
mov [frame_data.y],dword frame_2.y shl 16+frame_2.height
|
||||
mov [frame_data.text_pointer],dword select_path_text
|
||||
|
||||
push dword frame_data
|
||||
call [Frame_draw]
|
||||
push dword frame_data
|
||||
call [Frame_draw]
|
||||
;-----------------------------------
|
||||
; draw "url:" text
|
||||
mov ecx, [sc.work_text]
|
||||
@ -255,7 +255,7 @@ draw_window:
|
||||
; draw buttons
|
||||
mcall 8,<frame_1.x+frame_1.width-(68+15+50+15),68>,<frame_1.y+30,16>,22,[sc.work_button] ; reload
|
||||
mcall ,<frame_1.x+frame_1.width-(50+15),50>,<frame_1.y+30,16>, 24 ; stop
|
||||
|
||||
|
||||
mcall , <frame_2.x+frame_2.width-(54+15),54>,<frame_2.y+30,16>,26 ; save
|
||||
;-----------------------------------
|
||||
; draw buttons text
|
||||
@ -264,11 +264,11 @@ draw_window:
|
||||
mcall 4, <frame_1.x+frame_1.width-(68+15+50+15)+10,frame_1.y+35>, , button_text.1
|
||||
mcall , <frame_1.x+frame_1.width-(50+15)+15,frame_1.y+35>, , button_text.2
|
||||
mcall , <frame_2.x+frame_2.width-(54+15)+10,frame_2.y+35>, , button_text.3
|
||||
|
||||
|
||||
mcall 13,<frame_2.x+17,frame_2.width-15*2>,<frame_2.y+10,15>,0xffffff
|
||||
push dword PathShow_data_1
|
||||
call [PathShow_draw]
|
||||
|
||||
|
||||
mcall 12, 2 ; end window redraw
|
||||
|
||||
ret
|
||||
@ -283,8 +283,8 @@ library lib_http, 'http.obj', \
|
||||
proc_lib, 'proc_lib.obj'
|
||||
|
||||
import lib_http, \
|
||||
HTTP_get , 'get' , \
|
||||
HTTP_process , 'process' ,\
|
||||
HTTP_get , 'get', \
|
||||
HTTP_receive , 'receive', \
|
||||
HTTP_free , 'free'
|
||||
|
||||
import box_lib, \
|
||||
@ -330,22 +330,22 @@ select_addr_text db ' NETWORK ADDRESS: ',0
|
||||
select_path_text db ' PATH TO SAVE FILE: ',0
|
||||
;---------------------------------------------------------------------
|
||||
frame_data:
|
||||
.type dd 0 ;+0
|
||||
.type dd 0 ;+0
|
||||
.x:
|
||||
.x_size dw 0 ;+4
|
||||
.x_start dw 0 ;+6
|
||||
.x_size dw 0 ;+4
|
||||
.x_start dw 0 ;+6
|
||||
.y:
|
||||
.y_size dw 0 ;+8
|
||||
.y_start dw 0 ;+10
|
||||
.ext_fr_col dd 0x0 ;+12
|
||||
.int_fr_col dd 0xffffff ;+16
|
||||
.draw_text_flag dd 1 ;+20
|
||||
.text_pointer dd 0 ;+24
|
||||
.text_position dd 0 ;+28
|
||||
.font_number dd 0 ;+32
|
||||
.font_size_y dd 9 ;+36
|
||||
.font_color dd 0x0 ;+40
|
||||
.font_backgr_color dd 0xffffff ;+44
|
||||
.y_size dw 0 ;+8
|
||||
.y_start dw 0 ;+10
|
||||
.ext_fr_col dd 0x0 ;+12
|
||||
.int_fr_col dd 0xffffff ;+16
|
||||
.draw_text_flag dd 1 ;+20
|
||||
.text_pointer dd 0 ;+24
|
||||
.text_position dd 0 ;+28
|
||||
.font_number dd 0 ;+32
|
||||
.font_size_y dd 9 ;+36
|
||||
.font_color dd 0x0 ;+40
|
||||
.font_backgr_color dd 0xffffff ;+44
|
||||
;---------------------------------------------------------------------
|
||||
PathShow_data_1:
|
||||
.type dd 0 ;+0
|
||||
|
@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2014. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2014-2015. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; pasta.asm - Paste something to paste.kolibrios.org using POST ;;
|
||||
@ -42,13 +42,13 @@ START:
|
||||
test eax, eax
|
||||
jnz exit
|
||||
|
||||
invoke HTTP_get, sz_url, 0
|
||||
invoke HTTP_get, sz_url, 0, 0, 0
|
||||
test eax, eax
|
||||
jz error
|
||||
mov [identifier], eax
|
||||
|
||||
.again:
|
||||
invoke HTTP_process, [identifier]
|
||||
invoke HTTP_receive, [identifier]
|
||||
test eax, eax
|
||||
jnz .again
|
||||
|
||||
@ -78,7 +78,7 @@ START:
|
||||
|
||||
invoke HTTP_free, [identifier]
|
||||
|
||||
invoke HTTP_post, sz_url, sz_cookie, sz_ctype, sz_paste.length
|
||||
invoke HTTP_post, sz_url, 0, 0, sz_cookie, sz_ctype, sz_paste.length
|
||||
test eax, eax
|
||||
jz error
|
||||
mov [identifier], eax
|
||||
@ -87,7 +87,7 @@ START:
|
||||
mcall 75, 6, , sz_paste, sz_paste.length, 0
|
||||
|
||||
.again2:
|
||||
invoke HTTP_process, [identifier]
|
||||
invoke HTTP_receive, [identifier]
|
||||
test eax, eax
|
||||
jnz .again2
|
||||
|
||||
@ -142,11 +142,10 @@ library lib_http, 'http.obj'
|
||||
|
||||
import lib_http, \
|
||||
HTTP_get, 'get', \
|
||||
HTTP_process, 'process', \
|
||||
HTTP_free, 'free', \
|
||||
HTTP_stop, 'stop', \
|
||||
HTTP_post, 'post', \
|
||||
HTTP_find_header_field, 'find_header_field'
|
||||
HTTP_receive, 'receive', \
|
||||
HTTP_find_header_field, 'find_header_field', \
|
||||
HTTP_free, 'free'
|
||||
|
||||
|
||||
identifier dd 0
|
||||
|
@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; HTTP library for KolibriOS ;;
|
||||
@ -54,13 +54,15 @@ local .copyloop, .copydone
|
||||
.copydone:
|
||||
}
|
||||
|
||||
macro HTTP_init_buffer buffer, socketnum {
|
||||
macro HTTP_init_buffer buffer, socketnum, flags {
|
||||
|
||||
mov eax, buffer
|
||||
push socketnum
|
||||
popd [eax + http_msg.socket]
|
||||
lea esi, [eax + http_msg.http_header]
|
||||
mov [eax + http_msg.flags], FLAG_CONNECTED
|
||||
push flags
|
||||
pop [eax + http_msg.flags]
|
||||
or [eax + http_msg.flags], FLAG_CONNECTED
|
||||
mov [eax + http_msg.write_ptr], esi
|
||||
mov [eax + http_msg.buffer_length], BUFFERSIZE - http_msg.http_header
|
||||
mov [eax + http_msg.chunk_ptr], 0
|
||||
@ -176,25 +178,30 @@ proc HTTP_free identifier ;/////////////////////////////////////////////////////
|
||||
|
||||
endp
|
||||
|
||||
|
||||
|
||||
;;================================================================================================;;
|
||||
proc HTTP_get URL, add_header ;///////////////////////////////////////////////////////////////////;;
|
||||
proc HTTP_get URL, identifier, flags, add_header ;////////////////////////////////////////////////;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;? Initiates a HTTP connection, using 'GET' method. ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;> URL = pointer to ASCIIZ URL ;;
|
||||
;> add_header = pointer to additional header parameters (ASCIIZ), or null for none. ;;
|
||||
;> URL = pointer to ASCIIZ URL ;;
|
||||
;> identifier = Identifier of an already open connection, or NULL to create a new one. ;;
|
||||
;> flags = Flags indicating how to threat the connection. ;;
|
||||
;> add_header = pointer to additional header parameters (ASCIIZ), or NULL for none. ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;< eax = 0 (error) / buffer ptr ;;
|
||||
;;================================================================================================;;
|
||||
locals
|
||||
hostname dd ?
|
||||
pageaddr dd ?
|
||||
sockaddr dd ?
|
||||
socketnum dd ?
|
||||
buffer dd ?
|
||||
port dd ?
|
||||
endl
|
||||
|
||||
and [flags], FLAG_KEEPALIVE or FLAG_MULTIBUFF ; filter out invalid flags
|
||||
|
||||
pusha
|
||||
|
||||
; split the URL into hostname and pageaddr
|
||||
@ -205,13 +212,24 @@ endl
|
||||
mov [pageaddr], ebx
|
||||
mov [port], ecx
|
||||
|
||||
mov eax, [identifier]
|
||||
test eax, eax
|
||||
jz .open_new
|
||||
test [eax + http_msg.flags], FLAG_CONNECTED
|
||||
jz .error
|
||||
mov eax, [eax + http_msg.socket]
|
||||
mov [socketnum], eax
|
||||
jmp .send_request
|
||||
|
||||
; Connect to the other side.
|
||||
.open_new:
|
||||
stdcall open_connection, [hostname], [port]
|
||||
test eax, eax
|
||||
jz .error
|
||||
mov [socketnum], eax
|
||||
|
||||
; Create the HTTP request.
|
||||
.send_request:
|
||||
invoke mem.alloc, BUFFERSIZE
|
||||
test eax, eax
|
||||
jz .error
|
||||
@ -256,6 +274,11 @@ endl
|
||||
|
||||
mov esi, str_close
|
||||
mov ecx, str_close.length
|
||||
test [flags], FLAG_KEEPALIVE
|
||||
jz @f
|
||||
mov esi, str_keep
|
||||
mov ecx, str_keep.length
|
||||
@@:
|
||||
rep movsb
|
||||
|
||||
mov byte[edi], 0
|
||||
@ -275,12 +298,20 @@ endl
|
||||
jz .error
|
||||
DEBUGF 1, "Request has been sent to server.\n"
|
||||
|
||||
HTTP_init_buffer [buffer], [socketnum]
|
||||
cmp [identifier], 0
|
||||
jne .old_connection
|
||||
HTTP_init_buffer [buffer], [socketnum], [flags]
|
||||
|
||||
popa
|
||||
mov eax, [buffer] ; return buffer ptr
|
||||
ret
|
||||
|
||||
.old_connection:
|
||||
invoke mem.free, [buffer]
|
||||
popa
|
||||
mov eax, [identifier]
|
||||
ret
|
||||
|
||||
.error:
|
||||
DEBUGF 1, "Error!\n"
|
||||
popa
|
||||
@ -292,25 +323,28 @@ endp
|
||||
|
||||
|
||||
;;================================================================================================;;
|
||||
proc HTTP_head URL, add_header ;//////////////////////////////////////////////////////////////////;;
|
||||
proc HTTP_head URL, identifier, flags, add_header ;///////////////////////////////////////////////;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;? Initiates a HTTP connection, using 'HEAD' method. ;;
|
||||
;? This will only return HTTP header and status, no content ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;> URL = pointer to ASCIIZ URL ;;
|
||||
;> add_header = pointer to additional header parameters (ASCIIZ), or null for none. ;;
|
||||
;> URL = pointer to ASCIIZ URL ;;
|
||||
;> identifier = Identifier of an already open connection, or NULL to create a new one. ;;
|
||||
;> flags = Flags indicating how to threat the connection. ;;
|
||||
;> add_header = pointer to additional header parameters (ASCIIZ), or NULL for none. ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;< eax = 0 (error) / buffer ptr ;;
|
||||
;;================================================================================================;;
|
||||
locals
|
||||
hostname dd ?
|
||||
pageaddr dd ?
|
||||
sockaddr dd ?
|
||||
socketnum dd ?
|
||||
buffer dd ?
|
||||
port dd ?
|
||||
endl
|
||||
|
||||
and [flags], FLAG_KEEPALIVE or FLAG_MULTIBUFF ; filter out invalid flags
|
||||
|
||||
pusha
|
||||
; split the URL into hostname and pageaddr
|
||||
stdcall parse_url, [URL]
|
||||
@ -320,13 +354,24 @@ endl
|
||||
mov [pageaddr], ebx
|
||||
mov [port], ecx
|
||||
|
||||
mov eax, [identifier]
|
||||
test eax, eax
|
||||
jz .open_new
|
||||
test [eax + http_msg.flags], FLAG_CONNECTED
|
||||
jz .error
|
||||
mov eax, [eax + http_msg.socket]
|
||||
mov [socketnum], eax
|
||||
jmp .send_request
|
||||
|
||||
; Connect to the other side.
|
||||
.open_new:
|
||||
stdcall open_connection, [hostname], [port]
|
||||
test eax, eax
|
||||
jz .error
|
||||
mov [socketnum], eax
|
||||
|
||||
; Create the HTTP request.
|
||||
.send_request:
|
||||
invoke mem.alloc, BUFFERSIZE
|
||||
test eax, eax
|
||||
jz .error
|
||||
@ -371,12 +416,16 @@ endl
|
||||
|
||||
mov esi, str_close
|
||||
mov ecx, str_close.length
|
||||
test [flags], FLAG_KEEPALIVE
|
||||
jz @f
|
||||
mov esi, str_keep
|
||||
mov ecx, str_keep.length
|
||||
@@:
|
||||
rep movsb
|
||||
|
||||
mov byte[edi], 0
|
||||
DEBUGF 1, "Request:\n%s", [buffer]
|
||||
|
||||
|
||||
; Free unused memory
|
||||
push edi
|
||||
invoke mem.free, [pageaddr]
|
||||
@ -391,11 +440,19 @@ endl
|
||||
jz .error
|
||||
DEBUGF 1, "Request has been sent to server.\n"
|
||||
|
||||
HTTP_init_buffer [buffer], [socketnum]
|
||||
cmp [identifier], 0
|
||||
jne .old_connection
|
||||
HTTP_init_buffer [buffer], [socketnum], [flags]
|
||||
|
||||
popa
|
||||
mov eax, [buffer]
|
||||
ret ; return buffer ptr
|
||||
mov eax, [buffer] ; return buffer ptr
|
||||
ret
|
||||
|
||||
.old_connection:
|
||||
invoke mem.free, [buffer]
|
||||
popa
|
||||
mov eax, [identifier]
|
||||
ret
|
||||
|
||||
.error:
|
||||
DEBUGF 1, "Error!\n"
|
||||
@ -407,27 +464,30 @@ endp
|
||||
|
||||
|
||||
;;================================================================================================;;
|
||||
proc HTTP_post URL, add_header, content_type, content_length ;////////////////////////////////////;;
|
||||
proc HTTP_post URL, identifier, flags, add_header, content_type, content_length ;/////////////////;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;? Initiates a HTTP connection, using 'POST' method. ;;
|
||||
;? This method is used to send data to the HTTP server ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;> URL = pointer to ASCIIZ URL ;;
|
||||
;> add_header = pointer to additional header parameters (ASCIIZ), or null for none. ;;
|
||||
;> identifier = Identifier of an already open connection, or NULL to create a new one. ;;
|
||||
;> flags = Flags indicating how to threat the connection. ;;
|
||||
;> add_header = pointer to additional header parameters (ASCIIZ), or NULL for none. ;;
|
||||
;> content_type = pointer to ASCIIZ string containing content type ;;
|
||||
;> content_length = length of content (in bytes) ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;< eax = 0 (error) / buffer ptr ;;
|
||||
;< eax = 0 (error) / buffer ptr (aka Identifier) ;;
|
||||
;;================================================================================================;;
|
||||
locals
|
||||
hostname dd ?
|
||||
pageaddr dd ?
|
||||
sockaddr dd ?
|
||||
socketnum dd ?
|
||||
buffer dd ?
|
||||
port dd ?
|
||||
endl
|
||||
|
||||
and [flags], FLAG_KEEPALIVE or FLAG_MULTIBUFF ; filter out invalid flags
|
||||
|
||||
pusha
|
||||
; split the URL into hostname and pageaddr
|
||||
stdcall parse_url, [URL]
|
||||
@ -437,13 +497,24 @@ endl
|
||||
mov [pageaddr], ebx
|
||||
mov [port], ecx
|
||||
|
||||
mov eax, [identifier]
|
||||
test eax, eax
|
||||
jz .open_new
|
||||
test [eax + http_msg.flags], FLAG_CONNECTED
|
||||
jz .error
|
||||
mov eax, [eax + http_msg.socket]
|
||||
mov [socketnum], eax
|
||||
jmp .send_request
|
||||
|
||||
; Connect to the other side.
|
||||
.open_new:
|
||||
stdcall open_connection, [hostname], [port]
|
||||
test eax, eax
|
||||
jz .error
|
||||
mov [socketnum], eax
|
||||
|
||||
; Create the HTTP request.
|
||||
.send_request:
|
||||
invoke mem.alloc, BUFFERSIZE
|
||||
test eax, eax
|
||||
jz .error
|
||||
@ -502,6 +573,11 @@ endl
|
||||
|
||||
mov esi, str_close
|
||||
mov ecx, str_close.length
|
||||
test [flags], FLAG_KEEPALIVE
|
||||
jz @f
|
||||
mov esi, str_keep
|
||||
mov ecx, str_keep.length
|
||||
@@:
|
||||
rep movsb
|
||||
|
||||
mov byte[edi], 0
|
||||
@ -521,11 +597,22 @@ endl
|
||||
jz .error
|
||||
DEBUGF 1, "Request has been sent to server.\n"
|
||||
|
||||
HTTP_init_buffer [buffer], [socketnum]
|
||||
cmp [identifier], 0
|
||||
jne .old_connection
|
||||
HTTP_init_buffer [buffer], [socketnum], [flags]
|
||||
|
||||
popa
|
||||
mov eax, [buffer]
|
||||
ret ; return buffer ptr
|
||||
mov eax, [buffer] ; return buffer ptr
|
||||
ret
|
||||
|
||||
.old_connection:
|
||||
invoke mem.free, [buffer]
|
||||
mov ebx, [flags]
|
||||
mov eax, [identifier]
|
||||
or [eax + http_msg.flags], ebx
|
||||
popa
|
||||
mov eax, [identifier]
|
||||
ret
|
||||
|
||||
.error:
|
||||
DEBUGF 1, "Error!\n"
|
||||
@ -555,7 +642,22 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
|
||||
test [ebp + http_msg.flags], FLAG_CONNECTED
|
||||
jz .connection_closed
|
||||
|
||||
; If the buffer is full, allocate a new one
|
||||
cmp [ebp + http_msg.buffer_length], 0
|
||||
jne .receive
|
||||
|
||||
test [ebp + http_msg.flags], FLAG_MULTIBUFF
|
||||
jz .err_header
|
||||
|
||||
invoke mem.alloc, BUFFERSIZE
|
||||
test eax, eax
|
||||
jz .err_no_ram
|
||||
mov [ebp + http_msg.content_ptr], eax
|
||||
mov [ebp + http_msg.write_ptr], eax
|
||||
mov [ebp + http_msg.buffer_length], BUFFERSIZE
|
||||
|
||||
; Receive some data
|
||||
.receive:
|
||||
mcall recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \
|
||||
[ebp + http_msg.buffer_length], MSG_DONTWAIT
|
||||
cmp eax, 0xffffffff
|
||||
@ -841,6 +943,8 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
|
||||
mov edx, esi
|
||||
sub edx, [ebp + http_msg.chunk_ptr] ; edx is now length of chunkline
|
||||
sub [ebp + http_msg.write_ptr], edx
|
||||
test [ebp + http_msg.flags], FLAG_MULTIBUFF
|
||||
jnz .dont_resize
|
||||
; Realloc buffer, make it 'chunksize' bigger.
|
||||
lea edx, [ebx + BUFFERSIZE]
|
||||
mov [ebp + http_msg.buffer_length], edx ; remaining space in new buffer
|
||||
@ -853,6 +957,7 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
|
||||
jz .err_no_ram
|
||||
call recalculate_pointers ; Because it's possible that buffer begins on another address now
|
||||
add esi, eax ; recalculate esi too!
|
||||
.dont_resize:
|
||||
; Remove chunk header (aka chunkline) from the buffer by shifting all received data after chunkt_ptr to the left
|
||||
mov edi, [ebp + http_msg.chunk_ptr]
|
||||
rep movsb
|
||||
@ -887,7 +992,8 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
|
||||
ret
|
||||
|
||||
.buffer_full:
|
||||
; Lets make it bigger..
|
||||
test [ebp + http_msg.flags], FLAG_MULTIBUFF
|
||||
jnz .multibuff
|
||||
mov eax, [ebp + http_msg.write_ptr]
|
||||
add eax, BUFFERSIZE
|
||||
sub eax, [ebp + http_msg.content_ptr]
|
||||
@ -902,6 +1008,12 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
|
||||
dec eax
|
||||
ret
|
||||
|
||||
.multibuff:
|
||||
; This buffer is full
|
||||
popa
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.need_more_data_for_header:
|
||||
cmp [ebp + http_msg.buffer_length], 0
|
||||
je .err_header ; It's just too damn long!
|
||||
@ -1151,24 +1263,22 @@ endp
|
||||
|
||||
|
||||
;;================================================================================================;;
|
||||
proc HTTP_escape URI ;////////////////////////////////////////////////////////////////////////////;;
|
||||
proc HTTP_escape URI, length ;////////////////////////////////////////////////////////////////////;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;? ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;> URI = ptr to ASCIIZ URI ;;
|
||||
;> URI = ptr to ASCIIZ URI/data ;;
|
||||
;> length = length of URI/data ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;< eax = 0 (error) / ptr to ASCIIZ URI/data ;;
|
||||
;< ebx = length of escaped URI/data ;;
|
||||
;;================================================================================================;;
|
||||
|
||||
|
||||
; TODO: instead of static buffer allocation, make it 4096 bytes and larger only if needed
|
||||
|
||||
DEBUGF 1, "HTTP_escape: %s\n", [URI]
|
||||
|
||||
pusha
|
||||
|
||||
invoke mem.alloc, URLMAXLEN
|
||||
invoke mem.alloc, URLMAXLEN ; FIXME: use length provided by caller to guess final size.
|
||||
test eax, eax
|
||||
jz .error
|
||||
mov [esp + 7 * 4], eax ; return ptr in eax
|
||||
@ -1227,7 +1337,7 @@ endp
|
||||
|
||||
|
||||
;;================================================================================================;;
|
||||
proc HTTP_unescape URI ;//////////////////////////////////////////////////////////////////////////;;
|
||||
proc HTTP_unescape URI, length ;//////////////////////////////////////////////////////////////////;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;? ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
@ -1239,7 +1349,7 @@ proc HTTP_unescape URI ;////////////////////////////////////////////////////////
|
||||
DEBUGF 1, "HTTP_unescape: %s\n", [URI]
|
||||
pusha
|
||||
|
||||
invoke mem.alloc, URLMAXLEN
|
||||
invoke mem.alloc, URLMAXLEN ; FIXME: use length provided by caller
|
||||
test eax, eax
|
||||
jz .error
|
||||
mov [esp + 7 * 4], eax ; return ptr in eax
|
||||
@ -1768,7 +1878,9 @@ str_post_ct db 13, 10, 'Content-Type: '
|
||||
.length = $ - str_post_ct
|
||||
str_proxy_auth db 13, 10, 'Proxy-Authorization: Basic '
|
||||
.length = $ - str_proxy_auth
|
||||
str_close db 'User-Agent: KolibriOS libHTTP/1.0', 13, 10, 'Connection: Close', 13, 10, 13, 10
|
||||
str_close db 'User-Agent: KolibriOS libHTTP/1.1', 13, 10, 'Connection: Close', 13, 10, 13, 10
|
||||
.length = $ - str_close
|
||||
str_keep db 'User-Agent: KolibriOS libHTTP/1.1', 13, 10, 'Connection: Keepalive', 13, 10, 13, 10
|
||||
.length = $ - str_close
|
||||
|
||||
str_http db 'http://', 0
|
||||
|
@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; HTTP library for KolibriOS ;;
|
||||
@ -14,13 +14,20 @@
|
||||
|
||||
|
||||
; Bitflags for http_msg.flags
|
||||
|
||||
; status
|
||||
FLAG_HTTP11 = 1 shl 0
|
||||
FLAG_GOT_HEADER = 1 shl 1
|
||||
FLAG_GOT_ALL_DATA = 1 shl 2
|
||||
FLAG_CONTENT_LENGTH = 1 shl 3
|
||||
FLAG_CHUNKED = 1 shl 4
|
||||
FLAG_CONNECTED = 1 shl 5
|
||||
; ERROR flags go into the upper word
|
||||
|
||||
; user options
|
||||
FLAG_KEEPALIVE = 1 shl 8
|
||||
FLAG_MULTIBUFF = 1 shl 9
|
||||
|
||||
; error
|
||||
FLAG_INVALID_HEADER = 1 shl 16
|
||||
FLAG_NO_RAM = 1 shl 17
|
||||
FLAG_SOCKET_ERROR = 1 shl 18
|
||||
|
@ -1,20 +1,26 @@
|
||||
|
||||
get(*url, *add_header);
|
||||
get(*url, identifier, flags, *add_header);
|
||||
*url = pointer to ASCIIZ URL
|
||||
identifier = identified of previously opened connection, or 0 to open a new one
|
||||
flags = bit flags (see http.inc user flags)
|
||||
*add_header = pointer to ASCIIZ additional header parameters, or null for none.
|
||||
Every additional parameter must end with CR LF bytes, including the last line.
|
||||
Initiates a HTTP connection, using 'GET' method.
|
||||
- returns 0 on error, identifier otherwise.
|
||||
|
||||
head(*url, *add_header);
|
||||
head(*url, identifier, flags, *add_header);
|
||||
*url = pointer to ASCIIZ URL
|
||||
identifier = identified of previously opened connection, or 0 to open a new one
|
||||
flags = bit flags (see http.inc user flags)
|
||||
*add_header = pointer to ASCIIZ additional header parameters, or null for none.
|
||||
Every additional parameter must end with CR LF bytes, including the last line.
|
||||
Initiate a HTTP connection, using 'HEAD' method.
|
||||
- returns 0 on error, identifier otherwise
|
||||
|
||||
post(*url, *add_header, *content-type, content-length);
|
||||
post(*url, identifier, flags, *add_header, *content-type, content-length);
|
||||
*url = pointer to ASCIIZ URL
|
||||
identifier = identified of previously opened connection, or 0 to open a new one
|
||||
flags = bit flags (see http.inc user flags)
|
||||
*add_header = pointer to ASCIIZ additional header parameters, or null for none.
|
||||
Every additional parameter must end with CR LF bytes, including the last line.
|
||||
*content-type = pointer to ASCIIZ string containing content type.
|
||||
|
Loading…
Reference in New Issue
Block a user