diff --git a/bin/httpd b/bin/httpd index 5e42bd5..8d61836 100644 Binary files a/bin/httpd and b/bin/httpd differ diff --git a/bin/httpd.ini b/bin/httpd.ini index 4a81e84..cb36391 100644 --- a/bin/httpd.ini +++ b/bin/httpd.ini @@ -6,10 +6,6 @@ port=80 ; count open connection conn=100 -; 1000 - no parse http headers, raw data in CONNECT_DATA.message_body -; This flags using for http/2.0 and other protocol execution. -;flags=0000 ; parsing http headers - ; directory for find files work_dir=/usbhd0/3/server_data ; directory for find units(library) @@ -23,5 +19,11 @@ mime_file=/usbhd0/3/mime_types.bin ; not uning ' ' in unit_name;cmdline : "path = unit_name ; cmdline" is bad name test=test_unit.obj rasp=test_unit_2.obj +t1=test_unit4.obj; nrjkgfehkfgbvrjbgjkbdkg +t2=test_unit4.obj; -loadfile=file +t3=test_unit4.obj; -database="file.sqlite" +t4=test_unit4.obj +test5=test_unit5.obj +admin=srv_control.obj;123456 ;database/sqlite3=sqlite3_serv.obj ;database/cvs=cvs_table_server.obj \ No newline at end of file diff --git a/bin/modules/srv_control.obj b/bin/modules/srv_control.obj index 538ee4a..f69cf50 100644 Binary files a/bin/modules/srv_control.obj and b/bin/modules/srv_control.obj differ diff --git a/bin/modules/test_unit.obj b/bin/modules/test_unit.obj index 0fbb551..b7c3c56 100644 Binary files a/bin/modules/test_unit.obj and b/bin/modules/test_unit.obj differ diff --git a/bin/modules/test_unit4.obj b/bin/modules/test_unit4.obj index 3b52e93..030abb7 100644 Binary files a/bin/modules/test_unit4.obj and b/bin/modules/test_unit4.obj differ diff --git a/bin/modules/test_unit5.obj b/bin/modules/test_unit5.obj index 5ab89a5..f6850b1 100644 Binary files a/bin/modules/test_unit5.obj and b/bin/modules/test_unit5.obj differ diff --git a/bin/modules/test_unit_2.obj b/bin/modules/test_unit_2.obj index d655097..7247161 100644 Binary files a/bin/modules/test_unit_2.obj and b/bin/modules/test_unit_2.obj differ diff --git a/bin/server_data/docs/index.htm b/bin/server_data/docs/index.htm index d4589d4..56825e3 100644 --- a/bin/server_data/docs/index.htm +++ b/bin/server_data/docs/index.htm @@ -3,23 +3,40 @@ Simple-httpd +

Simple-httpd

-

Оглавление:

- - +
@@ -40,6 +57,7 @@

Дальнейшая настройка содержимого директории зависит от значений в файле httpd.ini .

+

Примечание: Файл должен использовать кодировку UTF-8. Другие кодировки могут привести к неправильной работе сервера.

В файле конфигурации можно выделяются 3 основных раздела:

    @@ -54,7 +72,8 @@
  1. mime_file

    Путь до файла сопоставления mime типов. Если параметр не указан используется встроенная таблица соответствия.

  2. modules_dir

    Директория, относительно которой в разделе [MODULES] указываются модули расширения.

  3. - + +

    Примечание: В качестве modules_dir могут использоватьбся только ASCII символы.

  4. [MODULES] @@ -65,6 +84,9 @@
  5. file_name - путь к файлу модуля, относительно "modules_dir"
  6. cmdline - Строка передаваемая модулю во время инициализации каждого ресурса, ассоциированного с ним
  7. +

    Примечание: В качестве uri_path и cmdline может использоваться строка в UTF-8 с любыми символами, но путь к модулю + всегда должен использовать только ASCII символы. Кодировка cmdline не стандартизированна, но желательно использовать + ASCII символы и проверять какую кодировку поддерживаем модуль.

  8. [TLS]

    Данный раздел содержит необходимые данные для использования TLS сервером. Все поля обязательны для заполнения.

    @@ -98,6 +120,9 @@ test3=test_unit4.obj; -database="file.sqlite" + Для большей совместимости рекомендуется обрабатывать эту командную строку в кодировке UTF-8. +

    +

    При успешной инициализации функция должна вернуть ненулевое значение, если же инициализация прошла неуспешно, то должен возвращаться ноль.

    Также для дальнейшей работы модуля предаётся указатель на таблицу экспортируемых сервером функций.

    @@ -134,9 +159,9 @@ ПараметрЗначение - Статус ответа"200" - Версия протокола"HTTP/1.1 " - Content-type"text/html" + Статус ответа"200" + Версия протокола"HTTP/1.1 " + Content-type"text/html"

    Также разработчик может указать битовые флаги конфигурации ответа, например следующие:

    @@ -219,6 +244,8 @@

  9. +

    Примечание: Все пути на файл или директорию должны быть в кодировке UTF-8 или совместимой с ней ASCII. + Строки должны использовать Null-турминатор. Кодировки UTF-16LE, cp866, cp1251 и тд нельзя использовать.

    Управление сервером

    void close_server();

    Функция производит завершение работы всех модулей, и основного потока этого сервера. На время завершения работы модулей сервер @@ -256,9 +283,8 @@

    1. Сетевой стек нестабилен и что-то может пойти не так.
    2. При отправки больших объёмов данных может быть утеря или изменение порядка пакетов
    3. -
    4. Сервер пока не умеет обрабатывать %XX символы в пути до ресурса
    5. +
    6. Отсутствует поддержка частичных http запросов
    7. Сервер не рассчитан на большие нагрузки
    8. -
    9. Все пути в конфигурации сервера должны быть в ascii и без русских символов
    10. Отсутствует поддержка TLS
    diff --git a/doc/index.htm b/doc/index.htm index d4589d4..56825e3 100644 --- a/doc/index.htm +++ b/doc/index.htm @@ -3,23 +3,40 @@ Simple-httpd +

    Simple-httpd

    -

    Оглавление:

    - - +
    @@ -40,6 +57,7 @@

    Дальнейшая настройка содержимого директории зависит от значений в файле httpd.ini .

    +

    Примечание: Файл должен использовать кодировку UTF-8. Другие кодировки могут привести к неправильной работе сервера.

    В файле конфигурации можно выделяются 3 основных раздела:

      @@ -54,7 +72,8 @@
    1. mime_file

      Путь до файла сопоставления mime типов. Если параметр не указан используется встроенная таблица соответствия.

    2. modules_dir

      Директория, относительно которой в разделе [MODULES] указываются модули расширения.

    3. - + +

      Примечание: В качестве modules_dir могут использоватьбся только ASCII символы.

    4. [MODULES] @@ -65,6 +84,9 @@
    5. file_name - путь к файлу модуля, относительно "modules_dir"
    6. cmdline - Строка передаваемая модулю во время инициализации каждого ресурса, ассоциированного с ним
    7. +

      Примечание: В качестве uri_path и cmdline может использоваться строка в UTF-8 с любыми символами, но путь к модулю + всегда должен использовать только ASCII символы. Кодировка cmdline не стандартизированна, но желательно использовать + ASCII символы и проверять какую кодировку поддерживаем модуль.

    8. [TLS]

      Данный раздел содержит необходимые данные для использования TLS сервером. Все поля обязательны для заполнения.

      @@ -98,6 +120,9 @@ test3=test_unit4.obj; -database="file.sqlite" + Для большей совместимости рекомендуется обрабатывать эту командную строку в кодировке UTF-8. +

      +

      При успешной инициализации функция должна вернуть ненулевое значение, если же инициализация прошла неуспешно, то должен возвращаться ноль.

      Также для дальнейшей работы модуля предаётся указатель на таблицу экспортируемых сервером функций.

      @@ -134,9 +159,9 @@ ПараметрЗначение - Статус ответа"200" - Версия протокола"HTTP/1.1 " - Content-type"text/html" + Статус ответа"200" + Версия протокола"HTTP/1.1 " + Content-type"text/html"

      Также разработчик может указать битовые флаги конфигурации ответа, например следующие:

      @@ -219,6 +244,8 @@

    9. +

      Примечание: Все пути на файл или директорию должны быть в кодировке UTF-8 или совместимой с ней ASCII. + Строки должны использовать Null-турминатор. Кодировки UTF-16LE, cp866, cp1251 и тд нельзя использовать.

      Управление сервером

      void close_server();

      Функция производит завершение работы всех модулей, и основного потока этого сервера. На время завершения работы модулей сервер @@ -256,9 +283,8 @@

      1. Сетевой стек нестабилен и что-то может пойти не так.
      2. При отправки больших объёмов данных может быть утеря или изменение порядка пакетов
      3. -
      4. Сервер пока не умеет обрабатывать %XX символы в пути до ресурса
      5. +
      6. Отсутствует поддержка частичных http запросов
      7. Сервер не рассчитан на большие нагрузки
      8. -
      9. Все пути в конфигурации сервера должны быть в ascii и без русских символов
      10. Отсутствует поддержка TLS
      diff --git a/httpd.asm b/httpd.asm index 7075c66..3c7de29 100644 --- a/httpd.asm +++ b/httpd.asm @@ -4,7 +4,7 @@ ; ; ; httpd - Simple http server for Kolibri OS. ; ; ; -; Version 0.2.3, 31 March 2024 ; +; Version 0.2.3, 07 April 2024 ; ; ; ;*****************************************************************************; @@ -205,11 +205,11 @@ thread_connect: call file_server.err_http_501 .end_work: add esp, 2048 - ; free OUT buffer - cmp dword[esp + CONNECT_DATA.buffer_response], 0 - jz .err_recv_sock - push dword[esp + CONNECT_DATA.buffer_response] - call Free +; ; free OUT buffer +; cmp dword[esp + CONNECT_DATA.buffer_response], 0 +; jz .err_recv_sock +; push dword[esp + CONNECT_DATA.buffer_response] +; call Free .err_recv_sock: ; free IN buffer cmp dword[esp + CONNECT_DATA.buffer_request], 0 diff --git a/httpd_lib.inc b/httpd_lib.inc index 1ecdb82..325e050 100644 --- a/httpd_lib.inc +++ b/httpd_lib.inc @@ -66,49 +66,58 @@ ; db 13, 10 ;.size = $ - http_err_response +align 4 default_http_version: db 'HTTP/1.1 ' .length = $ - default_http_version +align 4 default_http_connection: db 'Connection: ' .value = $ - default_http_connection db 'close ', 13, 10 ; or keep-alive .length = $ - default_http_connection +align 4 default_http_cont_encod: db 'Content-Encoding: identity', 13, 10 .length = $ - default_http_cont_encod +align 4 default_http_cont_type: db 'Content-type: ' .value = $ - default_http_cont_type db 'text/html ', 13, 10; .length = $ - default_http_cont_type +align 4 default_http_cache_ctl: db 'Cache-Control: no-cache', 13, 10 .length = $ - default_http_cache_ctl +align 4 default_http_cont_len: db 'Content-length: ' db '0000000000000000000000', 13, 10 .length = $ - default_http_cont_len +align 4 default_http_header_server: db 'Server: simple-httpd/0.3.0', 13, 10 .length = $ - default_http_header_server +align 4 http_header_transfer_chunked: db 'Transfer-Encoding: chunked', 13, 10 .length = $ - http_header_transfer_chunked +;align 4 ;default_http_date_header: ; db 'Date: ' ;.date: db 'Sun, 30 Oct 2022 09:29:13 GMT',13, 10 ;.length = $ - default_http_date_header - +align 4 http_response_err_501: db 'HTTP/1.1 ' db '501 ',13, 10 @@ -118,6 +127,7 @@ http_response_err_501: db 13, 10 .size = $ - http_response_err_501 +align 4 http_response_err_404: db 'HTTP/1.1 ' db '404 ',13, 10 @@ -129,6 +139,7 @@ http_response_err_404: db 'The server could not find the requested page.' .size = $ - http_response_err_404 +align 4 http_response_options: db 'HTTP/1.1 ' db '204 ',13, 10 @@ -143,6 +154,7 @@ http_response_options: ; "GET / HTTP/1.1" - 18 byte min_http_size = 18 +align 4 MIME_FILE_FORMAT: .html: db 5,'.html', 'text/html',0 .css: db 4,'.css', 'text/css ',0 @@ -157,6 +169,7 @@ MIME_FILE_FORMAT: .other: dd 0 db 'application/octet-stream',0 ; for unknow file - all file :) +align 4 STD_MIME_TYPE_ARR: dd MIME_FILE_FORMAT.html, \ MIME_FILE_FORMAT.css, \ @@ -173,5 +186,20 @@ _DIV_10_: dd 10 _DIV_100_: dd 100 _DIV_1000_: dd 1000 +align 4 hex_chars: db '0123456789ABCDEF' + +align 16 +hex_table db 256 dup -1 +repeat 10 + store byte %-1 at hex_table + '0' + %-1 +end repeat +repeat 6 + store byte 0x0A+%-1 at hex_table + 'A' + %-1 +end repeat +repeat 6 + store byte 0x0A+%-1 at hex_table + 'a' + %-1 +end repeat + + diff --git a/module_api.inc b/module_api.inc index 2837cd2..881bbf7 100644 --- a/module_api.inc +++ b/module_api.inc @@ -31,7 +31,7 @@ struct CONNECT_DATA ; 16*4 = 64 bytes num_headers dd 0 ; number items in REQUEST_DATA http_headers dd 0 ; pointer to array REQUEST_DATA of HTTP headers uri_scheme dd 0 ; указатель на схему - uri_authority dd 0 ; pointer to struct ? + uri_authority dd 0 ; pointer to string(%XX not converted) uri_path dd 0 ; указатель на декодированный путь к ресурсу(без параметров) num_uri_args dd 0 ; uri_arg dd 0 ; pointer to the REQUEST_DATA array of string uri arguments @@ -44,7 +44,7 @@ struct FILED offset rd 2 size rd 1 buffer rd 1 - rb 1 + name_encode rd 1 path rd 1 end_path rd 1 ends diff --git a/parser.inc b/parser.inc index 40d9585..af5b396 100644 --- a/parser.inc +++ b/parser.inc @@ -24,9 +24,6 @@ parse_url: ; \_/ \______________/\_________/ \_________/ \__/ ; | | | | | ; scheme authority path query fragment -; | _____________________|__ -; / \ / \ -; urn:example:animal:ferret:nose cmp byte[ecx], '/' ; check abs-path je .get_path @@ -53,7 +50,7 @@ parse_url: ja .error_exit inc ecx - ;cmp byte[ecx - 1], ' ' ;check end, не нужно, так как в http всегда / абс путь + ;cmp byte[ecx - 1], ' ' ;check end, in http always is used abs-path cmp byte[ecx - 1], '/' jne @b @@ -61,20 +58,48 @@ parse_url: .get_path: ;ecx = path-absolute mov [esi + CONNECT_DATA.uri_path], ecx -@@: + mov edi, ecx + mov al, byte[ecx] +.get_path.new_char: + stosb inc ecx cmp ecx, [esi + CONNECT_DATA.end_buffer_request] ja .error_exit - cmp byte[ecx], '?' + mov al, byte[ecx] + mov byte[edi], 0 + + cmp al, '?' je .get_query - cmp byte[ecx], '#' + cmp al, '#' je .get_fragment - cmp byte[ecx], ' ' ; check end path - jne @b + cmp al, ' ' ; check end path + je .get_path.end + + cmp al, '%' ; check end path + jne .get_path.new_char + + ; %00-%FF + inc ecx + movzx eax, byte[ecx] + mov al, byte[hex_table + eax] + cmp al, -1 + je .error_exit + mov edx, eax + + inc ecx + movzx eax, byte[ecx] + mov al, byte[hex_table + eax] + cmp al, -1 + je .error_exit + shl edx, 4 + add eax, edx + + jmp .get_path.new_char +.get_path.end: mov byte[ecx], 0 inc ecx jmp .exit @@ -104,10 +129,10 @@ parse_url: cmp byte[ecx], '=' je .get_args - cmp byte[ecx], '#' ; ЭТО БРЕД ПОЛНЫЙ, НО ВДРУГ + cmp byte[ecx], '#' ; THIS IS COMPLETE NONSENSE, BUT SUDDENLY je .get_fragment - cmp byte[ecx], ' ' ; http://cjkhr.bvgbfdkvdf.dmejfgehf/?1pr1 + cmp byte[ecx], ' ' ; http://cjkhr.bvgbfdkvdf.dmejfgehf/?1pr1 jne @b .exit_2: mov byte[ecx], 0 diff --git a/readme.md b/readme.md index d70b254..3f8dce9 100644 --- a/readme.md +++ b/readme.md @@ -5,47 +5,35 @@ Сервер отправляет содержимое файлов без сжатия в соответствии с заданной таблицей ассоциации MIME типа и расширения файла. Если запрос от клиента имеет uri путь который соответствует модулю сервера, то сервер передаёт управление коду в этом модуле с передачей всех необходимых для функционирования данных. +## install +Для установки сервера на диск скопируйте файлы из директории bin данного репозитория. В этой директории находятся слудеющие файлы: + - `httpd` - исполняемый файл сервера + - `mime_types.bin` - файл с расширенной таблицей ассоцияции MIME типа с расширением файла + - `httpd.ini` - файл конфигурации сервера -## Configuration -Для настройки сервера применяется файл конфигурации в формате ini, где указываются следующие параметры: +и директории: + - `modules` - Директория в которой хранятся некоторые примеры модулей, для демонстрации возможностей сервера + - `server_data` - Директория для размещения статичных данных сервера. Изначально в ней находится только документация по использованию сервером. -В секции MAIN - - ip - ip адрес сервера - - port - порт для подключения (по умолчанию 80) - - conn - максимальное количество открытых соединений(по умолчанию 10) - - work_dir - директория для размещения файлов, отправляемых сервером - - mime_file - путь к файлу с таблицей сопоставлениея mime типов и расширений файлов (если не указан, то используется встроенная в сервер таблица сопоставления) - - modules_dir - директория расположения модулей сервера +Готовый файл конфигурации уже настроен для использование и ожидает, что всё содержимое директории bin репозитория будет размешено по пути `/usbhd0/3/`. По этому для установки достаточно скопировать содержимое в корень третьего раздела usb диска и запустить файл httpd . - В секции MODULES может находиться множество параметров, имеющих вид uri_path=file_name;cmdline где: - - uri_path - путь указываемый клиентом во время запроса - - file_name - название/путь до файла модуля относительно modules_dir - - cmdline - строка параметров, которая передаётся в функцию инициализации модуля. Данное значение не обязательна и может не использоваться. +Подробная настройка сервера описана в документации, расположенной в директории doc этого репозитория. +## TODO +### Tasks on version 0.2.5 + - Update srv_control module + - Добавить модуль тестовой авторизации(base64 code in header) + - Добавить модуль генерации более сложного контента + (create json object with data of CSV table) + - Добавить демонстрационный модуль на Си + - Добавить демонстрационный модуль на FPC + - Добавить модуль демонстрации cookie + - Добавить модуль демонстрации websockets -## API for modules - -К серверу можно подключить дополнительные модули в виде библиотек со специальными экспортируемыми функциями: - - - uint32_t stdcall httpd_init(IMPORT_DATA* import, char* cmdline) - -Эта функция служит для инициализации модуля для каждого связанного с модулем uri . В файле конфигурации для конкретного uri можно добавить командную строку, передаваемую в эту функцию. Например - - ``` test3=test_unit4.obj; -database="file.sqlite" ``` - -При успешной инициализации функция должна вернуть ненулевое значение, если же инициализация прошла неуспешно, то должен возвращаться ноль. -Для упрощения многих операций, сервер передаёт в функцию инициализации модуля таблицу некоторых функций, необходимых для работы с сетью, с файловой системой и прочими интерфейсами. - - - void stdcall httpd_serv(CONNECT_DATA* request_data, uint32_t pdata) -Эта функция вызывается сервером при получении запроса с uri путём указанном в файле конфигурации для этого модуля. -Сервер передаёт в функцию контекст запроса, содержащий: аргументы, заголовки, тело запроса, http метод и версию; и значение возвращённое функцией httpd_init. - - - void stdcall httpd_close(uint32_t pdata) -Эта функция вызывается сервером при завершении работы или в процессе управления сервером. Данная функция предназначена для корректного завершения работы модуля и освобождением связанных с ним ресурсов. +### Tasks on version 0.3.0 +- Добавить поддержку TLS шифрования с использованием MbedTLS ## Bugs - - - Сервер не поддерживает работу с файлами, имеющими не ascii символы, так как не производит преобразование uri пути; - В ходе тестов был обнаружена ошибка отправки "больших" файлов. Это баг сетевого стека; - При длительной работе сервер может начать "подзависать" или перестать отвечать на сообщения. Это баг сетевого стека. diff --git a/sys_func.inc b/sys_func.inc index 6b4acc8..bef5e9e 100644 --- a/sys_func.inc +++ b/sys_func.inc @@ -198,10 +198,10 @@ FileInfo: mov dword[esp + FILED.opcode], 5 ; file info mov dword[esp + FILED.offset + 4], 0 ; zero flag mov dword[esp + FILED.buffer], edx - mov byte[esp + FILED.path - 1], 0 + mov dword[esp + FILED.name_encode], 3 ;UTF-8 mov dword[esp + FILED.path], ecx mov ebx, esp - mcall 70 + mcall 80 add esp, sizeof.FILED pop ebx ret 8 @@ -210,12 +210,13 @@ FileInfo: FileInitFILED: push ecx edi mov edi, [esp + 4*2 + 4] - mov ecx, sizeof.FILED + mov ecx, sizeof.FILED/4 xor eax, eax - rep stosb + rep stosd mov eax, [esp + 4*2 + 4] mov ecx, [esp + 4*2 + 8] mov [eax + FILED.path], ecx + mov dword[eax + FILED.name_encode], 3 ;UTF-8 dec ecx @@: inc ecx @@ -239,7 +240,7 @@ FileRead: mov [eax + FILED.buffer], ecx mov ebx, eax - mcall 70 + mcall 80 test eax, eax jz @f @@ -280,10 +281,10 @@ FileReadOfName: mov dword[esp + FILED.offset + 4], 0 mov dword[esp + FILED.size], eax mov dword[esp + FILED.buffer], edx - mov byte[esp + FILED.path - 1], 0 + mov dword[esp + FILED.name_encode], 3 ;UTF-8 mov dword[esp + FILED.path], ecx mov ebx, esp - mcall 70 + mcall 80 test eax, eax jz @f cmp eax, 6 ; EOF