diff --git a/example/test_unit.asm b/example/test_unit.asm
new file mode 100644
index 0000000..cb275ea
--- /dev/null
+++ b/example/test_unit.asm
@@ -0,0 +1,209 @@
+format MS COFF
+public @EXPORT as 'EXPORTS'
+
+include 'D:\kos\programs\macros.inc'
+
+struct EXPORT_DATA
+ netfunc_socket rd 1
+ netfunc_close rd 1
+ netfunc_bind rd 1
+ netfunc_accept rd 1
+ netfunc_listen rd 1
+ netfunc_recv rd 1
+ netfunc_send rd 1
+ FileInfo rd 1
+ FileRead rd 1
+ Alloc rd 1
+ Free rd 1
+
+ base_response rd 1
+ GLOBAL_DATA rd 1
+ends
+
+struct CONNECT_DATA ; 16*4 = 64 bytes
+ socket dd 0 ; номер сокета подключения
+ sockaddr dd 16/4 ; socaddr connection
+ buffer_request dd 0 ; pointer to buffer for geting message socket
+ request_size dd 0 ; size geted data from client
+ end_buffer_request dd 0 ; для парсера
+ buffer_response dd 0 ; pointer to buffwr for resp message
+ http_method dd 0 ; указатель на строку
+ http_verion dd 0 ; указатель на строку
+ num_headers dd 0 ; number items in REQUEST_DATA
+ http_headers dd 0 ; указатель на массив REQUEST_DATA
+ uri_scheme dd 0 ; указатель на схему
+ uri_authority dd 0 ; pointer to struct ?
+ uri_path dd 0 ; указатель на декодированный путь к ресурсу(без параметров)
+ num_uri_args dd 0 ;
+ uri_arg dd 0 ; pointer to array REQUEST_DATA аргументов uri строк
+ uri_fragment dd 0 ; указатель на строку
+ message_body dd 0 ; указатель на тело http запроса
+ends
+
+macro board_input message {
+ local ..str, ..end
+ push eax ebx ecx esi
+ mov esi, ..str
+@@:
+ mov cl, [esi]
+ mcall 63, 1
+ inc esi
+
+ cmp cl, 10
+ jne @b
+ jmp ..end
+..str:
+ db message,13, 10
+..end:
+ pop esi ecx ebx eax
+}
+
+section '.flat' code readable align 16
+
+unit_init:
+
+ mov eax, [esp + 4]
+ mov [import_httpd], eax
+
+ xor eax, eax
+ ret 4
+
+server_entry:
+ push esi edi
+ mov esi, [esp + 4*2 + 4]
+ ; work
+ board_input 'first'
+ inc dword[count_call]
+
+ cmp [esi + CONNECT_DATA.num_uri_args], 1
+ jb .no_args
+
+ mov eax, [esi + CONNECT_DATA.uri_arg]
+
+ mov ecx, [eax]
+ cmp dword[ecx], 'cmd'
+ jne .no_args
+ mov edx, [eax + 4]
+ cmp dword[edx], 'new'
+ je .no_del
+
+ cmp dword[edx], 'del'
+
+ mov dword[text_message], ' '
+ mov dword[text_message + 4], ' '
+ mov dword[text_message + 8], ' '
+ mov dword[text_message + 12], ' '
+ jmp .no_args
+
+.no_del:
+ cmp [esi + CONNECT_DATA.num_uri_args], 2
+ jb .no_args
+
+ mov ecx, [eax + 8]
+ cmp dword[ecx], 'txt'
+ jne .no_args
+
+ push esi edi
+ mov esi, [eax + 12]
+ mov edi, text_message
+ mov ecx, text_message.size
+@@:
+ movsb
+ dec ecx
+ jz @f
+ cmp byte[esi - 1], 0
+ jne @b
+@@:
+ pop edi esi
+.no_args:
+ board_input 'create message'
+ ; create http message
+ push dword 8*1024
+ mov eax, [import_httpd]
+ call [eax + EXPORT_DATA.Alloc]
+ test eax, eax
+ jz .exit
+
+ push esi edi
+ mov ecx, sceleton_resp.size
+ mov esi, sceleton_resp
+ mov edi, eax
+ rep movsd
+ pop edi esi
+
+ mov [esi + CONNECT_DATA.buffer_response], eax
+ ; copy message
+ mov ecx, [text_message]
+ mov [eax + sceleton_resp.message], ecx
+ mov ecx, [text_message + 4]
+ mov [eax + sceleton_resp.message + 4], ecx
+ mov ecx, [text_message + 8]
+ mov [eax + sceleton_resp.message + 8], ecx
+ mov ecx, [text_message + 12]
+ mov [eax + sceleton_resp.message + 12], ecx
+ ; copy count_call
+ mov edi, eax
+ xor edx, edx
+ mov eax, [count_call]
+ div dword[_10]
+ add byte[edi + sceleton_resp.count + 2], dl
+
+ ; set httpcode
+ mov dword[edi + sceleton_resp.code], '200 '
+ ; send http message
+ mov ecx, [import_httpd]
+
+ push dword 0 ; flags
+ push sceleton_resp.size
+ push edi
+ push dword[esi + CONNECT_DATA.socket]
+ call [ecx + EXPORT_DATA.netfunc_send]
+
+ board_input 'send'
+.exit:
+ pop edi esi
+ ret 4
+
+section '.data' data readable writable align 16
+
+_10: dd 10
+
+count_call dd 0
+
+import_httpd: dd 0
+
+sceleton_resp:
+ db 'HTTP/1.0 '
+.code = $ - sceleton_resp
+ db '000 ',13, 10
+ db 'Server: simple-httpd/0.0.1', 13, 10
+ db 'Cache-Control: no-cache', 13, 10
+ db 'Content-Encoding: identity', 13, 10
+ db 'Content-length: '
+ db '0336', 13, 10
+ db 'Content-type: text/html ', 13, 10;
+ db 'Connection: close', 13, 10
+ db 13, 10
+ db ''
+ db '
Test Server'
+ db ''
+ db 'Данные с сервера'
+ db 'Name'
+ db ' | Info |
'
+ db ''
+ db ' Количество запросов | '
+.count = $ - sceleton_resp
+ db '000 |
Сообщение | '
+.message = $ - sceleton_resp
+ db ' |
'
+.size = $ - sceleton_resp
+
+
+text_message:
+ db ' '
+.size = $ - text_message
+
+@EXPORT:
+export \
+ unit_init, 'httpd_init', \
+ server_entry, 'httpd_serv'
diff --git a/example/test_unit.obj b/example/test_unit.obj
new file mode 100644
index 0000000..9c360f3
Binary files /dev/null and b/example/test_unit.obj differ
diff --git a/file_server.inc b/file_server.inc
index 032a2c4..2f21adc 100644
--- a/file_server.inc
+++ b/file_server.inc
@@ -249,30 +249,25 @@ file_server:
; char* stdcall Get_MIME_Type(FILED* fd); //path is ASCIIZ string
Get_MIME_Type:
push esi edi
+ mov eax, [esp + 4*2 + 4]
+ mov eax, [eax + FILED.end_path]
mov edx, [GLOBAL_DATA.MIME_types_arr]
- mov esi, [esp + 4*2 + 4]
- sub edx, 8
-.next:
- add edx, 8
- mov ecx, [esi + FILED.end_path] ;pointer to \0 full path
-
- cmp dword[edx], 0
- jz .found
-
- mov edi, [edx]
- movzx eax, byte[edi]
- sub ecx, eax
@@:
- inc edi
- mov al, [edi]
- cmp byte[ecx], al
- jne .next
-
- inc ecx
- test al, al
- jne @b
-
-.found:
- mov eax, [edx + 4]
- pop edi esi
+ mov esi, [edx]
+ add edx, 4
+ cmp dword[esi], 0
+ jz .other
+
+ mov edi, eax
+ movzx ecx, byte [esi]
+ inc esi
+ sub edi, ecx
+ repe cmpsb
+ jne @b
+@@:
+ mov eax, esi
+ pop edi esi
ret 4
+.other:
+ add esi, 4
+ jmp @b
\ No newline at end of file
diff --git a/httpd.asm b/httpd.asm
index 33cd00c..edf2288 100644
--- a/httpd.asm
+++ b/httpd.asm
@@ -4,16 +4,19 @@
; ;
; httpd - Simple http server for Kolibri OS. ;
; ;
-; Version 0.0.1, 12 November 2023 ;
+; Version 0.0.3, 12 November 2023 ;
; ;
;*****************************************************************************;
;include "macros.inc"
-include 'D:\kos\programs\macros.inc'
-;include 'D:\kos\programs\network.inc'
use32
org 0
db 'MENUET01'
dd 1, START, I_END, MEM, STACKTOP, PATH, 0
+include 'D:\kos\programs\macros.inc'
+purge mov,add,sub
+include 'D:\kos\programs\proc32.inc'
+include 'D:\kos\programs\dll.inc'
+;include 'D:\kos\programs\network.inc'
;KOS_APP_START
include 'sys_func.inc'
@@ -24,6 +27,11 @@ START:
mcall 68, 11 ; init heap
mcall 40, EVM_STACK ;set event bitmap
+ ; init library
+ stdcall dll.Load, @IMPORT
+ test eax, eax
+ jnz .err_settings
+
mov ecx, PATH
cmp byte[ecx],0
jnz @f
@@ -142,15 +150,38 @@ thread_connect:
call parse_http_query ; ecx - buffer
test eax, eax
jz .err_parse
- ; вызов нужной функции из списка моделей
-
- ; TODO
+ ; вызов нужной функции из списка модулей
+ cmp dword[GLOBAL_DATA.units], 0
+ jz .no_units
+ mov eax, [GLOBAL_DATA.units]
+.next_unit:
+ push esi edi
+ mov esi, [esi + CONNECT_DATA.uri_path]
+ lea edi, [eax + 4*3]
+@@:
+ cmpsb
+ jne @f
+ cmp byte[edi - 1], 0
+ jne @b
+ ; found unit
+ pop edi esi
+
+ push esi
+ call dword[eax + 4*2] ; httpd_serv
+
+ jmp .end_work
+@@:
+ pop edi esi
+
+ mov eax, [eax]
+ test eax, eax ; terminate list
+ jne .next_unit
+
+.no_units:
; if not found units, call file_server
call file_server ; esi - struct
- ;TEST SERVER, DELETE ON RELISE
-
; end work thread
jmp .end_work
@@ -184,10 +215,59 @@ include 'file_server.inc'
; DATA AND FUNCTION
include 'httpd_lib.inc'
-default_ini_path: db 'httpd.ini',0
+
I_END:
;DATA
+@IMPORT:
+library libini, 'libini.obj'
+
+import libini,\
+ ini.get_str, 'ini_get_str',\
+ ini.get_int, 'ini_get_int',\
+ ini.enum_keys, 'ini_enum_keys'
+
+
+default_ini_path: db 'httpd.ini',0
+
+ini_section_units: db 'UNITS',0
+ini_section_main: db 'MAIN', 0
+
+ini_key_ip db 'ip',0
+ini_key_port db 'port',0
+ini_key_conn db 'conn',0
+;ini_key_flags db 'flags',0
+ini_key_work_dir db 'work_dir',0
+ini_key_units_dir db 'units_dir',0
+ini_key_mime_file db 'mime_file',0
+
+httpd_unit_init db 'httpd_init',0
+httpd_unit_serv db 'httpd_serv',0
+
+IMPORT_UNIT:
+ dd httpd_import, GLOBAL_DATA.unit_dir, 0
+
+httpd_import:
+.init dd httpd_unit_init
+.serv dd httpd_unit_serv
+ dd 0
+
+EXPORT_DATA:
+ dd netfunc_socket
+ dd netfunc_close
+ dd netfunc_bind
+ dd netfunc_accept
+ dd netfunc_listen
+ dd netfunc_recv
+ dd netfunc_send
+ dd FileInfo
+ dd FileRead
+ dd Alloc
+ dd Free
+
+ dd base_response
+ dd GLOBAL_DATA
+ dd 0
; DATA
;UDATA
@@ -204,16 +284,15 @@ srv_sockaddr:
.length = $ - srv_sockaddr
GLOBAL_DATA:
- .units rd 1 ; указатель на ассоциативный массив пути и указателя на функцию либы(см ниж)
- .unit_count rd 1 ; количество записей в массиве
- .libs rd 1 ; указатель на массив указателей на ассоциативные массивы библиотек
+ .units rd 1 ; указатель на двусвязный не кольцевой(null terminator) список
+ ; next, prev, ptr of httpd_serv(), uri path
.work_dir rb 1024 ; max size path to work directory
.work_dir.size rd 1 ; length string
.unit_dir rb 1024
- .unit_dir.size rd 1
+ .unit_dir.end rd 1
.MIME_types_arr rd 1
-;; .flags dd 0 ; 1 - all hosts(элемент hosts не указатель на массив, а на функцию)
+; .flags dd 0 ; 1 - all hosts(элемент hosts не указатель на массив, а на функцию)
PATH:
rb 256
diff --git a/httpd.ini b/httpd.ini
index cf72d17..10c21c1 100644
--- a/httpd.ini
+++ b/httpd.ini
@@ -1,25 +1,27 @@
[MAIN]
-# server IPv4 address. Non IPv6 address
-ip=127.0.0.1
-# server port number
+; server IPv4 address. Non IPv6 address
+ip=192.168.137.21
+; server port number
port=80
-# count open connection
+; 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
+; 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
+; directory for find files
work_dir=/sys/http_server/data
-# directory for find lib
+; directory for find lib
units_dir=/sys/http_units
-[UNITS]
-# list units
-# path = path to lib in units_dir
-database/sqlite3=sqlite3_serv.obj
-database/cvs=cvs_table_server.obj
+;mime_file=/sys/network/mime.bin
-# server called function httpd_unit_func(CONNECT_DATA* struct_server );
-# for init unit, server called function httpd_unit_init(void* global_data);
\ No newline at end of file
+;[UNITS]
+; list units
+; path = path to lib in units_dir
+;database/sqlite3=sqlite3_serv.obj
+;database/cvs=cvs_table_server.obj
+
+; server called function httpd_serv(CONNECT_DATA* struct_server );
+; for init unit, server called function httpd_init(void* global_data);
\ No newline at end of file
diff --git a/httpd.kex b/httpd.kex
index 2b23b94..57263c8 100644
Binary files a/httpd.kex and b/httpd.kex differ
diff --git a/httpd_lib.inc b/httpd_lib.inc
index fcd2741..3f0c284 100644
--- a/httpd_lib.inc
+++ b/httpd_lib.inc
@@ -69,29 +69,29 @@ http_method:
; db ''
; db '