mirror of
https://github.com/Doczom/simple-httpd.git
synced 2025-09-21 02:50:09 +02:00
Add support units in server
Added support for loading and calling server modules. Added the download of the configuration file(httpd.ini). Several bugs have been fixed. Added simple example for generating server units and mime types file.
This commit is contained in:
209
example/test_unit.asm
Normal file
209
example/test_unit.asm
Normal file
@@ -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 '<!DOCTYPE html>'
|
||||||
|
db '<html><head><meta charset="utf-8"><title>Test Server</title></head>'
|
||||||
|
db '<body><table cellspacing="0" border="1">'
|
||||||
|
db '<thead><caption>Данные с сервера</caption><tr>'
|
||||||
|
db '<th>Name'
|
||||||
|
db '<th>Info </thead>'
|
||||||
|
db '<tbody align="center">'
|
||||||
|
db '<tr><td> Количество запросов <td>'
|
||||||
|
.count = $ - sceleton_resp
|
||||||
|
db '000 <tr><td> Сообщение <td>'
|
||||||
|
.message = $ - sceleton_resp
|
||||||
|
db ' </tbody></table></body></html>'
|
||||||
|
.size = $ - sceleton_resp
|
||||||
|
|
||||||
|
|
||||||
|
text_message:
|
||||||
|
db ' '
|
||||||
|
.size = $ - text_message
|
||||||
|
|
||||||
|
@EXPORT:
|
||||||
|
export \
|
||||||
|
unit_init, 'httpd_init', \
|
||||||
|
server_entry, 'httpd_serv'
|
BIN
example/test_unit.obj
Normal file
BIN
example/test_unit.obj
Normal file
Binary file not shown.
@@ -249,30 +249,25 @@ file_server:
|
|||||||
; char* stdcall Get_MIME_Type(FILED* fd); //path is ASCIIZ string
|
; char* stdcall Get_MIME_Type(FILED* fd); //path is ASCIIZ string
|
||||||
Get_MIME_Type:
|
Get_MIME_Type:
|
||||||
push esi edi
|
push esi edi
|
||||||
|
mov eax, [esp + 4*2 + 4]
|
||||||
|
mov eax, [eax + FILED.end_path]
|
||||||
mov edx, [GLOBAL_DATA.MIME_types_arr]
|
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 esi, [edx]
|
||||||
mov al, [edi]
|
add edx, 4
|
||||||
cmp byte[ecx], al
|
cmp dword[esi], 0
|
||||||
jne .next
|
jz .other
|
||||||
|
|
||||||
inc ecx
|
mov edi, eax
|
||||||
test al, al
|
movzx ecx, byte [esi]
|
||||||
jne @b
|
inc esi
|
||||||
|
sub edi, ecx
|
||||||
.found:
|
repe cmpsb
|
||||||
mov eax, [edx + 4]
|
jne @b
|
||||||
pop edi esi
|
@@:
|
||||||
|
mov eax, esi
|
||||||
|
pop edi esi
|
||||||
ret 4
|
ret 4
|
||||||
|
.other:
|
||||||
|
add esi, 4
|
||||||
|
jmp @b
|
107
httpd.asm
107
httpd.asm
@@ -4,16 +4,19 @@
|
|||||||
; ;
|
; ;
|
||||||
; httpd - Simple http server for Kolibri OS. ;
|
; 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 "macros.inc"
|
||||||
include 'D:\kos\programs\macros.inc'
|
|
||||||
;include 'D:\kos\programs\network.inc'
|
|
||||||
use32
|
use32
|
||||||
org 0
|
org 0
|
||||||
db 'MENUET01'
|
db 'MENUET01'
|
||||||
dd 1, START, I_END, MEM, STACKTOP, PATH, 0
|
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
|
;KOS_APP_START
|
||||||
|
|
||||||
include 'sys_func.inc'
|
include 'sys_func.inc'
|
||||||
@@ -24,6 +27,11 @@ START:
|
|||||||
mcall 68, 11 ; init heap
|
mcall 68, 11 ; init heap
|
||||||
mcall 40, EVM_STACK ;set event bitmap
|
mcall 40, EVM_STACK ;set event bitmap
|
||||||
|
|
||||||
|
; init library
|
||||||
|
stdcall dll.Load, @IMPORT
|
||||||
|
test eax, eax
|
||||||
|
jnz .err_settings
|
||||||
|
|
||||||
mov ecx, PATH
|
mov ecx, PATH
|
||||||
cmp byte[ecx],0
|
cmp byte[ecx],0
|
||||||
jnz @f
|
jnz @f
|
||||||
@@ -142,15 +150,38 @@ thread_connect:
|
|||||||
call parse_http_query ; ecx - buffer
|
call parse_http_query ; ecx - buffer
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err_parse
|
jz .err_parse
|
||||||
; вызов нужной функции из списка моделей
|
; вызов нужной функции из списка модулей
|
||||||
|
cmp dword[GLOBAL_DATA.units], 0
|
||||||
; TODO
|
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
|
; if not found units, call file_server
|
||||||
call file_server ; esi - struct
|
call file_server ; esi - struct
|
||||||
;TEST SERVER, DELETE ON RELISE
|
|
||||||
|
|
||||||
; end work thread
|
; end work thread
|
||||||
jmp .end_work
|
jmp .end_work
|
||||||
|
|
||||||
@@ -184,10 +215,59 @@ include 'file_server.inc'
|
|||||||
; DATA AND FUNCTION
|
; DATA AND FUNCTION
|
||||||
include 'httpd_lib.inc'
|
include 'httpd_lib.inc'
|
||||||
|
|
||||||
default_ini_path: db 'httpd.ini',0
|
|
||||||
I_END:
|
I_END:
|
||||||
;DATA
|
;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
|
; DATA
|
||||||
|
|
||||||
;UDATA
|
;UDATA
|
||||||
@@ -204,16 +284,15 @@ srv_sockaddr:
|
|||||||
.length = $ - srv_sockaddr
|
.length = $ - srv_sockaddr
|
||||||
|
|
||||||
GLOBAL_DATA:
|
GLOBAL_DATA:
|
||||||
.units rd 1 ; указатель на ассоциативный массив пути и указателя на функцию либы(см ниж)
|
.units rd 1 ; указатель на двусвязный не кольцевой(null terminator) список
|
||||||
.unit_count rd 1 ; количество записей в массиве
|
; next, prev, ptr of httpd_serv(), uri path
|
||||||
.libs rd 1 ; указатель на массив указателей на ассоциативные массивы библиотек
|
|
||||||
.work_dir rb 1024 ; max size path to work directory
|
.work_dir rb 1024 ; max size path to work directory
|
||||||
.work_dir.size rd 1 ; length string
|
.work_dir.size rd 1 ; length string
|
||||||
.unit_dir rb 1024
|
.unit_dir rb 1024
|
||||||
.unit_dir.size rd 1
|
.unit_dir.end rd 1
|
||||||
|
|
||||||
.MIME_types_arr rd 1
|
.MIME_types_arr rd 1
|
||||||
;; .flags dd 0 ; 1 - all hosts(элемент hosts не указатель на массив, а на функцию)
|
; .flags dd 0 ; 1 - all hosts(элемент hosts не указатель на массив, а на функцию)
|
||||||
|
|
||||||
PATH:
|
PATH:
|
||||||
rb 256
|
rb 256
|
||||||
|
34
httpd.ini
34
httpd.ini
@@ -1,25 +1,27 @@
|
|||||||
[MAIN]
|
[MAIN]
|
||||||
# server IPv4 address. Non IPv6 address
|
; server IPv4 address. Non IPv6 address
|
||||||
ip=127.0.0.1
|
ip=192.168.137.21
|
||||||
# server port number
|
; server port number
|
||||||
port=80
|
port=80
|
||||||
# count open connection
|
; count open connection
|
||||||
conn=100
|
conn=100
|
||||||
|
|
||||||
# 1000 - no parse http headers, raw data in CONNECT_DATA.message_body
|
; 1000 - no parse http headers, raw data in CONNECT_DATA.message_body
|
||||||
# This flags using for http/2.0 and other protocol execution.
|
; This flags using for http/2.0 and other protocol execution.
|
||||||
flags=0000 # parsing http headers
|
;flags=0000 ; parsing http headers
|
||||||
|
|
||||||
# directory for find files
|
; directory for find files
|
||||||
work_dir=/sys/http_server/data
|
work_dir=/sys/http_server/data
|
||||||
# directory for find lib
|
; directory for find lib
|
||||||
units_dir=/sys/http_units
|
units_dir=/sys/http_units
|
||||||
|
|
||||||
[UNITS]
|
;mime_file=/sys/network/mime.bin
|
||||||
# list units
|
|
||||||
# path = path to lib in units_dir
|
|
||||||
database/sqlite3=sqlite3_serv.obj
|
|
||||||
database/cvs=cvs_table_server.obj
|
|
||||||
|
|
||||||
# server called function httpd_unit_func(CONNECT_DATA* struct_server );
|
;[UNITS]
|
||||||
# for init unit, server called function httpd_unit_init(void* global_data);
|
; 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);
|
@@ -69,29 +69,29 @@ http_method:
|
|||||||
; db '</center>'
|
; db '</center>'
|
||||||
; db '</html>',0
|
; db '</html>',0
|
||||||
|
|
||||||
http_err_response:
|
;http_err_response:
|
||||||
db 'HTTP/1.1 '
|
; db 'HTTP/1.1 '
|
||||||
.code = $ - http_err_response
|
;.code = $ - http_err_response
|
||||||
db '000 ',13, 10
|
; db '000 ',13, 10
|
||||||
db 'Server: simple-httpd/0.0.1', 13, 10
|
; db 'Server: simple-httpd/0.0.1', 13, 10 ; httpd(kolibri os)/0.0.1, 13, 10
|
||||||
db 'Date: '
|
; db 'Date: '
|
||||||
.date = $ - http_err_response
|
;.date = $ - http_err_response
|
||||||
db 'Sun, 30 Oct 2022 09:29:13 GMT',13, 10
|
; db 'Sun, 30 Oct 2022 09:29:13 GMT',13, 10
|
||||||
db 'Content-length: 0', 13, 10
|
; db 'Content-length: 0', 13, 10
|
||||||
db 'Content-type: text/plain', 13, 10;
|
; db 'Content-type: text/plain', 13, 10;
|
||||||
db 'Connection: close', 13, 10
|
; db 'Connection: close', 13, 10
|
||||||
db 13, 10
|
; db 13, 10
|
||||||
.size = $ - http_err_response
|
;.size = $ - http_err_response
|
||||||
|
|
||||||
http_response_err_501:
|
http_response_err_501:
|
||||||
db 'HTTP/1.1 '
|
db 'HTTP/1.1 '
|
||||||
db '501 ',13, 10
|
db '501 ',13, 10
|
||||||
|
db 'Error parsing your request message. The version is not supported or another error.'
|
||||||
db 'Server: simple-httpd/0.0.1', 13, 10
|
db 'Server: simple-httpd/0.0.1', 13, 10
|
||||||
db 'Content-length: 91', 13, 10
|
;db 'Content-length: 91', 13, 10
|
||||||
db 'Content-type: text/plain', 13, 10;
|
;db 'Content-type: text/plain', 13, 10;
|
||||||
db 'Connection: close', 13, 10
|
db 'Connection: close', 13, 10
|
||||||
db 13, 10
|
db 13, 10
|
||||||
db 'Error parsing your request message. The version is not supported or another error.'
|
|
||||||
.size = $ - http_response_err_501
|
.size = $ - http_response_err_501
|
||||||
|
|
||||||
http_response_err_404:
|
http_response_err_404:
|
||||||
@@ -122,7 +122,7 @@ response:
|
|||||||
db 'HTTP/1.0 '
|
db 'HTTP/1.0 '
|
||||||
.code = $ - response
|
.code = $ - response
|
||||||
db '000 ',13, 10
|
db '000 ',13, 10
|
||||||
db 'Server: simple-httpd/0.0.1', 13, 10 ; httpd(kolibri os)/0.0.1, 13, 10
|
db 'Server: simple-httpd/0.0.1', 13, 10
|
||||||
db 'Cache-Control: no-cache', 13, 10
|
db 'Cache-Control: no-cache', 13, 10
|
||||||
db 'Content-Encoding: '
|
db 'Content-Encoding: '
|
||||||
.content_encod = $ - response
|
.content_encod = $ - response
|
||||||
@@ -137,7 +137,7 @@ response:
|
|||||||
.content_type = $ - response
|
.content_type = $ - response
|
||||||
db ' ', 13, 10;
|
db ' ', 13, 10;
|
||||||
;'text/html; charset=utf-8'
|
;'text/html; charset=utf-8'
|
||||||
;.end_headers: ;нужно, когда базового заголовка не хватает
|
.end_headers: ;нужно, когда базового заголовка не хватает
|
||||||
.connection = $ - response
|
.connection = $ - response
|
||||||
db 'Connection: close', 13, 10
|
db 'Connection: close', 13, 10
|
||||||
db 13, 10
|
db 13, 10
|
||||||
@@ -147,43 +147,31 @@ response:
|
|||||||
; "GET / HTTP/1.1" - 18 byte
|
; "GET / HTTP/1.1" - 18 byte
|
||||||
min_http_size = 18
|
min_http_size = 18
|
||||||
|
|
||||||
|
|
||||||
MIME_TYPES:
|
|
||||||
.html: db 'text/html',0
|
|
||||||
.css: db 'text/css',0
|
|
||||||
.js: db 'text/javascript',0
|
|
||||||
.txt: db 'text/plain',0
|
|
||||||
.json: db 'application/json',0
|
|
||||||
.pdf: db 'application/pdf',0
|
|
||||||
|
|
||||||
.png: db 'image/png',0
|
|
||||||
.mp3: db 'audio/mpeg',0
|
|
||||||
.mp4: db 'video/mp4',0
|
|
||||||
.other: db 'application/octet-stream',0 ; for unknow file - all file :)
|
|
||||||
|
|
||||||
MIME_FILE_FORMAT:
|
MIME_FILE_FORMAT:
|
||||||
.html: db 5,'.html',0
|
.html: db 5,'.html', 'text/html',0
|
||||||
.css: db 4,'.css',0
|
.css: db 4,'.css', 'text/css',0
|
||||||
.js: db 3,'.js',0
|
.js: db 3,'.js', 'text/javascript',0
|
||||||
.txt: db 4,'.txt',0
|
.txt: db 4,'.txt', 'text/plain',0
|
||||||
.pdf: db 4,'.pdf',0
|
.pdf: db 4,'.pdf', 'application/pdf',0
|
||||||
.json: db 5,'.json',0
|
.json: db 5,'.json', 'application/json',0
|
||||||
|
|
||||||
.png: db 4,'.png',0
|
.png: db 4,'.png', 'image/png',0
|
||||||
.mp3: db 4,'.mp3',0
|
.mp3: db 4,'.mp3', 'audio/mpeg',0
|
||||||
.mp4: db 4,'.mp4',0
|
.mp4: db 4,'.mp4', 'video/mp4',0
|
||||||
|
.other: dd 0
|
||||||
|
db 'application/octet-stream',0 ; for unknow file - all file :)
|
||||||
|
|
||||||
STD_MIME_TYPE_ARR:
|
STD_MIME_TYPE_ARR:
|
||||||
dd MIME_FILE_FORMAT.html, MIME_TYPES.html,\
|
dd MIME_FILE_FORMAT.html, \
|
||||||
MIME_FILE_FORMAT.css, MIME_TYPES.css,\
|
MIME_FILE_FORMAT.css, \
|
||||||
MIME_FILE_FORMAT.js, MIME_TYPES.js,\
|
MIME_FILE_FORMAT.js, \
|
||||||
MIME_FILE_FORMAT.txt, MIME_TYPES.txt,\
|
MIME_FILE_FORMAT.txt, \
|
||||||
MIME_FILE_FORMAT.pdf, MIME_TYPES.pdf,\
|
MIME_FILE_FORMAT.pdf, \
|
||||||
MIME_FILE_FORMAT.json, MIME_TYPES.json,\
|
MIME_FILE_FORMAT.json, \
|
||||||
MIME_FILE_FORMAT.png, MIME_TYPES.png,\
|
MIME_FILE_FORMAT.png, \
|
||||||
MIME_FILE_FORMAT.mp3, MIME_TYPES.mp3,\
|
MIME_FILE_FORMAT.mp3, \
|
||||||
MIME_FILE_FORMAT.mp4, MIME_TYPES.mp4,\
|
MIME_FILE_FORMAT.mp4, \
|
||||||
0, MIME_TYPES.other
|
MIME_FILE_FORMAT.other ; terminate
|
||||||
|
|
||||||
_DIV_10_: dd 10
|
_DIV_10_: dd 10
|
||||||
_DIV_100_: dd 100
|
_DIV_100_: dd 100
|
||||||
|
29
parser.inc
29
parser.inc
@@ -2,6 +2,8 @@
|
|||||||
BASE_ARRAY_ARGS equ (esi - 1024)
|
BASE_ARRAY_ARGS equ (esi - 1024)
|
||||||
BASE_ARRAY_HEADERS equ (esi - 2048)
|
BASE_ARRAY_HEADERS equ (esi - 2048)
|
||||||
|
|
||||||
|
;TODO: fix checking end http packed
|
||||||
|
|
||||||
; IN:
|
; IN:
|
||||||
; esi - struct
|
; esi - struct
|
||||||
; ecx = ptr to str URI
|
; ecx = ptr to str URI
|
||||||
@@ -109,6 +111,9 @@ parse_url:
|
|||||||
cmp byte[ecx], '&'
|
cmp byte[ecx], '&'
|
||||||
jne @b
|
jne @b
|
||||||
|
|
||||||
|
mov byte[ecx], 0
|
||||||
|
inc ecx
|
||||||
|
|
||||||
jmp .get_query_new_arg
|
jmp .get_query_new_arg
|
||||||
|
|
||||||
.get_fragment:
|
.get_fragment:
|
||||||
@@ -206,7 +211,8 @@ parse_http_query:
|
|||||||
; message data
|
; message data
|
||||||
|
|
||||||
mov eax, [esi + CONNECT_DATA.request_size]
|
mov eax, [esi + CONNECT_DATA.request_size]
|
||||||
mov [esi + CONNECT_DATA.tmp_req_size], eax
|
add eax, [esi + CONNECT_DATA.buffer_request]
|
||||||
|
mov [esi + CONNECT_DATA.end_buffer_request], eax
|
||||||
|
|
||||||
; check size
|
; check size
|
||||||
cmp dword[esi + CONNECT_DATA.request_size], min_http_size
|
cmp dword[esi + CONNECT_DATA.request_size], min_http_size
|
||||||
@@ -215,6 +221,9 @@ parse_http_query:
|
|||||||
; get http METHOD this message
|
; get http METHOD this message
|
||||||
mov [esi + CONNECT_DATA.http_method], ecx
|
mov [esi + CONNECT_DATA.http_method], ecx
|
||||||
@@:
|
@@:
|
||||||
|
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||||||
|
ja .error_exit
|
||||||
|
|
||||||
inc ecx
|
inc ecx
|
||||||
cmp byte[ecx - 1], ' ' ; find end method
|
cmp byte[ecx - 1], ' ' ; find end method
|
||||||
jnz @b
|
jnz @b
|
||||||
@@ -230,17 +239,13 @@ parse_http_query:
|
|||||||
; ecx <- uri string
|
; ecx <- uri string
|
||||||
; парсинг uri строки в заголовке запроса(получение схемы, пути аргументов, фрагмента и тд)
|
; парсинг uri строки в заголовке запроса(получение схемы, пути аргументов, фрагмента и тд)
|
||||||
call parse_url
|
call parse_url
|
||||||
|
|
||||||
; check size
|
|
||||||
mov edx, ecx
|
|
||||||
sub edx, [esi + CONNECT_DATA.buffer_request]
|
|
||||||
sub edx, 7 ; H/0.0 0x0d0 x0a
|
|
||||||
cmp dword[esi + CONNECT_DATA.request_size], edx
|
|
||||||
jle .error_exit
|
|
||||||
|
|
||||||
; get http version(HTTP/1.1)
|
; get http version(HTTP/1.1)
|
||||||
mov [esi + CONNECT_DATA.http_verion], ecx
|
mov [esi + CONNECT_DATA.http_verion], ecx
|
||||||
@@:
|
@@:
|
||||||
|
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||||||
|
ja .error_exit
|
||||||
|
|
||||||
inc ecx
|
inc ecx
|
||||||
cmp word[ecx - 1], 0x0A0D
|
cmp word[ecx - 1], 0x0A0D
|
||||||
jnz @b
|
jnz @b
|
||||||
@@ -259,13 +264,11 @@ parse_http_query:
|
|||||||
|
|
||||||
|
|
||||||
; check size
|
; check size
|
||||||
mov edx, ecx
|
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||||||
sub edx, [esi + CONNECT_DATA.buffer_request]
|
je @f
|
||||||
cmp dword[esi + CONNECT_DATA.request_size], edx
|
|
||||||
jl .error_exit
|
|
||||||
|
|
||||||
mov [esi + CONNECT_DATA.message_body], ecx
|
mov [esi + CONNECT_DATA.message_body], ecx
|
||||||
; докачивается всё остальное
|
@@:
|
||||||
mov eax, esi
|
mov eax, esi
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
182
settings.inc
182
settings.inc
@@ -5,7 +5,7 @@ struct CONNECT_DATA ; 16*4 = 64 bytes
|
|||||||
sockaddr dd 16/4 ; socaddr connection
|
sockaddr dd 16/4 ; socaddr connection
|
||||||
buffer_request dd 0 ; pointer to buffer for geting message socket
|
buffer_request dd 0 ; pointer to buffer for geting message socket
|
||||||
request_size dd 0 ; size geted data from client
|
request_size dd 0 ; size geted data from client
|
||||||
tmp_req_size dd 0 ; для парсера
|
end_buffer_request dd 0 ; для парсера
|
||||||
buffer_response dd 0 ; pointer to buffwr for resp message
|
buffer_response dd 0 ; pointer to buffwr for resp message
|
||||||
http_method dd 0 ; указатель на строку
|
http_method dd 0 ; указатель на строку
|
||||||
http_verion dd 0 ; указатель на строку
|
http_verion dd 0 ; указатель на строку
|
||||||
@@ -20,6 +20,13 @@ struct CONNECT_DATA ; 16*4 = 64 bytes
|
|||||||
message_body dd 0 ; указатель на тело http запроса
|
message_body dd 0 ; указатель на тело http запроса
|
||||||
ends
|
ends
|
||||||
|
|
||||||
|
struct HTTPD_UNIT
|
||||||
|
next rd 1
|
||||||
|
prev rd 1
|
||||||
|
httpd_serv rd 1
|
||||||
|
uri_path rb 4096-3*4
|
||||||
|
ends
|
||||||
|
|
||||||
struct REQUEST_DATA
|
struct REQUEST_DATA
|
||||||
ptr_name dd 0 ;
|
ptr_name dd 0 ;
|
||||||
ptr_data dd 0 ;
|
ptr_data dd 0 ;
|
||||||
@@ -29,45 +36,162 @@ ends
|
|||||||
; ecx - path to file
|
; ecx - path to file
|
||||||
; OUT: eax - 0 or err_code
|
; OUT: eax - 0 or err_code
|
||||||
load_settings:
|
load_settings:
|
||||||
; check file path
|
mov ebp, ecx
|
||||||
;sub esp, 40 ; size file info struct
|
|
||||||
;push esp
|
sub esp, 16
|
||||||
;push ecx
|
mov esi, esp
|
||||||
;call FileInfo
|
invoke ini.get_str, ebp, ini_section_main, ini_key_ip, esi, 16, 0 ; ip
|
||||||
;lea esp, [esp + 40]
|
; xxx.xxx.xxx.xxx\n - 16 byte max
|
||||||
;test eax, eax
|
xor edx, edx
|
||||||
;jnz .err
|
xor eax, eax
|
||||||
|
mov ecx, 4 ; count '.'
|
||||||
|
@@:
|
||||||
|
add al, [esp]
|
||||||
|
sub al, '0'
|
||||||
|
inc esp
|
||||||
|
mul dword[_DIV_10_]
|
||||||
|
|
||||||
|
cmp byte[esp], '0' ; if . , space and other
|
||||||
|
jae @b
|
||||||
|
|
||||||
|
mov byte[srv_sockaddr.ip], al
|
||||||
|
ror dword[srv_sockaddr.ip], 8
|
||||||
|
add esp, 1
|
||||||
|
dec ecx
|
||||||
|
jnz @b
|
||||||
|
|
||||||
|
mov esp, esi
|
||||||
|
add esp, 16
|
||||||
|
|
||||||
|
|
||||||
; TEST SERVER
|
|
||||||
mov word[srv_sockaddr], AF_INET4
|
mov word[srv_sockaddr], AF_INET4
|
||||||
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
|
invoke ini.get_int, ebp, ini_section_main, ini_key_port, 80 ; standart port
|
||||||
|
xchg al, ah
|
||||||
|
mov [srv_sockaddr.port], ax
|
||||||
|
|
||||||
|
invoke ini.get_int, ebp, ini_section_main, ini_key_conn, 10 ; standart port
|
||||||
|
mov [srv_backlog], ax
|
||||||
|
|
||||||
|
; flags
|
||||||
|
|
||||||
|
; work_dir
|
||||||
|
invoke ini.get_str, ebp, ini_section_main, ini_key_work_dir, GLOBAL_DATA.work_dir, 1024, 0 ; ip
|
||||||
|
push edi
|
||||||
|
mov ecx, 1024
|
||||||
mov edi, GLOBAL_DATA.work_dir
|
mov edi, GLOBAL_DATA.work_dir
|
||||||
mov esi, test_workdir
|
xor eax, eax
|
||||||
mov ecx, test_workdir.size
|
repne scasb
|
||||||
rep movsb
|
dec edi
|
||||||
pop edi esi
|
sub edi, GLOBAL_DATA.work_dir
|
||||||
mov dword[GLOBAL_DATA.work_dir.size], test_workdir.size
|
mov [GLOBAL_DATA.work_dir.size], edi
|
||||||
|
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
|
||||||
|
|
||||||
|
; units_dir
|
||||||
|
invoke ini.get_str, ebp, ini_section_main, ini_key_units_dir, GLOBAL_DATA.unit_dir, 1024, 0 ; ip
|
||||||
|
push edi
|
||||||
|
mov ecx, 1024
|
||||||
|
mov edi, GLOBAL_DATA.unit_dir
|
||||||
|
xor eax, eax
|
||||||
|
repne scasb
|
||||||
|
mov byte[edi-1], '/'
|
||||||
|
mov [GLOBAL_DATA.unit_dir.end], edi
|
||||||
|
pop edi
|
||||||
|
|
||||||
|
; 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
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.add_unit: ; [esp + 4*3] - name [esp + 4*4] - value
|
||||||
|
; add new item in list
|
||||||
|
push dword sizeof.HTTPD_UNIT
|
||||||
|
call Alloc
|
||||||
|
test eax, eax
|
||||||
|
jz .add_unit.exit
|
||||||
|
|
||||||
|
mov ecx, [GLOBAL_DATA.units]
|
||||||
|
mov [eax], ecx
|
||||||
|
mov dword[eax + 4], GLOBAL_DATA.units
|
||||||
|
mov [GLOBAL_DATA.units], eax
|
||||||
|
test ecx, ecx
|
||||||
|
jnz @f
|
||||||
|
mov [ecx + 4], eax
|
||||||
|
@@:
|
||||||
|
; copy uri path
|
||||||
|
push esi edi
|
||||||
|
mov esi, [esp + 4*2 + 4*3] ; name
|
||||||
|
lea edi, [eax + 4*3 + 1]
|
||||||
|
mov byte[edi - 1], '/'
|
||||||
|
@@:
|
||||||
|
movsb
|
||||||
|
cmp byte[edi - 1], 0
|
||||||
|
jne @b
|
||||||
|
; copy file name
|
||||||
|
mov edi, [GLOBAL_DATA.unit_dir.end]
|
||||||
|
mov esi, [esp + 4*2 + 4*4]
|
||||||
|
@@:
|
||||||
|
movsb
|
||||||
|
cmp byte[edi - 1], 0
|
||||||
|
jne @b
|
||||||
|
|
||||||
|
pop edi esi
|
||||||
|
mov esi, eax
|
||||||
|
; load library
|
||||||
|
push esi
|
||||||
|
stdcall dll.Load, IMPORT_UNIT
|
||||||
|
pop esi
|
||||||
|
test eax, eax
|
||||||
|
jz @f
|
||||||
|
|
||||||
|
.add_unit.err:
|
||||||
|
; error
|
||||||
|
mov eax, [esi] ; next
|
||||||
|
mov [GLOBAL_DATA.units], eax
|
||||||
|
mov dword[eax + 4], GLOBAL_DATA.units
|
||||||
|
|
||||||
|
push esi
|
||||||
|
call Free
|
||||||
|
|
||||||
|
jmp .add_unit.exit
|
||||||
|
@@: ; good
|
||||||
|
; init httpd unit
|
||||||
|
push dword EXPORT_DATA
|
||||||
|
invoke httpd_import.init
|
||||||
|
test eax, eax
|
||||||
|
jnz .add_unit.err
|
||||||
|
|
||||||
|
mov eax, [httpd_import.serv]
|
||||||
|
mov dword[esi + 4*2], eax
|
||||||
|
|
||||||
|
mov [httpd_import.init], httpd_unit_init
|
||||||
|
mov [httpd_import.serv], httpd_unit_serv
|
||||||
|
.add_unit.exit:
|
||||||
|
ret 16
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.err:
|
.err:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
test_workdir: db '/sys'
|
;test_workdir: db '/sys'
|
||||||
.size = $ - test_workdir
|
;.size = $ - test_workdir
|
||||||
|
|
||||||
|
|
||||||
; Config format:
|
|
||||||
; Standart INI file:
|
|
||||||
; - ";" or "#" comments
|
|
||||||
; - [name] name of group
|
|
||||||
; - arg=val params in group
|
|
||||||
|
|
||||||
|
|
||||||
|
32
utils/mime_types.asm
Normal file
32
utils/mime_types.asm
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
format binary as "bin"
|
||||||
|
use32
|
||||||
|
org 0
|
||||||
|
|
||||||
|
macro table arg3, [arg1,arg2] {
|
||||||
|
local ..x,..x_end
|
||||||
|
forward
|
||||||
|
dd ..x
|
||||||
|
common
|
||||||
|
local ..other
|
||||||
|
dd ..other
|
||||||
|
; <20><><EFBFBD> size = ($ - <20><><EFBFBD><EFBFBD><EFBFBD>) / 8
|
||||||
|
forward
|
||||||
|
..x db ..x_end-..x - 1, arg1
|
||||||
|
..x_end db arg2, 0
|
||||||
|
common
|
||||||
|
..other dd 0
|
||||||
|
db arg3, 0
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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'
|
BIN
utils/mime_types.bin
Normal file
BIN
utils/mime_types.bin
Normal file
Binary file not shown.
Reference in New Issue
Block a user