Live data from Hacker News

TIL: You can make HTTP requests without curl using Bash /dev/TCP

mareksuppa.com

1–10 of 255 posts

Re: TIL: You can make HTTP requests without curl using Bash /dev/TCP

#2
I ran into this while checking connectivity between containers on an internal Docker network where the image had neither curl nor wget.

The main surprise was that Bash has /dev/tcp which lets you do the equivalent of an HTTP request with a bit of shell magic, for instance:

  exec 3/dev/tcp/service/8642
  printf 'GET /health HTTP/1.1\r\nHost: service\r\nConnection: close\r\n\r\n' >&3
  cat 
Where `service` is just the hostname of whatever you’re talking to and 8642 is the port you are trying to talk HTTP to.

Pretty cool!

Re: TIL: You can make HTTP requests without curl using Bash /dev/TCP

#3
post #2

I ran into this while checking connectivity between containers on an internal Docker network where the image had neither curl nor wget. The main surprise was that Bash has /dev/tcp which lets you do the equivalent of an HTTP request with a bit of shell magic, for instance: exec 3 /dev/tcp/service/8642 printf 'GET /health HTTP/1.1\r\nHost: service\r\nConnection: close\r\n\r\n' >&3 cat Where `service` is just the hostn…

It seems pretty cool, but I am wondering if there's any drawback on just using images that support curl? I can't think of any and to me it's kinda a must have, even on production images

Re: TIL: You can make HTTP requests without curl using Bash /dev/TCP

#5
This is pretty neat if all you need is to ping a local server but please use curl (or something equivalent) for contacting remote services. HTTP1.1 seems like such a simple protocol but in the real world you need to deal with proxies, different encodings, and redirects. Curl takes care of that (and a host of other annoying stuff) for you.

Re: TIL: You can make HTTP requests without curl using Bash /dev/TCP

#6
post #2

I ran into this while checking connectivity between containers on an internal Docker network where the image had neither curl nor wget. The main surprise was that Bash has /dev/tcp which lets you do the equivalent of an HTTP request with a bit of shell magic, for instance: exec 3 /dev/tcp/service/8642 printf 'GET /health HTTP/1.1\r\nHost: service\r\nConnection: close\r\n\r\n' >&3 cat Where `service` is just the hostn…

It seems pretty cool, but I am wondering if there's any drawback on just using images that support curl? I can't think of any and to me it's kinda a must have, even on production images

[deleted]

Re: TIL: You can make HTTP requests without curl using Bash /dev/TCP

#7
post #2

I ran into this while checking connectivity between containers on an internal Docker network where the image had neither curl nor wget. The main surprise was that Bash has /dev/tcp which lets you do the equivalent of an HTTP request with a bit of shell magic, for instance: exec 3 /dev/tcp/service/8642 printf 'GET /health HTTP/1.1\r\nHost: service\r\nConnection: close\r\n\r\n' >&3 cat Where `service` is just the hostn…

It seems pretty cool, but I am wondering if there's any drawback on just using images that support curl? I can't think of any and to me it's kinda a must have, even on production images

That is indeed a solid pushback! :)

For what its worth, this container used `python:3.12.2-slim-bookworm` and I really would not expect that sort of an image to bundle `curl` -- even if it is intended for production.

Re: TIL: You can make HTTP requests without curl using Bash /dev/TCP

#8
> As it turns out, bash can speak HTTP by itself.

No, it can not. Bash lets you open TCP sockets.

What you are doing here is trying to speak HTTP yourself, which is fine for testing and debugging, and hella cool for fun to do by hand, but you will shoot yourself in the foot if you try to use this pseudo http client unattended in reality. This toy code does not parse HTTP properly and will break.

You could of course write a full http/1.1 client in bash, you can even do a full http server in pure bash: https://github.com/bahamas10/bash-web-server

For less insane, non-bash shells there is always nc which is usually probably the wiser choice.

Re: TIL: You can make HTTP requests without curl using Bash /dev/TCP

#9

This is pretty neat if all you need is to ping a local server but please use curl (or something equivalent) for contacting remote services. HTTP1.1 seems like such a simple protocol but in the real world you need to deal with proxies, different encodings, and redirects. Curl takes care of that (and a host of other annoying stuff) for you.

Totally!

I was really just trying to see if intra-container connectivity works, and this ended up being a very quick way of doing so. (The alternative being building and deploying a new image, which would likely take significantly longer.)

Re: TIL: You can make HTTP requests without curl using Bash /dev/TCP

#10
post #2

I ran into this while checking connectivity between containers on an internal Docker network where the image had neither curl nor wget. The main surprise was that Bash has /dev/tcp which lets you do the equivalent of an HTTP request with a bit of shell magic, for instance: exec 3 /dev/tcp/service/8642 printf 'GET /health HTTP/1.1\r\nHost: service\r\nConnection: close\r\n\r\n' >&3 cat Where `service` is just the hostn…

It seems pretty cool, but I am wondering if there's any drawback on just using images that support curl? I can't think of any and to me it's kinda a must have, even on production images

This of course only supports http, not https. It's great for health checks e.g. in a docker environment. To do https, you'd have to use something like socat, but of course that doesn't use bash only.
Post reply on HN