mirror of
https://github.com/Doczom/simple-httpd.git
synced 2025-09-21 02:50:09 +02:00
Added file server
Added file server for no units URI paths. Fixed a lot of bugs in parser and mainloop. Added function Get_MIME_Type
This commit is contained in:
278
file_server.inc
Normal file
278
file_server.inc
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
; Это модуль для обработки стандартных запросов на получение файла
|
||||||
|
; по пути, который не относится к другому модулю
|
||||||
|
|
||||||
|
|
||||||
|
file_server:
|
||||||
|
|
||||||
|
; check http version (skip RTSP)
|
||||||
|
mov ecx, [esi + CONNECT_DATA.http_verion]
|
||||||
|
cmp dword[ecx], 'HTTP'
|
||||||
|
jne .err_http_501
|
||||||
|
cmp word[ecx + 4], '/1'
|
||||||
|
jne .err_http_501
|
||||||
|
|
||||||
|
; cmp byte[ecx + 7], '1'
|
||||||
|
; je .http_1_1
|
||||||
|
; ; http 1.0;
|
||||||
|
;
|
||||||
|
;.http_1_1:
|
||||||
|
|
||||||
|
; check name on ../../ and other bad items
|
||||||
|
mov ecx, [esi + CONNECT_DATA.uri_path]
|
||||||
|
@@:
|
||||||
|
cmp byte[ecx], 0
|
||||||
|
je .good_name
|
||||||
|
inc ecx
|
||||||
|
cmp dword[ecx - 1], '/../' ; if path "/.." then system read dir and
|
||||||
|
jne @b ; and skip this path with 404 error
|
||||||
|
jmp .err_http_501
|
||||||
|
|
||||||
|
.good_name:
|
||||||
|
|
||||||
|
; check file of name (generate full name: work_dir + path)
|
||||||
|
;
|
||||||
|
; alloc 4 kib for path to file name
|
||||||
|
; memory alloced on stack and for working program alloced with buffer
|
||||||
|
; for code stack
|
||||||
|
lea edx, [esp - 6*1024 - 4096] ; edx <- buffer for full path
|
||||||
|
|
||||||
|
mov edi, edx
|
||||||
|
sub edi, sizeof.FILED; edi <- struct FILED
|
||||||
|
mov [edi + FILED.path], edx
|
||||||
|
|
||||||
|
mov eax, esi
|
||||||
|
push esi edi
|
||||||
|
;; copy work_dir
|
||||||
|
mov esi, GLOBAL_DATA.work_dir
|
||||||
|
mov edi, edx
|
||||||
|
mov ecx, [GLOBAL_DATA.work_dir.size]
|
||||||
|
rep movsb
|
||||||
|
;; copy path
|
||||||
|
mov esi, [eax + CONNECT_DATA.uri_path]
|
||||||
|
@@:
|
||||||
|
movsb
|
||||||
|
cmp byte[esi - 1], 0
|
||||||
|
jne @b
|
||||||
|
|
||||||
|
mov eax, edi
|
||||||
|
dec eax
|
||||||
|
pop edi esi
|
||||||
|
mov [edi + FILED.end_path], eax
|
||||||
|
|
||||||
|
;; check file info (skip of directory and if syscall return error)
|
||||||
|
lea eax, [edi - 40] ; buffer for file info
|
||||||
|
mov [edi + FILED.buffer], eax
|
||||||
|
|
||||||
|
push edi
|
||||||
|
call FileInfo
|
||||||
|
test eax, eax
|
||||||
|
jnz .err_not_found
|
||||||
|
|
||||||
|
test dword[edi - 40], 11000b ; check dir OR disk partition
|
||||||
|
jnz .err_not_found
|
||||||
|
|
||||||
|
|
||||||
|
; check method OPTIONS
|
||||||
|
mov ecx, [esi + CONNECT_DATA.http_method]
|
||||||
|
cmp dword[ecx], 'OPTI'
|
||||||
|
jne @f
|
||||||
|
cmp dword[ecx + 4], 'ONS'
|
||||||
|
je .send_options
|
||||||
|
@@:
|
||||||
|
cmp dword[ecx], 'POST'
|
||||||
|
jne @f
|
||||||
|
cmp byte[ecx + 4], 0
|
||||||
|
je .send_file
|
||||||
|
@@:
|
||||||
|
cmp dword[ecx], 'GET'
|
||||||
|
jne .err_http_501
|
||||||
|
|
||||||
|
.send_file:
|
||||||
|
; create http response (set 200 code, MINE type and length of body)
|
||||||
|
;; alloc 33 kib
|
||||||
|
push dword 33*1024
|
||||||
|
call Alloc
|
||||||
|
test eax, eax
|
||||||
|
jz .err_http_501 ; error memory
|
||||||
|
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push eax ; save pointer for Free
|
||||||
|
|
||||||
|
mov esi, base_response
|
||||||
|
mov ecx, response.body
|
||||||
|
mov edi, [esp]
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
mov edi, [esp]
|
||||||
|
mov dword[edi + response.code], '200 '
|
||||||
|
|
||||||
|
push dword[esp + 4] ; <-FILED
|
||||||
|
call Get_MIME_Type
|
||||||
|
|
||||||
|
add edi, response.content_type
|
||||||
|
mov esi, eax
|
||||||
|
@@:
|
||||||
|
movsb
|
||||||
|
cmp byte[esi], 0
|
||||||
|
jne @b
|
||||||
|
|
||||||
|
|
||||||
|
pop edi ; buffer on 32 kib
|
||||||
|
pop ebx ; FD
|
||||||
|
pop esi ; CONNECT_DATA
|
||||||
|
|
||||||
|
; copy length
|
||||||
|
mov edx, [ebx - 40 + 36]
|
||||||
|
mov eax, [ebx - 40 + 32]
|
||||||
|
lea ecx, [edi + response.content_len + 21]
|
||||||
|
test eax, eax
|
||||||
|
jne @f
|
||||||
|
test edx, edx
|
||||||
|
jz .err_not_found_1
|
||||||
|
@@:
|
||||||
|
cmp edx, 1000 ; 999*4 - max length of file
|
||||||
|
jae .err_not_found_1
|
||||||
|
; edx:eax ecx - end char in string '000000'
|
||||||
|
.div1000:
|
||||||
|
div dword[_DIV_1000_]
|
||||||
|
push eax
|
||||||
|
|
||||||
|
mov eax, edx
|
||||||
|
xor edx, edx
|
||||||
|
;.div100:
|
||||||
|
div dword[_DIV_100_]
|
||||||
|
push eax
|
||||||
|
|
||||||
|
mov eax, edx
|
||||||
|
xor edx, edx
|
||||||
|
div dword[_DIV_10_]
|
||||||
|
add byte[ecx], dl
|
||||||
|
add byte[ecx - 1], al
|
||||||
|
sub ecx, 3
|
||||||
|
|
||||||
|
pop eax
|
||||||
|
add byte[ecx + 1], al
|
||||||
|
;xor edx, edx
|
||||||
|
;test eax, eax
|
||||||
|
;jne .div100
|
||||||
|
pop eax
|
||||||
|
xor edx, edx
|
||||||
|
test eax, eax
|
||||||
|
jne .div1000
|
||||||
|
|
||||||
|
;send_response_header
|
||||||
|
push dword 0 ; flags
|
||||||
|
push response.body
|
||||||
|
push edi
|
||||||
|
push dword[esi + CONNECT_DATA.socket]
|
||||||
|
call netfunc_send
|
||||||
|
cmp eax, -1
|
||||||
|
je .exit_free
|
||||||
|
|
||||||
|
mov dword[ebx + FILED.offset], 0
|
||||||
|
mov dword[ebx + FILED.offset + 4], 0
|
||||||
|
mov [ebx + FILED.buffer], edi
|
||||||
|
mov [ebx + FILED.size], 32*1024
|
||||||
|
.send_response_body:
|
||||||
|
; read 32 kib to file
|
||||||
|
push ebx
|
||||||
|
call FileRead
|
||||||
|
test eax, eax
|
||||||
|
jz @f
|
||||||
|
cmp eax, 6
|
||||||
|
jne .exit_free
|
||||||
|
@@:
|
||||||
|
; send this block data
|
||||||
|
push dword 0 ; flags
|
||||||
|
push 32*1024
|
||||||
|
push edi
|
||||||
|
push dword[esi + CONNECT_DATA.socket]
|
||||||
|
call netfunc_send
|
||||||
|
cmp eax, -1
|
||||||
|
je .exit_free
|
||||||
|
|
||||||
|
; check end file
|
||||||
|
mov ecx, [ebx + FILED.offset + 4]
|
||||||
|
cmp [ebx - 4], ecx
|
||||||
|
ja .add_offset
|
||||||
|
|
||||||
|
mov edx, [ebx + FILED.offset]
|
||||||
|
cmp [ebx - 8], edx
|
||||||
|
jbe .exit_free
|
||||||
|
|
||||||
|
.add_offset:
|
||||||
|
add [ebx + FILED.offset], 32*1024
|
||||||
|
adc [ebx + FILED.offset + 4], 0
|
||||||
|
|
||||||
|
jmp @b
|
||||||
|
|
||||||
|
.exit_free:
|
||||||
|
push edi
|
||||||
|
call Free
|
||||||
|
ret
|
||||||
|
|
||||||
|
.send_options:
|
||||||
|
; send standart options of file server
|
||||||
|
push dword 0 ; flags
|
||||||
|
push http_response_options.size
|
||||||
|
push http_response_options
|
||||||
|
push dword[esi + CONNECT_DATA.socket]
|
||||||
|
call netfunc_send
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.err_not_found_1:
|
||||||
|
push edi
|
||||||
|
call Free
|
||||||
|
.err_not_found:
|
||||||
|
; send error 404
|
||||||
|
push dword 0 ; flags
|
||||||
|
push http_response_err_404.size
|
||||||
|
push http_response_err_404
|
||||||
|
push dword[esi + CONNECT_DATA.socket]
|
||||||
|
call netfunc_send
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.err_http_501:
|
||||||
|
; send error 501
|
||||||
|
push dword 0 ; flags
|
||||||
|
push http_response_err_501.size
|
||||||
|
push http_response_err_501
|
||||||
|
push dword[esi + CONNECT_DATA.socket]
|
||||||
|
call netfunc_send
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; char* stdcall Get_MIME_Type(FILED* fd); //path is ASCIIZ string
|
||||||
|
Get_MIME_Type:
|
||||||
|
push esi edi
|
||||||
|
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
|
||||||
|
ret 4
|
72
httpd.asm
72
httpd.asm
@@ -7,15 +7,20 @@
|
|||||||
; Version 0.0.1, 12 November 2023 ;
|
; Version 0.0.1, 12 November 2023 ;
|
||||||
; ;
|
; ;
|
||||||
;*****************************************************************************;
|
;*****************************************************************************;
|
||||||
|
;include "macros.inc"
|
||||||
|
include 'D:\kos\programs\macros.inc'
|
||||||
|
;include 'D:\kos\programs\network.inc'
|
||||||
use32
|
use32
|
||||||
org 0
|
org 0
|
||||||
|
db 'MENUET01'
|
||||||
|
dd 1, START, I_END, MEM, STACKTOP, PATH, 0
|
||||||
|
;KOS_APP_START
|
||||||
|
|
||||||
include 'sys_func.inc'
|
include 'sys_func.inc'
|
||||||
include 'settings.inc'
|
include 'settings.inc'
|
||||||
|
|
||||||
|
;CODE
|
||||||
start:
|
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
|
||||||
|
|
||||||
@@ -30,7 +35,7 @@ start:
|
|||||||
jnz .err_settings
|
jnz .err_settings
|
||||||
|
|
||||||
;init server socket
|
;init server socket
|
||||||
push dword SO_NONBLOCK
|
push dword SO_NONBLOCK ; IPPROTO_TCP
|
||||||
push dword SOCK_STREAM
|
push dword SOCK_STREAM
|
||||||
push dword AF_INET4
|
push dword AF_INET4
|
||||||
call netfunc_socket; AF_INET4, SOCK_STREAM, SO_NONBLOCK ; we dont want to block on accept
|
call netfunc_socket; AF_INET4, SOCK_STREAM, SO_NONBLOCK ; we dont want to block on accept
|
||||||
@@ -64,9 +69,9 @@ start:
|
|||||||
.listen_err:
|
.listen_err:
|
||||||
.bind_err:
|
.bind_err:
|
||||||
push dword[srv_socket]
|
push dword[srv_socket]
|
||||||
call close; [srv_socket]
|
call netfunc_close; [srv_socket]
|
||||||
|
|
||||||
..err_settings:
|
.err_settings:
|
||||||
.sock_err:
|
.sock_err:
|
||||||
mcall -1
|
mcall -1
|
||||||
|
|
||||||
@@ -77,9 +82,12 @@ thread_connect:
|
|||||||
mcall 40, EVM_STACK ; set event bitmap - network event
|
mcall 40, EVM_STACK ; set event bitmap - network event
|
||||||
|
|
||||||
; ожидание подключения Accept, sockaddr находится на вершине стека нового потока
|
; ожидание подключения Accept, sockaddr находится на вершине стека нового потока
|
||||||
lea edx, [esp + CONNECT_DATA.sockaddr] ; new sockaddr
|
;lea edx, [esp + CONNECT_DATA.sockaddr] ; new sockaddr
|
||||||
push dword 16 ; 16 byte - sockaddr length
|
;push dword 16 ; 16 byte - sockaddr length
|
||||||
push edx
|
;push edx
|
||||||
|
push srv_sockaddr.length
|
||||||
|
push dword srv_sockaddr
|
||||||
|
|
||||||
push dword[srv_socket]
|
push dword[srv_socket]
|
||||||
call netfunc_accept
|
call netfunc_accept
|
||||||
|
|
||||||
@@ -119,8 +127,8 @@ thread_connect:
|
|||||||
test eax, eax
|
test eax, eax
|
||||||
jz @f
|
jz @f
|
||||||
add [esi + CONNECT_DATA.request_size], eax
|
add [esi + CONNECT_DATA.request_size], eax
|
||||||
cmp [esi + CONNECT_DATA.request_size], 0x8000 ; check end buffer
|
; cmp [esi + CONNECT_DATA.request_size], 0x8000 ; check end buffer
|
||||||
jb @b
|
; jb @b
|
||||||
@@:
|
@@:
|
||||||
; после получения всего запроса(более или менее всего) выделяем озу для
|
; после получения всего запроса(более или менее всего) выделяем озу для
|
||||||
; ассоциативного массива заголовков и аргументов запроса
|
; ассоциативного массива заголовков и аргументов запроса
|
||||||
@@ -130,20 +138,25 @@ thread_connect:
|
|||||||
sub esp, 2048
|
sub esp, 2048
|
||||||
|
|
||||||
; parse http message
|
; parse http message
|
||||||
call parse_http_query ; ecx - buffer edx - length data in buffer
|
mov ecx, [esi + CONNECT_DATA.buffer_request]
|
||||||
|
call parse_http_query ; ecx - buffer
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err_parse
|
jz .err_parse
|
||||||
; вызов нужной функции из списка моделей
|
; вызов нужной функции из списка моделей
|
||||||
|
|
||||||
; TODO
|
; TODO
|
||||||
|
|
||||||
|
|
||||||
|
; if not found units, call file_server
|
||||||
|
call file_server ; esi - struct
|
||||||
|
;TEST SERVER, DELETE ON RELISE
|
||||||
|
|
||||||
; end work thread
|
; end work thread
|
||||||
jmp .end_work
|
jmp .end_work
|
||||||
|
|
||||||
|
|
||||||
.err_parse:
|
.err_parse:
|
||||||
; send error 501
|
call file_server.err_http_501
|
||||||
|
|
||||||
.end_work:
|
.end_work:
|
||||||
add esp, 2048
|
add esp, 2048
|
||||||
; free OUT buffer
|
; free OUT buffer
|
||||||
@@ -167,14 +180,21 @@ thread_connect:
|
|||||||
|
|
||||||
include 'parser.inc'
|
include 'parser.inc'
|
||||||
|
|
||||||
|
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:
|
||||||
;DATA
|
;DATA
|
||||||
|
|
||||||
srv_backlog: dd 0 ; максимум одновременных подключений подключений
|
; DATA
|
||||||
|
|
||||||
srv_socket: dd 0
|
;UDATA
|
||||||
|
|
||||||
|
srv_backlog: rd 1 ; максимум одновременных подключений подключений
|
||||||
|
|
||||||
|
srv_socket: rd 1
|
||||||
|
|
||||||
srv_sockaddr:
|
srv_sockaddr:
|
||||||
dw AF_INET4
|
dw AF_INET4
|
||||||
@@ -184,9 +204,21 @@ srv_sockaddr:
|
|||||||
.length = $ - srv_sockaddr
|
.length = $ - srv_sockaddr
|
||||||
|
|
||||||
GLOBAL_DATA:
|
GLOBAL_DATA:
|
||||||
.units dd 0 ; указатель на ассоциативный массив пути и указателя на функцию либы(см ниж)
|
.units rd 1 ; указатель на ассоциативный массив пути и указателя на функцию либы(см ниж)
|
||||||
.unit_count dd 0 ; количество записей в массиве
|
.unit_count rd 1 ; количество записей в массиве
|
||||||
.libs dd 0 ; указатель на массив указателей на ассоциативные массивы библиотек
|
.libs rd 1 ; указатель на массив указателей на ассоциативные массивы библиотек
|
||||||
|
.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
|
||||||
|
|
||||||
|
.MIME_types_arr rd 1
|
||||||
;; .flags dd 0 ; 1 - all hosts(элемент hosts не указатель на массив, а на функцию)
|
;; .flags dd 0 ; 1 - all hosts(элемент hosts не указатель на массив, а на функцию)
|
||||||
|
|
||||||
|
PATH:
|
||||||
|
rb 256
|
||||||
|
; stack memory
|
||||||
|
rb 4096
|
||||||
|
STACKTOP:
|
||||||
|
MEM:
|
||||||
|
;KOS_APP_END
|
||||||
|
103
httpd_lib.inc
103
httpd_lib.inc
@@ -83,27 +83,108 @@ http_err_response:
|
|||||||
db 13, 10
|
db 13, 10
|
||||||
.size = $ - http_err_response
|
.size = $ - http_err_response
|
||||||
|
|
||||||
|
http_response_err_501:
|
||||||
|
db 'HTTP/1.1 '
|
||||||
|
db '501 ',13, 10
|
||||||
|
db 'Server: simple-httpd/0.0.1', 13, 10
|
||||||
|
db 'Content-length: 91', 13, 10
|
||||||
|
db 'Content-type: text/plain', 13, 10;
|
||||||
|
db 'Connection: close', 13, 10
|
||||||
|
db 13, 10
|
||||||
|
db 'Error parsing your request message. The version is not supported or another error.'
|
||||||
|
.size = $ - http_response_err_501
|
||||||
|
|
||||||
|
http_response_err_404:
|
||||||
|
db 'HTTP/1.1 '
|
||||||
|
db '404 ',13, 10
|
||||||
|
db 'Server: simple-httpd/0.0.1', 13, 10
|
||||||
|
db 'Content-length: 45', 13, 10
|
||||||
|
db 'Content-type: text/plain', 13, 10;
|
||||||
|
db 'Connection: close', 13, 10
|
||||||
|
db 13, 10
|
||||||
|
db 'The server could not find the requested page.'
|
||||||
|
.size = $ - http_response_err_404
|
||||||
|
|
||||||
|
http_response_options:
|
||||||
|
db 'HTTP/1.1 '
|
||||||
|
db '204 ',13, 10
|
||||||
|
db 'Server: simple-httpd/0.0.1', 13, 10
|
||||||
|
db 'Allow: OPTIONS, GET, POST', 13, 10
|
||||||
|
db 'Connection: close', 13, 10
|
||||||
|
db 13, 10
|
||||||
|
.size = $ - http_response_options
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
base_response:
|
base_response:
|
||||||
label response at 0
|
response:
|
||||||
db 'HTTP/1.0 '
|
db 'HTTP/1.0 '
|
||||||
.code: db '000 ',13, 10
|
.code = $ - response
|
||||||
db 'Server: httpd(kolibri os)/0.0.1', 13, 10
|
db '000 ',13, 10
|
||||||
|
db 'Server: simple-httpd/0.0.1', 13, 10 ; httpd(kolibri os)/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: db 'identity', 13, 10
|
.content_encod = $ - response
|
||||||
db 'Date: '
|
db 'identity', 13, 10
|
||||||
.date: db 'Sun, 30 Oct 2022 09:29:13 GMT',13, 10
|
; db 'Date: '
|
||||||
|
;.date: db 'Sun, 30 Oct 2022 09:29:13 GMT',13, 10
|
||||||
db 'Content-length: '
|
db 'Content-length: '
|
||||||
.content_len: db ' ', 13, 10
|
;.content_len: db ' ', 13, 10
|
||||||
|
.content_len = $ - response
|
||||||
|
db '0000000000000000000000', 13, 10
|
||||||
db 'Content-type: '
|
db 'Content-type: '
|
||||||
.content_type: db ' ', 13, 10;
|
.content_type = $ - response
|
||||||
|
db ' ', 13, 10;
|
||||||
;'text/html; charset=utf-8'
|
;'text/html; charset=utf-8'
|
||||||
.end_headers: ;нужно, когда базового заголовка не хватает
|
;.end_headers: ;нужно, когда базового заголовка не хватает
|
||||||
.connection db 'Connection: close', 13, 10
|
.connection = $ - response
|
||||||
|
db 'Connection: close', 13, 10
|
||||||
db 13, 10
|
db 13, 10
|
||||||
.body: ; с этого оффсета уже писать данные
|
.body = $ - response ; с этого оффсета уже писать данные
|
||||||
|
|
||||||
; min HTTP request size
|
; min HTTP request size
|
||||||
; "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:
|
||||||
|
.html: db 5,'.html',0
|
||||||
|
.css: db 4,'.css',0
|
||||||
|
.js: db 3,'.js',0
|
||||||
|
.txt: db 4,'.txt',0
|
||||||
|
.pdf: db 4,'.pdf',0
|
||||||
|
.json: db 5,'.json',0
|
||||||
|
|
||||||
|
.png: db 4,'.png',0
|
||||||
|
.mp3: db 4,'.mp3',0
|
||||||
|
.mp4: db 4,'.mp4',0
|
||||||
|
|
||||||
|
STD_MIME_TYPE_ARR:
|
||||||
|
dd MIME_FILE_FORMAT.html, MIME_TYPES.html,\
|
||||||
|
MIME_FILE_FORMAT.css, MIME_TYPES.css,\
|
||||||
|
MIME_FILE_FORMAT.js, MIME_TYPES.js,\
|
||||||
|
MIME_FILE_FORMAT.txt, MIME_TYPES.txt,\
|
||||||
|
MIME_FILE_FORMAT.pdf, MIME_TYPES.pdf,\
|
||||||
|
MIME_FILE_FORMAT.json, MIME_TYPES.json,\
|
||||||
|
MIME_FILE_FORMAT.png, MIME_TYPES.png,\
|
||||||
|
MIME_FILE_FORMAT.mp3, MIME_TYPES.mp3,\
|
||||||
|
MIME_FILE_FORMAT.mp4, MIME_TYPES.mp4,\
|
||||||
|
0, MIME_TYPES.other
|
||||||
|
|
||||||
|
_DIV_10_: dd 10
|
||||||
|
_DIV_100_: dd 100
|
||||||
|
_DIV_1000_: dd 1000
|
||||||
|
30
parser.inc
30
parser.inc
@@ -58,7 +58,7 @@ parse_url:
|
|||||||
je .get_query
|
je .get_query
|
||||||
|
|
||||||
cmp byte[ecx], '#'
|
cmp byte[ecx], '#'
|
||||||
je get_fragment
|
je .get_fragment
|
||||||
|
|
||||||
cmp byte[ecx], ' ' ; check end path
|
cmp byte[ecx], ' ' ; check end path
|
||||||
jne @b
|
jne @b
|
||||||
@@ -106,7 +106,7 @@ parse_url:
|
|||||||
cmp byte[ecx], ' '
|
cmp byte[ecx], ' '
|
||||||
je .exit_2
|
je .exit_2
|
||||||
|
|
||||||
cmp byte[ecx] '&'
|
cmp byte[ecx], '&'
|
||||||
jne @b
|
jne @b
|
||||||
|
|
||||||
jmp .get_query_new_arg
|
jmp .get_query_new_arg
|
||||||
@@ -122,7 +122,7 @@ parse_url:
|
|||||||
inc ecx
|
inc ecx
|
||||||
cmp byte[ecx - 1], ' '
|
cmp byte[ecx - 1], ' '
|
||||||
jne @b
|
jne @b
|
||||||
mov [ecx - 1], 0
|
mov byte[ecx - 1], 0
|
||||||
.exit:
|
.exit:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@@ -138,17 +138,31 @@ parse_url:
|
|||||||
parse_headers:
|
parse_headers:
|
||||||
; init array
|
; init array
|
||||||
mov [esi + CONNECT_DATA.num_headers], 0
|
mov [esi + CONNECT_DATA.num_headers], 0
|
||||||
mov [esi + CONNECT_DATA.http_headers], BASE_ARRAY_HEADERS
|
lea eax, [BASE_ARRAY_HEADERS]
|
||||||
|
mov [esi + CONNECT_DATA.http_headers], eax
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
|
|
||||||
|
; for check size
|
||||||
|
mov eax, [esi + CONNECT_DATA.request_size]
|
||||||
|
add eax, [esi + CONNECT_DATA.buffer_request]
|
||||||
|
|
||||||
.new_str:
|
.new_str:
|
||||||
|
cmp ecx, eax
|
||||||
|
jae .exit
|
||||||
|
|
||||||
cmp word[ecx], 0x0A0D ; \n
|
cmp word[ecx], 0x0A0D ; \n
|
||||||
jnz .find_header
|
jnz .find_header
|
||||||
|
.exit:
|
||||||
; end find heeaders
|
; end find heeaders
|
||||||
|
mov byte[ecx], 0
|
||||||
add ecx, 2 ; ecx = base for body message
|
add ecx, 2 ; ecx = base for body message
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.find_header:
|
.find_header:
|
||||||
; add new item in array headers
|
; add new item in array headers
|
||||||
|
cmp edx, 512 ; max count headers
|
||||||
|
jae .exit
|
||||||
|
|
||||||
inc edx
|
inc edx
|
||||||
mov dword[esi + CONNECT_DATA.num_headers], edx
|
mov dword[esi + CONNECT_DATA.num_headers], edx
|
||||||
; save pointer to name header
|
; save pointer to name header
|
||||||
@@ -157,6 +171,9 @@ parse_headers:
|
|||||||
@@:
|
@@:
|
||||||
inc ecx
|
inc ecx
|
||||||
|
|
||||||
|
cmp ecx, eax
|
||||||
|
jae .exit
|
||||||
|
|
||||||
cmp byte[ecx], ':'
|
cmp byte[ecx], ':'
|
||||||
jnz @b
|
jnz @b
|
||||||
|
|
||||||
@@ -165,8 +182,11 @@ parse_headers:
|
|||||||
; save pointer to value
|
; save pointer to value
|
||||||
mov dword[BASE_ARRAY_HEADERS + (edx-1)*8 + 4], ecx
|
mov dword[BASE_ARRAY_HEADERS + (edx-1)*8 + 4], ecx
|
||||||
@@:
|
@@:
|
||||||
|
cmp ecx, eax
|
||||||
|
jae .exit
|
||||||
|
|
||||||
inc ecx
|
inc ecx
|
||||||
cmp byte[ecx - 1], 0x0A0D
|
cmp word[ecx - 1], 0x0A0D
|
||||||
jnz @b
|
jnz @b
|
||||||
mov byte[ecx - 1], 0
|
mov byte[ecx - 1], 0
|
||||||
inc ecx ; set offset on new string
|
inc ecx ; set offset on new string
|
||||||
|
36
settings.inc
36
settings.inc
@@ -30,18 +30,40 @@ ends
|
|||||||
; OUT: eax - 0 or err_code
|
; OUT: eax - 0 or err_code
|
||||||
load_settings:
|
load_settings:
|
||||||
; check file path
|
; check file path
|
||||||
sub esp, 40 ; size file info struct
|
;sub esp, 40 ; size file info struct
|
||||||
push esp
|
;push esp
|
||||||
push ecx
|
;push ecx
|
||||||
call FileInfo
|
;call FileInfo
|
||||||
lea esp, [esp + 40]
|
;lea esp, [esp + 40]
|
||||||
test eax, eax
|
;test eax, eax
|
||||||
jnz .err
|
;jnz .err
|
||||||
|
|
||||||
|
; TEST SERVER
|
||||||
|
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
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
mov dword[GLOBAL_DATA.MIME_types_arr], STD_MIME_TYPE_ARR
|
||||||
|
|
||||||
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
.err:
|
.err:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
test_workdir: db '/sys'
|
||||||
|
.size = $ - test_workdir
|
||||||
|
|
||||||
|
|
||||||
; Config format:
|
; Config format:
|
||||||
; Standart INI file:
|
; Standart INI file:
|
||||||
; - ";" or "#" comments
|
; - ";" or "#" comments
|
||||||
|
141
sys_func.inc
141
sys_func.inc
@@ -1,5 +1,112 @@
|
|||||||
; ABSTRACT SYSTEM FUNCTIONS
|
; ABSTRACT SYSTEM FUNCTIONS
|
||||||
|
|
||||||
|
;======== inclede network.inc ========
|
||||||
|
; Socket types
|
||||||
|
SOCK_STREAM = 1
|
||||||
|
SOCK_DGRAM = 2
|
||||||
|
SOCK_RAW = 3
|
||||||
|
|
||||||
|
; IP protocols
|
||||||
|
IPPROTO_IP = 0
|
||||||
|
IPPROTO_ICMP = 1
|
||||||
|
IPPROTO_TCP = 6
|
||||||
|
IPPROTO_UDP = 17
|
||||||
|
IPPROTO_RAW = 255
|
||||||
|
|
||||||
|
; IP options
|
||||||
|
IP_TTL = 2
|
||||||
|
|
||||||
|
; Address families
|
||||||
|
AF_UNSPEC = 0
|
||||||
|
AF_LOCAL = 1
|
||||||
|
AF_INET4 = 2 ; IPv4
|
||||||
|
AF_INET6 = 10 ; IPv6
|
||||||
|
|
||||||
|
PF_UNSPEC = AF_UNSPEC
|
||||||
|
PF_LOCAL = AF_LOCAL
|
||||||
|
PF_INET4 = AF_INET4
|
||||||
|
PF_INET6 = AF_INET6
|
||||||
|
|
||||||
|
; Flags for addrinfo
|
||||||
|
AI_PASSIVE = 1
|
||||||
|
AI_CANONNAME = 2
|
||||||
|
AI_NUMERICHOST = 4
|
||||||
|
AI_NUMERICSERV = 8
|
||||||
|
AI_ADDRCONFIG = 0x400
|
||||||
|
|
||||||
|
; internal definition
|
||||||
|
AI_SUPPORTED = 0x40F
|
||||||
|
|
||||||
|
; for system function 76
|
||||||
|
API_ETH = 0 shl 16
|
||||||
|
API_IPv4 = 1 shl 16
|
||||||
|
API_ICMP = 2 shl 16
|
||||||
|
API_UDP = 3 shl 16
|
||||||
|
API_TCP = 4 shl 16
|
||||||
|
API_ARP = 5 shl 16
|
||||||
|
API_PPPOE = 6 shl 16
|
||||||
|
|
||||||
|
; Socket flags for user calls
|
||||||
|
MSG_PEEK = 0x02
|
||||||
|
MSG_DONTWAIT = 0x40
|
||||||
|
|
||||||
|
; Socket levels
|
||||||
|
SOL_SOCKET = 0xffff
|
||||||
|
|
||||||
|
; Socket options
|
||||||
|
SO_BINDTODEVICE = 1 shl 9
|
||||||
|
SO_NONBLOCK = 1 shl 31
|
||||||
|
|
||||||
|
struct sockaddr_in
|
||||||
|
sin_family dw ? ; sa_family_t
|
||||||
|
sin_port dw ? ; in_port_t
|
||||||
|
sin_addr dd ? ; struct in_addr
|
||||||
|
sin_zero rb 8 ; zero
|
||||||
|
ends
|
||||||
|
|
||||||
|
struct addrinfo
|
||||||
|
ai_flags dd ? ; bitmask of AI_*
|
||||||
|
ai_family dd ? ; PF_*
|
||||||
|
ai_socktype dd ? ; SOCK_*
|
||||||
|
ai_protocol dd ? ; 0 or IPPROTO_*
|
||||||
|
ai_addrlen dd ? ; length of ai_addr
|
||||||
|
ai_canonname dd ? ; char*
|
||||||
|
ai_addr dd ? ; struct sockaddr*
|
||||||
|
ai_next dd ? ; struct addrinfo*
|
||||||
|
ends
|
||||||
|
|
||||||
|
EAI_ADDRFAMILY = 1
|
||||||
|
EAI_AGAIN = 2
|
||||||
|
EAI_BADFLAGS = 3
|
||||||
|
EAI_FAIL = 4
|
||||||
|
EAI_FAMILY = 5
|
||||||
|
EAI_MEMORY = 6
|
||||||
|
EAI_NONAME = 8
|
||||||
|
EAI_SERVICE = 9
|
||||||
|
EAI_SOCKTYPE = 10
|
||||||
|
EAI_BADHINTS = 12
|
||||||
|
EAI_PROTOCOL = 13
|
||||||
|
EAI_OVERFLOW = 14
|
||||||
|
|
||||||
|
; Socket error codes
|
||||||
|
; Error Codes
|
||||||
|
ENOBUFS = 1
|
||||||
|
EINPROGRESS = 2
|
||||||
|
EOPNOTSUPP = 4
|
||||||
|
EWOULDBLOCK = 6
|
||||||
|
ENOTCONN = 9
|
||||||
|
EALREADY = 10
|
||||||
|
EINVAL = 11
|
||||||
|
EMSGSIZE = 12
|
||||||
|
ENOMEM = 18
|
||||||
|
EADDRINUSE = 20
|
||||||
|
ECONNREFUSED = 61
|
||||||
|
ECONNRESET = 52
|
||||||
|
EISCONN = 56
|
||||||
|
ETIMEDOUT = 60
|
||||||
|
ECONNABORTED = 53
|
||||||
|
;======== End include========
|
||||||
|
|
||||||
; stdcall socket(uint32_t domain, type, proto)
|
; stdcall socket(uint32_t domain, type, proto)
|
||||||
netfunc_socket:
|
netfunc_socket:
|
||||||
push ebx esi
|
push ebx esi
|
||||||
@@ -11,7 +118,7 @@ netfunc_socket:
|
|||||||
;stdcall close(uint32_t sock_number);
|
;stdcall close(uint32_t sock_number);
|
||||||
netfunc_close:
|
netfunc_close:
|
||||||
push ebx
|
push ebx
|
||||||
call 75, 1, [esp + 4 + 4]
|
mcall 75, 1, [esp + 4 + 4]
|
||||||
pop ebx
|
pop ebx
|
||||||
ret 4
|
ret 4
|
||||||
|
|
||||||
@@ -80,11 +187,31 @@ Free:
|
|||||||
pop ebx
|
pop ebx
|
||||||
ret 4
|
ret 4
|
||||||
|
|
||||||
;NTSTATUS stdcall FileInfo(const char* path, void* buff)
|
|
||||||
|
struct FILED
|
||||||
|
opcode rd 1
|
||||||
|
offset rd 2
|
||||||
|
size rd 1
|
||||||
|
buffer rd 1
|
||||||
|
rb 1
|
||||||
|
path rd 1
|
||||||
|
end_path rd 1
|
||||||
|
ends
|
||||||
|
|
||||||
|
;NTSTATUS stdcall FileInfo(FILED* file)
|
||||||
FileInfo:
|
FileInfo:
|
||||||
|
push ebx
|
||||||
ret 8
|
mov ebx, [esp + 4*1 + 4]
|
||||||
;NTSATTUS stdcall FileRead(const char* path, void* buff, uint32_t size)
|
mov dword[ebx], 5 ; file info
|
||||||
|
mov dword[ebx + FILED.offset + 4], 0 ; zero flag
|
||||||
|
mcall 70
|
||||||
|
pop ebx
|
||||||
|
ret 4
|
||||||
|
;NTSATTUS stdcall FileRead(FILED* file)
|
||||||
FileRead:
|
FileRead:
|
||||||
|
push ebx
|
||||||
ret 12
|
mov ebx, [esp + 4*1 + 4]
|
||||||
|
mov dword[ebx], 0 ; read file
|
||||||
|
mcall 70
|
||||||
|
pop ebx
|
||||||
|
ret 4
|
Reference in New Issue
Block a user