files
simple-httpd/parser.inc
Doczom b32a38a071 Release first beta version server
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
2023-12-10 18:21:37 +05:00

312 lines
8.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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