xinetd ler dados de postagem

1

Estou tentando escrever um manipulador simples para um webhook usando xinetd e bash. Eu tenho o caso trivial que trabalha com esta configuração para o xinetd:

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

e este script bash:

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

agora, eu quero ler os dados do post que estão sendo enviados no webhook para que eu possa fazer algo mais interessante que sempre retorna 200.

Como faço para ler os dados da postagem do meu script bash?

Eu tentei:

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

mas isso não está funcionando para mim.

Editar

Graças à sugestão abaixo, parei xinetd e usei nc para ver quais dados brutos estavam sendo transmitidos:

$nc -l 61000

e tenho isso:

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>

Então, os dados estão sendo enviados. Agora, sabendo que há exatamente 11 linhas sendo enviadas, eu li exatamente 11 linhas:

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

E obtenho a mesma saída (grande sucesso:)

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>

Talvez eu deva apenas ler 9 linhas e usar o parâmetro Content-Length para ler o resto? Eu ainda não entendo o que está acontecendo, então qualquer informação seria muito útil.

    
por spinlock 18.05.2016 / 01:06

2 respostas

0

OK, eu nunca descobri como ler enquanto há entrada, mas notei que há um comprimento no cabeçalho. Então, analiso o tamanho e depois leio esse número de caracteres:

#!/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"

E agora eu tenho os dados do post que o github está enviando.

    
por 19.05.2016 / 00:08
0

Para ler dados de postagem padrão para uma solicitação xinetd http, um programa apenas lê a entrada padrão.

Eu escrevi um script bash que lê e analisa os cabeçalhos http conforme transmitidos pela entrada padrão. Útil quando chamado do xinetd. Eu criei isso como um ponto de partida para alguém que deseja criar um serviço xinetd que possa reconhecer chamadas semelhantes a REST HTTP. link

Mas essencialmente, ler a entrada HTTP (cabeçalhos e dados POST) em um serviço xinetd é algo como isto:

# 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

Por que usar IFS=

  • O -r flag já lê os dados sem parar nos delimitadores
  • O IFS é o Separador de campo interno usado pelo bash para determinar como as palavras são divididas e como as linhas são divididas.
  • Esvaziamos IFS para garantir que o bash não altere nossos resultados esperados da leitura bruta read -r .

Para os parâmetros read :

  • O sinalizador -t 0.01 define o tempo limite de leitura em segundos (0,01 s)
  • O -r sinalizador lê os dados em bruto, o que ignora os delimitadores \r\n
  • O sinalizador -N <num> lê < num > personagens.
por 22.06.2018 / 00:26