diff --git a/programs/develop/libraries/http/http.asm b/programs/develop/libraries/http/http.asm index 718045317d..c8e617cba5 100644 --- a/programs/develop/libraries/http/http.asm +++ b/programs/develop/libraries/http/http.asm @@ -23,7 +23,7 @@ TIMEOUT = 500 ; in 1/100 s __DEBUG__ = 1 - __DEBUG_LEVEL__ = 1 + __DEBUG_LEVEL__ = 2 format MS COFF @@ -117,7 +117,7 @@ lib_init: ;//////////////////////////////////////////////////////////////////;; ret .error: - DEBUGF 1, "ERROR loading libraries\n" + DEBUGF 2, "ERROR loading http.obj dependencies\n" xor eax, eax inc eax ret @@ -145,7 +145,7 @@ proc HTTP_disconnect identifier ;/////////////////////////////////////////////// ret .error: - DEBUGF 1, "Cant close already closed connection!\n" + DEBUGF 2, "Cant close already closed connection!\n" popa ret @@ -313,7 +313,7 @@ endl ret .error: - DEBUGF 1, "Error!\n" + DEBUGF 2, "HTTP GET error!\n" popa xor eax, eax ; return 0 = error ret @@ -455,7 +455,7 @@ endl ret .error: - DEBUGF 1, "Error!\n" + DEBUGF 2, "HTTP HEAD error!\n" popa xor eax, eax ; return 0 = error ret @@ -615,7 +615,7 @@ endl ret .error: - DEBUGF 1, "Error!\n" + DEBUGF 1, "HTTP POST error!\n" popa xor eax, eax ; return 0 = error ret @@ -668,8 +668,13 @@ proc HTTP_receive identifier ;////////////////////////////////////////////////// ; Receive some data .receive: + mov edi, MSG_DONTWAIT + test [ebp + http_msg.flags], FLAG_BLOCK + jz @f + xor edi, edi + @@: mcall recv, [ebp + http_msg.socket], [ebp + http_msg.write_ptr], \ - [ebp + http_msg.buffer_length], MSG_DONTWAIT + [ebp + http_msg.buffer_length] cmp eax, 0xffffffff je .check_socket @@ -1082,28 +1087,28 @@ proc HTTP_receive identifier ;////////////////////////////////////////////////// jz .got_all_data .err_server_closed: pop eax - DEBUGF 1, "ERROR: server closed connection unexpectedly\n" + DEBUGF 2, "ERROR: server closed connection unexpectedly\n" or [ebp + http_msg.flags], FLAG_TRANSFER_FAILED jmp .abort .err_header: pop eax - DEBUGF 1, "ERROR: invalid header\n" + DEBUGF 2, "ERROR: invalid header\n" or [ebp + http_msg.flags], FLAG_INVALID_HEADER jmp .abort .err_no_ram: - DEBUGF 1, "ERROR: out of RAM\n" + DEBUGF 2, "ERROR: out of RAM\n" or [ebp + http_msg.flags], FLAG_NO_RAM jmp .abort .err_timeout: - DEBUGF 1, "ERROR: timeout\n" + DEBUGF 2, "ERROR: timeout\n" or [ebp + http_msg.flags], FLAG_TIMEOUT_ERROR jmp .abort .err_socket: - DEBUGF 1, "ERROR: socket error %u\n", ebx + DEBUGF 2, "ERROR: socket error %u\n", ebx or [ebp + http_msg.flags], FLAG_SOCKET_ERROR .abort: and [ebp + http_msg.flags], not FLAG_CONNECTED @@ -1268,7 +1273,7 @@ proc HTTP_find_header_field identifier, headername ;//////////////////////////// ret .fail: - DEBUGF 1, "Header field not found\n" + DEBUGF 2, "Header field not found\n" pop edi esi edx ecx ebx xor eax, eax ret @@ -1342,7 +1347,7 @@ proc HTTP_escape URI, length ;////////////////////////////////////////////////// ret .error: - DEBUGF 1, "ERROR: out of RAM!\n" + DEBUGF 2, "ERROR: out of RAM!\n" popa xor eax, eax ret @@ -1405,7 +1410,7 @@ proc HTTP_unescape URI, length ;//////////////////////////////////////////////// jmp .loop .fail: - DEBUGF 1, "ERROR: invalid URI!\n" + DEBUGF 2, "ERROR: invalid URI!\n" jmp .loop .done: @@ -1415,7 +1420,7 @@ proc HTTP_unescape URI, length ;//////////////////////////////////////////////// ret .error: - DEBUGF 1, "ERROR: out of RAM!\n" + DEBUGF 2, "ERROR: out of RAM!\n" popa xor eax, eax ret @@ -1659,12 +1664,12 @@ endl ret .no_mem: - DEBUGF 1, "Out of memory!\n" + DEBUGF 2, "Out of memory!\n" xor eax, eax ret .invalid: - DEBUGF 1, "Invalid URL!\n" + DEBUGF 2, "Invalid URL!\n" xor eax, eax ret diff --git a/programs/develop/libraries/http/http.inc b/programs/develop/libraries/http/http.inc index 650c75d55a..b406eced84 100644 --- a/programs/develop/libraries/http/http.inc +++ b/programs/develop/libraries/http/http.inc @@ -27,6 +27,7 @@ FLAG_CONNECTED = 1 shl 5 FLAG_KEEPALIVE = 1 shl 8 FLAG_STREAM = 1 shl 9 FLAG_REUSE_BUFFER = 1 shl 10 +FLAG_BLOCK = 1 shl 11 ; error FLAG_INVALID_HEADER = 1 shl 16 diff --git a/programs/develop/libraries/http/http_en.txt b/programs/develop/libraries/http/http_en.txt index 5a9bd219c8..1d0f53b2f4 100644 --- a/programs/develop/libraries/http/http_en.txt +++ b/programs/develop/libraries/http/http_en.txt @@ -2,7 +2,7 @@ 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) + flags = bit flags (see http.inc user flags and the end of this document) *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. @@ -11,7 +11,7 @@ Initiates a HTTP connection, using 'GET' method. 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) + flags = bit flags (see http.inc user flags and the end of this document) *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. @@ -20,7 +20,7 @@ Initiate a HTTP connection, using 'HEAD' method. 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) + flags = bit flags (see http.inc user flags and the end of this document) *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. @@ -35,6 +35,7 @@ receive(identifier); 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. +The receive procedure is non-blocking by default, but can be made to block by setting FLAG_BLOCK. The HTTP header 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.) @@ -54,5 +55,20 @@ send(identifier, *dataptr, datalength); datalength = length of the data to send (in bytes) This procedure can be used to send data to the server (POST) - returns number of bytes sent, -1 on error + + +User flags: -All procedures are non blocking! \ No newline at end of file + FLAG_KEEPALIVE will keep the connection open after first GET/POST/.. so you can send a second request on the same TCP session. +In this case, the session must be closed manually when done by using the exported disconnect() function. + + FLAG_STREAM will force receive() to put the received content in a series of fixed size buffers, instead of everything in one big buffer. +This can be used for example to receive an internet radio stream, +but also to download larger files for which it does not make sense to put them completely in RAM first. + + FLAG_REUSE_BUFFER is to be used in combination with FLAG_STREAM and will make receive() function re-use the same buffer. +This, for example, can be used when downloading a file straight to disk. + + FLAG_BLOCK will make receive() function blocking. This is only to be used when receiving one file from a thread that has no other work. +If however, you want to receive multiple files, or do other things in the program mainloop, +you should use system function 10 or 23 to wait for network event before calling one or more receive() functions.