← Назад к вопросам

Как выглядит HTTP сообщение?

2.2 Middle🔥 251 комментариев
#Сетевые протоколы и API

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Структура HTTP-сообщения

HTTP-сообщение — это формат обмена данными между клиентом (например, браузером) и сервером. Оно состоит из трёх основных частей: стартовой строки, заголовков и тела. В Go работа с HTTP сообщениями осуществляется через стандартный пакет net/http.

1. Стартовая строка (Start Line)

Определяет тип сообщения — запрос или ответ.

Для HTTP-запроса:

Содержит метод, URI и версию протокола.

GET /api/users HTTP/1.1

В Go метод и URI доступны в http.Request:

func handler(w http.ResponseWriter, r *http.Request) {
    method := r.Method      // "GET"
    uri := r.RequestURI     // "/api/users"
    proto := r.Proto        // "HTTP/1.1"
}

Для HTTP-ответа:

Содержит версию протокола, статус-код и статус-текст.

HTTP/1.1 200 OK

В Go статус устанавливается методом WriteHeader():

w.WriteHeader(http.StatusOK) // HTTP/1.1 200 OK

2. Заголовки (Headers)

Пары "ключ-значение", содержащие метаинформацию. Разделяются двоеточием.

Content-Type: application/json
User-Agent: Go-Client/1.0
Authorization: Bearer token123

В Go заголовки запроса доступны через r.Header, ответа — через w.Header():

// Чтение заголовка запроса
contentType := r.Header.Get("Content-Type")

// Установка заголовка ответа
w.Header().Set("Content-Type", "application/json")

3. Тело сообщения (Body)

Опциональная часть, содержащая данные. В запросах это может быть JSON, XML, форма; в ответах — HTML, JSON и т.д.

{"name": "Alice", "age": 30}

В Go тело запроса читается из r.Body (реализует io.ReadCloser), ответа — пишется в w (реализует io.Writer):

// Чтение тела запроса
body, _ := io.ReadAll(r.Body)
defer r.Body.Close()

// Запись тела ответа
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})

Полный пример HTTP-сообщения

HTTP-запрос:

POST /api/login HTTP/1.1
Host: example.com
Content-Type: application/json
User-Agent: MyGoApp/1.0
Authorization: Bearer xyz123

{"username": "alice", "password": "secret"}

HTTP-ответ:

HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 23 Jan 2023 10:00:00 GMT
Server: Go-HTTP-Server

{"token": "jwt.token.here", "expires_in": 3600}

Особенности в Go

  1. Буферизация заголовков: Заголовки ответа в Go буферизуются до первой записи в тело или вызова WriteHeader().
  2. Автоматические заголовки: Пакет net/http автоматически добавляет Date, Content-Length при необходимости.
  3. Обработка тела: Тело запроса в Go можно читать только один раз. Для повторного чтения нужно использовать r.GetBody() или буферизацию.
// Пример полной обработки HTTP в Go
func loginHandler(w http.ResponseWriter, r *http.Request) {
    // 1. Проверяем метод
    if r.Method != http.MethodPost {
        w.WriteHeader(http.StatusMethodNotAllowed)
        return
    }
    
    // 2. Проверяем заголовок
    if r.Header.Get("Content-Type") != "application/json" {
        w.WriteHeader(http.StatusUnsupportedMediaType)
        return
    }
    
    // 3. Читаем тело
    var creds struct {
        Username string `json:"username"`
        Password string `json:"password"`
    }
    if err := json.NewDecoder(r.Body).Decode(&creds); err != nil {
        w.WriteHeader(http.StatusBadRequest)
        return
    }
    
    // 4. Формируем ответ
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(map[string]string{
        "message": "Login successful",
    })
}

Важные моменты:

  • Пустая строка между заголовками и телом обязательна (CRLF)
  • В Go при использовании http.Server разбор сообщения происходит автоматически
  • Для низкоуровневой работы можно использовать http.ReadRequest() и http.ReadResponse()
  • Современные версии HTTP/2 и HTTP/3 используют бинарный формат, но в Go API остаётся тем же

Понимание структуры HTTP-сообщений критично для отладки, написания клиентов, серверов и промежуточного ПО в Go-экосистеме.

Как выглядит HTTP сообщение? | PrepBro