Реализуйте DoRequest. Она делает GET по адресу url с переданным ctx и дополнительно ограничивает запрос жёстким таймаутом 200 мс.
func DoRequest(ctx context.Context, url string) ([]byte, error)
Пример:
body, err := DoRequest(ctx, "http://fast.example/") // ответ за 10 мс
// body == []byte("hello"), err == nil
_, err = DoRequest(ctx, "http://slow.example/") // сервер отвечает 1 секунду
// через ~200 мс: err != nil, errors.Is(err, context.DeadlineExceeded)
Требования:
- Внутри функции из
ctx создаётся производный контекст с таймаутом 200 мс. Более ранний дедлайн или отмена внешнего ctx продолжают действовать: запрос живёт не дольше, чем позволяет каждый из них.
- Запрос строится через
http.NewRequestWithContext, чтобы отмена реально прерывала сетевой вызов.
- При успехе возвращается тело ответа целиком.
- При таймауте или отмене функция возвращает ошибку и не зависает. Тело ответа закрывается на всех путях, таймер контекста освобождается.
Тесты поднимают локальный httptest-сервер. Быстрый сервер отвечает hello. Медленный отвечает через секунду, и тест ждёт ошибку заметно раньше этого срока, причём errors.Is(err, context.DeadlineExceeded) и не раньше чем через 150 мс. Сервер, отвечающий за 80 мс, должен успеть. Внешний ctx с дедлайном 50 мс или отменой через 50 мс обрывает запрос примерно в эти же сроки. Тело в 1 МБ возвращается целиком. Закрытие тела ответа тесты не проверяют.
Сначала попробуй сам — подсказки не дают готовый ответ.