Мне нужно использовать openssl для выполнения некоторых HTTP-запросов GET в сценарии оболочки. Линия, которую я сейчас использую для этого, показана ниже. Это синтаксический анализ содержимого ответа XML следующих форматов.
<Result>success</Result>
<Result>failure</Result>
echo -e "GET /test HTTP/1.1\r\nHost:$(hostname)\r\n\r\n" | openssl 2>&1 s_client -quiet -connect server-url:443 | grep -o -P --color '(?<=Result\>).*(?=\</Result)'
Это работает и возвращает строку «успех» или «неудача» соответственно. Проблема, с которой я столкнулся, заключается в том, что openssl
Команда не завершается после выполнения запроса GET, а вместо этого сидит там, ожидая ввода дополнительных данных. Я считаю, что это связано с неявным -ign_eof
что предотвращает автоматическое завершение, вызванное -quiet
вариант. Я пробовал использовать -no_ign_eof
вариант, но это вызывает openssl
команда для завершения до того, как запрос GET получил ответ, поэтому я не могу получить содержимое ответа, если использую его.
Как я могу изменить эту команду, чтобы я мог передавать запрос GET через стандартный ввод (требуется, поскольку я хочу поместить это в цикл), но иметь openssl
завершать команду после каждого запроса?
Что ты действительно следует использовать инструмент, предназначенный для получения веб-ресурсов, например curl
, wget
, или libwww-perl's GET
команда. Если ничего не доступно, попросите системного администратора установить что-нибудь подходящее.
С этим в стороне ...
В openssl
команда не завершается, потому что веб-сервер не закрыл соединение.
Помните, что по умолчанию HTTP сохраняет соединения открытыми после каждого запроса в целях оптимизации производительности. После завершения одного запроса другой запрос может быть отправлен через то же соединение, а не закрытие и повторное открытие нового соединения.
Если вы хотите дать серверу команду закрыть соединение вместо этого, вы можете отправить Connection: close
Заголовок HTTP.
Еще одно простое (но, вероятно, худшее) решение - использовать HTTP / 1.0 вместо HTTP / 1.1.