mirror of
https://github.com/Doczom/simple-httpd.git
synced 2025-09-21 02:50:09 +02:00
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.
273 lines
7.3 KiB
PHP
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 |