Como acessar o servidor http do script bash com a conexão tcp existente?

3

Em um scash do bash shell, eu uso várias ferramentas de linha de comando ( wget , curl , httpie ) para testar meu servidor http.

Ao usar, e. Enrolada para invocar uma solicitação GET, vejo que uma conexão tcp é aberta para o meu servidor e fechada imediatamente após a conclusão da comunicação http.

$ curl http://10.5.1.1/favicon.ico -o /dev/null 

Para testar melhor o comportamento keep-alive do meu servidor, quero manter a conexão tcp aberta em vários ciclos de solicitação / resposta http.

Eu consigo realizar solicitações HTTP ruins diretamente do bash assim:

exec 3<>/dev/tcp/10.5.1.1/80
printf "GET /\r\n\r\n" >&3
while IFS= read -r -u3 -t2 line || [[ -n "$line" ]]; do echo "$line"; done
exec 3>&-
exec 3<&-

Mas como minha comunicação de teste é muito mais complexa (incl. authentication et cetera), não quero codificar isso completamente sozinho no bash ou em outra linguagem de script, mas quero usar as ferramentas existentes. A idéia agora é primeiro abrir um soquete TCP no bash e, em seguida, forçar algumas ferramentas de linha de comando a usar essa conexão, em vez de abrir seus próprios soquetes. Talvez assim:

exec 3<>/dev/tcp/10.5.1.1/80
curl http://10.5.1.1/message.txt --use-existing-socket-fd=3
# ... do some other testing stuff ...
wget http://10.5.1.1/message.txt --use-existing-socket-fd=3
# ... do some other testing stuff ...
http http://10.5.1.1/message.txt --use-existing-socket-fd=3
exec 3>&-
exec 3<&-

Isso pode ser possível usando as ferramentas acima mencionadas ou com outras ferramentas?

    
por Joe 21.09.2017 / 16:46

1 resposta

4

A ferramenta que você está procurando é socat . Como você está testando um único servidor da Web, pode solicitá-lo para estabelecer uma conexão permanente com esse servidor (desde que não escolha fechá-lo - ajuste seus tempos de espera de acordo) e, quando isso for feito, você poderá usar o servidor. conexão como um túnel. Abaixo estão duas maneiras de conseguir isso.

Consultando através de um socket Unix

curl tem uma opção --unix-socket que permite enviar solicitações HTTP e receber respostas HTTP através de um soquete Unix (obrigado, thrig, pelo seu comentário esclarecedor)

Você usaria assim:

socat TCP:10.5.1.1:80 UNIX-LISTEN:/tmp/curl.sock,fork

Então, em outro terminal:

curl --unix-socket /tmp/curl.sock http://10.5.1.1/message1.txt
curl --unix-socket /tmp/curl.sock http://10.5.1.1/message2.txt
...

Consultando por meio de um proxy HTTP pseudo

Você também pode disponibilizar seu encapsulamento como um pseudo-proxy através do qual wget , curl , ... se conectaria. Esta solução tem a vantagem de não se limitar a curl .

Desta vez, socat ouve uma porta TCP local (digamos 3128):

socat TCP:10.5.1.1:80 TCP-LISTEN:3128,fork,reuseaddr

Então, em outro terminal:

export http_proxy='http://localhost:3128'
curl http://10.5.1.1/message.txt
wget http://10.5.1.1/message.txt
....

Observe que, como o cliente HTTP está usando um proxy, a solicitação HTTP será levemente alterada e isso pode não ser desejável.

É claro que nenhuma dessas duas soluções se destina a ser usada com vários servidores HTTP, já que este é o seu servidor web no final do canal que recebe todas as solicitações.

    
por 21.09.2017 / 19:00