HTTP и веб-протоколы
HTTP выглядит обманчиво простым — текстовая строка запроса, заголовки key: value, пустая строка и тело. Из-за этой простоты его учат как набор аббревиатур и проваливаются на первом же вопросе «что произошло между нажатием Enter и приходом ответа». Настоящий предмет темы — стек: имя резолвится в адрес через DNS, ядро открывает сокет, TCP устанавливает соединение трёхсторонним рукопожатием, TLS договаривается о ключах, и только поверх всего этого едет текст HTTP. Каждый уровень решает ровно одну задачу и передаёт наверх свою абстракцию — сломайте цепочку в любом месте, и симптом проявится совсем не там, где причина.
Python удобен тем, что стандартная библиотека выставляет каждый уровень отдельно: socket — сырой транспорт, ssl — рукопожатие и проверку сертификата, http.client — разбор сообщения, urllib.request — редиректы и политику клиента, wsgiref — серверную сторону. Любое утверждение из теории проверяется руками за пять строк. Четыре ловушки назовём сразу. Первая — путаница между безопасностью и идемпотентностью: GET безопасен, PUT и DELETE идемпотентны, но не безопасны, а POST не является ни тем, ни другим. Вторая — 301 против 307: коды различаются не только «постоянством», но и правом клиента поменять метод. Третья — HTTPS шифрует тело и заголовки, но не прячет ни IP, ни имя хоста в SNI. Четвёртая — REST это набор архитектурных ограничений, а не «JSON по HTTP».
Карта темы
- Сетевой стек — какой уровень за что отвечает и что на самом деле происходит от
curlдо ответа сервера. - Сокеты — сокет как конечная точка транспорта и файловый дескриптор,
SOCK_STREAMпротивSOCK_DGRAM. - TCP — трёхстороннее рукопожатие, нумерация сегментов,
ACK, переотправка, скользящее окно и контроль перегрузки. - UDP — датаграмма без соединения и подтверждений, и почему её выбирают
DNS, видео и игры. - DNS — порядок разрешения имени, типы записей,
TTLи откат сUDP/53наTCP. - Протокол HTTP — текст, отсутствие состояния, стартовая строка, заголовки, пустая строка и тело.
- Методы HTTP — семантика методов и главное различие темы, safe против idempotent.
- Коды состояния — смысл в первой цифре, и почему валидация это
4xx, а не5xx. - Редиректы —
Locationплюс3xx, и чем301,302,307и308отличаются по методу. - Кэширование — свежесть по
Cache-Controlпротив ревалидации по валидатору. - ETag и условные запросы —
If-None-Match, ответ304с пустым телом, сильный и слабый валидатор. - HTTP против HTTPS — что именно добавляет
TLSи что он не скрывает. - REST — ограничения стиля, а не формат данных, и честное сравнение с
SOAP. - CGI — процесс на запрос как историческая модель и почему её сменили
WSGIиASGI.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
Считать HTTP протоколом транспортного уровня | Пропадает весь слой TCP — не объяснить ни рукопожатие, ни таймауты, ни keep-alive |
| Путать безопасность и идемпотентность | POST уходит в автоматический ретрай и создаёт дубли заказов, а повтор DELETE считают опасным |
Слать 301 при временном переезде | Браузер и поисковик кэшируют переезд надолго — откатить его без смены URL почти невозможно |
Повторять POST после 301/302 | Клиенты меняют метод на GET, тело теряется, а автор диагностирует «сервер не принимает данные» |
Думать, что HTTPS прячет адрес сайта | IP виден всегда, имя хоста уходит в SNI открытым текстом — скрыты только заголовки и тело |
Считать, что 304 несёт тело | Ответ 304 пустой по определению; тело клиент берёт из собственного кэша |
| Хранить сессию клиента в памяти процесса | Нарушено ограничение stateless — вторая реплика за балансировщиком теряет пользователя |
Называть REST-ом любой JSON поверх HTTP | Теряются ресурсная адресация, единый интерфейс и кэшируемость — остаётся RPC с красивым URL |
Значение для собеседований
Тему почти всегда открывают одним вопросом — «что происходит, когда вы выполняете curl https://example.com». Это проверка модели, а не эрудиции: интервьюер слушает, назовёте ли вы DNS до соединения, рукопожатие TCP до TLS, TLS до первого байта HTTP, и понимаете ли, что запрос спускается по уровням, а не «летит на сервер». Отсюда растут все уточнения — где сидит обратный прокси, что изменится для http://, почему keep-alive экономит именно рукопожатие. Второй обязательный блок — методы и коды, и здесь лежит самый проваливаемый пункт темы: safe против idempotent. GET и HEAD безопасны, PUT и DELETE идемпотентны, но меняют состояние, POST не обладает ни одним из свойств. Ответ «идемпотентный значит только читает» уже сказал про кандидата главное.
Дальше идут детали, отличающие практику от чтения документации. Разница 301, 302, 307 и 308 — не про «постоянно или временно», а про право клиента сменить метод на GET. Кэширование разбирают в два шага — сначала свежесть (Cache-Control, max-age), затем ревалидация (ETag, If-None-Match, ответ 304), а разница no-cache и no-store — стандартный уточняющий вопрос. По HTTPS ждут не «там шифрование», а три гарантии — конфиденциальность, целостность, аутентификация сервера сертификатом — и честное признание, что домен в SNI наблюдателю виден. По REST проверяют, назовёте ли вы ограничения стиля вместо формата; ответ «REST — это JSON вместо XML» закрывает вопрос не в вашу пользу. Замыкает тему CGI — его спрашивают, чтобы услышать, понимаете ли вы, зачем появились WSGI и ASGI.