diff --git a/README.md b/README.md index bc7469d..5c5e17a 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,37 @@ У всех трёх одинаковое устройство входа. Форма `#login` с полями `#username` и `#password` и кнопкой `button.primary[data-test=login-button]`, флеш-сообщение `#flash`, выход по `/<курс>/logout`. Приложения описаны конфигом `apps` в `custom-server/src/ui-pages.ts`, страницы лежат фрагментами в `custom-server/assets/ui-pages/<курс>/`, префикс в них записан как `{{prefix}}`. +## Демонстрации HTTP для автоматизации + +Курс использует отдельные обработчики сессии, кеширования, событий и повторных запросов. Общие коллекции задач, пользователей и публикаций сохраняются. + +| Метод и путь | Результат | +| --- | --- | +| `GET /http-protocol/login-form` | Форма с учебным именем `student` | +| `POST /http-protocol/session` | Куки `session=hexlet-demo` на пять минут | +| `GET /http-protocol/session` | `Guest` без куки, `Welcome, student!` с учебной куки | +| `DELETE /http-protocol/session` | Удаление куки клиента | +| `GET /http-protocol/cache` | Расписание, `ETag` и `private, max-age=60` | +| `GET /http-protocol/cache/revalidate` | То же расписание с `no-cache` | +| `GET /http-protocol/cache/no-store` | То же расписание с `no-store` | +| `POST /http-protocol/webhooks/inboxes` | Новый приёмник, его `callback_url` и `events_url` | +| `POST /http-protocol/webhooks/inboxes/{id}/subscription` | Подписка с полученным `callback_url` | +| `POST /http-protocol/webhooks/inboxes/{id}/trigger` | Отправка учебного события настоящим HTTP-запросом в свой приёмник | +| `GET /http-protocol/webhooks/inboxes/{id}/events` | Сохранённые входящие сообщения и ответы приёмника | +| `POST /http-protocol/reliability/runs` | Новый отдельный опыт с `run_id` и `base_url` | +| `GET {base_url}/temporary` | Первый ответ 503 с `Retry-After: 1`, следующий 200 | +| `GET {base_url}/limited` | 429 с `Retry-After: 1`, после ожидания 200 | +| `GET {base_url}/slow` | Ответ через две секунды для проверки таймаута | +| `POST {base_url}/operations?lose_response=1` | Создание операции с обрывом связи до ответа | +| `GET {base_url}/operations` | Результаты созданных операций | +| `GET {base_url}/journal` | Связь попыток с результатами операций | + +Вебхуки принимают только подготовленные поля события. Подписка допускает приёмник этого же опыта, произвольные внешние адреса не вызываются. Реальный HTTP-запрос идёт на локальный порт приложения, за тем же публичным адресом. Получатель проверяет учебный `X-Webhook-Key: hexlet-demo-webhook` и подтверждает сохранение сообщения кодом 204. Этот общедоступный пример показывает форму проверки источника, настоящие учётные данные не используются. + +При создании операции поле `title` обязательно. Если `Idempotency-Key` повторяется с тем же названием, сервер возвращает существующую операцию. Другое название под тем же ключом даёт 409. Без ключа каждый запрос создаёт отдельную запись. Параметр `lose_response=1` закрывает соединение после записи новой операции; уже найденная по ключу операция возвращается обычным ответом. При обращении через Caddy первый обрыв превращается в ответ 502 без результата операции. Это тоже оставляет клиенту задачу проверить, было ли изменение выполнено. + +Приёмник и опыт живут 30 минут, данные хранятся только в памяти. Число опытов и размеры журналов ограничены. После истечения срока или перезапуска создаётся новый опыт. Фиксированный маркер сессии служит для демонстрации обмена куки, проверку настоящего аккаунта он не выполняет. + ## Prerequisites - [mise](https://mise.jdx.dev) (ставит Node, pnpm, Caddy и jactionlint по `mise.toml`) diff --git a/custom-server/assets/http-protocol/index.html b/custom-server/assets/http-protocol/index.html index 59cd05c..95a0377 100644 --- a/custom-server/assets/http-protocol/index.html +++ b/custom-server/assets/http-protocol/index.html @@ -13,6 +13,8 @@