files
simple-httpd/doc/index.htm
Doczom aca8a10141 Update to 0.2.4 version
Added suport for UTF-8 paths of file and uri name.
Update docs file
Translate commentaries
2024-04-07 20:22:19 +05:00

298 lines
26 KiB
HTML
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.

<html>
<head>
<meta charset="utf-8">
<meta lang="ru">
<title>Simple-httpd</title>
<style>
code {
background-color: #babfc766;
}
.menu {
background-color: aliceblue;
border: 1px solid black;
width: 40%;
}
h1 {
text-align: center;
}
h2 {
margin-left: 20pt;
}
</style>
</head>
<body>
<h1>Simple-httpd</h1>
<div class="menu">
<h2>Оглавление:</h2>
<ul>
<li><a href="#about">Описание программы и её возможностей</a></li>
<li><a href="#install">Установка и настройка</a></li>
<li><a href="#api">Документация на API модулей</a></li>
<li><a href="#other-soft">Дополнительные программы и средства </a>
<ul>
<li><a href="#MIME-macro">Генерация файла MIME типов</a></li>
</ul>
</li>
<li><a href="#Bugs">Известные баги и особенности</a></li>
</ul>
</div>
<hr>
<!-- Описание -->
<h2 id="about">Описание программы и её возможностей</h2>
<p>
Simple-httpd - это небольшой http сервер для Колибри ОС, позволяющий размещать файлы, создавать
динамические сайты и различные сетевые ресурсы.
</p>
<!-- Установка -->
<hr>
<h2 id="install">Установка и настройка</h2>
<p>
Для упрощения установки в репозитории находится директория bin, которая представляет из себя сервер, файл конфигурации и
некоторое количество демонстрационных модулей. Файл конфигурации в этой директории рассчитан на то, что сервер будет размещён
в корне раздела "/usbhd0/3/".
</p>
<p>
Дальнейшая настройка содержимого директории зависит от значений в файле httpd.ini .
</p>
<p><b>Примечание:</b> Файл должен использовать кодировку UTF-8. Другие кодировки могут привести к неправильной работе сервера.</p>
<p>
В файле конфигурации можно выделяются 3 основных раздела:
<ol>
<li>
<code>[MAIN]</code>
<p> Данный раздел содержит в себе базовые элементы конфигурации, такие как:</p>
<ul>
<li><code>ip</code><p> IPv4 адрес, на котором будет работать сервер. Параметр обязателен для заполнения </p></li>
<li><code>port</code><p> Порт подключения к серверу. При отсутствии параметра используется порт 80</p></li>
<li><code>conn</code><p> Максимальное количество открытых соединений. При отсутствии параметра используется значение 10</p></li>
<li><code>work_dir</code><p> Директория для размещения статичных файлов сервера, является корнем для uri путей. Параметр обязателен для заполнения </p></li>
<li><code>mime_file</code><p> Путь до файла сопоставления mime типов. Если параметр не указан используется встроенная таблица соответствия.</p></li>
<li><code>modules_dir</code><p> Директория, относительно которой в разделе [MODULES] указываются модули расширения.</p></li>
<li><code></code><p> </p></li>
</ul>
<p><b>Примечание:</b> В качестве modules_dir могут использоватьбся только ASCII символы.</p>
</li>
<li>
<code>[MODULES]</code>
<p> Данный раздел может содержать множество элементов, представленных в виде: <br>
<code>uri_path=file_name;cmdline</code> , где </p>
<ul>
<li><b>uri_path</b> - uri путь ресурса без начального "/" </li>
<li><b>file_name</b> - путь к файлу модуля, относительно "modules_dir"</li>
<li><b>cmdline</b> - Строка передаваемая модулю во время инициализации каждого ресурса, ассоциированного с ним</li>
</ul>
<p><b>Примечание:</b> В качестве uri_path и cmdline может использоваться строка в UTF-8 с любыми символами, но путь к модулю
всегда должен использовать только ASCII символы. Кодировка cmdline не стандартизированна, но желательно использовать
ASCII символы и проверять какую кодировку поддерживаем модуль.</p>
</li>
<li><code>[TLS]</code>
<p>Данный раздел содержит необходимые данные для использования TLS сервером. Все поля обязательны для заполнения.</p>
<ul>
<li><code>mbedtls</code><p> Полный путь до библиотеки MbedTLS.</p></li>
<li><code>ca_cer</code><p> Полный путь до файла корневого сертификата.</p></li>
<li><code>srv_crt</code><p> Полный путь до файла сертификата сервера.</p></li>
<li><code>srv_key</code><p> Полный путь до файла содержащего секретный ключ сервера</p></li>
</ul>
<p>Если сервер находит этот раздел, то он автоматически предполагает использоваться в режиме HTTPS сервера. Переход в
этот режим будет использовать TLS для получения и отправки http данных, при этом порт подключения всё равно выбирается
полем port в разделе [MAIN]. Если порт не задан, то в качестве стандартного порта будет выбран порт 443.</p>
<p>Сервер одновременно может функционировать только в одном режиме, либо полностью использовать TLS, либо полностью не
использовать. Это необходимо для предотвращения использования модулей, опирающихся на шифрование HTTPS протокола,
в незащищённой среде передачи данных.</p>
</li>
</ol>
</p>
<!-- АПИ модулей -->
<hr>
<h2 id="api">Документация на API модулей</h2>
<p>
Модули сервера позволяют обрабатывать запросы и отправлять отправлять ответ, в том числе и формируемый динамически.
По своей структуре, модуль является обычной динамической библиотекой, экспортирующей 3 специальные функции:
</p>
<ol>
<li><code>uint32_t __stdcall httpd_init(IMPORT_DATA* import, char* cmdline)</code>
<p> Функция для инициализации ресурса(uri_path), ассоциированного с модулем .
В файле конфигурации для каждого ресурса можно добавить командную строку, передаваемую в эту функцию. Например
<code> test3=test_unit4.obj; -database="file.sqlite" </code>
Для большей совместимости рекомендуется обрабатывать эту командную строку в кодировке UTF-8.
</p>
<p>
При успешной инициализации функция должна вернуть ненулевое значение, если же инициализация прошла неуспешно, то должен возвращаться ноль.
</p>
<p> Также для дальнейшей работы модуля предаётся указатель на таблицу экспортируемых сервером функций.</p>
</li>
<li><code>void __stdcall httpd_serv(CONNECT_DATA* request_data, uint32_t pdata)</code>
<p>
Данная функция вызывается сервером при получении запроса на ресурс(uri_path) ассоциированным с модулем . Для обеспечения работы сервер передаёт
в функцию уникальное значение, которое вернула функция "httpd_init" и указатель на структуру контекста запроса.
</p>
<p> В этой функции модуль производит обработку запроса используя экспортируемые сервером функции и прямой доступ к некоторым полями структуры контекста.
Эти имеющиеся возможности позволяют реализовать максимально гибкую обработку запросов, в том числе для протоколов, производных от http, например RTSP.
</p>
</li>
<li><code>void __stdcall httpd_close(uint32_t pdata)</code>
<p> Функция вызывается сервером при завершении работы и необходима для правильности завершения обработки запросов в
модулях и сохранения различных временных данных, если это необходимо. В функцию передаётся уникальное значение,
возвращённое функцией "httpd_init".</p>
<p> Завершение работы сервера производится вызовом экспортируемой функции "close_server".</p>
<p> Алгоритм завершения работы модулей и самого сервера заключается в том, что сервер блокирует все новые запросы на
подключение и вызывает функцию "httpd_close", для того чтобы модули завершили все открытые запросы и сохранили свои
данные. После завершения всех модулей сервер полностью завершает свою работу.</p>
</li>
</ol>
<h3>Создание ответа на запрос</h3>
<p> Любой запрос так или иначе требует ответа со стороны модуля. Этот ответ можно отправить используя экспортируемые ядром функции,
позволяющие создать экземпляр класса RESPD и через него производить отправку ответа на запрос.
</p>
<p>Далее будут перечислены некоторые функции для данного класса. Для полного ознакомления с функциями следует ознакомиться с примерами в директории example и файлом modules_api.inc в репозитории проекта.</p>
<ul>
<li><code>RESPD* __stdcall create_resp(CONNECT_DATA* session, uint32_t flags);</code>
<p> Функция создаёт объект RESPD, который имеет базовые настройки:</p>
<table border="1">
<thead>
<tr><th>Параметр</th><th>Значение</th></tr>
</thead>
<tbody>
<tr><td>Статус ответа</td><td>"200"</td> </tr>
<tr><td>Версия протокола</td><td>"HTTP/1.1 "</td></tr>
<tr><td>Content-type</td><td>"text/html"</td></tr>
</tbody>
</table>
<p> Также разработчик может указать битовые флаги конфигурации ответа, например следующие:</p>
<ul>
<li><code>FLAG_TRANSFER_CHUNKED</code>
<p>Этот флаг выбирает "chunked" тип передачи данных с сервера к клиенту, что позволяет отправлять данные
неограниченной или неизвестной длины. </p></li>
<li><code>FLAG_RAW_STREAM</code>
<p>Этот флаг позволяет отправлять тело ответа небольшими пакетами, что можно использовать потоковую передачу
данных поверх http протокола, например для реализации интернет радио</p></li>
<li><code>FLAG_NO_CACHE_CONTROL</code>
<p>Этот флаг указывает, что в ответе не будет дефолтного заголовка "Cache-Control"</p></li>
<li><code>FLAG_KEEP_ALIVE</code>
<p>Этот флаг указывает, что в ответе будет дефолтный заголовок "Connection: keep-alive"</p></li>
</ul>
</li>
<li><code>void __stdcall destruct_resp(RESPD* ptr);</code>
<p>Функция производит удаление объекта RESPD.</p>
</li>
<li><code>void __stdcall set_http_status(RESPD* ptr, uint32_t status); </code>
<p>Функция производит изменение статуса ответа. Статус записывается в виде строки вида "201 " упакованной в dword(0x20313032).</p>
</li>
<li><code>void __stdcall set_http_ver(RESPD* ptr, char* version, uint32_t length);</code>
<p>Функция производит изменение версии, отправляемой в ответе. Версия должна иметь вид строки, например "RTSP/1.1"</p>
</li>
<li><code>uint32_t __stdcall add_http_header(RESPD* ptr, char* ptr_header, uint32_t length);</code>
<p>Функция производит добавление новых заголовков в виде стоки. Функция не производит проверки содержимого строки.</p>
</li>
<li><code>uint32_t __stdcall del_http_header(RESPD* ptr, char* ptr_header);</code>
<p>Функция производит удаление дополнительного заголовка. Память под строку никак не изменяется.</p>
</li>
<li><code>uint32_t __stdcall begin_send_resp(RESPD* ptr, uint64_t content_length); </code>
<p>Функция производит отправку HTTP строки статуса и заголовков для флагов FLAG_TRANSFER_CHUNKED и FLAG_RAW_STREAM.</p>
</li>
<li><code>uint32_t __stdcall send_resp(RESPD* ptr, char* content, uint32_t length); </code>
<p>Функция производит отправку http ответа целиком или его части для флагов FLAG_TRANSFER_CHUNKED и FLAG_RAW_STREAM .</p>
</li>
<li><code>uint32_t __stdcall finish_send_resp(RESPD* ptr);</code>
<p>Функция производит завершение отправки данных для флагов FLAG_TRANSFER_CHUNKED</p>
</li>
</ul>
<p>В использовании функций добавления дополнительных заголовков и изменения версии есть особенность: строки должны существовать
до момента деструктуризации объекта RESPD. Также модуль сам должен отслеживать и освобождать память под эти строки.
</p>
<h3>Обработка данных запроса </h3>
<ul>
<li><code>char* __stdcall find_uri_arg(CONNECT_DATA* session, char* key); </code>
<p>Функция производит поиск аргумента uri строки по его названию. Если аргумент найден, то возвращается указатель на
строку с его значением, иначе ноль</p>
</li>
<li><code>char* __stdcall find_header(CONNECT_DATA* session, char* key);</code>
<p>Функция производит поиск http заголовка по его названию. Если аргумент найден, то возвращается указатель на
строку с его значением, иначе ноль</p>
</li>
<p>Для получения остальной информации, такой как: метод запроса, версии протокола, фрагмент uri строки и тело сообщения;
используется доступ к структуре CONNECT_DATA. Описание этой структуры есть в файле modules_api.inc репозитория.</p>
</ul>
<h3>Работа с файлами</h3>
<ul>
<li><code>void __stdcall FileInitFILED(FILED* buffer, char* path);</code>
<p> Функция производит инициализацию структуры FILED для её использования в файловых операциях.</p>
</li>
<li><code>FS_STATUS __stdcall FileInfo(char* path, void* buffer);</code>
<p> Функция производит чтение информации о файле в буфер по его пути и возвращает код ответа файловой системы.
Если возвращён 0 - операция выполнена успешно, иначе возникла ошибка.
</p>
</li>
<li><code>uint32_t __stdcall FileRead(FILED* file, void* buffer, uint32_t size);</code>
<p> Функция производит чтение части файла и автоматически увеличивает смещение чтение на количество прочитанных байт.
По завершению чтения функция вернёт количество прочитанных байт в буфер, при ошибках чтение это значение равно нулю.
</p>
</li>
<li><code>void __stdcall FileSetOffset(FILED* file, uint64_t offset);</code>
<p> Функция изменяет смещения чтения из файла. </p>
</li>
<li><code>uint32_t __stdcall FileReadOfName(char* path, void* buffer, uint32_t size)</code>
<p> Функция производит чтение файла по его названию начиная с нулевого смещения. Может использоваться для работы с небольшими
файлами с различными настройками модуля. Функция возвращает количество прочитанных байт, если же возвращён 0, то вероятно
произошла ошибка чтения.
</p>
</li>
</ul>
<p><b>Примечание:</b> Все пути на файл или директорию должны быть в кодировке UTF-8 или совместимой с ней ASCII.
Строки должны использовать Null-турминатор. Кодировки UTF-16LE, cp866, cp1251 и тд нельзя использовать.</p>
<h3>Управление сервером</h3>
<code>void close_server();</code>
<p> Функция производит завершение работы всех модулей, и основного потока этого сервера. На время завершения работы модулей сервер
блокирует все новые подключения, позволяя модулям завершить открытые соединения.
</p>
<h3>Дополнительные функции</h3>
<code>char* __stdcall Get_MIME_Type(FILED* fd);</code>
<p> Функция производит анализ названия файла по его структуре FILED и возвращает MIME тип, соответствующий расширению файла.
Данные о MIME типах берутся из встроенной таблицы соответствий либо из дополнительно загружаемого <a href="#MIME-macro">файла</a>.
</p>
<!-- Дополнительные средства -->
<hr>
<h2 id="other-soft">Дополнительные программы и средства</h2>
<h3 id="MIME-macro">Генератор файла MIME типов</h3>
<p>Хоть сервер и имеет встроенную таблицу сопоставления расширения файла и MIME типа, но этого недостаточно. По этой причине
у сервера есть возможность загружать внешний файл с такой таблицей. Для генерации этого файла был создан макрос для fasm,
позволяющий в удобном виде создать такой файл и указать все необходимые MIME типы.
</p>
<p> Файл с расширенными MIME типами находится в репозитории в директории "utils" в этом же файле написан сам макрос.
Последовательность передаваемых параметров в макрос следующая:
<ol>
<li>Строка с MIME типом, который должен использоваться если не один другой тип не подходит</li>
<li>Неопределённое количество последовательно идущих пар аргументов: сначала строка с расширением, например ".pdf",
а после неё строка с MIME типом.
</li>
</ol>
</p>
<h3>Что-то</h3>
<!-- Баги -->
<hr>
<h2 id="Bugs">Известные баги и особенности</h2>
<ol>
<li>Сетевой стек нестабилен и что-то может пойти не так.</li>
<li>При отправки больших объёмов данных может быть утеря или изменение порядка пакетов</li>
<li>Отсутствует поддержка частичных http запросов</li>
<li>Сервер не рассчитан на большие нагрузки</li>
<li>Отсутствует поддержка TLS</li>
</ol>
<!-- Авторы -->
<hr>
<footer id="Autor">
<p>Автор: Махаил Фролов aka Doczom</p>
</footer>
</body>
</html>