Запросы и ответы
Отправка запросов
Функции пакета
Нет необходимости создавать клиент — отправляйте запросы напрямую:
result, err := httpc.Get("https://api.example.com/data")
if err != nil {
log.Fatal(err)
}
fmt.Println(result.StatusCode())
fmt.Println(result.Body())Поддерживаемые HTTP-методы: Get, Post, Put, Patch, Delete, Head, Options.
Экземпляр клиента
client, err := httpc.New()
if err != nil {
log.Fatal(err)
}
defer client.Close()
result, err := client.Get("https://api.example.com/data")Универсальный метод запроса
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
result, err := httpc.Request(ctx, "GET", "https://api.example.com/data")Параметры запроса
Заголовки запроса
result, err := client.Get(url,
httpc.WithHeader("Authorization", "Bearer token"),
httpc.WithHeader("X-Custom", "value"),
httpc.WithHeaderMap(map[string]string{
"Accept": "application/json",
"X-Request-ID": "123",
}),
httpc.WithUserAgent("my-app/1.0"),
)Тело запроса
// JSON
result, err := client.Post(url, httpc.WithJSON(map[string]any{
"name": "test",
}))
// XML
result, err := client.Post(url, httpc.WithXML(data))
// Форма
result, err := client.Post(url, httpc.WithForm(map[string]string{
"username": "admin",
"password": "secret",
}))
// Бинарный (по умолчанию application/octet-stream)
result, err := client.Post(url, httpc.WithBinary(data))
// С указанием типа
result, err := client.Post(url, httpc.WithBinary(data, "image/png"))
// Автоопределение типа
result, err := client.Post(url, httpc.WithBody(data))
// string → text/plain; charset=utf-8, []byte → application/octet-stream,
// map[string]string → application/x-www-form-urlencoded,
// *FormData → multipart/form-data, io.Reader → передаётся как есть,
// другие → application/json
// Можно явно указать: httpc.WithBody(data, httpc.BodyJSON)Параметры запроса
result, err := client.Get(url,
httpc.WithQuery("page", 1),
httpc.WithQuery("limit", 10),
)
// Или с использованием Map
result, err := client.Get(url,
httpc.WithQueryMap(map[string]any{
"page": 1,
"limit": 10,
}),
)Аутентификация
// Bearer Token
result, err := client.Get(url, httpc.WithBearerToken("my-token"))
// Basic Auth
result, err := client.Get(url, httpc.WithBasicAuth("user", "pass"))Cookie
result, err := client.Get(url,
httpc.WithCookie(http.Cookie{Name: "session", Value: "abc"}),
httpc.WithCookieMap(map[string]string{"session": "abc", "lang": "zh"}),
httpc.WithCookieString("session=abc; lang=zh"),
)Управление запросом
// Таймаут
result, err := client.Get(url, httpc.WithTimeout(10*time.Second))
// Повторные попытки
result, err := client.Get(url, httpc.WithMaxRetries(5))
// Перенаправления
result, err := client.Get(url,
httpc.WithFollowRedirects(false), // запретить перенаправления
)WithMaxRedirects(0) не отключает
WithMaxRedirects(0) не отключает перенаправления — движок рассматривает 0 как «не задано» и возвращается к значению по умолчанию 10. Чтобы полностью отключить следование перенаправлениям, используйте WithFollowRedirects(false).
Обратные вызовы
result, err := client.Get(url,
httpc.WithOnRequest(func(req httpc.RequestMutator) error {
log.Printf("Отправка запроса: %s %s", req.Method(), req.URL())
return nil
}),
httpc.WithOnResponse(func(resp httpc.ResponseMutator) error {
log.Printf("Получен ответ: %d", resp.StatusCode())
return nil
}),
)Обработка ответов
result, err := client.Get("https://api.example.com/users/1")
if err != nil {
log.Fatal(err)
}
// Проверка состояния
result.StatusCode() // 200
result.IsSuccess() // true (2xx)
result.IsRedirect() // false (3xx)
result.IsClientError() // false (4xx)
result.IsServerError() // false (5xx)
// Чтение ответа
result.Body() // строка
result.RawBody() // []byte
result.Proto() // "HTTP/1.1"
// Парсинг JSON
var user User
if err := result.Unmarshal(&user); err != nil {
log.Fatal(err)
}
// Cookie
cookie := result.GetCookie("session")
if cookie != nil {
fmt.Println(cookie.Value)
}
// Метаданные запроса
fmt.Println(result.Meta.Duration) // время выполнения запроса
fmt.Println(result.Meta.Attempts) // количество повторных попыток
fmt.Println(result.Meta.RedirectCount) // количество перенаправленийУправление контекстом
// Управление таймаутом
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
result, err := httpc.Request(ctx, "GET", url)
// Управление отменой
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(5 * time.Second)
cancel() // отмена через 5 секунд
}()
result, err := httpc.Request(ctx, "GET", url)Потоковые ответы
WithStreamBody(true) — внутренний механизм, используемый при загрузке файлов, чтобы избежать кэширования полного тела ответа в памяти. При включении тело ответа не считывается в Result (Body() и RawBody() возвращают пустые значения).
WARNING
WithStreamBody(true) используется внутри API загрузки файлов. Если нужно потоковое получение содержимого ответа, используйте API загрузки файлов.
Если нужно загрузить большой файл, используйте API загрузки:
cfg := httpc.DefaultDownloadConfig()
cfg.FilePath = "/path/to/file"
result, err := client.Download(context.Background(), url, cfg)Распаковка ответов
HTTPC автоматически обрабатывает распаковку содержимого gzip, deflate и других кодировок. Можно ограничить размер распаковки через настройки безопасности для предотвращения атак с распакованными бомбами:
cfg := httpc.DefaultConfig()
cfg.Security.MaxResponseBodySize = 10 * 1024 * 1024 // Лимит тела ответа: принудительно при потоковой загрузке; запасной вариант для лимита распакованного тела при непотоковом чтении
cfg.Security.MaxDecompressedBodySize = 100 * 1024 * 1024 // Максимальный размер распакованного тела 100MB| Настройка | Значение по умолчанию | Описание |
|---|---|---|
MaxResponseBodySize | 10MB | Лимит тела ответа при потоковой загрузке; запасной вариант для лимита распакованного тела при непотоковом чтении |
MaxDecompressedBodySize | 100MB | Верхний предел размера распакованного тела ответа |
Для байтов сжатого тела ответа предусмотрен отдельный жёсткий лимит 100 МБ (maxCompressedSize, не настраивается), предназначенный для защиты от бомб распаковки, независимый от MaxResponseBodySize.
При превышении лимита возвращается ошибка с сообщением "exceeds limit", которую можно обработать через тип ClientError. ErrResponseBodyTooLarge возвращается при парсинге JSON через Result.Unmarshal() для ответов размером более 50MB (независимо от MaxResponseBodySize).
Что дальше
- Загрузка и выгрузка файлов - руководство по передаче файлов
- Доменный клиент и сессии - управление сессиями
- Параметры запроса API - полный справочник параметров
- Result API - справочник обработки ответов