Назад | Перейти на главную страницу

веб-браузеру не нравится xinetd

Как я могу сделать службу 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
  • Сервер должен отправить Content-Length.
  • Вывод должен быть сначала записан в файл, а затем отправлен с 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