Из чего состоит HTTP-запрос?

Ответ

HTTP-запрос — это текстовое сообщение, которое клиент (например, браузер) отправляет серверу. Он имеет четкую структуру и состоит из следующих частей:

  1. Стартовая строка (Request Line) Содержит три элемента, разделенных пробелами:

    • Метод (Method): Тип запроса (GET, POST, PUT, DELETE и т.д.).
    • URI (Uniform Resource Identifier): Путь к запрашиваемому ресурсу (например, /users/123).
    • Версия HTTP: Версия протокола (например, HTTP/1.1 или HTTP/2). Пример: GET /api/search?q=golang HTTP/1.1
  2. Заголовки (Headers) Строки в формате ключ: значение, которые передают метаинформацию о запросе. Примеры популярных заголовков:

    • Host: доменное имя сервера.
    • Content-Type: MIME-тип тела запроса (например, application/json).
    • Authorization: данные для аутентификации (например, Bearer <token>).
    • User-Agent: информация о клиенте.
  3. Пустая строка-разделитель Одна пустая строка (CRLF), которая является обязательным разделителем между заголовками и телом запроса.

  4. Тело запроса (Body) Необязательная часть, содержащая данные, которые отправляются на сервер. Обычно используется с методами POST, PUT, PATCH. Пример тела в формате JSON:

    {"username": "alex", "score": 100}

В Go для создания HTTP-запроса используется пакет net/http:

import (
    "net/http",
    "strings"
)

// Создаем тело запроса
requestBody := strings.NewReader(`{"name": "John Doe"}`)

// Формируем запрос
req, err := http.NewRequest("POST", "https://example.com/api/users", requestBody)
if err != nil {
    // обработка ошибки
}

// Добавляем заголовки
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer my-secret-token")

// Далее запрос можно выполнить с помощью http.Client
// client := &http.Client{}
// resp, err := client.Do(req)

Ответ 18+ 🔞

А, слушай, вот эта ваша HTTP-хуйня, которую все так боятся! Да не бойся ты, это же просто текст, который один комп другому шлёт. Как записка в армии, только по правилам, блядь.

Представь: ты — браузер, такой хитрожопый курьер. Тебе надо к серверу сходить, что-то спросить или отдать. Ты пишешь ему бумажку. И в этой бумажке ВСЁ должно быть по полочкам, а то сервер — тупой валенок, он не догадается, ёпта.

Вот из чего эта бумажка состоит, смотри:

  1. Первая строчка — что хочешь сделать. Тут три слова, через пробел, как заклинание, блядь:

    • Что делаем? GET (посмотреть), POST (отправить), PUT (заменить), DELETE (удалить) — ну, в общем, команда.
    • Куда лезем? Путь, типа /photos/cats/nyan.
    • На каком языке говорим? Версия протокола, HTTP/1.1. Сказал "1.1" — говори на "1.1", а то не поймёт. Вот пример: GET /api/search?q=golang HTTP/1.1. Переводится: "Эй, сервак, дай-ка мне поисковые результаты по слову 'golang', по старой схеме, блядь!"
  2. Заголовки — это как сопроводиловка. Куча строчек ключ: значение. Тут всякая служебная хуйня. Сервер по ним смотрит, кто ты и что тебе надо.

    • Host: example.com — "Я к тебе, в example.com, пришёл, не путай!"
    • Content-Type: application/json — "В теле у меня данные в формате JSON, будь готов, сука!"
    • Authorization: Bearer <token> — "Я свой, вот мой пропуск, не бей!"
    • User-Agent: Mozilla/5.0... — "Я вот такой вот браузер, извини за внешний вид".
  3. Пустая строка — САМАЯ ВАЖНАЯ ЧАСТЬ, БЛЯДЬ! Сервер, этот тупой робот, ждёт одну пустую строку. Как стук в дверь. Нет стука — он не поймёт, где кончились заголовки и началось тело. Всё, запрос в пизду. Обязательно надо отстучаться!

  4. Тело запроса — ну, собственно, посылка. Бывает, а бывает и нет. Если просто смотришь (GET) — тела нет. Если отправляешь данные (POST, PUT) — вот тут оно, родное. Пример, JSON:

    {"username": "alex", "score": 100}

    Переводится: "Держи, сервер, пользователя 'alex' со счетом 100, обработай это, ёбта!"


А теперь, как эту всю муть на Go написать? Да легко, пакет net/http тебе в помощь.

Смотри, вот как письмо с телом состряпать:

import (
    "net/http"
    "strings"
)

// Готовим посылку (тело запроса)
requestBody := strings.NewReader(`{"name": "John Doe"}`) // Джонни, блядь, Доу!

// Пишем само письмо: метод, адрес, тело
req, err := http.NewRequest("POST", "https://example.com/api/users", requestBody)
if err != nil {
    // Ой, всё! Не получилось письмо сложить.
    panic(err) // или делай что умнее, конечно
}

// Приписываем сопроводиловку (заголовки)
req.Header.Set("Content-Type", "application/json") // Говорим, что внутри JSON
req.Header.Set("Authorization", "Bearer my-secret-token") // И кладём волшебный ключик

// Всё, письмо готово. Теперь можно отдать курьеру (http.Client) и отправить.
// client := &http.Client{}
// resp, err := client.Do(req)

Вот и вся магия, блядь. Ничего страшного. Главное — не забыть пустую строку, а то сервер тебя не поймёт и будет сидеть, как мартышлюшка, ждать, пока ты догадаешься.