files
simple-httpd/file_server.inc
Doczom 28f8ec4964 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.
2023-12-03 04:14:48 +05:00

273 lines
7.3 KiB
PHP

; Это модуль для обработки стандартных запросов на получение файла
; по пути, который не относится к другому модулю
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 eax, [esp + 4*2 + 4]
mov eax, [eax + FILED.end_path]
mov edx, [GLOBAL_DATA.MIME_types_arr]
@@:
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