mirror of
https://github.com/Doczom/simple-httpd.git
synced 2025-09-21 02:50:09 +02:00
Update to 0.2.5 version
- Added support for uploading a configuration file over a long path - Added support for special uri paths (using the "*" symbol) in the configuration for groups of similar uri paths - Added the function of reading the contents of an http request - Changed the format of the uri address in the configuration file - Added a request redirection module - Added a module for blocking access to files by url path - Updated documentation - Updated module examples
This commit is contained in:
@@ -16,14 +16,18 @@ mime_file=/usbhd0/3/mime_types.bin
|
|||||||
[MODULES]
|
[MODULES]
|
||||||
; list units
|
; list units
|
||||||
; path = unit_name;cmdline
|
; path = unit_name;cmdline
|
||||||
; not uning ' ' in unit_name;cmdline : "path = unit_name ; cmdline" is bad name
|
; not uning ' ' in unit_name;cmdline : "path = unit_name,cmdline" is bad name
|
||||||
test=test_unit.obj
|
/=redirect.obj, /docs/index.htm
|
||||||
rasp=test_unit_2.obj
|
/test=test_unit.obj
|
||||||
t1=test_unit4.obj; nrjkgfehkfgbvrjbgjkbdkg
|
/rasp=test_unit_2.obj
|
||||||
t2=test_unit4.obj; -loadfile=file
|
/t1=test_unit4.obj, nrjkgfehkfgbvrjbgjkbdkg
|
||||||
t3=test_unit4.obj; -database="file.sqlite"
|
/t2=test_unit4.obj, -loadfile=file
|
||||||
t4=test_unit4.obj
|
/t3=test_unit4.obj, -database="file.sqlite"
|
||||||
test5=test_unit5.obj
|
/t4=test_unit4.obj
|
||||||
admin=srv_control.obj;123456
|
*/.*=block_access.obj
|
||||||
;database/sqlite3=sqlite3_serv.obj
|
/logs=block_access.obj, 400 Bad request
|
||||||
;database/cvs=cvs_table_server.obj
|
*.lua=test_unit4.obj, -database="sqlite.db"
|
||||||
|
/test5=test_unit5.obj
|
||||||
|
/admin=srv_control.obj,123456
|
||||||
|
;/database/sqlite3=sqlite3_serv.obj
|
||||||
|
;/database/cvs=cvs_table_server.obj
|
BIN
bin/modules/block_access.obj
Normal file
BIN
bin/modules/block_access.obj
Normal file
Binary file not shown.
BIN
bin/modules/redirect.obj
Normal file
BIN
bin/modules/redirect.obj
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -10,13 +10,17 @@
|
|||||||
.menu {
|
.menu {
|
||||||
background-color: aliceblue;
|
background-color: aliceblue;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
width: 40%;
|
width: 40%;
|
||||||
|
margin-left: 20pt;
|
||||||
}
|
}
|
||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
h2 {
|
h3 {
|
||||||
margin-left: 20pt;
|
margin-left: 20pt;
|
||||||
|
}
|
||||||
|
.menu-header {
|
||||||
|
margin-left: 20pt;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -24,14 +28,23 @@
|
|||||||
<h1>Simple-httpd</h1>
|
<h1>Simple-httpd</h1>
|
||||||
|
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<h2>Оглавление:</h2>
|
<h2 class="menu-header">Оглавление:</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#about">Описание программы и её возможностей</a></li>
|
<li><a href="#about">Описание программы и её возможностей</a></li>
|
||||||
<li><a href="#install">Установка и настройка</a></li>
|
<li><a href="#install">Установка и настройка</a></li>
|
||||||
<li><a href="#api">Документация на API модулей</a></li>
|
<li><a href="#api">Документация на API модулей</a></li>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#api.response">Создание ответа на запрос</a></li>
|
||||||
|
<li><a href="#api.request">Обработка данных запроса</a></li>
|
||||||
|
<li><a href="#api.file">Работа с файлами</a></li>
|
||||||
|
<li><a href="#api.control">Управление сервером</a></li>
|
||||||
|
<li><a href="#api.other">Дополнительные функции и возможности</a></li>
|
||||||
|
</ul>
|
||||||
<li><a href="#other-soft">Дополнительные программы и средства </a>
|
<li><a href="#other-soft">Дополнительные программы и средства </a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#MIME-macro">Генерация файла MIME типов</a></li>
|
<li><a href="#MIME-macro">Генерация файла MIME типов</a></li>
|
||||||
|
<li><a href="#redirect">Модуль перенаправления запросов</a></li>
|
||||||
|
<li><a href="#block_access">Модуль блокировки доступа к файлам</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#Bugs">Известные баги и особенности</a></li>
|
<li><a href="#Bugs">Известные баги и особенности</a></li>
|
||||||
@@ -80,15 +93,28 @@
|
|||||||
<p> Данный раздел может содержать множество элементов, представленных в виде: <br>
|
<p> Данный раздел может содержать множество элементов, представленных в виде: <br>
|
||||||
<code>uri_path=file_name;cmdline</code> , где </p>
|
<code>uri_path=file_name;cmdline</code> , где </p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>uri_path</b> - uri путь ресурса без начального "/" </li>
|
<li><b>uri_path</b> - uri путь ресурса с начальным символом "/" </li>
|
||||||
<li><b>file_name</b> - путь к файлу модуля, относительно "modules_dir"</li>
|
<li><b>file_name</b> - путь к файлу модуля, относительно "modules_dir"</li>
|
||||||
<li><b>cmdline</b> - Строка передаваемая модулю во время инициализации каждого ресурса, ассоциированного с ним</li>
|
<li><b>cmdline</b> - Строка передаваемая модулю во время инициализации каждого ресурса, ассоциированного с ним</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<p>
|
||||||
|
<b>Особенности работы:</b> каждый модуль добавляется последовательно и поиск нужного модуля также производится последовательно. Из-за этой особенности нужно учитывать расположение uri в данной секции.
|
||||||
|
Для того, чтобы uri модуля сравнивался с путём в запросе раньше всех остальных он должен находится в самом конце списка, чтобы
|
||||||
|
</p>
|
||||||
<p><b>Примечание:</b> В качестве uri_path и cmdline может использоваться строка в UTF-8 с любыми символами, но путь к модулю
|
<p><b>Примечание:</b> В качестве uri_path и cmdline может использоваться строка в UTF-8 с любыми символами, но путь к модулю
|
||||||
всегда должен использовать только ASCII символы. Кодировка cmdline не стандартизированна, но желательно использовать
|
всегда должен использовать только ASCII символы и не использовать символ ",". Кодировка cmdline не стандартизированна, но желательно использовать
|
||||||
ASCII символы и проверять какую кодировку поддерживаем модуль.</p>
|
ASCII символы и проверять какую кодировку поддерживает модуль.</p>
|
||||||
|
<p> Сервер имеет возможность установить модуль для некоторого диапазона uri путей, для этого используется символ "*", обозначающий неопределённое количество(включая ноль) любых символов.
|
||||||
|
Например: При наличии записи <code>/img/*=img_module.obj</code> в секции модулей, сервер будет вызывать модуль для любых uri путей, имеющих в начале "/img/".
|
||||||
|
Также для установки модуля на все возможные uri пути необходимо прописать соответствие модуля с путём "/*".
|
||||||
|
</p>
|
||||||
|
<p> Другие примеры:
|
||||||
|
<code>*.lua=lua_module.obj</code> Любой путь, имеющий в конце ".lua".<br>
|
||||||
|
<code>*/.*=err401.obj</code> Любой путь, имеющий в названии директорию, начинающуюся с символа ".".<br>
|
||||||
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li><code>[TLS]</code>
|
<li><code>[TLS]</code>
|
||||||
|
<p><b>ВНИМАНИЕ!!! TLS шифрование на данный момент не поддерживается сервером</b></p>
|
||||||
<p>Данный раздел содержит необходимые данные для использования TLS сервером. Все поля обязательны для заполнения.</p>
|
<p>Данный раздел содержит необходимые данные для использования TLS сервером. Все поля обязательны для заполнения.</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>mbedtls</code><p> Полный путь до библиотеки MbedTLS.</p></li>
|
<li><code>mbedtls</code><p> Полный путь до библиотеки MbedTLS.</p></li>
|
||||||
@@ -114,7 +140,7 @@
|
|||||||
По своей структуре, модуль является обычной динамической библиотекой, экспортирующей 3 специальные функции:
|
По своей структуре, модуль является обычной динамической библиотекой, экспортирующей 3 специальные функции:
|
||||||
</p>
|
</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>uint32_t __stdcall httpd_init(IMPORT_DATA* import, char* cmdline)</code>
|
<li><code>uint32_t __stdcall httpd_init(IMPORT_DATA* import, char* cmdline, char* uri_path)</code>
|
||||||
<p> Функция для инициализации ресурса(uri_path), ассоциированного с модулем .
|
<p> Функция для инициализации ресурса(uri_path), ассоциированного с модулем .
|
||||||
В файле конфигурации для каждого ресурса можно добавить командную строку, передаваемую в эту функцию. Например
|
В файле конфигурации для каждого ресурса можно добавить командную строку, передаваемую в эту функцию. Например
|
||||||
|
|
||||||
@@ -146,7 +172,7 @@
|
|||||||
данные. После завершения всех модулей сервер полностью завершает свою работу.</p>
|
данные. После завершения всех модулей сервер полностью завершает свою работу.</p>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h3>Создание ответа на запрос</h3>
|
<h3 id="api.response">Создание ответа на запрос</h3>
|
||||||
<p> Любой запрос так или иначе требует ответа со стороны модуля. Этот ответ можно отправить используя экспортируемые ядром функции,
|
<p> Любой запрос так или иначе требует ответа со стороны модуля. Этот ответ можно отправить используя экспортируемые ядром функции,
|
||||||
позволяющие создать экземпляр класса RESPD и через него производить отправку ответа на запрос.
|
позволяющие создать экземпляр класса RESPD и через него производить отправку ответа на запрос.
|
||||||
</p>
|
</p>
|
||||||
@@ -160,7 +186,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr><td>Статус ответа</td><td>"200"</td> </tr>
|
<tr><td>Статус ответа</td><td>"200"</td> </tr>
|
||||||
<tr><td>Версия протокола</td><td>"HTTP/1.1 "</td></tr>
|
<tr><td>Версия протокола</td><td>"HTTP/1.1"</td></tr>
|
||||||
<tr><td>Content-type</td><td>"text/html"</td></tr>
|
<tr><td>Content-type</td><td>"text/html"</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -206,7 +232,7 @@
|
|||||||
<p>В использовании функций добавления дополнительных заголовков и изменения версии есть особенность: строки должны существовать
|
<p>В использовании функций добавления дополнительных заголовков и изменения версии есть особенность: строки должны существовать
|
||||||
до момента деструктуризации объекта RESPD. Также модуль сам должен отслеживать и освобождать память под эти строки.
|
до момента деструктуризации объекта RESPD. Также модуль сам должен отслеживать и освобождать память под эти строки.
|
||||||
</p>
|
</p>
|
||||||
<h3>Обработка данных запроса </h3>
|
<h3 id="api.request">Обработка данных запроса </h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>char* __stdcall find_uri_arg(CONNECT_DATA* session, char* key); </code>
|
<li><code>char* __stdcall find_uri_arg(CONNECT_DATA* session, char* key); </code>
|
||||||
<p>Функция производит поиск аргумента uri строки по его названию. Если аргумент найден, то возвращается указатель на
|
<p>Функция производит поиск аргумента uri строки по его названию. Если аргумент найден, то возвращается указатель на
|
||||||
@@ -216,10 +242,14 @@
|
|||||||
<p>Функция производит поиск http заголовка по его названию. Если аргумент найден, то возвращается указатель на
|
<p>Функция производит поиск http заголовка по его названию. Если аргумент найден, то возвращается указатель на
|
||||||
строку с его значением, иначе ноль</p>
|
строку с его значением, иначе ноль</p>
|
||||||
</li>
|
</li>
|
||||||
<p>Для получения остальной информации, такой как: метод запроса, версии протокола, фрагмент uri строки и тело сообщения;
|
<li><code>uint32_t __stdcall read_http_body(CONNECT_DATA* session, char* buff, uint32_t len);</code>
|
||||||
|
<p>Функция производит чтение части содержимого http запроса в буфер и возвращает количество прочитанных байт.
|
||||||
|
В случае ошибки сервер вернёт значение -1</p>
|
||||||
|
</li>
|
||||||
|
<p>Для получения остальной информации, такой как: метод запроса, версии протокола и фрагмент uri строки
|
||||||
используется доступ к структуре CONNECT_DATA. Описание этой структуры есть в файле modules_api.inc репозитория.</p>
|
используется доступ к структуре CONNECT_DATA. Описание этой структуры есть в файле modules_api.inc репозитория.</p>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>Работа с файлами</h3>
|
<h3 id="api.file">Работа с файлами</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>void __stdcall FileInitFILED(FILED* buffer, char* path);</code>
|
<li><code>void __stdcall FileInitFILED(FILED* buffer, char* path);</code>
|
||||||
<p> Функция производит инициализацию структуры FILED для её использования в файловых операциях.</p>
|
<p> Функция производит инициализацию структуры FILED для её использования в файловых операциях.</p>
|
||||||
@@ -246,13 +276,13 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<p><b>Примечание:</b> Все пути на файл или директорию должны быть в кодировке UTF-8 или совместимой с ней ASCII.
|
<p><b>Примечание:</b> Все пути на файл или директорию должны быть в кодировке UTF-8 или совместимой с ней ASCII.
|
||||||
Строки должны использовать Null-турминатор. Кодировки UTF-16LE, cp866, cp1251 и тд нельзя использовать.</p>
|
Строки должны использовать Null-турминатор. Кодировки UTF-16LE, cp866, cp1251 и тд нельзя использовать.</p>
|
||||||
<h3>Управление сервером</h3>
|
<h3 id="api.control">Управление сервером</h3>
|
||||||
<code>void close_server();</code>
|
<code>void close_server();</code>
|
||||||
<p> Функция производит завершение работы всех модулей, и основного потока этого сервера. На время завершения работы модулей сервер
|
<p> Функция производит завершение работы всех модулей, и основного потока этого сервера. На время завершения работы модулей сервер
|
||||||
блокирует все новые подключения, позволяя модулям завершить открытые соединения.
|
блокирует все новые подключения, позволяя модулям завершить открытые соединения.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3>Дополнительные функции</h3>
|
<h3 id="api.other">Дополнительные функции и возможности</h3>
|
||||||
<code>char* __stdcall Get_MIME_Type(FILED* fd);</code>
|
<code>char* __stdcall Get_MIME_Type(FILED* fd);</code>
|
||||||
<p> Функция производит анализ названия файла по его структуре FILED и возвращает MIME тип, соответствующий расширению файла.
|
<p> Функция производит анализ названия файла по его структуре FILED и возвращает MIME тип, соответствующий расширению файла.
|
||||||
Данные о MIME типах берутся из встроенной таблицы соответствий либо из дополнительно загружаемого <a href="#MIME-macro">файла</a>.
|
Данные о MIME типах берутся из встроенной таблицы соответствий либо из дополнительно загружаемого <a href="#MIME-macro">файла</a>.
|
||||||
@@ -275,7 +305,18 @@
|
|||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</p>
|
</p>
|
||||||
<h3>Что-то</h3>
|
<h3 id="redirect">Модуль перенаправления запросов</h3>
|
||||||
|
<p>
|
||||||
|
При эксплуатации сервера может потребоваться возможность перенаправить запросы на какой-либо определённый файл(например на index.html) или модуль. Для данных целей к серверу был создан модуль "redirect.obj", позволяющий огранизовать перенаправление на определённые ресурсы как в пределах сервера, так и на внешние ресурсы. Для использования модуля необходимо задать модуль для всех необходимых uri путей и прописать для каждого такого uri командную строку, содержащую либо полный путь к ресурсу на этом сервере, либо полную uri ссылку. Пример использования:
|
||||||
|
</p>
|
||||||
|
<code>/=redirect.obj, /docs/index.htm</code> <p> перенаправление запросов на главную страницу сервера из корня.</p>
|
||||||
|
|
||||||
|
<h3 id="block_access">Модуль блокировки доступа к файлам </h3>
|
||||||
|
<p>
|
||||||
|
При работе сервера, модули могут создавать различные "системные" файлы, например логи, к которым должен быть заблокирован доступ из запросов клиентов. Для этих целей к серверу был создан модуль "block_access.obj", позволяющий задать http код статуса и короткое сообщение в теле ответа сервера. Для использования необходимо связать модуль с uri путём и задать строку параметров: код статуса ответа и, через пробел, короткое сообщение. Пример использования:
|
||||||
|
</p>
|
||||||
|
<code>*/.*=block_access.obj, 400 access error</code> <p>Блокировка доступа к файлам и дерикториям начинающимся с символа "." .</p>
|
||||||
|
<p>Также можно не указывать текстовое сообщение, тогда сервер отправит только http статус. Если не указывать никаких параметров, то сервер будет по умолчанию отправлять код "403".</p>
|
||||||
|
|
||||||
<!-- Баги -->
|
<!-- Баги -->
|
||||||
<hr>
|
<hr>
|
||||||
|
@@ -10,13 +10,17 @@
|
|||||||
.menu {
|
.menu {
|
||||||
background-color: aliceblue;
|
background-color: aliceblue;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
width: 40%;
|
width: 40%;
|
||||||
|
margin-left: 20pt;
|
||||||
}
|
}
|
||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
h2 {
|
h3 {
|
||||||
margin-left: 20pt;
|
margin-left: 20pt;
|
||||||
|
}
|
||||||
|
.menu-header {
|
||||||
|
margin-left: 20pt;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -24,14 +28,23 @@
|
|||||||
<h1>Simple-httpd</h1>
|
<h1>Simple-httpd</h1>
|
||||||
|
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<h2>Оглавление:</h2>
|
<h2 class="menu-header">Оглавление:</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#about">Описание программы и её возможностей</a></li>
|
<li><a href="#about">Описание программы и её возможностей</a></li>
|
||||||
<li><a href="#install">Установка и настройка</a></li>
|
<li><a href="#install">Установка и настройка</a></li>
|
||||||
<li><a href="#api">Документация на API модулей</a></li>
|
<li><a href="#api">Документация на API модулей</a></li>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#api.response">Создание ответа на запрос</a></li>
|
||||||
|
<li><a href="#api.request">Обработка данных запроса</a></li>
|
||||||
|
<li><a href="#api.file">Работа с файлами</a></li>
|
||||||
|
<li><a href="#api.control">Управление сервером</a></li>
|
||||||
|
<li><a href="#api.other">Дополнительные функции и возможности</a></li>
|
||||||
|
</ul>
|
||||||
<li><a href="#other-soft">Дополнительные программы и средства </a>
|
<li><a href="#other-soft">Дополнительные программы и средства </a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#MIME-macro">Генерация файла MIME типов</a></li>
|
<li><a href="#MIME-macro">Генерация файла MIME типов</a></li>
|
||||||
|
<li><a href="#redirect">Модуль перенаправления запросов</a></li>
|
||||||
|
<li><a href="#block_access">Модуль блокировки доступа к файлам</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#Bugs">Известные баги и особенности</a></li>
|
<li><a href="#Bugs">Известные баги и особенности</a></li>
|
||||||
@@ -80,15 +93,28 @@
|
|||||||
<p> Данный раздел может содержать множество элементов, представленных в виде: <br>
|
<p> Данный раздел может содержать множество элементов, представленных в виде: <br>
|
||||||
<code>uri_path=file_name;cmdline</code> , где </p>
|
<code>uri_path=file_name;cmdline</code> , где </p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>uri_path</b> - uri путь ресурса без начального "/" </li>
|
<li><b>uri_path</b> - uri путь ресурса с начальным символом "/" </li>
|
||||||
<li><b>file_name</b> - путь к файлу модуля, относительно "modules_dir"</li>
|
<li><b>file_name</b> - путь к файлу модуля, относительно "modules_dir"</li>
|
||||||
<li><b>cmdline</b> - Строка передаваемая модулю во время инициализации каждого ресурса, ассоциированного с ним</li>
|
<li><b>cmdline</b> - Строка передаваемая модулю во время инициализации каждого ресурса, ассоциированного с ним</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<p>
|
||||||
|
<b>Особенности работы:</b> каждый модуль добавляется последовательно и поиск нужного модуля также производится последовательно. Из-за этой особенности нужно учитывать расположение uri в данной секции.
|
||||||
|
Для того, чтобы uri модуля сравнивался с путём в запросе раньше всех остальных он должен находится в самом конце списка, чтобы
|
||||||
|
</p>
|
||||||
<p><b>Примечание:</b> В качестве uri_path и cmdline может использоваться строка в UTF-8 с любыми символами, но путь к модулю
|
<p><b>Примечание:</b> В качестве uri_path и cmdline может использоваться строка в UTF-8 с любыми символами, но путь к модулю
|
||||||
всегда должен использовать только ASCII символы. Кодировка cmdline не стандартизированна, но желательно использовать
|
всегда должен использовать только ASCII символы и не использовать символ ",". Кодировка cmdline не стандартизированна, но желательно использовать
|
||||||
ASCII символы и проверять какую кодировку поддерживаем модуль.</p>
|
ASCII символы и проверять какую кодировку поддерживает модуль.</p>
|
||||||
|
<p> Сервер имеет возможность установить модуль для некоторого диапазона uri путей, для этого используется символ "*", обозначающий неопределённое количество(включая ноль) любых символов.
|
||||||
|
Например: При наличии записи <code>/img/*=img_module.obj</code> в секции модулей, сервер будет вызывать модуль для любых uri путей, имеющих в начале "/img/".
|
||||||
|
Также для установки модуля на все возможные uri пути необходимо прописать соответствие модуля с путём "/*".
|
||||||
|
</p>
|
||||||
|
<p> Другие примеры:
|
||||||
|
<code>*.lua=lua_module.obj</code> Любой путь, имеющий в конце ".lua".<br>
|
||||||
|
<code>*/.*=err401.obj</code> Любой путь, имеющий в названии директорию, начинающуюся с символа ".".<br>
|
||||||
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li><code>[TLS]</code>
|
<li><code>[TLS]</code>
|
||||||
|
<p><b>ВНИМАНИЕ!!! TLS шифрование на данный момент не поддерживается сервером</b></p>
|
||||||
<p>Данный раздел содержит необходимые данные для использования TLS сервером. Все поля обязательны для заполнения.</p>
|
<p>Данный раздел содержит необходимые данные для использования TLS сервером. Все поля обязательны для заполнения.</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>mbedtls</code><p> Полный путь до библиотеки MbedTLS.</p></li>
|
<li><code>mbedtls</code><p> Полный путь до библиотеки MbedTLS.</p></li>
|
||||||
@@ -114,7 +140,7 @@
|
|||||||
По своей структуре, модуль является обычной динамической библиотекой, экспортирующей 3 специальные функции:
|
По своей структуре, модуль является обычной динамической библиотекой, экспортирующей 3 специальные функции:
|
||||||
</p>
|
</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li><code>uint32_t __stdcall httpd_init(IMPORT_DATA* import, char* cmdline)</code>
|
<li><code>uint32_t __stdcall httpd_init(IMPORT_DATA* import, char* cmdline, char* uri_path)</code>
|
||||||
<p> Функция для инициализации ресурса(uri_path), ассоциированного с модулем .
|
<p> Функция для инициализации ресурса(uri_path), ассоциированного с модулем .
|
||||||
В файле конфигурации для каждого ресурса можно добавить командную строку, передаваемую в эту функцию. Например
|
В файле конфигурации для каждого ресурса можно добавить командную строку, передаваемую в эту функцию. Например
|
||||||
|
|
||||||
@@ -146,7 +172,7 @@
|
|||||||
данные. После завершения всех модулей сервер полностью завершает свою работу.</p>
|
данные. После завершения всех модулей сервер полностью завершает свою работу.</p>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h3>Создание ответа на запрос</h3>
|
<h3 id="api.response">Создание ответа на запрос</h3>
|
||||||
<p> Любой запрос так или иначе требует ответа со стороны модуля. Этот ответ можно отправить используя экспортируемые ядром функции,
|
<p> Любой запрос так или иначе требует ответа со стороны модуля. Этот ответ можно отправить используя экспортируемые ядром функции,
|
||||||
позволяющие создать экземпляр класса RESPD и через него производить отправку ответа на запрос.
|
позволяющие создать экземпляр класса RESPD и через него производить отправку ответа на запрос.
|
||||||
</p>
|
</p>
|
||||||
@@ -160,7 +186,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr><td>Статус ответа</td><td>"200"</td> </tr>
|
<tr><td>Статус ответа</td><td>"200"</td> </tr>
|
||||||
<tr><td>Версия протокола</td><td>"HTTP/1.1 "</td></tr>
|
<tr><td>Версия протокола</td><td>"HTTP/1.1"</td></tr>
|
||||||
<tr><td>Content-type</td><td>"text/html"</td></tr>
|
<tr><td>Content-type</td><td>"text/html"</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@@ -206,7 +232,7 @@
|
|||||||
<p>В использовании функций добавления дополнительных заголовков и изменения версии есть особенность: строки должны существовать
|
<p>В использовании функций добавления дополнительных заголовков и изменения версии есть особенность: строки должны существовать
|
||||||
до момента деструктуризации объекта RESPD. Также модуль сам должен отслеживать и освобождать память под эти строки.
|
до момента деструктуризации объекта RESPD. Также модуль сам должен отслеживать и освобождать память под эти строки.
|
||||||
</p>
|
</p>
|
||||||
<h3>Обработка данных запроса </h3>
|
<h3 id="api.request">Обработка данных запроса </h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>char* __stdcall find_uri_arg(CONNECT_DATA* session, char* key); </code>
|
<li><code>char* __stdcall find_uri_arg(CONNECT_DATA* session, char* key); </code>
|
||||||
<p>Функция производит поиск аргумента uri строки по его названию. Если аргумент найден, то возвращается указатель на
|
<p>Функция производит поиск аргумента uri строки по его названию. Если аргумент найден, то возвращается указатель на
|
||||||
@@ -216,10 +242,14 @@
|
|||||||
<p>Функция производит поиск http заголовка по его названию. Если аргумент найден, то возвращается указатель на
|
<p>Функция производит поиск http заголовка по его названию. Если аргумент найден, то возвращается указатель на
|
||||||
строку с его значением, иначе ноль</p>
|
строку с его значением, иначе ноль</p>
|
||||||
</li>
|
</li>
|
||||||
<p>Для получения остальной информации, такой как: метод запроса, версии протокола, фрагмент uri строки и тело сообщения;
|
<li><code>uint32_t __stdcall read_http_body(CONNECT_DATA* session, char* buff, uint32_t len);</code>
|
||||||
|
<p>Функция производит чтение части содержимого http запроса в буфер и возвращает количество прочитанных байт.
|
||||||
|
В случае ошибки сервер вернёт значение -1</p>
|
||||||
|
</li>
|
||||||
|
<p>Для получения остальной информации, такой как: метод запроса, версии протокола и фрагмент uri строки
|
||||||
используется доступ к структуре CONNECT_DATA. Описание этой структуры есть в файле modules_api.inc репозитория.</p>
|
используется доступ к структуре CONNECT_DATA. Описание этой структуры есть в файле modules_api.inc репозитория.</p>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>Работа с файлами</h3>
|
<h3 id="api.file">Работа с файлами</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>void __stdcall FileInitFILED(FILED* buffer, char* path);</code>
|
<li><code>void __stdcall FileInitFILED(FILED* buffer, char* path);</code>
|
||||||
<p> Функция производит инициализацию структуры FILED для её использования в файловых операциях.</p>
|
<p> Функция производит инициализацию структуры FILED для её использования в файловых операциях.</p>
|
||||||
@@ -246,13 +276,13 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<p><b>Примечание:</b> Все пути на файл или директорию должны быть в кодировке UTF-8 или совместимой с ней ASCII.
|
<p><b>Примечание:</b> Все пути на файл или директорию должны быть в кодировке UTF-8 или совместимой с ней ASCII.
|
||||||
Строки должны использовать Null-турминатор. Кодировки UTF-16LE, cp866, cp1251 и тд нельзя использовать.</p>
|
Строки должны использовать Null-турминатор. Кодировки UTF-16LE, cp866, cp1251 и тд нельзя использовать.</p>
|
||||||
<h3>Управление сервером</h3>
|
<h3 id="api.control">Управление сервером</h3>
|
||||||
<code>void close_server();</code>
|
<code>void close_server();</code>
|
||||||
<p> Функция производит завершение работы всех модулей, и основного потока этого сервера. На время завершения работы модулей сервер
|
<p> Функция производит завершение работы всех модулей, и основного потока этого сервера. На время завершения работы модулей сервер
|
||||||
блокирует все новые подключения, позволяя модулям завершить открытые соединения.
|
блокирует все новые подключения, позволяя модулям завершить открытые соединения.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3>Дополнительные функции</h3>
|
<h3 id="api.other">Дополнительные функции и возможности</h3>
|
||||||
<code>char* __stdcall Get_MIME_Type(FILED* fd);</code>
|
<code>char* __stdcall Get_MIME_Type(FILED* fd);</code>
|
||||||
<p> Функция производит анализ названия файла по его структуре FILED и возвращает MIME тип, соответствующий расширению файла.
|
<p> Функция производит анализ названия файла по его структуре FILED и возвращает MIME тип, соответствующий расширению файла.
|
||||||
Данные о MIME типах берутся из встроенной таблицы соответствий либо из дополнительно загружаемого <a href="#MIME-macro">файла</a>.
|
Данные о MIME типах берутся из встроенной таблицы соответствий либо из дополнительно загружаемого <a href="#MIME-macro">файла</a>.
|
||||||
@@ -275,7 +305,18 @@
|
|||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</p>
|
</p>
|
||||||
<h3>Что-то</h3>
|
<h3 id="redirect">Модуль перенаправления запросов</h3>
|
||||||
|
<p>
|
||||||
|
При эксплуатации сервера может потребоваться возможность перенаправить запросы на какой-либо определённый файл(например на index.html) или модуль. Для данных целей к серверу был создан модуль "redirect.obj", позволяющий огранизовать перенаправление на определённые ресурсы как в пределах сервера, так и на внешние ресурсы. Для использования модуля необходимо задать модуль для всех необходимых uri путей и прописать для каждого такого uri командную строку, содержащую либо полный путь к ресурсу на этом сервере, либо полную uri ссылку. Пример использования:
|
||||||
|
</p>
|
||||||
|
<code>/=redirect.obj, /docs/index.htm</code> <p> перенаправление запросов на главную страницу сервера из корня.</p>
|
||||||
|
|
||||||
|
<h3 id="block_access">Модуль блокировки доступа к файлам </h3>
|
||||||
|
<p>
|
||||||
|
При работе сервера, модули могут создавать различные "системные" файлы, например логи, к которым должен быть заблокирован доступ из запросов клиентов. Для этих целей к серверу был создан модуль "block_access.obj", позволяющий задать http код статуса и короткое сообщение в теле ответа сервера. Для использования необходимо связать модуль с uri путём и задать строку параметров: код статуса ответа и, через пробел, короткое сообщение. Пример использования:
|
||||||
|
</p>
|
||||||
|
<code>*/.*=block_access.obj, 400 access error</code> <p>Блокировка доступа к файлам и дерикториям начинающимся с символа "." .</p>
|
||||||
|
<p>Также можно не указывать текстовое сообщение, тогда сервер отправит только http статус. Если не указывать никаких параметров, то сервер будет по умолчанию отправлять код "403".</p>
|
||||||
|
|
||||||
<!-- Баги -->
|
<!-- Баги -->
|
||||||
<hr>
|
<hr>
|
||||||
|
7
example/readme.md
Normal file
7
example/readme.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Examples of modules
|
||||||
|
|
||||||
|
- `test_unit.asm` - Модуль обрабатывает аргументы URI строки и отправляет ответ в виде RAW данных, без генерации заголовков и строки статуса сервером.
|
||||||
|
- `test_unit_2.asm` - Модуль обрабатывает агрументы URI, проверяет и устанавливет cookie и отправляет ответ в виде html данных, строка статуса и заголовки генерируются самим сервером. Модуль добавляет дополнительный заголовок в ответ.
|
||||||
|
- `test_unit4.asm` - Модуль отправляет в ответе заданную в файле конфигурации строку параметров и uri адрес запроса клиента. Используется chunked передача ответа.
|
||||||
|
- `test_unit5.asm` - Модуль отправляет ответ используя chunked передачу.
|
||||||
|
- `srv_control.asm` - Модуль, позволяющий удалённо выключать сервер.
|
@@ -49,7 +49,7 @@ unit_init:
|
|||||||
;unit init successful
|
;unit init successful
|
||||||
.exit:
|
.exit:
|
||||||
pop edi esi
|
pop edi esi
|
||||||
ret 8
|
ret 12
|
||||||
|
|
||||||
|
|
||||||
server_entry:
|
server_entry:
|
||||||
@@ -127,13 +127,45 @@ key_token:
|
|||||||
key_cmd:
|
key_cmd:
|
||||||
db 'cmd',0
|
db 'cmd',0
|
||||||
|
|
||||||
|
CMD_STOP = 'S'
|
||||||
|
CMD_REBOOT = 'R'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
text403:
|
text403:
|
||||||
db 'Access to server management is prohibited.',\
|
db '<html><head><title>Login</title><style>',\
|
||||||
' An unknown token has been entered'
|
'body {display: grid;',\
|
||||||
|
'grid-template-rows: 1fr 1fr 1fr;',\
|
||||||
|
'text-align: center;',\
|
||||||
|
'background-color: blanchedalmond;',\
|
||||||
|
'}',\
|
||||||
|
'.f {',\
|
||||||
|
'display: grid;',\
|
||||||
|
'grid-template-columns: 1fr 1fr 1fr;',\
|
||||||
|
'}',\
|
||||||
|
'.f1 {background-color: aqua;',\
|
||||||
|
'border: 1px solid black;',\
|
||||||
|
'border-radius: 2%;}',\
|
||||||
|
'form {',\
|
||||||
|
'left: 50%;',\
|
||||||
|
'position: absolute;',\
|
||||||
|
'top: 50%;',\
|
||||||
|
'transform: translate(-50%, -50%);}',\
|
||||||
|
'</style></head>',\
|
||||||
|
'<body><h1>Access to server management is prohibited.',\
|
||||||
|
' An unknown token has been entered</h1>',\
|
||||||
|
'<div class="f"><div></div>',\
|
||||||
|
'<div class="f1"><form method="get">',\
|
||||||
|
'<h2>Enter token:</h2> <input type="text" name="token" /><br />',\
|
||||||
|
'<input type="submit" value="Submit" />',\
|
||||||
|
'</form></div>',\
|
||||||
|
'<div></div></div><div></div>',\
|
||||||
|
'</body></html>'
|
||||||
.length = $ - text403
|
.length = $ - text403
|
||||||
|
|
||||||
text_board:
|
text_board:
|
||||||
db '<body> <h1> Control panel of simple-httpd</h1> <a href="?cmd=S&token='
|
db '<body> <h1> Control panel of simple-httpd</h1>',\
|
||||||
|
'<a href="?cmd=S&token='
|
||||||
.token:
|
.token:
|
||||||
db ' ">Stop Server</a></body>'
|
db ' ">Stop Server</a></body>'
|
||||||
.size = $ - text_board
|
.size = $ - text_board
|
||||||
|
@@ -45,7 +45,7 @@ unit_init:
|
|||||||
mov eax, 1 ;no zero return - unit init successful
|
mov eax, 1 ;no zero return - unit init successful
|
||||||
.exit:
|
.exit:
|
||||||
pop edi esi
|
pop edi esi
|
||||||
ret 8
|
ret 12
|
||||||
|
|
||||||
|
|
||||||
server_entry:
|
server_entry:
|
||||||
|
@@ -47,7 +47,7 @@ unit_init:
|
|||||||
;unit init successful
|
;unit init successful
|
||||||
.exit:
|
.exit:
|
||||||
pop edi esi
|
pop edi esi
|
||||||
ret 8
|
ret 12
|
||||||
|
|
||||||
|
|
||||||
server_entry:
|
server_entry:
|
||||||
@@ -58,14 +58,33 @@ server_entry:
|
|||||||
cmp dword[edi], 0
|
cmp dword[edi], 0
|
||||||
je .no_cmd
|
je .no_cmd
|
||||||
|
|
||||||
|
mov edx, [esi + CONNECT_DATA.uri_path]
|
||||||
|
xor ecx, ecx
|
||||||
|
dec ecx
|
||||||
|
@@:
|
||||||
|
inc ecx
|
||||||
|
cmp byte[edx + ecx], 0
|
||||||
|
jne @b
|
||||||
|
push ecx
|
||||||
|
|
||||||
add edi, 4
|
add edi, 4
|
||||||
invoke IMPORT.create_resp, esi, 0
|
invoke IMPORT.create_resp, esi, FLAG_TRANSFER_CHUNKED\
|
||||||
|
+ FLAG_NO_CONTENT_LENGTH
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .exit
|
jz .exit
|
||||||
|
|
||||||
push eax
|
push eax
|
||||||
|
invoke IMPORT.begin_send_resp, eax, 0, 0
|
||||||
|
mov eax, [esp]
|
||||||
invoke IMPORT.send_resp, eax, edi, [edi - 4]
|
invoke IMPORT.send_resp, eax, edi, [edi - 4]
|
||||||
|
mov eax, [esp]
|
||||||
|
invoke IMPORT.send_resp, eax, text_br, text_br.size
|
||||||
|
mov eax, [esp]
|
||||||
|
invoke IMPORT.send_resp, eax,\
|
||||||
|
[esi + CONNECT_DATA.uri_path],\
|
||||||
|
[esp + 4]
|
||||||
invoke IMPORT.destruct_resp ; arg in stack
|
invoke IMPORT.destruct_resp ; arg in stack
|
||||||
|
add esp, 4
|
||||||
.exit:
|
.exit:
|
||||||
pop edi esi
|
pop edi esi
|
||||||
ret 8
|
ret 8
|
||||||
@@ -89,6 +108,9 @@ section '.data' data readable writable align 16
|
|||||||
text_no_cmd:
|
text_no_cmd:
|
||||||
db 'For this unit in config not set arguments'
|
db 'For this unit in config not set arguments'
|
||||||
.size = $ - text_no_cmd
|
.size = $ - text_no_cmd
|
||||||
|
text_br:
|
||||||
|
db '<br>'
|
||||||
|
.size = $ - text_br
|
||||||
|
|
||||||
@EXPORT:
|
@EXPORT:
|
||||||
export \
|
export \
|
||||||
|
@@ -27,7 +27,7 @@ unit_init:
|
|||||||
mov eax, 1 ;no zero return - module init successful
|
mov eax, 1 ;no zero return - module init successful
|
||||||
.exit:
|
.exit:
|
||||||
pop edi esi
|
pop edi esi
|
||||||
ret 8
|
ret 12
|
||||||
|
|
||||||
|
|
||||||
server_entry:
|
server_entry:
|
||||||
|
@@ -46,12 +46,12 @@ unit_init:
|
|||||||
mov eax, 1 ;no zero return - unit init successful
|
mov eax, 1 ;no zero return - unit init successful
|
||||||
.exit:
|
.exit:
|
||||||
pop edi esi
|
pop edi esi
|
||||||
ret 8
|
ret 12
|
||||||
|
|
||||||
|
|
||||||
server_entry:
|
server_entry:
|
||||||
push esi edi
|
push esi edi ebp
|
||||||
mov esi, [esp + 4*2 + 4]
|
mov esi, [esp + 4*3 + 4]
|
||||||
; work
|
; work
|
||||||
board_input 'first'
|
board_input 'first'
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ server_entry:
|
|||||||
mov ecx, [eax + 4]
|
mov ecx, [eax + 4]
|
||||||
cmp dword[ecx], 'bpo'
|
cmp dword[ecx], 'bpo'
|
||||||
jne .no_bpo
|
jne .no_bpo
|
||||||
|
.bpo:
|
||||||
board_input 'bpo'
|
board_input 'bpo'
|
||||||
invoke IMPORT.Alloc, sceleton_resp.size
|
invoke IMPORT.Alloc, sceleton_resp.size
|
||||||
test eax, eax
|
test eax, eax
|
||||||
@@ -94,11 +94,13 @@ server_entry:
|
|||||||
rep movsb
|
rep movsb
|
||||||
pop esi
|
pop esi
|
||||||
|
|
||||||
|
mov ebp, cookie_bpo
|
||||||
|
|
||||||
jmp .send_data
|
jmp .send_data
|
||||||
.no_bpo:
|
.no_bpo:
|
||||||
cmp dword[ecx], 'btp'
|
cmp dword[ecx], 'btp'
|
||||||
jne .err_404
|
jne .err_404
|
||||||
|
.btp:
|
||||||
board_input 'btp'
|
board_input 'btp'
|
||||||
invoke IMPORT.Alloc, sceleton_resp.size
|
invoke IMPORT.Alloc, sceleton_resp.size
|
||||||
test eax, eax
|
test eax, eax
|
||||||
@@ -121,9 +123,24 @@ server_entry:
|
|||||||
rep movsb
|
rep movsb
|
||||||
pop esi
|
pop esi
|
||||||
|
|
||||||
|
mov ebp, cookie_btp
|
||||||
|
|
||||||
jmp .send_data
|
jmp .send_data
|
||||||
.no_args:
|
.no_args:
|
||||||
board_input 'no_arg'
|
board_input 'no_arg'
|
||||||
|
; check cookie
|
||||||
|
invoke IMPORT.find_header, esi, key_cookie
|
||||||
|
test eax, eax
|
||||||
|
jz .no_args.send
|
||||||
|
|
||||||
|
cmp dword[eax], 'gr=b'
|
||||||
|
jne .no_args.send
|
||||||
|
|
||||||
|
cmp word[eax + 4], 'tp'
|
||||||
|
je .btp
|
||||||
|
cmp word[eax + 4], 'po'
|
||||||
|
je .bpo
|
||||||
|
.no_args.send:
|
||||||
invoke IMPORT.create_resp, esi, 0
|
invoke IMPORT.create_resp, esi, 0
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .exit
|
jz .exit
|
||||||
@@ -132,7 +149,7 @@ server_entry:
|
|||||||
invoke IMPORT.send_resp, eax, sceleton_resp, sceleton_resp.size
|
invoke IMPORT.send_resp, eax, sceleton_resp, sceleton_resp.size
|
||||||
invoke IMPORT.destruct_resp ; arg in stack
|
invoke IMPORT.destruct_resp ; arg in stack
|
||||||
.exit:
|
.exit:
|
||||||
pop edi esi
|
pop ebp edi esi
|
||||||
ret 8
|
ret 8
|
||||||
|
|
||||||
.send_data: ; eax - ptr to buffer
|
.send_data: ; eax - ptr to buffer
|
||||||
@@ -144,6 +161,10 @@ server_entry:
|
|||||||
|
|
||||||
board_input 'send_data'
|
board_input 'send_data'
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
|
invoke IMPORT.add_http_header, eax, ebp, cookie_length
|
||||||
|
|
||||||
|
mov eax, [esp]
|
||||||
invoke IMPORT.send_resp, eax, edi, sceleton_resp.size
|
invoke IMPORT.send_resp, eax, edi, sceleton_resp.size
|
||||||
invoke IMPORT.destruct_resp ; arg in stack
|
invoke IMPORT.destruct_resp ; arg in stack
|
||||||
|
|
||||||
@@ -198,6 +219,12 @@ btp_name:
|
|||||||
db 'Технологи'
|
db 'Технологи'
|
||||||
.size = $ - btp_name
|
.size = $ - btp_name
|
||||||
|
|
||||||
|
key_cookie: db 'Cookie', 0
|
||||||
|
|
||||||
|
cookie_bpo: db 'Set-Cookie: gr=bpo'
|
||||||
|
cookie_length = $ - cookie_bpo
|
||||||
|
cookie_btp: db 'Set-Cookie: gr=btp'
|
||||||
|
|
||||||
@EXPORT:
|
@EXPORT:
|
||||||
export \
|
export \
|
||||||
unit_init, 'httpd_init', \
|
unit_init, 'httpd_init', \
|
||||||
|
@@ -9,15 +9,12 @@ file_server:
|
|||||||
mov ecx, [esi + CONNECT_DATA.http_verion]
|
mov ecx, [esi + CONNECT_DATA.http_verion]
|
||||||
cmp dword[ecx], 'HTTP'
|
cmp dword[ecx], 'HTTP'
|
||||||
jne .err_http_501
|
jne .err_http_501
|
||||||
cmp word[ecx + 4], '/1'
|
cmp dword[ecx + 4], '/1.0'
|
||||||
jne .err_http_501
|
je @f
|
||||||
|
|
||||||
; cmp byte[ecx + 7], '1'
|
cmp dword[ecx + 4], '/1.1'
|
||||||
; je .http_1_1
|
jne .err_http_501
|
||||||
; ; http 1.0;
|
@@:
|
||||||
;
|
|
||||||
;.http_1_1:
|
|
||||||
|
|
||||||
; check name on ../../ and other bad items
|
; check name on ../../ and other bad items
|
||||||
mov ecx, [esi + CONNECT_DATA.uri_path]
|
mov ecx, [esi + CONNECT_DATA.uri_path]
|
||||||
@@:
|
@@:
|
||||||
@@ -74,8 +71,12 @@ file_server:
|
|||||||
cmp dword[ecx + 4], 'ONS'
|
cmp dword[ecx + 4], 'ONS'
|
||||||
je .send_options
|
je .send_options
|
||||||
@@:
|
@@:
|
||||||
|
cmp dword[ecx], 'HEAD'
|
||||||
|
je ..check_zero
|
||||||
|
|
||||||
cmp dword[ecx], 'POST'
|
cmp dword[ecx], 'POST'
|
||||||
jne @f
|
jne @f
|
||||||
|
..check_zero:
|
||||||
cmp byte[ecx + 4], 0
|
cmp byte[ecx + 4], 0
|
||||||
je .send_file
|
je .send_file
|
||||||
@@:
|
@@:
|
||||||
@@ -122,6 +123,10 @@ file_server:
|
|||||||
|
|
||||||
stdcall begin_send_resp, ebp, [edi - 40 + 32], [edi - 40 + 36]
|
stdcall begin_send_resp, ebp, [edi - 40 + 32], [edi - 40 + 36]
|
||||||
;cmp eax, -1
|
;cmp eax, -1
|
||||||
|
mov ecx, [esi + CONNECT_DATA.http_method]
|
||||||
|
cmp dword[ecx], 'HEAD'
|
||||||
|
je .finish_send_file
|
||||||
|
|
||||||
.send_block_file:
|
.send_block_file:
|
||||||
mov eax, [esp] ; allocated buffer
|
mov eax, [esp] ; allocated buffer
|
||||||
stdcall FileRead, edi, eax, SIZE_FILE_BUFFER
|
stdcall FileRead, edi, eax, SIZE_FILE_BUFFER
|
||||||
|
116
httpd.asm
116
httpd.asm
@@ -4,7 +4,7 @@
|
|||||||
; ;
|
; ;
|
||||||
; httpd - Simple http server for Kolibri OS. ;
|
; httpd - Simple http server for Kolibri OS. ;
|
||||||
; ;
|
; ;
|
||||||
; Version 0.2.3, 07 April 2024 ;
|
; Version 0.2.5, 13 June 2024 ;
|
||||||
; ;
|
; ;
|
||||||
;*****************************************************************************;
|
;*****************************************************************************;
|
||||||
|
|
||||||
@@ -12,7 +12,9 @@
|
|||||||
use32
|
use32
|
||||||
org 0
|
org 0
|
||||||
db 'MENUET01'
|
db 'MENUET01'
|
||||||
dd 1, START, I_END, MEM, STACKTOP, PATH, 0
|
dd 1, START, I_END, MEM, STACKTOP
|
||||||
|
M01header.params:
|
||||||
|
dd PATH, 0
|
||||||
include "macros.inc"
|
include "macros.inc"
|
||||||
purge mov,add,sub
|
purge mov,add,sub
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ include 'module_api.inc'
|
|||||||
|
|
||||||
include "proc32.inc"
|
include "proc32.inc"
|
||||||
include "dll.inc"
|
include "dll.inc"
|
||||||
|
include "KOSfuncs.inc"
|
||||||
;include 'D:\kos\programs\network.inc'
|
;include 'D:\kos\programs\network.inc'
|
||||||
;KOS_APP_START
|
;KOS_APP_START
|
||||||
|
|
||||||
@@ -28,29 +31,43 @@ include 'settings.inc'
|
|||||||
|
|
||||||
;CODE
|
;CODE
|
||||||
START:
|
START:
|
||||||
mcall 68, 11 ; init heap
|
mcall SF_SYS_MISC, SSF_HEAP_INIT ; init heap
|
||||||
mcall 40, EVM_STACK ;set event bitmap
|
mcall SF_SET_EVENTS_MASK, EVM_STACK ;set event bitmap
|
||||||
|
|
||||||
; init library
|
; init library
|
||||||
stdcall dll.Load, @IMPORT
|
stdcall dll.Load, @IMPORT
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .err_settings
|
jnz .err_settings
|
||||||
|
|
||||||
mov ecx, default_ini_path
|
mov ecx, default_ini_path
|
||||||
cmp byte[PATH],0
|
mov eax, [M01header.params]
|
||||||
jz @f
|
cmp byte[eax],0
|
||||||
|
jz .load_settings
|
||||||
mov ecx, PATH
|
|
||||||
; TODO: add check ""
|
|
||||||
|
|
||||||
|
mov edx, ' '
|
||||||
|
mov ecx, eax
|
||||||
|
cmp byte[eax], '"'
|
||||||
|
jne @f
|
||||||
|
mov dl, '"'
|
||||||
|
inc ecx
|
||||||
@@:
|
@@:
|
||||||
|
mov esi, ecx
|
||||||
|
@@:
|
||||||
|
lodsb
|
||||||
|
test al, al
|
||||||
|
jz @f
|
||||||
|
cmp al, dl
|
||||||
|
jne @b
|
||||||
|
@@:
|
||||||
|
mov byte[esi - 1], 0
|
||||||
|
.load_settings:
|
||||||
; get settings
|
; get settings
|
||||||
call load_settings ; ecx -> string to config file
|
call load_settings ; ecx -> string to config file
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz .err_settings
|
jnz .err_settings
|
||||||
|
|
||||||
;init server socket
|
;init server socket
|
||||||
push dword SO_NONBLOCK ;IPPROTO_TCP
|
push dword SO_NONBLOCK ;IPPROTO_TCP
|
||||||
push dword SOCK_STREAM
|
push dword SOCK_STREAM
|
||||||
push dword AF_INET4
|
push dword AF_INET4
|
||||||
call netfunc_socket; AF_INET4, SOCK_STREAM, SO_NONBLOCK ; we dont want to block on accept
|
call netfunc_socket; AF_INET4, SOCK_STREAM, SO_NONBLOCK ; we dont want to block on accept
|
||||||
@@ -95,13 +112,13 @@ START:
|
|||||||
|
|
||||||
.err_settings:
|
.err_settings:
|
||||||
.sock_err:
|
.sock_err:
|
||||||
mcall -1
|
mcall SF_TERMINATE_PROCESS
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
|
|
||||||
thread_connect:
|
thread_connect:
|
||||||
sub esp, sizeof.CONNECT_DATA
|
sub esp, sizeof.CONNECT_DATA
|
||||||
mcall 40, EVM_STACK ; set event bitmap - network event
|
mcall SF_SET_EVENTS_MASK, EVM_STACK ; set event - network event
|
||||||
|
|
||||||
; ожидание подключения Accept, sockaddr находится на вершине стека нового потока
|
; ожидание подключения Accept, sockaddr находится на вершине стека нового потока
|
||||||
;lea edx, [esp + CONNECT_DATA.sockaddr] ; new sockaddr
|
;lea edx, [esp + CONNECT_DATA.sockaddr] ; new sockaddr
|
||||||
@@ -115,7 +132,7 @@ thread_connect:
|
|||||||
|
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
jz .err_accept
|
jz .err_accept
|
||||||
|
|
||||||
mov [esp + CONNECT_DATA.socket], eax
|
mov [esp + CONNECT_DATA.socket], eax
|
||||||
mov ebp, esp
|
mov ebp, esp
|
||||||
|
|
||||||
@@ -142,7 +159,7 @@ thread_connect:
|
|||||||
add [esp], eax
|
add [esp], eax
|
||||||
push dword[esi + CONNECT_DATA.socket]
|
push dword[esi + CONNECT_DATA.socket]
|
||||||
call netfunc_recv
|
call netfunc_recv
|
||||||
|
|
||||||
cmp eax, -1
|
cmp eax, -1
|
||||||
jz .err_recv_sock
|
jz .err_recv_sock
|
||||||
|
|
||||||
@@ -152,42 +169,85 @@ thread_connect:
|
|||||||
; cmp [esi + CONNECT_DATA.request_size], 0x8000 ; check end buffer
|
; cmp [esi + CONNECT_DATA.request_size], 0x8000 ; check end buffer
|
||||||
; jb @b
|
; jb @b
|
||||||
@@:
|
@@:
|
||||||
; после получения всего запроса(более или менее всего) выделяем озу для
|
; после получения всего запроса(более или менее всего) выделяем озу для
|
||||||
; ассоциативного массива заголовков и аргументов запроса
|
; ассоциативного массива заголовков и аргументов запроса
|
||||||
; 8*50 + 8*100
|
; 8*50 + 8*100
|
||||||
; esp .. esp + 1024 -> for http headers
|
; esp .. esp + 1024 -> for http headers
|
||||||
; esp + 1024 .. esp + 2048 -> for URI args
|
; esp + 1024 .. esp + 2048 -> for URI args
|
||||||
sub esp, 2048
|
sub esp, 2048
|
||||||
|
|
||||||
; parse http message
|
; parse http message
|
||||||
mov ecx, [esi + CONNECT_DATA.buffer_request]
|
mov ecx, [esi + CONNECT_DATA.buffer_request]
|
||||||
call parse_http_query ; ecx - buffer
|
call parse_http_query ; ecx - buffer
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err_parse
|
jz .err_parse
|
||||||
; find unit for uri path
|
; find unit for uri path
|
||||||
cmp dword[GLOBAL_DATA.modules], 0
|
cmp dword[GLOBAL_DATA.modules], 0
|
||||||
jz .no_modules
|
jz .no_modules
|
||||||
|
|
||||||
mov eax, [GLOBAL_DATA.modules]
|
mov eax, [GLOBAL_DATA.modules]
|
||||||
.next_unit:
|
.next_unit:
|
||||||
push esi edi
|
push esi edi
|
||||||
mov esi, [esi + CONNECT_DATA.uri_path]
|
mov esi, [esi + CONNECT_DATA.uri_path]
|
||||||
lea edi, [eax + HTTPD_MODULE.uri_path]
|
lea edi, [eax + HTTPD_MODULE.uri_path]
|
||||||
|
; check module for all uri path
|
||||||
@@:
|
@@:
|
||||||
cmpsb
|
cmpsb
|
||||||
jne @f
|
jne @f
|
||||||
|
|
||||||
cmp byte[edi - 1], 0
|
cmp byte[edi - 1], 0
|
||||||
jne @b
|
jne @b
|
||||||
|
.found_module:
|
||||||
; found module
|
; found module
|
||||||
pop edi esi
|
pop edi esi
|
||||||
|
|
||||||
push dword[eax + HTTPD_MODULE.pdata] ; context of module
|
push dword[eax + HTTPD_MODULE.pdata] ; context of module
|
||||||
push esi ; coutext of request
|
push esi ; coutext of request
|
||||||
call dword[eax + HTTPD_MODULE.httpd_serv] ; call unit function
|
call dword[eax + HTTPD_MODULE.httpd_serv] ; call unit function
|
||||||
|
|
||||||
jmp .end_work
|
jmp .end_work
|
||||||
@@:
|
@@:
|
||||||
|
.found_special_char:
|
||||||
|
cmp byte[edi - 1], '*'
|
||||||
|
jne .no_special_char
|
||||||
|
|
||||||
|
;je .found_module
|
||||||
|
; check next char in uri of modules
|
||||||
|
cmp byte[edi], 0
|
||||||
|
je .found_module
|
||||||
|
; uri path "*name" or "*name*"
|
||||||
|
dec esi
|
||||||
|
.special_char_loop:
|
||||||
|
cmp byte[esi], 0
|
||||||
|
je .no_special_char
|
||||||
|
|
||||||
|
;inc esi
|
||||||
|
|
||||||
|
xor ecx, ecx
|
||||||
|
@@:
|
||||||
|
inc ecx
|
||||||
|
mov dl, byte[edi + ecx - 1]
|
||||||
|
|
||||||
|
cmp dl, '*'
|
||||||
|
je @f
|
||||||
|
|
||||||
|
cmp byte[esi + ecx - 1], dl
|
||||||
|
lea esi, [esi + 1]
|
||||||
|
jne .special_char_loop
|
||||||
|
dec esi
|
||||||
|
|
||||||
|
test dl, dl
|
||||||
|
jnz @b
|
||||||
|
|
||||||
|
jmp .found_module
|
||||||
|
@@:
|
||||||
|
; found substr
|
||||||
|
add esi, ecx
|
||||||
|
add edi, ecx
|
||||||
|
|
||||||
|
jmp .found_special_char
|
||||||
|
|
||||||
|
.no_special_char:
|
||||||
pop edi esi
|
pop edi esi
|
||||||
|
|
||||||
mov eax, [eax] ; HTTPD_MODULE.next
|
mov eax, [eax] ; HTTPD_MODULE.next
|
||||||
@@ -196,20 +256,15 @@ thread_connect:
|
|||||||
|
|
||||||
.no_modules:
|
.no_modules:
|
||||||
; if not found modules, call file_server
|
; if not found modules, call file_server
|
||||||
call file_server ; esi - struct
|
call file_server ; esi - struct
|
||||||
; end work thread
|
; end work thread
|
||||||
jmp .end_work
|
jmp .end_work
|
||||||
|
|
||||||
|
|
||||||
.err_parse:
|
.err_parse:
|
||||||
call file_server.err_http_501
|
call file_server.err_http_501
|
||||||
.end_work:
|
.end_work:
|
||||||
add esp, 2048
|
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
|
|
||||||
.err_recv_sock:
|
.err_recv_sock:
|
||||||
; free IN buffer
|
; free IN buffer
|
||||||
cmp dword[esp + CONNECT_DATA.buffer_request], 0
|
cmp dword[esp + CONNECT_DATA.buffer_request], 0
|
||||||
@@ -222,7 +277,7 @@ thread_connect:
|
|||||||
.err_accept:
|
.err_accept:
|
||||||
lea ecx,[esp + sizeof.CONNECT_DATA - 0x4000] ; get pointer to alloc memory
|
lea ecx,[esp + sizeof.CONNECT_DATA - 0x4000] ; get pointer to alloc memory
|
||||||
mcall 68, 13 ; free
|
mcall 68, 13 ; free
|
||||||
mcall -1 ; close thread
|
mcall SF_TERMINATE_PROCESS ; close thread
|
||||||
|
|
||||||
include 'parser.inc'
|
include 'parser.inc'
|
||||||
|
|
||||||
@@ -307,6 +362,7 @@ EXPORT_DATA: ; in modules for this table using struct IMPORT_DATA
|
|||||||
|
|
||||||
dd find_uri_arg
|
dd find_uri_arg
|
||||||
dd find_header
|
dd find_header
|
||||||
|
dd read_http_body
|
||||||
dd Get_MIME_Type
|
dd Get_MIME_Type
|
||||||
dd close_server
|
dd close_server
|
||||||
|
|
||||||
@@ -333,7 +389,7 @@ srv_sockaddr:
|
|||||||
|
|
||||||
GLOBAL_DATA:
|
GLOBAL_DATA:
|
||||||
.modules rd 1 ; pointer to a doubly connected non-cyclic list (null terminator)
|
.modules rd 1 ; pointer to a doubly connected non-cyclic list (null terminator)
|
||||||
; next, prev, ptr of httpd_serv(), uri path
|
; next, prev, ptr of httpd_serv(), uri path
|
||||||
.work_dir rb 1024 ; max size path to work directory
|
.work_dir rb 1024 ; max size path to work directory
|
||||||
.work_dir.size rd 1 ; length string
|
.work_dir.size rd 1 ; length string
|
||||||
.modules_dir rb 1024
|
.modules_dir rb 1024
|
||||||
|
@@ -28,27 +28,20 @@
|
|||||||
|
|
||||||
; HTTP-date = rfc1123-date | rfc850-date | asctime-date
|
; HTTP-date = rfc1123-date | rfc850-date | asctime-date
|
||||||
; rfc1123-date = wkday "," SP date1 SP time SP "GMT"
|
; rfc1123-date = wkday "," SP date1 SP time SP "GMT"
|
||||||
; rfc850-date = weekday "," SP date2 SP time SP "GMT"
|
|
||||||
; asctime-date = wkday SP date3 SP time SP 4DIGIT
|
; asctime-date = wkday SP date3 SP time SP 4DIGIT
|
||||||
; date1 = 2DIGIT SP month SP 4DIGIT
|
; date1 = 2DIGIT SP month SP 4DIGIT
|
||||||
; ; day month year (e.g., 02 Jun 1982)
|
; ; day month year (e.g., 02 Jun 1982)
|
||||||
; date2 = 2DIGIT "-" month "-" 2DIGIT
|
|
||||||
; ; day-month-year (e.g., 02-Jun-82)
|
|
||||||
; date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))
|
; date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))
|
||||||
; ; month day (e.g., Jun 2)
|
; ; month day (e.g., Jun 2)
|
||||||
; time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
|
; time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
|
||||||
; ; 00:00:00 - 23:59:59
|
; ; 00:00:00 - 23:59:59
|
||||||
; wkday = "Mon" | "Tue" | "Wed"
|
; wkday = "Mon" | "Tue" | "Wed"
|
||||||
; | "Thu" | "Fri" | "Sat" | "Sun"
|
; | "Thu" | "Fri" | "Sat" | "Sun"
|
||||||
; weekday = "Monday" | "Tuesday" | "Wednesday"
|
|
||||||
; | "Thursday" | "Friday" | "Saturday" | "Sunday"
|
|
||||||
; month = "Jan" | "Feb" | "Mar" | "Apr"
|
; month = "Jan" | "Feb" | "Mar" | "Apr"
|
||||||
; | "May" | "Jun" | "Jul" | "Aug"
|
; | "May" | "Jun" | "Jul" | "Aug"
|
||||||
; | "Sep" | "Oct" | "Nov" | "Dec"
|
; | "Sep" | "Oct" | "Nov" | "Dec"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;serv_header:
|
;serv_header:
|
||||||
; .Accept_Ranges db 'Accept-Ranges: bytes',13,10
|
; .Accept_Ranges db 'Accept-Ranges: bytes',13,10
|
||||||
|
|
||||||
@@ -68,7 +61,7 @@
|
|||||||
|
|
||||||
align 4
|
align 4
|
||||||
default_http_version:
|
default_http_version:
|
||||||
db 'HTTP/1.1 '
|
db 'HTTP/1.1'
|
||||||
.length = $ - default_http_version
|
.length = $ - default_http_version
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
|
6
makefile
6
makefile
@@ -5,14 +5,16 @@ examples=$(wildcard example/*.asm)
|
|||||||
examples_obj=$(patsubst %.asm,%.obj,$(examples))
|
examples_obj=$(patsubst %.asm,%.obj,$(examples))
|
||||||
|
|
||||||
|
|
||||||
all: build-main build-mime $(examples_obj) copy_docs
|
all: build-main build-utils $(examples_obj) copy_docs
|
||||||
|
|
||||||
|
|
||||||
build-main:
|
build-main:
|
||||||
fasm httpd.asm $(OUTPUT_DIR)/httpd
|
fasm httpd.asm $(OUTPUT_DIR)/httpd
|
||||||
|
|
||||||
build-mime:
|
build-utils:
|
||||||
fasm utils/mime_types.asm $(OUTPUT_DIR)/mime_types.bin
|
fasm utils/mime_types.asm $(OUTPUT_DIR)/mime_types.bin
|
||||||
|
fasm utils/redirect.asm $(OUTPUT_MODULES)/redirect.obj
|
||||||
|
fasm utils/block_access.asm $(OUTPUT_MODULES)/block_access.obj
|
||||||
|
|
||||||
example/%.obj: example/%.asm
|
example/%.obj: example/%.asm
|
||||||
fasm $< $(OUTPUT_MODULES)/$(notdir $(basename $@)).obj
|
fasm $< $(OUTPUT_MODULES)/$(notdir $(basename $@)).obj
|
||||||
|
@@ -24,19 +24,22 @@ struct CONNECT_DATA ; 16*4 = 64 bytes
|
|||||||
sockaddr dd 16/4 ; socaddr connection
|
sockaddr dd 16/4 ; socaddr connection
|
||||||
buffer_request dd 0 ; pointer to buffer for geting message socket
|
buffer_request dd 0 ; pointer to buffer for geting message socket
|
||||||
request_size dd 0 ; size geted data from client
|
request_size dd 0 ; size geted data from client
|
||||||
end_buffer_request dd 0 ; для парсера
|
end_buffer_request dd 0 ; privat data for parser
|
||||||
buffer_response dd 0 ; pointer to buffwr for resp message
|
buffer_response dd 0 ; pointer to buffwr for resp message
|
||||||
http_method dd 0 ; указатель на строку
|
http_method dd 0 ; pointer to string
|
||||||
http_verion dd 0 ; pointer to the asciiz string with protocol version
|
http_verion dd 0 ; pointer to the asciiz string with
|
||||||
|
; protocol version
|
||||||
num_headers dd 0 ; number items in REQUEST_DATA
|
num_headers dd 0 ; number items in REQUEST_DATA
|
||||||
http_headers dd 0 ; pointer to array REQUEST_DATA of HTTP headers
|
http_headers dd 0 ; pointer to array REQUEST_DATA of HTTP headers
|
||||||
uri_scheme dd 0 ; указатель на схему
|
uri_scheme dd 0 ; pointer to string
|
||||||
uri_authority dd 0 ; pointer to string(%XX not converted)
|
uri_authority dd 0 ; pointer to string(%XX not converted)
|
||||||
uri_path dd 0 ; указатель на декодированный путь к ресурсу(без параметров)
|
uri_path dd 0 ; pointer to converted uri path in UTF-8 string
|
||||||
num_uri_args dd 0 ;
|
num_uri_args dd 0 ;
|
||||||
uri_arg dd 0 ; pointer to the REQUEST_DATA array of string uri arguments
|
uri_arg dd 0 ; pointer to the REQUEST_DATA array of string
|
||||||
uri_fragment dd 0 ; указатель на строку
|
; uri arguments
|
||||||
message_body dd 0 ; указатель на тело http запроса
|
uri_fragment dd 0 ; pointer to string
|
||||||
|
message_body dd 0 ; pointer to body of http request
|
||||||
|
message_body_len dd 0 ; length message_body in buffer
|
||||||
ends
|
ends
|
||||||
|
|
||||||
struct FILED
|
struct FILED
|
||||||
@@ -69,11 +72,11 @@ struct IMPORT_DATA
|
|||||||
FileInfo rd 1
|
FileInfo rd 1
|
||||||
;FS_STATUS stdcall FileInfo(char* path, void* buffer);
|
;FS_STATUS stdcall FileInfo(char* path, void* buffer);
|
||||||
FileRead rd 1
|
FileRead rd 1
|
||||||
;uint32_t stdcall FileRead(FILED* file, void* buffer, uint32_t size);
|
;uint32_t stdcall FileRead(FILED* file, void* buff, uint32_t size);
|
||||||
FileSetOffset rd 1
|
FileSetOffset rd 1
|
||||||
;void stdcall FileSetOffset(FILED* file, uint64_t offset);
|
;void stdcall FileSetOffset(FILED* file, uint64_t offset);
|
||||||
FileReadOfName rd 1
|
FileReadOfName rd 1
|
||||||
;uint32_t stdcall FileReadOfName(char* path, void* buffer, uint32_t size);
|
;uint32_t FileReadOfName(char* path, void* buff, uint32_t size);
|
||||||
;---------------------------------------------------------------------
|
;---------------------------------------------------------------------
|
||||||
send_resp rd 1
|
send_resp rd 1
|
||||||
; send_resp(RESPD* ptr, char* content, uint32_t length);
|
; send_resp(RESPD* ptr, char* content, uint32_t length);
|
||||||
@@ -85,9 +88,9 @@ struct IMPORT_DATA
|
|||||||
; void set_http_status(RESPD* ptr, uint32_t status);
|
; void set_http_status(RESPD* ptr, uint32_t status);
|
||||||
; status in '200' format
|
; status in '200' format
|
||||||
add_http_header rd 1
|
add_http_header rd 1
|
||||||
; uint32_t add_http_header(RESPD* ptr, char* ptr_header, uint32_t length);
|
; uint32_t add_http_header(RESPD* ptr, char* header, uint32_t length);
|
||||||
del_http_header rd 1
|
del_http_header rd 1
|
||||||
; uint32_t del_http_header(RESPD* ptr, char* ptr_header);
|
; uint32_t del_http_header(RESPD* ptr, char* header);
|
||||||
; no del std header
|
; no del std header
|
||||||
set_http_ver rd 1
|
set_http_ver rd 1
|
||||||
; void set_http_ver(RESPD* ptr, char* version, uint32_t length);
|
; void set_http_ver(RESPD* ptr, char* version, uint32_t length);
|
||||||
@@ -101,6 +104,8 @@ struct IMPORT_DATA
|
|||||||
;char* find_uri_arg(CONNECT_DATA* session, char* key);
|
;char* find_uri_arg(CONNECT_DATA* session, char* key);
|
||||||
find_header rd 1
|
find_header rd 1
|
||||||
;char* find_header(CONNECT_DATA* session, char* key);
|
;char* find_header(CONNECT_DATA* session, char* key);
|
||||||
|
read_http_body rd 1
|
||||||
|
;uint32_t read_http_body(CONNECT_DATA* session, char* buff, uint32_t len)
|
||||||
get_mime_type rd 1
|
get_mime_type rd 1
|
||||||
;char* stdcall Get_MIME_Type(FILED* fd); //path is ASCIIZ string
|
;char* stdcall Get_MIME_Type(FILED* fd); //path is ASCIIZ string
|
||||||
close_server rd 1
|
close_server rd 1
|
||||||
|
18
parser.inc
18
parser.inc
@@ -240,7 +240,15 @@ parse_headers:
|
|||||||
jnz @b
|
jnz @b
|
||||||
|
|
||||||
mov byte[ecx], 0 ; \0
|
mov byte[ecx], 0 ; \0
|
||||||
inc ecx
|
@@:
|
||||||
|
inc ecx
|
||||||
|
|
||||||
|
cmp ecx, eax
|
||||||
|
jae .error_exit
|
||||||
|
|
||||||
|
cmp byte[ecx], ' '
|
||||||
|
je @b
|
||||||
|
|
||||||
; save pointer to value
|
; save pointer to value
|
||||||
mov dword[BASE_ARRAY_HEADERS + (edx-1)*8 + 4], ecx
|
mov dword[BASE_ARRAY_HEADERS + (edx-1)*8 + 4], ecx
|
||||||
@@:
|
@@:
|
||||||
@@ -252,6 +260,11 @@ parse_headers:
|
|||||||
cmp word[ecx - 1], 0x0A0D
|
cmp word[ecx - 1], 0x0A0D
|
||||||
jnz @b
|
jnz @b
|
||||||
|
|
||||||
|
cmp byte[ecx + 1], ' ' ; SP
|
||||||
|
je @b
|
||||||
|
cmp byte[ecx + 1], 0x09 ; HT
|
||||||
|
je @b
|
||||||
|
|
||||||
mov byte[ecx - 1], 0
|
mov byte[ecx - 1], 0
|
||||||
inc ecx ; set offset on new string
|
inc ecx ; set offset on new string
|
||||||
jmp .new_str
|
jmp .new_str
|
||||||
@@ -328,6 +341,9 @@ parse_http_query:
|
|||||||
je @f
|
je @f
|
||||||
|
|
||||||
mov [esi + CONNECT_DATA.message_body], ecx
|
mov [esi + CONNECT_DATA.message_body], ecx
|
||||||
|
mov eax, [esi + CONNECT_DATA.end_buffer_request]
|
||||||
|
sub eax, ecx
|
||||||
|
mov [esi + CONNECT_DATA.message_body_len], eax
|
||||||
@@:
|
@@:
|
||||||
mov eax, esi
|
mov eax, esi
|
||||||
ret
|
ret
|
||||||
|
15
readme.md
15
readme.md
@@ -20,19 +20,14 @@
|
|||||||
Подробная настройка сервера описана в документации, расположенной в директории doc этого репозитория.
|
Подробная настройка сервера описана в документации, расположенной в директории doc этого репозитория.
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
### Tasks on version 0.3.0
|
||||||
### Tasks on version 0.2.5
|
- Добавить модуль демонстрации websockets
|
||||||
- Update srv_control module
|
- Добавить демонстрационный модуль на Си
|
||||||
|
- Добавить демонстрационный модуль на FPC
|
||||||
- Добавить модуль тестовой авторизации(base64 code in header)
|
- Добавить модуль тестовой авторизации(base64 code in header)
|
||||||
- Добавить модуль генерации более сложного контента
|
- Добавить модуль генерации более сложного контента
|
||||||
(create json object with data of CSV table)
|
(create json object with data of CSV table)
|
||||||
- Добавить демонстрационный модуль на Си
|
- Добавить поддержку TLS шифрования с использованием MbedTLS
|
||||||
- Добавить демонстрационный модуль на FPC
|
|
||||||
- Добавить модуль демонстрации cookie
|
|
||||||
- Добавить модуль демонстрации websockets
|
|
||||||
|
|
||||||
### Tasks on version 0.3.0
|
|
||||||
- Добавить поддержку TLS шифрования с использованием MbedTLS
|
|
||||||
|
|
||||||
## Bugs
|
## Bugs
|
||||||
- В ходе тестов был обнаружена ошибка отправки "больших" файлов. Это баг сетевого стека;
|
- В ходе тестов был обнаружена ошибка отправки "больших" файлов. Это баг сетевого стека;
|
||||||
|
@@ -147,8 +147,9 @@ load_settings:
|
|||||||
; copy uri path
|
; copy uri path
|
||||||
push esi edi
|
push esi edi
|
||||||
mov esi, [esp + 4*2 + 4*3] ; name
|
mov esi, [esp + 4*2 + 4*3] ; name
|
||||||
lea edi, [eax + HTTPD_MODULE.uri_path + 1]
|
;lea edi, [eax + HTTPD_MODULE.uri_path + 1]
|
||||||
mov byte[edi - 1], '/'
|
;mov byte[edi - 1], '/'
|
||||||
|
lea edi, [eax + HTTPD_MODULE.uri_path]
|
||||||
@@:
|
@@:
|
||||||
movsb
|
movsb
|
||||||
cmp byte[edi - 1], 0
|
cmp byte[edi - 1], 0
|
||||||
@@ -162,7 +163,7 @@ load_settings:
|
|||||||
cmp byte[edi - 1], 0
|
cmp byte[edi - 1], 0
|
||||||
je @f
|
je @f
|
||||||
|
|
||||||
cmp byte[esi - 1], ';'
|
cmp byte[esi - 1], ','
|
||||||
jne @b
|
jne @b
|
||||||
mov byte[edi - 1], 0
|
mov byte[edi - 1], 0
|
||||||
mov [GLOBAL_DATA._module_cmd], esi
|
mov [GLOBAL_DATA._module_cmd], esi
|
||||||
@@ -188,6 +189,8 @@ load_settings:
|
|||||||
jmp .add_module.exit
|
jmp .add_module.exit
|
||||||
@@: ; good
|
@@: ; good
|
||||||
; init httpd module
|
; init httpd module
|
||||||
|
lea eax, [esi + HTTPD_MODULE.uri_path]
|
||||||
|
push eax
|
||||||
push dword[GLOBAL_DATA._module_cmd]
|
push dword[GLOBAL_DATA._module_cmd]
|
||||||
push dword EXPORT_DATA
|
push dword EXPORT_DATA
|
||||||
invoke httpd_import.init
|
invoke httpd_import.init
|
||||||
|
90
sys_func.inc
90
sys_func.inc
@@ -110,7 +110,8 @@ ECONNABORTED = 53
|
|||||||
; stdcall socket(uint32_t domain, type, proto)
|
; stdcall socket(uint32_t domain, type, proto)
|
||||||
netfunc_socket:
|
netfunc_socket:
|
||||||
push ebx esi
|
push ebx esi
|
||||||
mcall 75, 0, [esp + 2*4 + 4], [esp + 2*4 + 8], [esp + 2*4 + 12]
|
mcall SF_NETWORK_SOCKET, SSF_OPEN,\
|
||||||
|
[esp + 2*4 + 4], [esp + 2*4 + 8], [esp + 2*4 + 12]
|
||||||
;mov [fs:0], ebx ;errno
|
;mov [fs:0], ebx ;errno
|
||||||
pop esi ebx
|
pop esi ebx
|
||||||
ret 12
|
ret 12
|
||||||
@@ -118,48 +119,53 @@ netfunc_socket:
|
|||||||
;stdcall close(uint32_t sock_number);
|
;stdcall close(uint32_t sock_number);
|
||||||
netfunc_close:
|
netfunc_close:
|
||||||
push ebx
|
push ebx
|
||||||
mcall 75, 1, [esp + 4 + 4]
|
mcall SF_NETWORK_SOCKET, SSF_CLOSE, [esp + 4 + 4]
|
||||||
pop ebx
|
pop ebx
|
||||||
ret 4
|
ret 4
|
||||||
|
|
||||||
;stdcall bind(uint32_t sock_num, sockaddr* _sockaddr_struct, uint32_t sockaddr_size)
|
;stdcall bind(uint32_t sock_num, sockaddr* _sockaddr_struct, uint32_t sockaddr_size)
|
||||||
netfunc_bind:
|
netfunc_bind:
|
||||||
push esi ebx
|
push esi ebx
|
||||||
mcall 75, 2, [esp + 2*4 + 4], [esp + 2*4 + 8], [esp + 2*4 + 12]
|
mcall SF_NETWORK_SOCKET, SSF_BIND,\
|
||||||
|
[esp + 2*4 + 4], [esp + 2*4 + 8], [esp + 2*4 + 12]
|
||||||
pop ebx esi
|
pop ebx esi
|
||||||
ret 12
|
ret 12
|
||||||
|
|
||||||
;stdcall listen(uint32_t socket, uint32_t backlog)
|
;stdcall listen(uint32_t socket, uint32_t backlog)
|
||||||
netfunc_listen:
|
netfunc_listen:
|
||||||
push ebx
|
push ebx
|
||||||
mcall 75, 3, [esp + 4 + 4], [esp + 4 + 8]
|
mcall SF_NETWORK_SOCKET, SSF_LISTEN,\
|
||||||
|
[esp + 4 + 4], [esp + 4 + 8]
|
||||||
pop ebx
|
pop ebx
|
||||||
ret 8
|
ret 8
|
||||||
;stdcall accept(uint32_t socket, sockaddr* new_sockaddr_struct, uint32_t sockaddr_size)
|
;stdcall accept(uint32_t socket, sockaddr* new_sockaddr_struct, uint32_t sockaddr_size)
|
||||||
netfunc_accept:
|
netfunc_accept:
|
||||||
push esi ebx
|
push esi ebx
|
||||||
mcall 75, 5, [esp + 2*4 + 4], [esp + 2*4 + 8], [esp + 2*4 + 12]
|
mcall SF_NETWORK_SOCKET, SSF_ACCEPT,\
|
||||||
|
[esp + 2*4 + 4], [esp + 2*4 + 8], [esp + 2*4 + 12]
|
||||||
pop ebx esi
|
pop ebx esi
|
||||||
ret 12
|
ret 12
|
||||||
;stdcall send(uint32_t socket, void* buff, uint32_t len_buff, uint32_t flags)
|
;stdcall send(uint32_t socket, void* buff, uint32_t len_buff, uint32_t flags)
|
||||||
netfunc_send:
|
netfunc_send:
|
||||||
push esi edi ebx
|
push esi edi ebx
|
||||||
mcall 75, 6, [esp + 3*4 + 4], [esp + 3*4 + 8],\
|
mcall SF_NETWORK_SOCKET, SSF_SEND,\
|
||||||
[esp + 3*4 + 12], [esp + 3*4 + 16]
|
[esp + 3*4 + 4], [esp + 3*4 + 8],\
|
||||||
|
[esp + 3*4 + 12], [esp + 3*4 + 16]
|
||||||
pop ebx edi esi
|
pop ebx edi esi
|
||||||
ret 16
|
ret 16
|
||||||
;stdcall recv(uint32_t socket, void* buff, uint32_t len_buff, uint32_t flags)
|
;stdcall recv(uint32_t socket, void* buff, uint32_t len_buff, uint32_t flags)
|
||||||
netfunc_recv:
|
netfunc_recv:
|
||||||
push esi edi ebx
|
push esi edi ebx
|
||||||
mcall 75, 7, [esp + 3*4 + 4], [esp + 3*4 + 8],\
|
mcall SF_NETWORK_SOCKET, SSF_RECEIVE,\
|
||||||
[esp + 3*4 + 12], [esp + 3*4 + 16]
|
[esp + 3*4 + 4], [esp + 3*4 + 8],\
|
||||||
|
[esp + 3*4 + 12], [esp + 3*4 + 16]
|
||||||
pop ebx edi esi
|
pop ebx edi esi
|
||||||
ret 16
|
ret 16
|
||||||
|
|
||||||
; stdcall CreatThread(void* entry_thread);
|
; stdcall CreatThread(void* entry_thread);
|
||||||
CreateThread:
|
CreateThread:
|
||||||
push ebx edi
|
push ebx edi
|
||||||
mcall 68, 12, 0x4000 ;alloc memory 16 kib for stack
|
mcall SF_SYS_MISC, SSF_MEM_ALLOC, 0x4000 ;alloc memory 16 kib for stack
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
|
|
||||||
@@ -170,20 +176,20 @@ CreateThread:
|
|||||||
xor eax, eax
|
xor eax, eax
|
||||||
rep stosd
|
rep stosd
|
||||||
add edx, 0x4000
|
add edx, 0x4000
|
||||||
mcall 51, 1, [esp + 2*4 + 4] ;<- thread entry
|
mcall SF_CREATE_THREAD, 1, [esp + 2*4 + 4] ;<- thread entry
|
||||||
.err:
|
.err:
|
||||||
pop ebx edi
|
pop ebx edi
|
||||||
ret 4
|
ret 4
|
||||||
; stdcall Alloc(uint32_t size)
|
; stdcall Alloc(uint32_t size)
|
||||||
Alloc:
|
Alloc:
|
||||||
push ebx
|
push ebx
|
||||||
mcall 68, 12, [esp + 4 + 4]
|
mcall SF_SYS_MISC, SSF_MEM_ALLOC, [esp + 4 + 4]
|
||||||
pop ebx
|
pop ebx
|
||||||
ret 4
|
ret 4
|
||||||
; stdcall Free(void* ptr)
|
; stdcall Free(void* ptr)
|
||||||
Free:
|
Free:
|
||||||
push ebx
|
push ebx
|
||||||
mcall 68, 13, [esp + 4 + 4]
|
mcall SF_SYS_MISC, SSF_MEM_FREE, [esp + 4 + 4]
|
||||||
pop ebx
|
pop ebx
|
||||||
ret 4
|
ret 4
|
||||||
|
|
||||||
@@ -195,7 +201,7 @@ FileInfo:
|
|||||||
mov edx, [esp + 8]
|
mov edx, [esp + 8]
|
||||||
push ebx
|
push ebx
|
||||||
sub esp, sizeof.FILED
|
sub esp, sizeof.FILED
|
||||||
mov dword[esp + FILED.opcode], 5 ; file info
|
mov dword[esp + FILED.opcode], SSF_GET_INFO ; file info
|
||||||
mov dword[esp + FILED.offset + 4], 0 ; zero flag
|
mov dword[esp + FILED.offset + 4], 0 ; zero flag
|
||||||
mov dword[esp + FILED.buffer], edx
|
mov dword[esp + FILED.buffer], edx
|
||||||
mov dword[esp + FILED.name_encode], 3 ;UTF-8
|
mov dword[esp + FILED.name_encode], 3 ;UTF-8
|
||||||
@@ -235,7 +241,7 @@ FileRead:
|
|||||||
mov edx, [esp + 12]
|
mov edx, [esp + 12]
|
||||||
|
|
||||||
push ebx
|
push ebx
|
||||||
mov [eax + FILED.opcode], 0
|
mov [eax + FILED.opcode], SSF_READ_FILE
|
||||||
mov [eax + FILED.size], edx
|
mov [eax + FILED.size], edx
|
||||||
mov [eax + FILED.buffer], ecx
|
mov [eax + FILED.buffer], ecx
|
||||||
|
|
||||||
@@ -244,7 +250,7 @@ FileRead:
|
|||||||
|
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz @f
|
jz @f
|
||||||
cmp eax, 6 ; EOF
|
cmp eax, FSERR_END_OF_FILE ; EOF
|
||||||
je @f
|
je @f
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
@@:
|
@@:
|
||||||
@@ -276,7 +282,7 @@ FileReadOfName:
|
|||||||
mov eax, [esp + 12]
|
mov eax, [esp + 12]
|
||||||
push ebx
|
push ebx
|
||||||
sub esp, sizeof.FILED
|
sub esp, sizeof.FILED
|
||||||
mov dword[esp + FILED.opcode], 0
|
mov dword[esp + FILED.opcode], SSF_READ_FILE
|
||||||
mov dword[esp + FILED.offset], 0
|
mov dword[esp + FILED.offset], 0
|
||||||
mov dword[esp + FILED.offset + 4], 0
|
mov dword[esp + FILED.offset + 4], 0
|
||||||
mov dword[esp + FILED.size], eax
|
mov dword[esp + FILED.size], eax
|
||||||
@@ -287,7 +293,7 @@ FileReadOfName:
|
|||||||
mcall 80
|
mcall 80
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz @f
|
jz @f
|
||||||
cmp eax, 6 ; EOF
|
cmp eax, FSERR_END_OF_FILE ; EOF
|
||||||
je @f
|
je @f
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
@@:
|
@@:
|
||||||
@@ -794,6 +800,54 @@ finish_send_resp:
|
|||||||
.exit:
|
.exit:
|
||||||
ret 4
|
ret 4
|
||||||
|
|
||||||
|
; uint32_t read_http_body(CONNECT_DATA* session, char* buff, uint32_t len)
|
||||||
|
read_http_body:
|
||||||
|
push esi edi
|
||||||
|
; check length in buffer
|
||||||
|
xor eax, eax
|
||||||
|
mov edx, [esp + 4*2 + 4]
|
||||||
|
mov ecx, [esp + 4*2 + 12]
|
||||||
|
mov edi, [esp + 4*2 + 8]
|
||||||
|
cmp dword[edx + CONNECT_DATA.message_body_len], 0
|
||||||
|
jz .get_new_buffer
|
||||||
|
.local_buffer:
|
||||||
|
mov esi, [edx + CONNECT_DATA.message_body]
|
||||||
|
cmp ecx, [edx + CONNECT_DATA.message_body_len]
|
||||||
|
pushfd
|
||||||
|
jbe @f
|
||||||
|
mov ecx, [edx + CONNECT_DATA.message_body_len]
|
||||||
|
@@:
|
||||||
|
sub [edx + CONNECT_DATA.message_body_len], ecx
|
||||||
|
add [edx + CONNECT_DATA.message_body], ecx
|
||||||
|
push ecx
|
||||||
|
rep movsb
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
popfd
|
||||||
|
jbe .exit
|
||||||
|
sub ecx, eax
|
||||||
|
; ecx - not readed bytes
|
||||||
|
; eax - count reading bytes
|
||||||
|
.get_new_buffer:
|
||||||
|
push eax
|
||||||
|
|
||||||
|
;read data from socket
|
||||||
|
push dword 0 ;flags
|
||||||
|
push ecx
|
||||||
|
push esi
|
||||||
|
push dword[edx + CONNECT_DATA.socket]
|
||||||
|
call netfunc_recv
|
||||||
|
|
||||||
|
cmp eax, -1
|
||||||
|
je .exit
|
||||||
|
|
||||||
|
add eax, [esp]
|
||||||
|
add esp, 4
|
||||||
|
.exit:
|
||||||
|
pop edi esi
|
||||||
|
ret 12
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;void close_server()
|
;void close_server()
|
||||||
; TODO: added free HTTPD_MODULE structures
|
; TODO: added free HTTPD_MODULE structures
|
||||||
|
117
utils/block_access.asm
Normal file
117
utils/block_access.asm
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
; test api 0.1.0 - get cmd path and get context unit
|
||||||
|
format MS COFF ;<- this is lib format
|
||||||
|
public @EXPORT as 'EXPORTS'
|
||||||
|
|
||||||
|
NO_DEBUG_INPUT = 0
|
||||||
|
include "macros.inc"
|
||||||
|
purge mov,add,sub
|
||||||
|
include "proc32.inc"
|
||||||
|
|
||||||
|
include '../module_api.inc'
|
||||||
|
|
||||||
|
section '.flat' code readable align 16
|
||||||
|
|
||||||
|
; cmdline: <http_code> <text for body http response>
|
||||||
|
|
||||||
|
unit_init:
|
||||||
|
xor eax, eax
|
||||||
|
push esi edi
|
||||||
|
mov esi, [esp + 4*2 + 4]
|
||||||
|
|
||||||
|
cmp dword[esi + IMPORT_DATA.version], API_VERSION
|
||||||
|
jne .exit
|
||||||
|
|
||||||
|
mov edi, IMPORT
|
||||||
|
mov ecx, [esi + IMPORT_DATA.sizeof]
|
||||||
|
shr ecx, 2 ; div 4
|
||||||
|
rep movsd
|
||||||
|
|
||||||
|
mov esi, [esp + 4*2 + 8]
|
||||||
|
test esi, esi
|
||||||
|
jnz @f
|
||||||
|
xor ecx, ecx
|
||||||
|
jmp .alloc
|
||||||
|
@@:
|
||||||
|
cmp byte[esi], ' '
|
||||||
|
jne @f
|
||||||
|
inc esi
|
||||||
|
jmp @b
|
||||||
|
@@:
|
||||||
|
xor ecx, ecx
|
||||||
|
dec ecx
|
||||||
|
@@:
|
||||||
|
inc ecx
|
||||||
|
cmp byte[esi+ecx], 0
|
||||||
|
jnz @b
|
||||||
|
.alloc:
|
||||||
|
add ecx, 4
|
||||||
|
push ecx
|
||||||
|
; create unit context
|
||||||
|
invoke IMPORT.Alloc, ecx ; for cmd path
|
||||||
|
pop ecx
|
||||||
|
test eax, eax
|
||||||
|
jz .exit
|
||||||
|
|
||||||
|
mov edi, eax
|
||||||
|
add edi, 4
|
||||||
|
sub ecx, 4
|
||||||
|
mov [eax], ecx
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
;unit init successful
|
||||||
|
.exit:
|
||||||
|
pop edi esi
|
||||||
|
ret 12
|
||||||
|
|
||||||
|
|
||||||
|
server_entry:
|
||||||
|
push esi edi
|
||||||
|
mov esi, [esp + 4*2 + 4] ; request context
|
||||||
|
|
||||||
|
mov edi, [esp + 4*2 + 8] ; unit context
|
||||||
|
add edi, 4
|
||||||
|
|
||||||
|
invoke IMPORT.create_resp, esi, 0
|
||||||
|
test eax, eax
|
||||||
|
jz .exit
|
||||||
|
|
||||||
|
mov esi, eax
|
||||||
|
|
||||||
|
mov eax, '403'
|
||||||
|
cmp dword[edi - 4], 3
|
||||||
|
jb @f
|
||||||
|
mov eax, [edi]
|
||||||
|
@@:
|
||||||
|
invoke IMPORT.set_http_status, esi, eax
|
||||||
|
|
||||||
|
lea eax, [edi + 4]
|
||||||
|
mov ecx, [edi - 4]
|
||||||
|
sub ecx, 4
|
||||||
|
cmp dword[edi - 4], 5
|
||||||
|
jae @f
|
||||||
|
|
||||||
|
xor eax, eax
|
||||||
|
xor ecx, ecx
|
||||||
|
@@:
|
||||||
|
invoke IMPORT.send_resp, esi, eax, ecx
|
||||||
|
invoke IMPORT.destruct_resp, esi
|
||||||
|
.exit:
|
||||||
|
pop edi esi
|
||||||
|
ret 8
|
||||||
|
|
||||||
|
server_close:
|
||||||
|
push dword[esp + 4]
|
||||||
|
invoke IMPORT.Free
|
||||||
|
ret 4
|
||||||
|
|
||||||
|
|
||||||
|
section '.data' data readable writable align 16
|
||||||
|
|
||||||
|
@EXPORT:
|
||||||
|
export \
|
||||||
|
unit_init, 'httpd_init', \
|
||||||
|
server_entry, 'httpd_serv',\
|
||||||
|
server_close, 'httpd_close'
|
||||||
|
|
||||||
|
|
||||||
|
IMPORT IMPORT_DATA
|
101
utils/redirect.asm
Normal file
101
utils/redirect.asm
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
; test api 0.1.0 - get cmd path and get context unit
|
||||||
|
format MS COFF ;<- this is lib format
|
||||||
|
public @EXPORT as 'EXPORTS'
|
||||||
|
|
||||||
|
NO_DEBUG_INPUT = 0
|
||||||
|
include "macros.inc"
|
||||||
|
purge mov,add,sub
|
||||||
|
include "proc32.inc"
|
||||||
|
|
||||||
|
include '../module_api.inc'
|
||||||
|
|
||||||
|
section '.flat' code readable align 16
|
||||||
|
|
||||||
|
; cmdline: <redirect uri path>
|
||||||
|
|
||||||
|
unit_init:
|
||||||
|
xor eax, eax
|
||||||
|
push esi edi
|
||||||
|
mov esi, [esp + 4*2 + 4]
|
||||||
|
|
||||||
|
cmp dword[esi + IMPORT_DATA.version], API_VERSION
|
||||||
|
jne .exit
|
||||||
|
|
||||||
|
mov edi, IMPORT
|
||||||
|
mov ecx, [esi + IMPORT_DATA.sizeof]
|
||||||
|
shr ecx, 2 ; div 4
|
||||||
|
rep movsd
|
||||||
|
|
||||||
|
; create unit context
|
||||||
|
invoke IMPORT.Alloc, 4096 ; for cmd path
|
||||||
|
test eax, eax
|
||||||
|
jz .exit
|
||||||
|
|
||||||
|
mov dword[eax], 0
|
||||||
|
mov dword[eax + 4], 'Loca'
|
||||||
|
mov dword[eax + 8], 'tion'
|
||||||
|
mov word[eax + 12], ': '
|
||||||
|
mov edi, eax
|
||||||
|
add edi, 14
|
||||||
|
|
||||||
|
mov esi, [esp + 4*2 + 8]
|
||||||
|
@@:
|
||||||
|
inc esi
|
||||||
|
cmp byte[esi - 1], ' '
|
||||||
|
je @b
|
||||||
|
dec esi
|
||||||
|
@@:
|
||||||
|
cmp byte[esi], 0
|
||||||
|
jz @f
|
||||||
|
movsb
|
||||||
|
jmp @b
|
||||||
|
@@:
|
||||||
|
sub edi, eax
|
||||||
|
sub edi, 4
|
||||||
|
mov [eax], edi
|
||||||
|
;unit init successful
|
||||||
|
.exit:
|
||||||
|
pop edi esi
|
||||||
|
ret 12
|
||||||
|
|
||||||
|
|
||||||
|
server_entry:
|
||||||
|
push esi edi
|
||||||
|
mov esi, [esp + 4*2 + 4] ; request context
|
||||||
|
|
||||||
|
mov edi, [esp + 4*2 + 8] ; unit context
|
||||||
|
add edi, 4
|
||||||
|
|
||||||
|
invoke IMPORT.create_resp, esi, FLAG_NO_CONTENT_ENCODING\
|
||||||
|
+ FLAG_NO_CONTENT_TYPE\
|
||||||
|
+ FLAG_NO_CACHE_CONTROL
|
||||||
|
test eax, eax
|
||||||
|
jz .exit
|
||||||
|
|
||||||
|
mov esi, eax
|
||||||
|
|
||||||
|
invoke IMPORT.set_http_status, esi, dword '301'
|
||||||
|
invoke IMPORT.add_http_header, esi, edi, [edi - 4]
|
||||||
|
|
||||||
|
invoke IMPORT.begin_send_resp, esi, 0, 0
|
||||||
|
invoke IMPORT.destruct_resp, esi
|
||||||
|
.exit:
|
||||||
|
pop edi esi
|
||||||
|
ret 8
|
||||||
|
|
||||||
|
server_close:
|
||||||
|
push dword[esp + 4]
|
||||||
|
invoke IMPORT.Free
|
||||||
|
ret 4
|
||||||
|
|
||||||
|
|
||||||
|
section '.data' data readable writable align 16
|
||||||
|
|
||||||
|
@EXPORT:
|
||||||
|
export \
|
||||||
|
unit_init, 'httpd_init', \
|
||||||
|
server_entry, 'httpd_serv',\
|
||||||
|
server_close, 'httpd_close'
|
||||||
|
|
||||||
|
|
||||||
|
IMPORT IMPORT_DATA
|
Reference in New Issue
Block a user