Самьюэл Алекс
Шрифт:
/* HTTP-ответ, заголовок и шаблон страницы на случай,
когда запрашиваемый документ не найден. */
static char* not_found_response_template =
"HTTP/1.0 404 Not Found\n"
"Content-type: text/html\n"
"\n"
"<html>\n"
" <body>\n"
" <h1>Not Found</h1>\n"
" The requested URL %s was not found on this server.\n"
" </body>\n"
"</html>\n";
/* HTTP-ответ, заголовок к шаблон страницы на случай,
когда запрашивается непонятный метод */
static char* bad_method_response_template =
"HTTP/1.0 501 Method Not Implemented\n"
"Content-type: text/html\n"
"\n"
"<html>\n"
" <body>\n"
" <h1>Method Not Implemented</h1>\n"
" The method %s is not implemented by this server.\n"
" </body>\n"
"</html>\n";
/* Обработчик сигнала SIGCHLD, удаляющий завершившиеся
дочерние процессы. */
static void clean_up_child_process(int signal_number) {
int status;
wait(&status);
}
/* Обработка HTTP-запроса "GET" к странице PAGE и
запись результата в файл с дескриптором CONNECTION_FD. */
static void handle_get(int connection_fd, const char* page) {
struct server_module* module = NULL;
/* Убеждаемся, что имя страницы начинается с косой черты и
не содержит других символов косой черты, так как
подкаталоги не поддерживаются. */
if (*page == '/' && strchr(page + 1, '/') == NULL) {
char module_file_name[64];
/* Имя страницы правильно. Формируем имя модуля, добавляя
расширение ".so" к имени страницы. */
snprintf(module_file_name, sizeof(module_file_name),
"%s.so", page + 1);
/* Попытка открытия модуля. */
module = module_open(module_file_name);
}
if (module == NULL) {
/* Имя страницы неправильно сформировано или не удалось
открыть модуль с указанным именем. В любом случае
возвращается HTTP-ответ "404. Not Found". */
char response[1024];
/* Формирование ответного сообщения. */
snprintf(response, sizeof(response),
not_found_response_template, page);
/* Отправка его клиенту. */
write(connection_fd, response, strlen(response));
} else {
/* Запрашиваемый модуль успешно загружен. */
/* Выдача HTTP-ответа, обозначающего успешную обработку
запроса, и HTTP-заголовка для HTML-страницы. */
write(connection_fd, ok_response, strlen(ok_response));
/* Вызов модуля, генерирующего HTML-код страницы и
записывающего этот код в указанный файл. */
(*module->generate_function)(connection_fd);
/* Работа с модулем окончена. */
module_close(module);
}
}
/* Обработка клиентского запроса на подключение. */
static void handle_connection(int connection_fd) {
char buffer[256];
ssize_t bytes_read;