Последние несколько часов я ломал себе голову, пытаясь построить http-сервер бедняка с помощью socat. Не спрашивайте почему и не предлагайте альтернативы. Мне нужно сделать это в чистом bash. Итак, я запускаю socat следующим образом:
socat -v TCP-LISTEN:1234,reuseaddr,fork SYSTEM:./httpd.sh
Предполагается, что httpd.sh читает http-запрос, анализирует его и затем отправляет ответ.
например GET /index.html выведет Index!, а GET /random выведет случайное число.
У меня проблема с чтением всего http-запроса. Рассмотрим следующий код, используемый для чтения каждой строки http-запроса:
while read -r LINE
do
echo "$LINE"
done
Обычно он должен возвращать запрос в браузер. Проблема в том, что после того, как я открываю 127.0.0.1:1234, он просто зависает в ожидании чего-то. Если я CTRL + C socat, соединение закрывается, и ответ отображается в браузере. Я думаю, что цикл while продолжается вечно, что предотвращает передачу ответа.
Если я использую код ниже:
while read -r LINE
do
echo "$LINE"
[ -z "$LINE" ] && break
done
цикл while прерывается, и браузер больше не зависает. Кажется хорошим решением. Но... в случае запроса POST данные POST не записываются, потому что разрыв происходит сразу после заголовков (пустая строка)...
POST /index.html HTTP/1.0
User-Agent: Firefox
Content-Type: application/x-www-form-urlencoded
parameter1=test
Что я могу сделать, чтобы прочитать весь HTTP-запрос через сценарий оболочки, обработать его и отправить ответ без каких-либо зависаний?
ИЗМЕНИТЬ:
Вот кое-что, что, я думаю, может содержать ответ. Если я запускаю эту команду:
socat TCP4-LISTEN:1234,reuseaddr,fork,crlf SYSTEM:"echo hello world"
Все работает нормально, всегда выводится hello world.
Как Socat узнает, когда заканчивается HTTP-запрос?