Как запросить главную страницу google.com через telnet
Что проверяют
Понимаете ли вы, что HTTP это обычный текст поверх TCP, и знаете ли минимальный корректный запрос. Следом почти всегда спрашивают про HTTPS: почему через telnet не выйдет и чем его заменить. Для Python-разработчика логичное продолжение: повторить то же на socket.
Как отвечать
Подключение на 80-й порт: telnet www.google.com 80. После строки «Connected» вводите запрос и завершаете его пустой строкой:
- стартовая строка:
GET / HTTP/1.1; - Host:
Host: www.google.com, в HTTP/1.1 заголовок обязателен, без него сервер ответит 400; - Connection:
Connection: close, иначе соединение останется открытым, в HTTP/1.1 keep-alive включён по умолчанию; - пустая строка: конец заголовков. Строки в HTTP разделяются CRLF, telnet отправляет его по Enter.
Если в Host указать просто google.com, скорее всего придёт 301 Moved Permanently с заголовком Location на www. Это нормальный ответ, и хорошо, если вы его объясните, а не решите, что запрос сломан. Тело часто приходит с Transfer-Encoding: chunked: оно разбито на куски, перед каждым длина в шестнадцатеричном виде.
Выход из telnet: Ctrl+], затем quit. Для HTTPS нужен TLS, поэтому вместо telnet берут openssl s_client -connect www.google.com:443 -servername www.google.com -crlf и вводят тот же запрос.
На Python то же самое: socket.create_connection(("www.google.com", 80)), sendall с байтами запроса, чтение recv в цикле, пока не придёт пустой ответ. Для HTTPS сокет оборачивают через ssl.create_default_context().wrap_socket(sock, server_hostname=...).
Где спотыкаются
Забывают пустую строку в конце и ждут ответа, которого не будет: сервер всё ещё ждёт заголовки.
Опускают Connection: close и не понимают, почему после ответа сессия висит. В HTTP/1.1 сервер держит соединение открытым для следующего запроса.
Пробуют telnet на 443 и получают обрыв или непонятные байты. Сервер не сломан: там TLS, и до любого HTTP нужно пройти рукопожатие.