forked from KolibriOS/kolibrios
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:
|
case evNetwork:
|
||||||
if (http_transfer > 0) {
|
if (http_transfer > 0) {
|
||||||
http_process stdcall (http_transfer);
|
http_receive stdcall (http_transfer);
|
||||||
$push EAX
|
$push EAX
|
||||||
ESI = http_transfer;
|
ESI = http_transfer;
|
||||||
wv_progress_bar.max = ESI.http_msg.content_length;
|
wv_progress_bar.max = ESI.http_msg.content_length;
|
||||||
@ -618,7 +618,7 @@ void OpenPage()
|
|||||||
if (strncmp(#URL,"http:",5)==0)
|
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);
|
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;
|
http_transfer = EAX;
|
||||||
if (http_transfer == 0)
|
if (http_transfer == 0)
|
||||||
{
|
{
|
||||||
|
@ -88,7 +88,7 @@ void Downloader()
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if (DL_Form.width==0) || (DL_http_transfer <= 0) break;
|
if (DL_Form.width==0) || (DL_http_transfer <= 0) break;
|
||||||
http_process stdcall (DL_http_transfer);
|
http_receive stdcall (DL_http_transfer);
|
||||||
$push EAX
|
$push EAX
|
||||||
ESI = DL_http_transfer;
|
ESI = DL_http_transfer;
|
||||||
DL_progress_bar.max = ESI.http_msg.content_length;
|
DL_progress_bar.max = ESI.http_msg.content_length;
|
||||||
@ -220,7 +220,7 @@ void StartDownloading()
|
|||||||
{
|
{
|
||||||
download_state = STATE_IN_PROGRESS;
|
download_state = STATE_IN_PROGRESS;
|
||||||
DL_address_box.color = DL_address_box.blur_border_color = DL_address_box.focus_border_color = 0xdddDDD;
|
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_http_transfer = EAX;
|
||||||
DL_progress_bar.value = 0;
|
DL_progress_bar.value = 0;
|
||||||
DL_Draw_Window();
|
DL_Draw_Window();
|
||||||
|
@ -96,7 +96,7 @@ void main()
|
|||||||
default:
|
default:
|
||||||
if (Form.width==0) break;
|
if (Form.width==0) break;
|
||||||
if (http_transfer <= 0) break;
|
if (http_transfer <= 0) break;
|
||||||
http_process stdcall (http_transfer);
|
http_receive stdcall (http_transfer);
|
||||||
if (EAX == 0) {
|
if (EAX == 0) {
|
||||||
ESI = http_transfer;
|
ESI = http_transfer;
|
||||||
bufpointer = ESI.http_msg.content_ptr;
|
bufpointer = ESI.http_msg.content_ptr;
|
||||||
@ -222,7 +222,7 @@ void StartDownloading()
|
|||||||
if (strncmp(#URL,"http:",5)==0)
|
if (strncmp(#URL,"http:",5)==0)
|
||||||
{
|
{
|
||||||
address_box.color = address_box.blur_border_color = address_box.focus_border_color = 0xededed;
|
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;
|
http_transfer = EAX;
|
||||||
Draw_Window();
|
Draw_Window();
|
||||||
if (http_transfer == 0)
|
if (http_transfer == 0)
|
||||||
|
@ -8,9 +8,10 @@ dword http_get = #aHTTPget;
|
|||||||
dword http_head = #aHTTPhead;
|
dword http_head = #aHTTPhead;
|
||||||
dword http_post = #aHTTPpost;
|
dword http_post = #aHTTPpost;
|
||||||
dword http_find_header_field = #aFHF;
|
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_free = #aHTTPfree;
|
||||||
dword http_stop = #aHTTPstop;
|
|
||||||
dword uri_escape = #aURIescape;
|
dword uri_escape = #aURIescape;
|
||||||
dword uri_unescape = #aURIunescape;
|
dword uri_unescape = #aURIunescape;
|
||||||
$DD 2 dup 0
|
$DD 2 dup 0
|
||||||
@ -20,12 +21,14 @@ char aHTTPget[4] = "get\0";
|
|||||||
char aHTTPhead[5] = "head\0";
|
char aHTTPhead[5] = "head\0";
|
||||||
char aHTTPpost[5] = "post\0";
|
char aHTTPpost[5] = "post\0";
|
||||||
char aFHF[18] = "find_header_field\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 aHTTPfree[5] = "free\0";
|
||||||
char aHTTPstop[5] = "stop\0";
|
|
||||||
char aURIescape[7] = "escape\0";
|
char aURIescape[7] = "escape\0";
|
||||||
char aURIunescape[9] = "unescape\0";
|
char aURIunescape[9] = "unescape\0";
|
||||||
|
|
||||||
|
// status flags
|
||||||
#define FLAG_HTTP11 1 << 0
|
#define FLAG_HTTP11 1 << 0
|
||||||
#define FLAG_GOT_HEADER 1 << 1
|
#define FLAG_GOT_HEADER 1 << 1
|
||||||
#define FLAG_GOT_ALL_DATA 1 << 2
|
#define FLAG_GOT_ALL_DATA 1 << 2
|
||||||
@ -33,7 +36,11 @@ char aURIunescape[9] = "unescape\0";
|
|||||||
#define FLAG_CHUNKED 1 << 4
|
#define FLAG_CHUNKED 1 << 4
|
||||||
#define FLAG_CONNECTED 1 << 5
|
#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_INVALID_HEADER 1 << 16
|
||||||
#define FLAG_NO_RAM 1 << 17
|
#define FLAG_NO_RAM 1 << 17
|
||||||
#define FLAG_SOCKET_ERROR 1 << 18
|
#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 ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; downloader.asm - HTTP client for KolibriOS ;;
|
;; downloader.asm - HTTP client for KolibriOS ;;
|
||||||
@ -168,13 +168,13 @@ fail:
|
|||||||
download_1:
|
download_1:
|
||||||
DEBUGF 1, "Starting download\n"
|
DEBUGF 1, "Starting download\n"
|
||||||
|
|
||||||
invoke HTTP_get, params, 0
|
invoke HTTP_get, 0, 0, params, 0
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz fail
|
jz fail
|
||||||
mov [identifier], eax
|
mov [identifier], eax
|
||||||
|
|
||||||
.loop:
|
.loop:
|
||||||
invoke HTTP_process, [identifier]
|
invoke HTTP_receive, [identifier]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .loop
|
jnz .loop
|
||||||
ret
|
ret
|
||||||
@ -283,8 +283,8 @@ library lib_http, 'http.obj', \
|
|||||||
proc_lib, 'proc_lib.obj'
|
proc_lib, 'proc_lib.obj'
|
||||||
|
|
||||||
import lib_http, \
|
import lib_http, \
|
||||||
HTTP_get , 'get' , \
|
HTTP_get , 'get', \
|
||||||
HTTP_process , 'process' ,\
|
HTTP_receive , 'receive', \
|
||||||
HTTP_free , 'free'
|
HTTP_free , 'free'
|
||||||
|
|
||||||
import box_lib, \
|
import box_lib, \
|
||||||
|
@ -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 ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; pasta.asm - Paste something to paste.kolibrios.org using POST ;;
|
;; pasta.asm - Paste something to paste.kolibrios.org using POST ;;
|
||||||
@ -42,13 +42,13 @@ START:
|
|||||||
test eax, eax
|
test eax, eax
|
||||||
jnz exit
|
jnz exit
|
||||||
|
|
||||||
invoke HTTP_get, sz_url, 0
|
invoke HTTP_get, sz_url, 0, 0, 0
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz error
|
jz error
|
||||||
mov [identifier], eax
|
mov [identifier], eax
|
||||||
|
|
||||||
.again:
|
.again:
|
||||||
invoke HTTP_process, [identifier]
|
invoke HTTP_receive, [identifier]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .again
|
jnz .again
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ START:
|
|||||||
|
|
||||||
invoke HTTP_free, [identifier]
|
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
|
test eax, eax
|
||||||
jz error
|
jz error
|
||||||
mov [identifier], eax
|
mov [identifier], eax
|
||||||
@ -87,7 +87,7 @@ START:
|
|||||||
mcall 75, 6, , sz_paste, sz_paste.length, 0
|
mcall 75, 6, , sz_paste, sz_paste.length, 0
|
||||||
|
|
||||||
.again2:
|
.again2:
|
||||||
invoke HTTP_process, [identifier]
|
invoke HTTP_receive, [identifier]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .again2
|
jnz .again2
|
||||||
|
|
||||||
@ -142,11 +142,10 @@ library lib_http, 'http.obj'
|
|||||||
|
|
||||||
import lib_http, \
|
import lib_http, \
|
||||||
HTTP_get, 'get', \
|
HTTP_get, 'get', \
|
||||||
HTTP_process, 'process', \
|
|
||||||
HTTP_free, 'free', \
|
|
||||||
HTTP_stop, 'stop', \
|
|
||||||
HTTP_post, 'post', \
|
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
|
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 ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; HTTP library for KolibriOS ;;
|
;; HTTP library for KolibriOS ;;
|
||||||
@ -54,13 +54,15 @@ local .copyloop, .copydone
|
|||||||
.copydone:
|
.copydone:
|
||||||
}
|
}
|
||||||
|
|
||||||
macro HTTP_init_buffer buffer, socketnum {
|
macro HTTP_init_buffer buffer, socketnum, flags {
|
||||||
|
|
||||||
mov eax, buffer
|
mov eax, buffer
|
||||||
push socketnum
|
push socketnum
|
||||||
popd [eax + http_msg.socket]
|
popd [eax + http_msg.socket]
|
||||||
lea esi, [eax + http_msg.http_header]
|
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.write_ptr], esi
|
||||||
mov [eax + http_msg.buffer_length], BUFFERSIZE - http_msg.http_header
|
mov [eax + http_msg.buffer_length], BUFFERSIZE - http_msg.http_header
|
||||||
mov [eax + http_msg.chunk_ptr], 0
|
mov [eax + http_msg.chunk_ptr], 0
|
||||||
@ -176,25 +178,30 @@ proc HTTP_free identifier ;/////////////////////////////////////////////////////
|
|||||||
|
|
||||||
endp
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;================================================================================================;;
|
;;================================================================================================;;
|
||||||
proc HTTP_get URL, add_header ;///////////////////////////////////////////////////////////////////;;
|
proc HTTP_get URL, identifier, flags, add_header ;////////////////////////////////////////////////;;
|
||||||
;;------------------------------------------------------------------------------------------------;;
|
;;------------------------------------------------------------------------------------------------;;
|
||||||
;? Initiates a HTTP connection, using 'GET' method. ;;
|
;? Initiates a HTTP connection, using 'GET' method. ;;
|
||||||
;;------------------------------------------------------------------------------------------------;;
|
;;------------------------------------------------------------------------------------------------;;
|
||||||
;> URL = pointer to ASCIIZ URL ;;
|
;> 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. ;;
|
||||||
;;------------------------------------------------------------------------------------------------;;
|
;;------------------------------------------------------------------------------------------------;;
|
||||||
;< eax = 0 (error) / buffer ptr ;;
|
;< eax = 0 (error) / buffer ptr ;;
|
||||||
;;================================================================================================;;
|
;;================================================================================================;;
|
||||||
locals
|
locals
|
||||||
hostname dd ?
|
hostname dd ?
|
||||||
pageaddr dd ?
|
pageaddr dd ?
|
||||||
sockaddr dd ?
|
|
||||||
socketnum dd ?
|
socketnum dd ?
|
||||||
buffer dd ?
|
buffer dd ?
|
||||||
port dd ?
|
port dd ?
|
||||||
endl
|
endl
|
||||||
|
|
||||||
|
and [flags], FLAG_KEEPALIVE or FLAG_MULTIBUFF ; filter out invalid flags
|
||||||
|
|
||||||
pusha
|
pusha
|
||||||
|
|
||||||
; split the URL into hostname and pageaddr
|
; split the URL into hostname and pageaddr
|
||||||
@ -205,13 +212,24 @@ endl
|
|||||||
mov [pageaddr], ebx
|
mov [pageaddr], ebx
|
||||||
mov [port], ecx
|
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.
|
; Connect to the other side.
|
||||||
|
.open_new:
|
||||||
stdcall open_connection, [hostname], [port]
|
stdcall open_connection, [hostname], [port]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .error
|
jz .error
|
||||||
mov [socketnum], eax
|
mov [socketnum], eax
|
||||||
|
|
||||||
; Create the HTTP request.
|
; Create the HTTP request.
|
||||||
|
.send_request:
|
||||||
invoke mem.alloc, BUFFERSIZE
|
invoke mem.alloc, BUFFERSIZE
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .error
|
jz .error
|
||||||
@ -256,6 +274,11 @@ endl
|
|||||||
|
|
||||||
mov esi, str_close
|
mov esi, str_close
|
||||||
mov ecx, str_close.length
|
mov ecx, str_close.length
|
||||||
|
test [flags], FLAG_KEEPALIVE
|
||||||
|
jz @f
|
||||||
|
mov esi, str_keep
|
||||||
|
mov ecx, str_keep.length
|
||||||
|
@@:
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
mov byte[edi], 0
|
mov byte[edi], 0
|
||||||
@ -275,12 +298,20 @@ endl
|
|||||||
jz .error
|
jz .error
|
||||||
DEBUGF 1, "Request has been sent to server.\n"
|
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
|
popa
|
||||||
mov eax, [buffer] ; return buffer ptr
|
mov eax, [buffer] ; return buffer ptr
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.old_connection:
|
||||||
|
invoke mem.free, [buffer]
|
||||||
|
popa
|
||||||
|
mov eax, [identifier]
|
||||||
|
ret
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
DEBUGF 1, "Error!\n"
|
DEBUGF 1, "Error!\n"
|
||||||
popa
|
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. ;;
|
;? Initiates a HTTP connection, using 'HEAD' method. ;;
|
||||||
;? This will only return HTTP header and status, no content ;;
|
;? This will only return HTTP header and status, no content ;;
|
||||||
;;------------------------------------------------------------------------------------------------;;
|
;;------------------------------------------------------------------------------------------------;;
|
||||||
;> URL = pointer to ASCIIZ URL ;;
|
;> 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. ;;
|
||||||
;;------------------------------------------------------------------------------------------------;;
|
;;------------------------------------------------------------------------------------------------;;
|
||||||
;< eax = 0 (error) / buffer ptr ;;
|
;< eax = 0 (error) / buffer ptr ;;
|
||||||
;;================================================================================================;;
|
;;================================================================================================;;
|
||||||
locals
|
locals
|
||||||
hostname dd ?
|
hostname dd ?
|
||||||
pageaddr dd ?
|
pageaddr dd ?
|
||||||
sockaddr dd ?
|
|
||||||
socketnum dd ?
|
socketnum dd ?
|
||||||
buffer dd ?
|
buffer dd ?
|
||||||
port dd ?
|
port dd ?
|
||||||
endl
|
endl
|
||||||
|
|
||||||
|
and [flags], FLAG_KEEPALIVE or FLAG_MULTIBUFF ; filter out invalid flags
|
||||||
|
|
||||||
pusha
|
pusha
|
||||||
; split the URL into hostname and pageaddr
|
; split the URL into hostname and pageaddr
|
||||||
stdcall parse_url, [URL]
|
stdcall parse_url, [URL]
|
||||||
@ -320,13 +354,24 @@ endl
|
|||||||
mov [pageaddr], ebx
|
mov [pageaddr], ebx
|
||||||
mov [port], ecx
|
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.
|
; Connect to the other side.
|
||||||
|
.open_new:
|
||||||
stdcall open_connection, [hostname], [port]
|
stdcall open_connection, [hostname], [port]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .error
|
jz .error
|
||||||
mov [socketnum], eax
|
mov [socketnum], eax
|
||||||
|
|
||||||
; Create the HTTP request.
|
; Create the HTTP request.
|
||||||
|
.send_request:
|
||||||
invoke mem.alloc, BUFFERSIZE
|
invoke mem.alloc, BUFFERSIZE
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .error
|
jz .error
|
||||||
@ -371,12 +416,16 @@ endl
|
|||||||
|
|
||||||
mov esi, str_close
|
mov esi, str_close
|
||||||
mov ecx, str_close.length
|
mov ecx, str_close.length
|
||||||
|
test [flags], FLAG_KEEPALIVE
|
||||||
|
jz @f
|
||||||
|
mov esi, str_keep
|
||||||
|
mov ecx, str_keep.length
|
||||||
|
@@:
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
mov byte[edi], 0
|
mov byte[edi], 0
|
||||||
DEBUGF 1, "Request:\n%s", [buffer]
|
DEBUGF 1, "Request:\n%s", [buffer]
|
||||||
|
|
||||||
|
|
||||||
; Free unused memory
|
; Free unused memory
|
||||||
push edi
|
push edi
|
||||||
invoke mem.free, [pageaddr]
|
invoke mem.free, [pageaddr]
|
||||||
@ -391,11 +440,19 @@ endl
|
|||||||
jz .error
|
jz .error
|
||||||
DEBUGF 1, "Request has been sent to server.\n"
|
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
|
popa
|
||||||
mov eax, [buffer]
|
mov eax, [buffer] ; return buffer ptr
|
||||||
ret ; return buffer ptr
|
ret
|
||||||
|
|
||||||
|
.old_connection:
|
||||||
|
invoke mem.free, [buffer]
|
||||||
|
popa
|
||||||
|
mov eax, [identifier]
|
||||||
|
ret
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
DEBUGF 1, "Error!\n"
|
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. ;;
|
;? Initiates a HTTP connection, using 'POST' method. ;;
|
||||||
;? This method is used to send data to the HTTP server ;;
|
;? This method is used to send data to the HTTP server ;;
|
||||||
;;------------------------------------------------------------------------------------------------;;
|
;;------------------------------------------------------------------------------------------------;;
|
||||||
;> URL = pointer to ASCIIZ URL ;;
|
;> 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_type = pointer to ASCIIZ string containing content type ;;
|
||||||
;> content_length = length of content (in bytes) ;;
|
;> content_length = length of content (in bytes) ;;
|
||||||
;;------------------------------------------------------------------------------------------------;;
|
;;------------------------------------------------------------------------------------------------;;
|
||||||
;< eax = 0 (error) / buffer ptr ;;
|
;< eax = 0 (error) / buffer ptr (aka Identifier) ;;
|
||||||
;;================================================================================================;;
|
;;================================================================================================;;
|
||||||
locals
|
locals
|
||||||
hostname dd ?
|
hostname dd ?
|
||||||
pageaddr dd ?
|
pageaddr dd ?
|
||||||
sockaddr dd ?
|
|
||||||
socketnum dd ?
|
socketnum dd ?
|
||||||
buffer dd ?
|
buffer dd ?
|
||||||
port dd ?
|
port dd ?
|
||||||
endl
|
endl
|
||||||
|
|
||||||
|
and [flags], FLAG_KEEPALIVE or FLAG_MULTIBUFF ; filter out invalid flags
|
||||||
|
|
||||||
pusha
|
pusha
|
||||||
; split the URL into hostname and pageaddr
|
; split the URL into hostname and pageaddr
|
||||||
stdcall parse_url, [URL]
|
stdcall parse_url, [URL]
|
||||||
@ -437,13 +497,24 @@ endl
|
|||||||
mov [pageaddr], ebx
|
mov [pageaddr], ebx
|
||||||
mov [port], ecx
|
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.
|
; Connect to the other side.
|
||||||
|
.open_new:
|
||||||
stdcall open_connection, [hostname], [port]
|
stdcall open_connection, [hostname], [port]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .error
|
jz .error
|
||||||
mov [socketnum], eax
|
mov [socketnum], eax
|
||||||
|
|
||||||
; Create the HTTP request.
|
; Create the HTTP request.
|
||||||
|
.send_request:
|
||||||
invoke mem.alloc, BUFFERSIZE
|
invoke mem.alloc, BUFFERSIZE
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .error
|
jz .error
|
||||||
@ -502,6 +573,11 @@ endl
|
|||||||
|
|
||||||
mov esi, str_close
|
mov esi, str_close
|
||||||
mov ecx, str_close.length
|
mov ecx, str_close.length
|
||||||
|
test [flags], FLAG_KEEPALIVE
|
||||||
|
jz @f
|
||||||
|
mov esi, str_keep
|
||||||
|
mov ecx, str_keep.length
|
||||||
|
@@:
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
mov byte[edi], 0
|
mov byte[edi], 0
|
||||||
@ -521,11 +597,22 @@ endl
|
|||||||
jz .error
|
jz .error
|
||||||
DEBUGF 1, "Request has been sent to server.\n"
|
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
|
popa
|
||||||
mov eax, [buffer]
|
mov eax, [buffer] ; return buffer ptr
|
||||||
ret ; 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:
|
.error:
|
||||||
DEBUGF 1, "Error!\n"
|
DEBUGF 1, "Error!\n"
|
||||||
@ -555,7 +642,22 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
|
|||||||
test [ebp + http_msg.flags], FLAG_CONNECTED
|
test [ebp + http_msg.flags], FLAG_CONNECTED
|
||||||
jz .connection_closed
|
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 some data
|
||||||
|
.receive:
|
||||||
mcall recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \
|
mcall recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \
|
||||||
[ebp + http_msg.buffer_length], MSG_DONTWAIT
|
[ebp + http_msg.buffer_length], MSG_DONTWAIT
|
||||||
cmp eax, 0xffffffff
|
cmp eax, 0xffffffff
|
||||||
@ -841,6 +943,8 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
|
|||||||
mov edx, esi
|
mov edx, esi
|
||||||
sub edx, [ebp + http_msg.chunk_ptr] ; edx is now length of chunkline
|
sub edx, [ebp + http_msg.chunk_ptr] ; edx is now length of chunkline
|
||||||
sub [ebp + http_msg.write_ptr], edx
|
sub [ebp + http_msg.write_ptr], edx
|
||||||
|
test [ebp + http_msg.flags], FLAG_MULTIBUFF
|
||||||
|
jnz .dont_resize
|
||||||
; Realloc buffer, make it 'chunksize' bigger.
|
; Realloc buffer, make it 'chunksize' bigger.
|
||||||
lea edx, [ebx + BUFFERSIZE]
|
lea edx, [ebx + BUFFERSIZE]
|
||||||
mov [ebp + http_msg.buffer_length], edx ; remaining space in new buffer
|
mov [ebp + http_msg.buffer_length], edx ; remaining space in new buffer
|
||||||
@ -853,6 +957,7 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
|
|||||||
jz .err_no_ram
|
jz .err_no_ram
|
||||||
call recalculate_pointers ; Because it's possible that buffer begins on another address now
|
call recalculate_pointers ; Because it's possible that buffer begins on another address now
|
||||||
add esi, eax ; recalculate esi too!
|
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
|
; 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]
|
mov edi, [ebp + http_msg.chunk_ptr]
|
||||||
rep movsb
|
rep movsb
|
||||||
@ -887,7 +992,8 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
.buffer_full:
|
.buffer_full:
|
||||||
; Lets make it bigger..
|
test [ebp + http_msg.flags], FLAG_MULTIBUFF
|
||||||
|
jnz .multibuff
|
||||||
mov eax, [ebp + http_msg.write_ptr]
|
mov eax, [ebp + http_msg.write_ptr]
|
||||||
add eax, BUFFERSIZE
|
add eax, BUFFERSIZE
|
||||||
sub eax, [ebp + http_msg.content_ptr]
|
sub eax, [ebp + http_msg.content_ptr]
|
||||||
@ -902,6 +1008,12 @@ proc HTTP_receive identifier ;//////////////////////////////////////////////////
|
|||||||
dec eax
|
dec eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.multibuff:
|
||||||
|
; This buffer is full
|
||||||
|
popa
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
|
||||||
.need_more_data_for_header:
|
.need_more_data_for_header:
|
||||||
cmp [ebp + http_msg.buffer_length], 0
|
cmp [ebp + http_msg.buffer_length], 0
|
||||||
je .err_header ; It's just too damn long!
|
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 ;;
|
;< eax = 0 (error) / ptr to ASCIIZ URI/data ;;
|
||||||
;< ebx = length of escaped 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]
|
DEBUGF 1, "HTTP_escape: %s\n", [URI]
|
||||||
|
|
||||||
pusha
|
pusha
|
||||||
|
|
||||||
invoke mem.alloc, URLMAXLEN
|
invoke mem.alloc, URLMAXLEN ; FIXME: use length provided by caller to guess final size.
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .error
|
jz .error
|
||||||
mov [esp + 7 * 4], eax ; return ptr in eax
|
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]
|
DEBUGF 1, "HTTP_unescape: %s\n", [URI]
|
||||||
pusha
|
pusha
|
||||||
|
|
||||||
invoke mem.alloc, URLMAXLEN
|
invoke mem.alloc, URLMAXLEN ; FIXME: use length provided by caller
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .error
|
jz .error
|
||||||
mov [esp + 7 * 4], eax ; return ptr in eax
|
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
|
.length = $ - str_post_ct
|
||||||
str_proxy_auth db 13, 10, 'Proxy-Authorization: Basic '
|
str_proxy_auth db 13, 10, 'Proxy-Authorization: Basic '
|
||||||
.length = $ - str_proxy_auth
|
.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
|
.length = $ - str_close
|
||||||
|
|
||||||
str_http db 'http://', 0
|
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 ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; HTTP library for KolibriOS ;;
|
;; HTTP library for KolibriOS ;;
|
||||||
@ -14,13 +14,20 @@
|
|||||||
|
|
||||||
|
|
||||||
; Bitflags for http_msg.flags
|
; Bitflags for http_msg.flags
|
||||||
|
|
||||||
|
; status
|
||||||
FLAG_HTTP11 = 1 shl 0
|
FLAG_HTTP11 = 1 shl 0
|
||||||
FLAG_GOT_HEADER = 1 shl 1
|
FLAG_GOT_HEADER = 1 shl 1
|
||||||
FLAG_GOT_ALL_DATA = 1 shl 2
|
FLAG_GOT_ALL_DATA = 1 shl 2
|
||||||
FLAG_CONTENT_LENGTH = 1 shl 3
|
FLAG_CONTENT_LENGTH = 1 shl 3
|
||||||
FLAG_CHUNKED = 1 shl 4
|
FLAG_CHUNKED = 1 shl 4
|
||||||
FLAG_CONNECTED = 1 shl 5
|
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_INVALID_HEADER = 1 shl 16
|
||||||
FLAG_NO_RAM = 1 shl 17
|
FLAG_NO_RAM = 1 shl 17
|
||||||
FLAG_SOCKET_ERROR = 1 shl 18
|
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
|
*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.
|
*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.
|
Every additional parameter must end with CR LF bytes, including the last line.
|
||||||
Initiates a HTTP connection, using 'GET' method.
|
Initiates a HTTP connection, using 'GET' method.
|
||||||
- returns 0 on error, identifier otherwise.
|
- returns 0 on error, identifier otherwise.
|
||||||
|
|
||||||
head(*url, *add_header);
|
head(*url, identifier, flags, *add_header);
|
||||||
*url = pointer to ASCIIZ URL
|
*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.
|
*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.
|
Every additional parameter must end with CR LF bytes, including the last line.
|
||||||
Initiate a HTTP connection, using 'HEAD' method.
|
Initiate a HTTP connection, using 'HEAD' method.
|
||||||
- returns 0 on error, identifier otherwise
|
- 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
|
*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.
|
*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.
|
Every additional parameter must end with CR LF bytes, including the last line.
|
||||||
*content-type = pointer to ASCIIZ string containing content type.
|
*content-type = pointer to ASCIIZ string containing content type.
|
||||||
|
Loading…
Reference in New Issue
Block a user