Я повторил твою проблему. Когда я подключаюсь к другому nc
вместо браузера, я вижу, что ответ отправляется немедленно. Я думаю, что ваш браузер также получает ответ, но поскольку nc
не прерывает соединение, браузер не знает, что это все, и можно продолжить перенаправление.
(Примечание: во время моих тестов мне понадобился последний \r\n
в ответе от nc
чтобы успешно перенаправить мой браузер, поэтому все мои примеры используют это исправление.)
Редактировать: простое исправление
Здесь я нашел следующее:
HTTP-запросы и HTTP-ответы используют общий формат сообщения RFC 822 для передачи требуемых данных. Этот общий формат сообщения состоит из следующих четырех элементов.
- [...]
- [...]
- Пустая строка (т. Е. Строка, не предшествующая CRLF), указывающая конец полей заголовка
- [...]
Итак, ваш ответ должен быть:
printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n\r\n' | ...
После получения этого ваш браузер должен продолжить перенаправление, прервав соединение с nc
от своего имени. В начале декабря 2017 года он работает с Оперой и Вивальди; он не работает с Firefox, Chrome или Safari, для которых вам может потребоваться другое исправление (см. ниже).
Оригинальный, теперь неполноценный ответ (он все еще может быть полезен для связи не по HTTP с nc
)
В соответствии с этим ответом о сбое сервера вам нужно использовать -c
, -q
или аналогичный параметр, в зависимости от реализации nc
В моем Debian установлена версия с поддержкой -q
. затем
printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n' | nc -q 0 -l -p 2345
работает нормально (обратите внимание, мне также нужно -p
чтобы указать порт). Объяснение:
-q seconds
после EOF
на stdin
, подождите указанное количество секунд и затем выйдите. Если секунды отрицательны, подождите вечно (по умолчанию).
Если у вашего nc
нет правильной опции, то обходной путь может заключаться в обнаружении связи с клиентом и уничтожении всей командной строки. Пример, который работает в моем Debian, bash
:
printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n' | nc -l -p 2345 | { read foo; sleep 1; kill 0; }
При запуске канала bash
помещает каждый процесс в одну группу процессов; kill 0
отправляет сигналы всей группе процессов. Таким образом, nc
уничтожается примерно через 1 секунду после получения любого запроса, запускающего read
.