diff --git a/example/httpd.ini b/example/httpd.ini new file mode 100644 index 0000000..1715a62 --- /dev/null +++ b/example/httpd.ini @@ -0,0 +1,28 @@ +[MAIN] +; server IPv4 address. Non IPv6 address +ip=192.168.137.21 +; server port number +port=80 +; count open connection +conn=100 + +; 1000 - no parse http headers, raw data in CONNECT_DATA.message_body +; This flags using for http/2.0 and other protocol execution. +;flags=0000 ; parsing http headers + +; directory for find files +work_dir=/usbhd0/3/server_data +; directory for find units(library) +units_dir=/usbhd0/3 + +mime_file=/usbhd0/3/mime_types.bin + +[UNITS] +; list units +; path = path to lib in units_dir +test=test_unit.obj +;database/sqlite3=sqlite3_serv.obj +;database/cvs=cvs_table_server.obj + +; server calling function httpd_serv(CONNECT_DATA* struct_server ); +; for init unit, server calling function httpd_init(void* global_data); \ No newline at end of file diff --git a/example/test_unit.asm b/example/test_unit.asm index cb275ea..d779424 100644 --- a/example/test_unit.asm +++ b/example/test_unit.asm @@ -1,6 +1,7 @@ format MS COFF public @EXPORT as 'EXPORTS' +NO_DEBUG_INPUT = 1 include 'D:\kos\programs\macros.inc' struct EXPORT_DATA @@ -41,6 +42,7 @@ struct CONNECT_DATA ; 16*4 = 64 bytes ends macro board_input message { +if NO_DEBUG_INPUT = 0 local ..str, ..end push eax ebx ecx esi mov esi, ..str @@ -56,6 +58,7 @@ macro board_input message { db message,13, 10 ..end: pop esi ecx ebx eax +end if } section '.flat' code readable align 16 @@ -108,11 +111,12 @@ server_entry: mov edi, text_message mov ecx, text_message.size @@: - movsb dec ecx jz @f - cmp byte[esi - 1], 0 - jne @b + cmp byte[esi], 0 + jz @f + movsb + jmp @b @@: pop edi esi .no_args: @@ -147,6 +151,19 @@ server_entry: mov eax, [count_call] div dword[_10] add byte[edi + sceleton_resp.count + 2], dl + test eax, eax + jz @f + + xor edx, edx + div dword[_10] + add byte[edi + sceleton_resp.count + 1], dl + test eax, eax + jz @f + + xor edx, edx + div dword[_10] + add byte[edi + sceleton_resp.count], dl +@@: ; set httpcode mov dword[edi + sceleton_resp.code], '200 ' @@ -180,7 +197,7 @@ sceleton_resp: db 'Cache-Control: no-cache', 13, 10 db 'Content-Encoding: identity', 13, 10 db 'Content-length: ' - db '0336', 13, 10 + db '0377', 13, 10 db 'Content-type: text/html ', 13, 10; db 'Connection: close', 13, 10 db 13, 10 diff --git a/example/test_unit.obj b/example/test_unit.obj index 9c360f3..0caa622 100644 Binary files a/example/test_unit.obj and b/example/test_unit.obj differ diff --git a/file_server.inc b/file_server.inc index 2f21adc..2b3c5e5 100644 --- a/file_server.inc +++ b/file_server.inc @@ -1,5 +1,5 @@ -; Это модуль для обработки стандартных запросов на получение файла -; по пути, который не относится к другому модулю +; This is a module for processing standard requests to get a file along +; a path that does not belong to another module. file_server: diff --git a/httpd.asm b/httpd.asm index edf2288..fd3a0b6 100644 --- a/httpd.asm +++ b/httpd.asm @@ -4,7 +4,7 @@ ; ; ; httpd - Simple http server for Kolibri OS. ; ; ; -; Version 0.0.3, 12 November 2023 ; +; Version 0.0.4, 12 November 2023 ; ; ; ;*****************************************************************************; ;include "macros.inc" @@ -43,7 +43,7 @@ START: jnz .err_settings ;init server socket - push dword SO_NONBLOCK ; IPPROTO_TCP + push dword SO_NONBLOCK ; IPPROTO_TCP ? push dword SOCK_STREAM push dword AF_INET4 call netfunc_socket; AF_INET4, SOCK_STREAM, SO_NONBLOCK ; we dont want to block on accept @@ -150,7 +150,7 @@ thread_connect: call parse_http_query ; ecx - buffer test eax, eax jz .err_parse - ; вызов нужной функции из списка модулей + ; find unit for uri path cmp dword[GLOBAL_DATA.units], 0 jz .no_units @@ -158,7 +158,7 @@ thread_connect: .next_unit: push esi edi mov esi, [esi + CONNECT_DATA.uri_path] - lea edi, [eax + 4*3] + lea edi, [eax + HTTPD_UNIT.uri_path] @@: cmpsb jne @f @@ -169,13 +169,13 @@ thread_connect: pop edi esi push esi - call dword[eax + 4*2] ; httpd_serv + call dword[eax + HTTPD_UNIT.httpd_serv] ; call unit function jmp .end_work @@: pop edi esi - mov eax, [eax] + mov eax, [eax] ; HTTPD_UNIT.next test eax, eax ; terminate list jne .next_unit @@ -277,9 +277,9 @@ srv_backlog: rd 1 ; максимум одновременных подклю srv_socket: rd 1 srv_sockaddr: - dw AF_INET4 - .port dw 0 - .ip dd 0 + rw 1 + .port rw 1 + .ip rd 1 rb 8 .length = $ - srv_sockaddr @@ -292,7 +292,7 @@ GLOBAL_DATA: .unit_dir.end rd 1 .MIME_types_arr rd 1 -; .flags dd 0 ; 1 - all hosts(элемент hosts не указатель на массив, а на функцию) +; .flags rd 1 PATH: rb 256 diff --git a/httpd.kex b/httpd.kex index 57263c8..5fb6720 100644 Binary files a/httpd.kex and b/httpd.kex differ diff --git a/httpd_lib.inc b/httpd_lib.inc index 3f0c284..06ea312 100644 --- a/httpd_lib.inc +++ b/httpd_lib.inc @@ -130,18 +130,17 @@ response: ; db 'Date: ' ;.date: db 'Sun, 30 Oct 2022 09:29:13 GMT',13, 10 db 'Content-length: ' -;.content_len: db ' ', 13, 10 .content_len = $ - response db '0000000000000000000000', 13, 10 db 'Content-type: ' .content_type = $ - response db ' ', 13, 10; ;'text/html; charset=utf-8' -.end_headers: ;нужно, когда базового заголовка не хватает +.end_headers: ; for adding new headers, and save connection(keep-alive) .connection = $ - response db 'Connection: close', 13, 10 db 13, 10 -.body = $ - response ; с этого оффсета уже писать данные +.body = $ - response ; offset for add http body in simple response ; min HTTP request size ; "GET / HTTP/1.1" - 18 byte diff --git a/parser.inc b/parser.inc index a154666..3c1f93b 100644 --- a/parser.inc +++ b/parser.inc @@ -259,7 +259,7 @@ parse_http_query: cmp dword[esi + CONNECT_DATA.request_size], edx jle .error_exit - ; получение заголовков запроса (ключ + значение-строка) + ; get headers request (key + value string) call parse_headers diff --git a/settings.inc b/settings.inc index 3f25584..05a59f8 100644 --- a/settings.inc +++ b/settings.inc @@ -76,7 +76,7 @@ load_settings: ; flags ; work_dir - invoke ini.get_str, ebp, ini_section_main, ini_key_work_dir, GLOBAL_DATA.work_dir, 1024, 0 ; ip + invoke ini.get_str, ebp, ini_section_main, ini_key_work_dir, GLOBAL_DATA.work_dir, 1024, 0 push edi mov ecx, 1024 mov edi, GLOBAL_DATA.work_dir @@ -88,10 +88,11 @@ load_settings: pop edi ; TODO: get mime file - mov dword[GLOBAL_DATA.MIME_types_arr], STD_MIME_TYPE_ARR - + ;mov dword[GLOBAL_DATA.MIME_types_arr], STD_MIME_TYPE_ARR + call load_mime_file + ; units_dir - invoke ini.get_str, ebp, ini_section_main, ini_key_units_dir, GLOBAL_DATA.unit_dir, 1024, 0 ; ip + invoke ini.get_str, ebp, ini_section_main, ini_key_units_dir, GLOBAL_DATA.unit_dir, 1024, 0 push edi mov ecx, 1024 mov edi, GLOBAL_DATA.unit_dir @@ -103,19 +104,6 @@ load_settings: ; get all units invoke ini.enum_keys, ebp, ini_section_units, .add_unit - - ; TEST SERVER - ;mov word[srv_sockaddr.port], 0x5000 ; 80 port - ;mov dword[srv_sockaddr.ip], 0x1589A8C0 ; 192.168.137.21 or 0xc0a88915 ? - ;mov dword[srv_backlog], 10 - - ;push esi edi - ;mov edi, GLOBAL_DATA.work_dir - ;mov esi, test_workdir - ;mov ecx, test_workdir.size - ;rep movsb - ;pop edi esi - ;mov dword[GLOBAL_DATA.work_dir.size], test_workdir.size xor eax, eax ret @@ -128,17 +116,17 @@ load_settings: jz .add_unit.exit mov ecx, [GLOBAL_DATA.units] - mov [eax], ecx - mov dword[eax + 4], GLOBAL_DATA.units + mov [eax + HTTPD_UNIT.next], ecx + mov dword[eax + HTTPD_UNIT.prev], GLOBAL_DATA.units mov [GLOBAL_DATA.units], eax test ecx, ecx jnz @f - mov [ecx + 4], eax + mov [ecx + HTTPD_UNIT.prev], eax @@: ; copy uri path push esi edi mov esi, [esp + 4*2 + 4*3] ; name - lea edi, [eax + 4*3 + 1] + lea edi, [eax + HTTPD_UNIT.uri_path + 1] mov byte[edi - 1], '/' @@: movsb @@ -163,9 +151,9 @@ load_settings: .add_unit.err: ; error - mov eax, [esi] ; next + mov eax, [esi + HTTPD_UNIT.next] ; next mov [GLOBAL_DATA.units], eax - mov dword[eax + 4], GLOBAL_DATA.units + mov dword[eax + HTTPD_UNIT.prev], GLOBAL_DATA.units push esi call Free @@ -179,7 +167,7 @@ load_settings: jnz .add_unit.err mov eax, [httpd_import.serv] - mov dword[esi + 4*2], eax + mov dword[esi + HTTPD_UNIT.httpd_serv], eax mov [httpd_import.init], httpd_unit_init mov [httpd_import.serv], httpd_unit_serv @@ -191,7 +179,61 @@ load_settings: .err: ret -;test_workdir: db '/sys' -;.size = $ - test_workdir +load_mime_file: + stdcall Alloc, 4096 + test eax, eax + jz .err + push eax + mov edi, eax + xor eax, eax + mov ecx, 1024 + rep stosd + pop eax + mov esi, eax + lea ecx, [eax + sizeof.FILED + 40] + mov [esi + FILED.path], ecx + invoke ini.get_str, ebp, ini_section_main, ini_key_mime_file, ecx, 1024, 0 + test eax, eax + jnz .no_file + + lea ecx, [esi + sizeof.FILED] + mov [esi + FILED.buffer], ecx + stdcall FileInfo, esi + test eax, eax + jnz .no_file + + mov ecx, [esi + sizeof.FILED + 32] + stdcall Alloc, ecx + test eax, eax + jz .no_file + + mov ecx, [esi + sizeof.FILED + 32] + mov edi, eax + mov [esi + FILED.buffer], eax + mov [esi + FILED.size], ecx + mov [esi + FILED.offset], 0 + mov dword[esi + FILED.offset + 4], 0 + stdcall FileRead, esi + test eax, eax + jnz .error_read + + mov dword[GLOBAL_DATA.MIME_types_arr], edi + mov eax, edi +@@: + add [edi], eax + mov ecx, [edi] + add edi, 4 + cmp dword[ecx], 0 + jne @b + + stdcall Free, esi + ret +.error_read: + stdcall Free, edi +.no_file: + stdcall Free, esi +.err: + mov dword[GLOBAL_DATA.MIME_types_arr], STD_MIME_TYPE_ARR + ret \ No newline at end of file diff --git a/utils/mime_types.asm b/utils/mime_types.asm index 9a55d41..2e11578 100644 --- a/utils/mime_types.asm +++ b/utils/mime_types.asm @@ -20,13 +20,20 @@ macro table arg3, [arg1,arg2] { } -table 'application/octet-stream' ,\ - '.html', 'text/html' ,\ - '.css', 'text/css' ,\ - '.js', 'text/javascript' ,\ - '.txt', 'text/plain' ,\ - '.pdf', 'application/pdf' ,\ - '.json', 'application/json' ,\ - '.png', 'image/png' ,\ - '.mp3', 'audio/mpeg' ,\ - '.mp4', 'video/mp4' +table 'application/octet-stream' ,\ + '.html', 'text/html' ,\ + '.htm', 'text/html' ,\ + '.css', 'text/css' ,\ + '.js', 'text/javascript' ,\ + '.txt', 'text/plain; charset=utf-8' ,\ + '.pdf', 'application/pdf' ,\ + '.json', 'application/json' ,\ + '.png', 'image/png' ,\ + '.mp3', 'audio/mpeg' ,\ + '.mp4', 'video/mp4' ,\ + '.gif', 'image/gif' ,\ + '.webp', 'image/webp' ,\ + '.svg', 'image/svg+xml' ,\ + '.apng', 'image/apng' ,\ + '.jpeg', 'image/jpeg' ,\ + '.jpg','image/jpeg' diff --git a/utils/mime_types.bin b/utils/mime_types.bin index bed7dc8..72ac9a6 100644 Binary files a/utils/mime_types.bin and b/utils/mime_types.bin differ