Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Структура 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
- Буферизация заголовков: Заголовки ответа в Go буферизуются до первой записи в тело или вызова
WriteHeader(). - Автоматические заголовки: Пакет
net/httpавтоматически добавляетDate,Content-Lengthпри необходимости. - Обработка тела: Тело запроса в 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-экосистеме.