Featured image

What I enjoy most about programming in Ruby is how concisely and effortlessly you can manage low-level concepts like TCP sockets. If you want to get a better grasp on how HTTP actually works under the hood, I highly recommend trying to build a simple GET request yourself without relying on any HTTP client (not even Net::HTTP) - just pure TCPSocket and IO. In short, all you need to do is construct the request headers correctly and stream the socket response into a buffer until you hit the EOF marker.

Have you ever built raw TCP socket clients in your projects, or do you stick strictly to high-level HTTP libraries?

require 'uri'
require 'socket'

def simple_get(url)
  uri = URI(url)
  s = TCPSocket.new(uri.host, uri.port || 80)
  s.write(
    "GET #{uri.path.empty? ? '/' : uri.path} HTTP/1.1\r\n" \
    "Host: #{uri.host}\r\n" \
    "Connection: close\r\n" \
    "\r\n"
  )
  r = StringIO.new
  IO.copy_stream(s, r)
  r.string
ensure
  s.close if s && !s.closed?
end

resp = simple_get('http://example.com/some-path')
# HTTP/1.1 404 Not Found\r\nDate: Wed, 17 Sep 2026 08:24:32 GMT\r\nContent-Type: text/html\r\nTransfer-Encoding: chunked ...