Как я могу сделать службу xinetd таким образом, чтобы веб-браузер мог надежно показать свой вывод?
Служба всегда видит HTTP-запрос GET на своем стандартном вводе и отправляет свой ответ на стандартный вывод. xinetd обрабатывает TCP-соединение.
Fire Fox иногда правильно показывает вывод. Но иногда он утверждает, что сервер сбросил соединение, пока он все еще загружал страницу. Иногда он показывает весь вывод, но продолжает ждать большего (и когда я нажимаю ESC, он устанавливает новое соединение с сервером с пустым HTTP-запросом).
Определение службы xinetd:
service test
{
disable = no
id = test
type = UNLISTED
port = 8043
wait = no
socket_type = stream
flags = IPv4
user = root
server = /usr/local/bin/test.sh
}
Скрипт для этого простого теста игнорирует ввод, просто повторяет минимальный HTML. Это вызывает ту же проблему, что и реальная вещь, хотя я добавил команду, чтобы закрыть stdout в конце.
echo 'HTTP/1.1 200 OK'
echo 'Content-Type: text/html; charset=UTF-8'
echo ''
echo '<html>'
echo '<body style="background:#dfd">'
echo '<b>hello, world!</b><br>'
echo `date`
echo '</body>'
echo '</html>'
Чем это отличается от того, что делал бы веб-сервер?
Я нашел два возможных ответа в xinetd 'сброс соединения одноранговым узлом':
Оказывается, я должен сделать и то, и другое, плюс еще одно:
HTTP/1.0
вместо того HTTP/1.1
cat
Кто-нибудь видит более простой способ? Imho стандарт HTTP / 1.1 позволяет опустить Content-Length и вместо этого закрыть соединение. И где разница между одним cat
и ряд echo
команды?
cat или echo приемлемы. В обоих случаях данные выходят стандартно.
HTTP-ответ можно отправить с помощью следующей функции bash:
#
# The HTTP response
# Syntax: http_response 200 "Success Message"
# http_response 503 "Service Unavailable Message"
#
http_response () {
HTTP_CODE=$1
MESSAGE=${2:-Message Undefined}
length=${#MESSAGE}
if [ "$HTTP_CODE" -eq 503 ]; then
echo -en "HTTP/1.1 503 Service Unavailable\r\n"
elif [ "$HTTP_CODE" -eq 200 ]; then
echo -en "HTTP/1.1 200 OK\r\n"
else
echo -en "HTTP/1.1 ${HTTP_CODE} UNKNOWN\r\n"
fi
echo -en "Content-Type: text/plain\r\n"
echo -en "Connection: close\r\n"
echo -en "Content-Length: ${length}\r\n"
echo -en "\r\n"
echo -en "$MESSAGE"
echo -en "\r\n"
sleep 0.1
exit 0
}
Я написал службу mini bash-http для xinetd, которая может оказаться полезной.
http://github.com/rglaue/xinetd_bash_http_service
Он принимает запросы HTTP / 1.0, включая анализ заголовков HTTP, таких как HTTP-запрос и параметры. И он возвращает соответствующий HTTP-ответ. Он также удобен для командной строки.
bash~$ echo "GET /weight-value?inverse-weight=0&max-weight=100 HTTP/1.0" | xinetdhttpservice.sh --http-status
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: close
Content-Length: 15
WEIGHT_VALUE=99