Skip to content

AmDogma/42Webserv

Repository files navigation

webserver

  • (автоперевод сабжекта, переведенного с французского на английский)

Здесь вы окончательно поймете почему URL начинается с HTTP. Цель данного проекта написать собственный HTTP сервер. Вы должны будете протестировать его на реальном браузере. HTTP один из самых используемых протоколов в интернете. Знания в данной таинственной области является очень полезным для студента, даже если вы никогда не будете работать с веб-сайтами.

Введение

The Hypertext transfer protocol (Протокол передачи гипертекста) или HTTP — протокол прикладного уровня применяемый в распределенных, совместных и гипермедийных информационных системах. HTTP является фундаментом для передачи данных по Всемирной компьютерной сети (World Wide Web). В HTTP гипертекстовые документы включают в себя гиперссылки на другие ресурсы, к которым пользователь легко может получить доступ, например простой клик мышки по картинке в веб-браузере. Протокол HTTP был разработан, чтобы облегчить работу с гипертекстом, что в свою очередь облегчает работу со Всемирной сетью. Первичным функционалом веб-сервера являются хранение, обработка веб-страниц, также доставка веб-страниц клиентам. Связь между клиентом и сервером осуществляется за счет использования протокола передачи гипертекста HTTP. Обычно в качестве объекта доставки выступают HTML документы, которые могут включать изображения, таблицы стилей и скрипты в дополнении к текстовому контенту. Для веб-сайта с высоким трафиком могут использоваться несколько веб-серверов. В качестве агента пользователя в основном выступают веб-браузер или поисковый робот. Они начинают коммуникацию путем отправки запроса на получение определенного ресурса используя HTTP, и сервер в ответ отправляет содержимое ресурса, в ином случае сообщение об ошибке. Под ресурсом обычно имеется в виду реальный файл, находящийся во вторичном хранилище сервера, но это является необязательным кейсом и зависит от того как реализован веб-сервер. Если основной функционал веб-сервера занимается хранением, обработкой и доставкой контента, то в полной реализации веб-сервера включены разные способы получения контента от клиентов. Данная реализация дает возможность получения веб-форм, включая загрузку (upload) файлов.

Основная часть

Название программы: webserv Файлы: Любые Makefile: Необходим Функции: Все функции в С++ 98. htons, htonl, ntohs, ntohl, select, poll, epoll, kqueue, socket, accept, listen, send, recv, bind, connect, inet_addr, setsockopt, getsockname, fcntl. libft: Запрещен Описание: Напишите HTTP сервер на С++ 98. Однако всегда предпочтительнее использовать аналоги в С++. При программировании на С++ вы должны использовать С++98 стандарт. Ваш проект должен компилироваться в данном стандарте. Внешние библиотеки запрещены, Boost и т.д. Старайтесь всегда использовать С++ стиль написания кода (например вместо <string.h>) Ваш сервер должен быть совместим с веб-браузером, который вы выбрали. Мы будем предполагать, что Nginx совместим с HTTP 1.1 и может использоваться для сравнение заголовков и ответов. В сабже, а также в жизни мы рекомендуем вам использовать функцию poll, но вы можете использовать аналоги типа: select, kqueue, epoll. Сервер должен быть неблокирующим. И использовать только 1 poll(или аналог) для всех IO между клиентом и сервером(с учетом listens). poll(или аналог) должен проверять чтение и запись в одно и тоже время. Ваш сервер никогда не блокирует, и в случае необходимости клиент должен суметь отключиться. Вам нельзя производить операцию чтение и операцию записи без использования функции poll(или аналога). Вам запрещено проверять значения глобальной переменной errno после ошибки в функциях read и write. Запрос отправленный на ваш сервер не должен висеть вечно. Ваш сервер обязан иметь error page: стандартный или свой. Ваша программа не должна иметь утечек и не должна крашиться (даже при нехватке памяти, когда все уже инициализировано) Нельзя использовать fork, за исключением CGI. Нельзя запускать другой webserver через execve(). Ваша программа должна иметь конфигурационный файл, который указывается либо как аргумент программы, либо должен быть статичным. Вам не надо использовать poll(или аналог) до чтения вашего конфигурационного файла. Ваш веб-сервер должен суметь обслужить полностью статичный сайт. Клиент должен иметь возможность загрузить(upload) файлы. Ваши HTTP статус-коды должны быть точны. Вы должны минимум реализовать методы GET, POST и DELETE. Ваш сервер должен любой ценной оставаться доступным, при любых стресс тестах. Ваш сервер должен иметь возможность прослушивать несколько портов. Вам разрешено использование fcntl, потому что в Mac OS X функция write реализована по-другому, нежели в других Unix OS! Вы должны использовать неблокируемый FD для того, чтобы получить аналогичное поведение (как в других OS). Благодаря использованию неблокируемого FD, вы сможете использовать функции read/recv или write/send без опроса(polling) и ваш сервер будет неблокирующим. Но мы против этого. Использование read/recv или write/send без опроса(polling) запрещено, в случае пренебрежения данного правила будет выставлена оценка 0. Вы можете использовать fcntl в следующей форме: fcntl(fd, F_SETFL, O_NONBLOCK); Любые другие флаги запрещены. Конфигурационный файл Вы можете вдохновить себя посмотрев конфигурационный файл Nginx, а именно часть 'server'. В конфигурационном файле мы должны иметь следующие поля: Выбор порта и хоста для каждого 'server'(обяз). Установка имени_сервера(необяз). Первый сервер для host:port должен быть дефолтным для этого host:port (это значит, что он должен отвечать на все запросы, которые не относятся другому серверу). Установка дефолтного error page. Лимит размера тела клиента. Установка маршрутов с одним или несколькими следующими правилами/конфигурациями (маршруты не будут использовать redexp):

  • Определить список разрешенных HTTP методов для маршрута.
  • Определить HTTP редиректы.
  • Определить директорию или расположение файла, где должен происходить поиск файла (для примера: если url /kapouet находится в /tmp/www, то url /kapouet/pouic/toto/pouet будет /tmp/www/pouic/toto/pouet)
  • Включить или выключить прослушивание директории.
  • Установка дефолтного файла, который будет отправлен как ответ в случае, если запрос является директорией.
  • Дать маршруту возможность загружать файлы и определить место их хранения.
  • Исполнение CGI на основе определенного расширения (например .php) — Знаете что такое CGI? → link. — Так как вы не будете вызывать CGI напрямую используйте полный путь как PATH_INFO. — Помните, что фрагментированный запрос должен быть обратно собран сервером и CGI будет ожидать EOF, в качестве конца тела. — Тоже самое применимо и для вывода CGI, если не указан content_length. — Ваша программа должна вызывать CGI вместе с файлом, который указан в качестве первого аргумента. — CGI должен запускаться в правильной директории для доступа к файлам по относительному пути. — Ваш сервер должен работать только с одним CGI (php-cgi, python...). Для проверки вы должны предоставить несколько конфигурационных файлов и базовые файлы по-умолчанию для тестирования. Если у вас возник вопрос по поводу некоторого поведения, вам следует сравнить это с Nginx. Например: проверьте как работает server_name. Мы также предоставили вам небольшой тестер, он не настолько хорошо, чтобы с ним сдать проект. Но он поможет вам словить некоторые особенные баги. Пожалуйста прочитайте RFC и проведите тесты с telnet и Nginx перед тем как начать этот проект. Даже если вы не будете реализовывать все в RFC, чтение всего RFC сильно поможет вам в реализации ваших функций. Самое главное — это устойчивость. Ваш сервер не должен умирать! Не тестируйте ваш проект только одной программой, напишите собственные тесты! Вы можете сделать это на любом языке программирования. Например: python, golang, C++, C и т.д.

Бонусная часть

Если основная часть неидеальная, даже не думайте про бонусы. Поддержка cookie и Управление сессиями (не забудьте тесты). Обработка нескольких CGI.