mirror of
https://github.com/Doczom/simple-httpd.git
synced 2025-09-21 22:53:54 +02:00
Version 0.1.0 has been released: - Added a feature for easily sending an http response - Minor bugs have been fixed - Updated API for server modules - Added a readme file
312 lines
8.3 KiB
PHP
312 lines
8.3 KiB
PHP
|
||
BASE_ARRAY_ARGS equ (esi - 1024)
|
||
BASE_ARRAY_HEADERS equ (esi - 2048)
|
||
|
||
MAX_COUNT_ARG = 1024/(4+4)
|
||
MAX_COUNT_HEADER = 1024/(4+4)
|
||
|
||
;TODO: fix checking end http packed
|
||
|
||
; IN:
|
||
; esi - struct
|
||
; ecx - ptr to str URI
|
||
; OUT:
|
||
; ecx = new base for reading data ('HTTP/1.1 ...')
|
||
; eax = -1 - error
|
||
; 0 - good
|
||
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
|
||
@@:
|
||
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||
ja .error_exit
|
||
|
||
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
|
||
@@:
|
||
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||
ja .error_exit
|
||
|
||
inc ecx
|
||
;cmp byte[ecx - 1], ' ' ;check end, не нужно, так как в http всегда / абс путь
|
||
|
||
cmp byte[ecx - 1], '/'
|
||
jne @b
|
||
dec ecx
|
||
.get_path:
|
||
;ecx = path-absolute
|
||
mov [esi + CONNECT_DATA.uri_path], ecx
|
||
@@:
|
||
inc ecx
|
||
|
||
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||
ja .error_exit
|
||
|
||
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
|
||
|
||
cmp edx, MAX_COUNT_HEADER
|
||
jae .error_exit
|
||
|
||
mov dword[BASE_ARRAY_ARGS + (edx-1)*8], ecx
|
||
mov [esi + CONNECT_DATA.num_uri_args], edx
|
||
dec ecx
|
||
@@:
|
||
inc ecx
|
||
|
||
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||
ja .error_exit
|
||
|
||
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 ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||
ja .error_exit
|
||
|
||
cmp byte[ecx], '#'
|
||
je .get_fragment
|
||
|
||
cmp byte[ecx], ' '
|
||
je .exit_2
|
||
|
||
cmp byte[ecx], '&'
|
||
jne @b
|
||
|
||
mov byte[ecx], 0
|
||
inc ecx
|
||
|
||
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
|
||
@@:
|
||
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||
ja .error_exit
|
||
|
||
inc ecx
|
||
cmp byte[ecx - 1], ' '
|
||
jne @b
|
||
mov byte[ecx - 1], 0
|
||
.exit:
|
||
xor eax, eax
|
||
ret
|
||
|
||
.error_exit:
|
||
; set return value
|
||
mov eax, -1
|
||
ret
|
||
|
||
; IN:
|
||
; esi - struct
|
||
; ecx - ptr to begin headers block
|
||
; OUT:
|
||
; ecx = new base for reading body message HTTP query
|
||
; eax = -1 - error
|
||
; 0 - good
|
||
parse_headers:
|
||
; init array
|
||
mov [esi + CONNECT_DATA.num_headers], 0
|
||
lea eax, [BASE_ARRAY_HEADERS]
|
||
mov [esi + CONNECT_DATA.http_headers], eax
|
||
xor edx, edx
|
||
|
||
; for check size
|
||
mov eax, [esi + CONNECT_DATA.end_buffer_request]
|
||
.new_str:
|
||
cmp ecx, eax
|
||
jae .error_exit
|
||
|
||
cmp word[ecx], 0x0A0D ; \n
|
||
jnz .find_header
|
||
.exit:
|
||
; end find heeaders
|
||
mov byte[ecx], 0
|
||
add ecx, 2 ; ecx = base for body message
|
||
xor eax, eax
|
||
ret
|
||
.error_exit:
|
||
mov eax, -1
|
||
ret
|
||
|
||
.find_header:
|
||
; add new item in array headers
|
||
cmp edx, MAX_COUNT_HEADER
|
||
jae .error_exit
|
||
|
||
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
|
||
; check size
|
||
cmp ecx, eax
|
||
jae .error_exit
|
||
|
||
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
|
||
@@:
|
||
; check size
|
||
cmp ecx, eax
|
||
jae .error_exit
|
||
|
||
inc ecx
|
||
cmp word[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]
|
||
add eax, [esi + CONNECT_DATA.buffer_request]
|
||
mov [esi + CONNECT_DATA.end_buffer_request], 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
|
||
@@:
|
||
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||
ja .error_exit
|
||
|
||
inc ecx
|
||
cmp byte[ecx - 1], ' ' ; find end method
|
||
jnz @b
|
||
mov byte[ecx - 1], 0
|
||
|
||
; check size
|
||
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||
ja .error_exit
|
||
|
||
; ecx <- uri string
|
||
; parsing the URI string in the start line of the query
|
||
; (getting the schema, path, arguments, fragment, etc.)
|
||
call parse_url
|
||
test eax, eax
|
||
jnz .error_exit
|
||
|
||
; get http version(HTTP/1.1)
|
||
mov [esi + CONNECT_DATA.http_verion], ecx
|
||
@@:
|
||
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||
ja .error_exit
|
||
|
||
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
|
||
|
||
; get headers request (key + value string)
|
||
call parse_headers
|
||
test eax, eax
|
||
jnz .error_exit
|
||
|
||
; check size
|
||
cmp ecx, [esi + CONNECT_DATA.end_buffer_request]
|
||
je @f
|
||
|
||
mov [esi + CONNECT_DATA.message_body], ecx
|
||
@@:
|
||
mov eax, esi
|
||
ret
|
||
|
||
.error_exit:
|
||
xor eax, eax
|
||
ret |