Bash Shell sciptでは、いくつかのコマンドラインツール(wget
、curl
、httpie
)を使用してhttpサーバーをテストします。
使用する場合curlでGETリクエストを呼び出すと、tcp接続がサーバーに対して開かれ、http通信が完了した直後に閉じられます。
$ curl http://10.5.1.1/favicon.ico -o /dev/null
サーバーのキープアライブ動作をより適切にテストするために、複数のhttp要求/応答サイクルにわたってtcp接続を開いたままにしておきたいです。
次のようにbashから直接貧弱なhttpリクエストを実行できます。
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<&-
しかし、私のテスト通信ははるかに複雑なため(認証など)、これを完全にbashまたは他のスクリプト言語で自分でコーディングするのではなく、既存のツールを使用したいと考えています。アイデアは、最初にbashでtcpソケットを開き、次にいくつかのコマンドラインツールに、独自のソケットを開く代わりにこの接続を使用するように強制することです。多分このように;
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<&-
これは、上記のツールを使用して、または他のツールを使用して可能ですか?
お探しのツールはsocat
です。 1つのWebサーバーをテストしているので、そのサーバーへの永続的な接続を確立するように要求できます(サーバーが閉じることを選択しない限り、タイムアウトを調整します)。これが完了すると、トンネルとしての接続。これを実現する2つの方法を次に示します。
curl
には--unix-socket
オプションを使用すると、UNIXソケットを介してHTTP要求を送信し、HTTP応答を受信できます(啓発的なコメントをありがとう)
次のように使用します。
socat TCP:10.5.1.1:80 UNIX-LISTEN:/tmp/curl.sock,fork
次に、別の端末で:
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
...
トンネルを、wget
、curl
、...が接続する疑似プロキシとして利用できるようにすることもできます。このソリューションには、curl
に限定されないという利点があります。
今回は、socat
がローカルのTCPポートをリッスンします(たとえば3128)):
socat TCP:10.5.1.1:80 TCP-LISTEN:3128,fork,reuseaddr
次に、別の端末で:
export http_proxy='http://localhost:3128'
curl http://10.5.1.1/message.txt
wget http://10.5.1.1/message.txt
....
HTTPクライアントはプロキシを使用しているため、HTTPリクエストはわずかに変更され、これは望ましくない場合があります。
もちろん、これらの2つのソリューションはいずれも、複数のHTTPサーバーで使用することを意図したものではありません。これは、すべての要求を受信するチャネルの最後にあるWebサーバーだからです。