HTTP زدن با خود bash، بدون curl و wget
خلاصهٔ کاملتر
نویسنده تعریف میکنه که نیاز داشته از داخل یه کانتینر بررسی کنه که یه سرویس به سرویس دیگه رو شبکهی داخلی داکر میرسه یا نه؛ یه GET /health ساده. کار عادی این بود که با curl بزنه، ولی ایمیج اپ اونقدر لخت بوده که نه curl داشته نه wget و نه هیچ ابزار دیگهای برای بازکردن سوکت.
راهحل این بوده که خود bash میتونه HTTP حرف بزنه. بش میتونه یه سوکت TCP باز کنه و تو دستی یه درخواست HTTP توش بنویسی، بدون هیچ چیزی جز همون شلی که از قبل هست. هستهی ترفند اینه:
exec 3<>/dev/tcp/service/8642
printf 'GET /health HTTP/1.1\r\nHost: service\r\nConnection: close\r\n\r\n' >&3
cat <&3اینجا service فقط نام میزبان چیزیه که باهاش حرف میزنی و باید resolve بشه و از جایی که اجرا میکنی در دسترس باشه؛ یه نام کانتینر رو شبکهی داکر یا هر DNSای که resolve میشه. همین چند خط، کل پاسخ رو چاپ میکنه: خط وضعیت، هدرها، خط خالی و بدنه. برای اضافهکردن هدری مثل Authorization، فقط یه خط دیگه که با \r\n تموم میشه رو قبل از خط خالی پایانی میذاری.
نکتهای که بار اول گیجش کرده این بوده که /dev/tcp اصلاً یه فایل دستگاه واقعی نیست؛ همچین مسیری رو دیسک وجود نداره و ls چیزی پیدا نمیکنه. این یه ریدایرکشنه که خود bash داخلی هندلش میکنه: بش خودش DNS و connect رو انجام میده و exec 3 یه فایلتوصیفگر (شمارهی ۳) بهت میده که مثل هر توصیفگر دیگهای ازش میخونی و روش مینویسی.
چند چیز هم بهتره بدونی. این یه کلاینت واقعی HTTP نیست و ریدایرکت، پاسخ chunked، فشردهسازی، retry و TLS رو هندل نمیکنه؛ برای https باید بری سراغ openssl s_client. هدر Connection: close هم مهمه، وگرنه cat تا ابد منتظر بایتهایی میمونه که نمیان؛ پیچیدن دستور تو timeout هم حواست رو جمع میکنه.
ضمناً این یه امکان bash هست نه POSIX، پس با dash و zsh کار نمیکنه و رو سیستمهای خیلی مینیمال هم ممکنه غیرفعال باشه. نویسنده میگه برای کار روزمره هنوز curl ابزار درسته، ولی این ترفند وقتی نمیتونی چیزی نصب کنی، یه چک سریع رو راه میندازه.
نکات کلیدی:
- خود bash میتونه با /dev/tcp/host/port یه سوکت TCP باز کنه و HTTP بزنه
- مناسب کانتینرهای لخت که curl و wget ندارن
- کلاینت کامل HTTP نیست؛ TLS، ریدایرکت و chunked رو هندل نمیکنه
- هدر Connection: close لازمه وگرنه cat تا ابد بلاک میشه
- امکان bash هست نه POSIX؛ رو dash و zsh کار نمیکنه




