xinetd читает данные поста

Я пытаюсь написать простой обработчик для веб-перехватчика с использованием xinetd и bash. У меня есть тривиальный случай, когда я работаю с этой конфигурацией для xinetd:

service github-hooks
{
    port            = 61000
    socket_type     = stream
    protocol        = tcp
    wait            = no
    user            = ubuntu
    server          = /home/ubuntu/github-hooks.sh
}

и этим сценарием bash:

#!/bin/bash
echo -e "HTTP/1.1 200 OK"

, теперь я хочу прочитать данные сообщения, которые отправляются в веб-перехватчике, чтобы я мог сделать что-то более интересное, что всегда возвращается 200.

Как мне прочитать данные сообщения из моего сценария bash?

Я пробовал:

while read line; do
    echo "$line" >> /home/ubuntu/test
done < /dev/stdin

, но у меня это не работает.

Изменить

Благодаря предложенному ниже предложению я остановил xinetd и использовал nc , чтобы посмотреть, какие необработанные данные передаются по сети:

$nc -l 61000

, и получил следующее:

POST / HTTP/1.1
Host: <snip>:61000
Accept: */*
User-Agent: GitHub-Hookshot/375c44e
X-GitHub-Event: pull_request
X-GitHub-Delivery: 2dc1fb00-1c8e-11e6-9955-64afafb6ce32
content-type: application/json
X-Hub-Signature: sha1=45afd85b7d4312fa8ac4c56638e8e9699e2ddb36
Content-Length: 20558

{"action":"opened","number":116,"pull_request": <snip>

Итак, данные отправляются. Теперь, зная, что отправлено ровно 11 строк, я прочитал ровно 11 строк:

for i in {0..10}
do
    read line
    echo "$line" >> /home/ubuntu/test
done

И я получил тот же результат (большой успех: )

POST / HTTP/1.1
Host: <snip>:61000
Accept: */*
User-Agent: GitHub-Hookshot/375c44e
X-GitHub-Event: pull_request
X-GitHub-Delivery: 2dc1fb00-1c8e-11e6-9955-64afafb6ce32
content-type: application/json
X-Hub-Signature: sha1=45afd85b7d4312fa8ac4c56638e8e9699e2ddb36
Content-Length: 20558

{"action":"opened","number":116,"pull_request": <snip>

Может быть, мне просто прочитать 9 строк, а затем использовать параметр Content-Length для чтения остальных? Я до сих пор не совсем понимаю, что происходит, поэтому любая информация будет очень полезной.

1
задан 18 May 2016 в 20:56
3 ответа

Хорошо,Я так и не понял, как читать, пока есть ввод, но я заметил, что в заголовке есть длина. Итак, я анализирую длину, а затем читаю это количество символов:

#!/bin/bash
for i in {1..9}
do
  read line
done

array=(${line})
length=${array[1]}

read line
read -n ${length:0:-1} line

echo "$line" >> /home/ubuntu/test

echo -e "HTTP/1.1 200 OK"

И теперь у меня есть почтовые данные, которые отправляет github.

0
ответ дан 4 December 2019 в 06:17

Для чтения стандартных почтовых данных для http-запроса xinetd программа просто читает стандартный ввод.

Я написал сценарий bash, который читает и анализирует заголовки http, переданные через стандартный ввод . Полезно при вызове из xinetd. Я создал это как отправную точку для тех, кто хочет создать службу xinetd, которая может распознавать HTTP-запросы, подобные REST. https://github.com/rglaue/xinetd_bash_http_service

Но по сути, чтение ввода HTTP (Заголовки и данные POST) в службе xinetd выглядит примерно так:

# Read HTTP Headers, line by line
# We're looking for the Content-Length HTTP header
: ${HTTP_CONTENT_LENGTH:=0}
while read -t 0.01 line; do
    # If the line is empty, stop reading headers
    if [ -z "$line" ]; then break; fi
    # Read each HTTP Header
    if echo "${line}" | grep -qi "^some-header:"; then
      # do something here
    elif echo "${line}" | grep -qi "^Content-Length:"; then
      HTTP_CONTENT_LENGTH="$(echo "${line}"|cut -d" " -f 2-)"
    fi
done
# Next read from standard input into the HTTP_POST_DATA variable
# (This assumes the request is a POST)
while IFS= read -N $HTTP_CONTENT_LENGTH -r -t 0.01 post_buffer; do
    echo "Reading in the HTTP Post Data"
    HTTP_POST_DATA="${HTTP_POST_DATA}${post_buffer}"
    if [ ${#HTTP_POST_DATA} -ge ${HTTP_CONTENT_LENGTH} ]; then
      # Make sure we stop reading, since we have read enough.
      break;
    fi
done

Зачем использовать IFS =

  • Флаг -r уже считывает данные без остановки на разделителях
  • IFS - это внутренний разделитель полей, используемый bash для определения того, как разделяются слова и как разделяются строки.
  • Мы очищаем IFS , чтобы убедиться, что bash не изменит наши ожидаемые результаты от необработанного чтения read -r .

Для параметров чтения :

  • Флаг -t 0.01 определяет тайм-аут чтения в секундах (0,01 сек)
  • -r флаг читает данные в необработанном виде, игнорируя разделители \ r \ n
  • . Флаг -N читает символы .
0
ответ дан 4 December 2019 в 06:17

буквально cat или xargs или grep . или что-то еще, что читается со стандартного ввода.

0
ответ дан 9 January 2020 в 13:52

Теги

Похожие вопросы