An open API service indexing awesome lists of open source software.

https://github.com/daddyingrave/http-server-task


https://github.com/daddyingrave/http-server-task

Last synced: 3 months ago
JSON representation

Awesome Lists containing this project

README

        

### Задача: HTTP сервер

#### "Бизнес" требования

**Первая итерация**

- я как пользователь сервера хочу иметь возможность использовать его для одновременного хостинга на нем одного и более статических сайтов
- я должен иметь возможность конфигурировать названия сайтов и их содержимое перед запуском сервера
- для конфигурации я хочу использовать следующий подход:
- в произвольном месте в файловой системе сервера будет создана папка
- местоположение этой папки будет сообщено серверу через переменную окружения либо через параметры запуска (второе имеет более высокий приоритет)
- в данной папке будет лежать файл конфигурации сервера и подпапки с сайтами
- имя каждой подпапки с сайтом будет являться именем сайта (без www)
- на имя сайта должны действовать те же ограничения что и на валидный hostname согласно http спецификации
- в случае ошибки в имени сайта, сервер должен вывести в лог сообщение о том что имя невалидно. После этого он должен продолжить свою работу если есть хотя бы один сайт который сконфигурирован корректно, иначе немедленная остановка
- после запуска сервера с корректной конфигурацией для сайтов my-site.com и my-site666.com при отправке http GET на URL `http://my-site.com` и на `http://my-site666.com` мне должно вернуться соответствующее содержимое
- сервер должен корректно отображать URI на файловую структуру. Пример:

```
1. пользователь отправляет GET запрос на URL http://my-site.com
2. на сервере данный сайт представлен следующей файловой структурой:

my-site.com
├── css
│   ├── foo.css
│   └── bar.css
├── js
│   └── script.js
├── index.html
└── vasian.html

3. сервер возвращает в ответ index.html
4. index.html в свою очередь использует файлы со стилями и js, что заставит браузер сходить на сервер
по соответствующим ссылкам, например для foo.css это будет http://my-site.com/css/foo.css
5. для этого серверу нужно будет понять что для запроса http://my-site.com/css/foo.css он должен будет
вернуть файл css/foo.css из файловой структуры сервера
```

**Вторая итерация**

- сделать так, чтобы сервер динамически перечитывал конфигурацию для отдаваемых сайтов, он должен обрабатывать следующие ситуации
- добавление нового сайта
- удаление существующего сайта
- изменение названия или содержимого существующего
- отправка электронных писем в случае критической ошибки
- ошибка при добавлении нового сайта (например недопустимый символ в названии)
- в случае если на работающем сервере больше не осталось корректно настроенных сайтов
- если у работающего сервера не останется корректно сконфигурированных сайтов, он должен ожидать установленное количество времени после чего завершить свою работу

Пример папки с конфигурацией и сайтами:

```
server
├── become-poor.now
│   ├── index.html
│   └── site-name.json
├── become-rich.now
│   └── index.html
└── config.properties
```

`config.properties` обязательно должен содержать следующие настройки:
- порт на котором ожидаются входящие соединения
- количество потоков в пуле соединений

#### Технические требования

- для каждой фичи заводим новую ветку, ветка именуется по номеру карточки в трелло + часть названия таски. Например для [задачи](https://trello.com/c/m6y9ItCp/42-%D1%80%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-httpparser) ветка должна называться 42-http-parser
- не используем `null`. Все что может быть `null` оборачиваем в `Optional`
- контракт именования переменных окружения такой же как и у констант в java. То есть upper-case и нижнее подчеркивание как разделитель
- во время работы сервер, на всех уровнях должен логировать свою работу
- должен возвращать разумные HTTP коды в случае успеха или ошибки
- все зависимости в классы должны поставляться только через конструкторы (в особых случаях это может быть обсуждаемо)
- используем интерфейсы
- пишем тесты, сначала изолированные для каждого класса (если это уместно), потом будем писать интеграционные поднимая сервер
- из внешних зависимостей на данный момент используем только junit

#### Дополнительно

- реализовать пул ресурсов, в первую очередь для входящих соединений
- логгер. Почитай [вот это](http://tutorials.jenkov.com/java-logging/index.html) и сделай так же