In a bash shell scipt, I use several command line tools (wget, curl, httpie) to test my http server.

When using e.g. curl to invoke a GET request, I see that a tcp connection is opened to my server and closed immediatly after the http communication has been completed.

$ curl -o /dev/null 

For better testing the keep-alive behaviour of my server, I want to keep the tcp connection open over multiple http request / response cycles.

I am able to perform poor http requests directly from bash like this:

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

But because my testing communication is much more complex (incl. authentication et cetera), I don't want to code this completely myself in bash or other scripting language but want to use existing tools instead. The idea is now to first open a tcp socket in bash and then forcing some command line tools to use this connection instead of open their own sockets. Maybe like this;

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

Might this be possible using the above mentioned tools or with other tools?

2 Answers 2


The tool you are looking for is socat. Since you are testing one single web server, you can ask it to establish a permanent connection to that server (as long as it doesn't choose to close it -- adjust your timeouts accordingly) and once this is done, you can use the connection as a tunnel. Below are two ways to accomplish this.

Querying through a Unix socket

curl has a --unix-socket option that allows you to send HTTP requests and receive HTTP replies through a Unix socket (thank you, thrig, for your enlightening comment)

You would use it like this:

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

Then, on another terminal:

curl --unix-socket /tmp/curl.sock
curl --unix-socket /tmp/curl.sock

Querying through a pseudo-HTTP-proxy

You can also make your tunnel available as a pseudo-proxy through which wget, curl,... would connect. This solution has the advantage to not be limited to curl.

This time, socat listens to a local TCP port (say 3128):

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

Then, on another terminal:

export http_proxy='http://localhost:3128'

Note that since the HTTP client is using a proxy, the HTTP request will be slightly altered and this may not be desirable.

Of course, none of those two solutions are intended to be used with multiple HTTP servers since this is your web-server at the end of the channel that receives all the requests.

  • curl (of sufficient version) can use --abstract-unix-socket or --unix-socket though those after some fiddling around appear less practical than just using TCP
    – thrig
    Sep 21, 2017 at 17:13
  • Thanks a lot @thrig, I didn't know those options and I have updated my answer accordingly (only with --unix-socket though, since my curl is not fresh enough to support the --abstract-unix-socket option).
    – xhienne
    Sep 21, 2017 at 20:48
  • When I looked at tcpdump the socket option was sending SYN packets for each command, unlike when TCP is used, so they may be different.
    – thrig
    Sep 21, 2017 at 21:09
  • 1
    Ahh, I had the UNIX-LISTEN before the TCP, opposite of what you have
    – thrig
    Sep 21, 2017 at 22:20
  • 1
    Pseudo-HTTP-proxy approach: The request will be altered from GET /message.txt to GET and this o.a. let Digest Access Authentication fail (because of altered URI). I'd now changed my server to strip that from the URI and now it also works with Digest Access Authentication :-)
    – Joe
    Sep 24, 2017 at 12:01

If you only used cURL as a command line tool in your tests scenarios you could use its --next option to enable persistent connections. For example,

curl -v http://google.com --next http://google.com |& grep -i connect

is reusing the open connection as attested by its output

* Connected to google.com ( port 80
* Connection #0 to host google.com left intact
* Re-using existing connection with host google.com
* Connection #0 to host google.com left intact
  • Wget and HTTPie might support persistent connections as well
    – darw
    Oct 2, 2023 at 14:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .