mirror of
https://github.com/Doczom/simple-httpd.git
synced 2025-09-21 02:50:09 +02:00
Added basic files: - httpd.asm - main loop server, include other files; - httpd_lib - file for data(constants, response string, headers etc.); - parser.inc - function for generation structure of HTTP request; - settings.inc - description request structure and function for read config file; - sys_func.inc - list function, for worked with sockets, filesystem and other functions system; NOTE: The server does not work in this version, but the main loop and the parser work.
254 lines
7.1 KiB
PHP
254 lines
7.1 KiB
PHP
|
||
BASE_ARRAY_ARGS equ (esi - 1024)
|
||
BASE_ARRAY_HEADERS equ (esi - 2048)
|
||
|
||
; IN:
|
||
; esi - struct
|
||
; ecx = ptr to str URI
|
||
; OUT:
|
||
; ecx - new base for reading data ('HTTP/1.1 ...')
|
||
; eax -
|
||
; NOTE: this function don`t check buffer size
|
||
parse_url:
|
||
; URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
|
||
;
|
||
; hier-part = "//" authority path-abempty
|
||
; / path-absolute
|
||
; / path-rootless
|
||
; / path-empty
|
||
;
|
||
; foo://example.com:8042/over/there?name=ferret#nose
|
||
; \_/ \______________/\_________/ \_________/ \__/
|
||
; | | | | |
|
||
; scheme authority path query fragment
|
||
; | _____________________|__
|
||
; / \ / \
|
||
; urn:example:animal:ferret:nose
|
||
|
||
cmp byte[ecx], '/' ; check abs-path
|
||
je .get_path
|
||
|
||
;get scheme
|
||
mov [esi + CONNECT_DATA.uri_scheme], ecx
|
||
@@:
|
||
inc ecx
|
||
cmp byte[ecx - 1], ':'
|
||
jne @b
|
||
mov byte[ecx - 1], 0
|
||
|
||
cmp word[ecx], '//'
|
||
jne .get_path
|
||
|
||
add ecx, 2
|
||
mov [esi + CONNECT_DATA.uri_authority], ecx
|
||
;get authority
|
||
@@:
|
||
inc ecx
|
||
;cmp byte[ecx - 1], ' ' ;check end, не нужно, так как в http всегда / абс путь
|
||
|
||
cmp byte[ecx - 1], '/'
|
||
jne @b
|
||
dec ecx
|
||
.get_path:
|
||
;path-absolute
|
||
mov [esi + CONNECT_DATA.uri_path], ecx
|
||
@@:
|
||
inc ecx
|
||
cmp byte[ecx], '?'
|
||
je .get_query
|
||
|
||
cmp byte[ecx], '#'
|
||
je get_fragment
|
||
|
||
cmp byte[ecx], ' ' ; check end path
|
||
jne @b
|
||
mov byte[ecx], 0
|
||
inc ecx
|
||
jmp .exit
|
||
|
||
.get_query:
|
||
mov byte[ecx], 0
|
||
inc ecx
|
||
lea eax, [BASE_ARRAY_ARGS]
|
||
mov dword[esi + CONNECT_DATA.uri_arg], eax
|
||
xor edx, edx ; counter items
|
||
; add new item
|
||
.get_query_new_arg:
|
||
inc edx
|
||
mov dword[BASE_ARRAY_ARGS + (edx-1)*8], ecx
|
||
mov [esi + CONNECT_DATA.num_uri_args], edx
|
||
dec ecx
|
||
@@:
|
||
inc ecx
|
||
cmp byte[ecx], '='
|
||
je .get_args
|
||
|
||
cmp byte[ecx], '#' ; ЭТО БРЕД ПОЛНЫЙ, НО ВДРУГ
|
||
je .get_fragment
|
||
|
||
cmp byte[ecx], ' ' ; http://cjkhr.bvgbfdkvdf.dmejfgehf/?1pr1
|
||
jne @b
|
||
.exit_2:
|
||
mov byte[ecx], 0
|
||
inc ecx
|
||
jmp .exit
|
||
|
||
.get_args:
|
||
mov byte[ecx], 0
|
||
inc ecx
|
||
mov dword[BASE_ARRAY_ARGS + (edx-1)*8 + 4], ecx
|
||
dec ecx
|
||
@@:
|
||
inc ecx
|
||
cmp byte[ecx], '#'
|
||
je .get_fragment
|
||
|
||
cmp byte[ecx], ' '
|
||
je .exit_2
|
||
|
||
cmp byte[ecx] '&'
|
||
jne @b
|
||
|
||
jmp .get_query_new_arg
|
||
|
||
.get_fragment:
|
||
cmp byte[ecx], '#'
|
||
jne .exit
|
||
|
||
mov byte[ecx], 0
|
||
inc ecx
|
||
mov [esi + CONNECT_DATA.uri_fragment], ecx
|
||
@@:
|
||
inc ecx
|
||
cmp byte[ecx - 1], ' '
|
||
jne @b
|
||
mov [ecx - 1], 0
|
||
.exit:
|
||
ret
|
||
|
||
|
||
; IN:
|
||
; esi - struct
|
||
; ecx - ptr to begin headers block
|
||
; edx - free mem ptr
|
||
; OUT:
|
||
; ecx - new base for reading body message HTTP query
|
||
; eax -
|
||
; NOTE: this function don`t check buffer size
|
||
parse_headers:
|
||
; init array
|
||
mov [esi + CONNECT_DATA.num_headers], 0
|
||
mov [esi + CONNECT_DATA.http_headers], BASE_ARRAY_HEADERS
|
||
xor edx, edx
|
||
.new_str:
|
||
cmp word[ecx], 0x0A0D ; \n
|
||
jnz .find_header
|
||
; end find heeaders
|
||
add ecx, 2 ; ecx = base for body message
|
||
ret
|
||
|
||
.find_header:
|
||
; add new item in array headers
|
||
inc edx
|
||
mov dword[esi + CONNECT_DATA.num_headers], edx
|
||
; save pointer to name header
|
||
mov dword[BASE_ARRAY_HEADERS + (edx-1)*8], ecx
|
||
dec ecx
|
||
@@:
|
||
inc ecx
|
||
|
||
cmp byte[ecx], ':'
|
||
jnz @b
|
||
|
||
mov byte[ecx], 0 ; \0
|
||
inc ecx
|
||
; save pointer to value
|
||
mov dword[BASE_ARRAY_HEADERS + (edx-1)*8 + 4], ecx
|
||
@@:
|
||
inc ecx
|
||
cmp byte[ecx - 1], 0x0A0D
|
||
jnz @b
|
||
mov byte[ecx - 1], 0
|
||
inc ecx ; set offset on new string
|
||
jmp .new_str
|
||
|
||
; IN:
|
||
; ecx - raw data query
|
||
; esi - ptr to CONNECT_DATA
|
||
; OUT: eax = 0 error
|
||
; eax = prt to struct CONNECT_DATA
|
||
parse_http_query:
|
||
;method scheme://host:port/abs_path HTTP/1.1 0x0d 0x0a
|
||
;header_1:value 0x0d 0x0a
|
||
; ...
|
||
;header_N:value 0x0d 0x0a
|
||
;0xd 0xa
|
||
; message data
|
||
|
||
mov eax, [esi + CONNECT_DATA.request_size]
|
||
mov [esi + CONNECT_DATA.tmp_req_size], eax
|
||
|
||
; check size
|
||
cmp dword[esi + CONNECT_DATA.request_size], min_http_size
|
||
jb .error_exit
|
||
|
||
; get http METHOD this message
|
||
mov [esi + CONNECT_DATA.http_method], ecx
|
||
@@:
|
||
inc ecx
|
||
cmp byte[ecx - 1], ' ' ; find end method
|
||
jnz @b
|
||
mov byte[ecx - 1], 0
|
||
|
||
; check size
|
||
mov edx, ecx
|
||
sub edx, [esi + CONNECT_DATA.buffer_request]
|
||
sub edx, 2 ; / 0x20
|
||
cmp dword[esi + CONNECT_DATA.request_size], edx
|
||
jle .error_exit
|
||
|
||
; ecx <- uri string
|
||
; парсинг uri строки в заголовке запроса(получение схемы, пути аргументов, фрагмента и тд)
|
||
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)
|
||
mov [esi + CONNECT_DATA.http_verion], ecx
|
||
@@:
|
||
inc ecx
|
||
cmp word[ecx - 1], 0x0A0D
|
||
jnz @b
|
||
mov word[ecx - 1], 0
|
||
inc ecx ; <- start first header
|
||
|
||
; check size
|
||
mov edx, ecx
|
||
sub edx, [esi + CONNECT_DATA.buffer_request]
|
||
sub edx, 2 ; 0x0d 0x0a
|
||
cmp dword[esi + CONNECT_DATA.request_size], edx
|
||
jle .error_exit
|
||
|
||
; получение заголовков запроса (ключ + значение-строка)
|
||
call parse_headers
|
||
|
||
|
||
; check size
|
||
mov edx, ecx
|
||
sub edx, [esi + CONNECT_DATA.buffer_request]
|
||
cmp dword[esi + CONNECT_DATA.request_size], edx
|
||
jl .error_exit
|
||
|
||
mov [esi + CONNECT_DATA.message_body], ecx
|
||
; докачивается всё остальное
|
||
mov eax, esi
|
||
ret
|
||
|
||
.error_exit:
|
||
xor eax, eax
|
||
ret |