From Click to Response: The Full Life of an HTTPS Request
The HTTP/2 Rabbit Hole: From a Simple Go Server to the Bottom of the Ocean It started out as a simple weekend experiment: I wanted to build…
From Click to Response: The Full Life of an HTTPS Request
The HTTP/2 Rabbit Hole: From a Simple Go Server to the Bottom of the Ocean It started out as a simple weekend experiment: I wanted to build a basic JSON-RPC server in Go using HTTP/2. I generated my self-signed certificates (cert.pem and key.pem), wrote a quick main.go file, and fired up Postman to test it. I even disabled SSL verification in Postman to account for my self-signed cert.
I hit “Send.” The response came back perfectly. But when I looked closely at the network tab, I saw a betrayal: Protocol: HTTP/1.1.
Why was my HTTP/2 server falling back to HTTP/1.1? Trying to answer that one simple question pushed me down a rabbit hole that completely rewired how I understand the internet, encryption, and the network stack.
Here is everything I learned.
Doubt 1: The Postman Betrayal and the “Fake ID” My first thought was that my Go code was broken. But as I learned, Go’s net/http package natively upgrades to HTTP/2 when you use ListenAndServeTLS. The problem wasn’t my server; it was Postman.
To speak HTTP/2, the client and server must negotiate it during the initial TLS handshake (a process called ALPN). But because I was using a self-signed certificate, Postman’s underlying network library was getting spooked and falling back to HTTP/1.1.
This led to my next question: If I have the certificate locally, why do I need to explicitly tell clients to ignore the self-signed warning? It comes down to the difference between Encryption and Trust.
-> Trust: Generating a self-signed certificate is like printing your own ID badge on a home printer. Even if you wear it, a security guard (your browser or Postman) will reject it because it wasn’t issued by a recognized authority. You have to explicitly tell the client, “I vouch for this guy.”
-> Encryption: Even if the client doesn’t trust your homemade ID, the mathematical encryption still works flawlessly! The client uses your public key to snap a padlock shut, ensuring no one sniffing your local network can read the data.
Doubt 2: The Russian Nesting Dolls of the Network Once I got the HTTP/2 connection working, I wanted to understand exactly what was happening under the hood. I used to think of HTTPS as one big protocol. I thought HTTP itself handled the encryption.
I was wrong. HTTP is completely blind to encryption.
The best way to visualize the network stack is like a Russian Nesting Doll, or a mail delivery system:
The Letter (HTTP): This is your JSON payload and headers. It is just plain paper. It has no locks and no idea how to navigate the internet.
The Briefcase (TLS): The letter is placed inside a titanium briefcase. This is where the heavy cryptography math (like Elliptic Curve Diffie-Hellman) happens to generate a symmetric session key. The briefcase locks the letter.
The Delivery Truck (TCP): The briefcase is handed to a delivery driver. The driver cannot read the letter and doesn’t have the key to the briefcase. His only job is to drive it to the destination.
This is why the math to generate session keys isn’t found in HTTP code. It lives entirely in the TLS layer (like Go’s crypto/tls package). HTTP just writes the letter and assumes the layers below it will keep it safe.
Doubt 3: The Physical Reality of TCP and “Blind” Routers So, how does that TCP delivery truck actually find its way across the globe?
First, I realized that HTTP doesn’t even contain the destination IP address; it only has the domain name. The operating system does a DNS Lookup (the phonebook) to find the IP address before TCP even starts its engine.
Then, the data is chopped into tiny 1,500-byte chunks called Packets. These packets are translated into electricity or light and fired out of your house.
Here was the biggest mind-bender for me: The routers on the internet are completely TCP-blind. As your packets bounce from a router in Mumbai, to Tokyo, to Seattle via submarine glass cables, those physical routers have no idea what a “TCP Connection” is. They just look at the IP label and toss the packet like a hot potato to the next intersection.
A TCP connection doesn’t exist in the wires. It is a software agreement exclusively between the Operating System on your computer and the Operating System on the server. They both hold the packets in RAM, organize them by sequence numbers, and mutually agree to keep a “virtual tube” open.
(And if you are testing on localhost like I was? The data never leaves your motherboard. Windows uses a “Loopback Interface” to hand the packets directly from your Go client’s RAM to your Go server’s RAM).
Doubt 4: What is a Socket, anyway? If TCP is the pneumatic tube system built into Windows, how does my specific Go program plug into it?
Enter the Socket. A socket is simply: IP Address + Port Number. Think of the IP address as an apartment building, and the Port (like 8443) as a specific apartment. The socket is the physical mailbox slot on the door. When I call ListenAndServe, my Go program asks Windows to install a mailbox on Port 8443. When TCP deliveries arrive, Windows shoves the data through that socket file, waking my program up.
(To operating system, a socket is just a software file. When your Go program wants to send data, it doesn’t know how to talk to Wi-Fi or Ethernet. It literally just “writes” your HTTP/2 data into that socket file. The Windows OS sits there watching that file; the second it sees new data appear in the socket, Windows grabs it, wraps it in TCP, and fires it across the internet.)
Doubt 5: HTTP/1.1 vs. HTTP/2 (The 1-Second Gap) With the physical network understood, I finally looked at why HTTP/2 is actually better.
I asked myself: If I send 30 requests, but I wait 1 second between each request, is HTTP/2 faster than HTTP/1.1? The answer is No. They are exactly the same speed.
HTTP/2’s superpower is Multiplexing, and it only activates when there is a traffic jam.
HTTP/1.1 forces you to use the TCP tube one letter at a time. If you send 30 requests at once, you have to wait for request #1 to finish before sending request #2 (Head-of-Line blocking).
HTTP/2 chops all 30 letters into tiny binary puzzle pieces (frames) and throws them all down the tube at the exact same millisecond.
(Both versions keep the TCP connection open when they are done, but the server usually acts as the bouncer. If you are idle for 30 seconds, the server sends a FIN packet and forces your client to close the tube to save RAM).
Doubt 6: If HTTP/2 is so fast, why do WebSockets exist? My final question was about WebSockets.
Both HTTP/1.1 and HTTP/2 share one strict, unbreakable rule: The server is never allowed to speak unless the client asks a question first. Even with HTTP/2’s speed, if you are building a chat app, the client has to constantly annoy the server asking, “Any new messages?”
A WebSocket throws this rule away. It starts as a standard HTTP request, but it asks the server to “upgrade.” If the server agrees, HTTP is killed, and the WebSocket software hijacks that exact same TCP tube. It turns the tube into a full-duplex telephone call, where the server can shove data to the client instantly without asking permission.
Use HTTP/2 for APIs where the client knows what it wants (like my JSON-RPC server).
Use WebSockets for real-time, bi-directional streams like chat apps or live stock tickers.
🌍 Full End-to-End Journey
1. The App and the GPS (DNS & IP)
I hit send on https://api.mycompany.com:8443/rpc. Before doing anything else, my operating system pauses and checks the DNS phonebook to translate api.mycompany.com into a physical IP address (like 142.250.190.46). The GPS is set.
📸 Visualize DNS like this:
2. The Mailbox (The Socket)
My Go server is already running on the destination machine. It has asked its Windows OS to install a “mailbox slot” (a Socket) on Port 8443. Meanwhile, my local client OS creates a temporary, random Socket (like Port 58869) so the response has a mailbox to return to.
3. The Tube is Built (TCP Handshake)
The client OS fires a tiny packet of light across the internet’s fiber-optic cables to the server.
- SYN (“Are you awake?”)
- SYN-ACK (“Yes, are you?”)
- ACK (“Yes, let’s talk.”)
The TCP pneumatic tube is now open between the two operating systems. The routers in the middle have no idea this tube exists; they just blindly forwarded the packets.
📸 TCP 3-Way Handshake
4. The Briefcase is Locked (TLS Handshake & ALPN)
Now that the tube is open, the two computers introduce themselves.
The server hands over its Public Key (its ID card).
During this introduction, they look at a menu and agree to speak HTTP/2 (the ALPN negotiation).
Finally, they use complex Elliptic Curve math to generate a shared, super-fast symmetric Session Key.
The titanium briefcase is officially locked.
📸 TLS Handshake + ALPN
5. The Shredder (HTTP/2 Framing)
Only now does HTTP actually enter the picture.
My JSON payload and headers are handed to the HTTP/2 software. Because it’s HTTP/2, my letter isn’t sent as plain text. It is shoved through a shredder, chopped into tiny binary puzzle pieces (Frames), and packed into the TLS briefcase.
📸 HTTP/2 Frames & Multiplexing
6. The Hot Potato (Physical Routing)
The encrypted briefcase is chopped into 1,500-byte TCP packets and fired out of my house.
They hit my ISP, turn into light, and bounce across dozens of physical intersections (routers) across the globe.
Each router just looks at the IP address and tosses the packet to the next closest city.
📸 Internet Routing & Fiber Optics
7. Reassembly and Delivery
The chaotic storm of packets arrives at the server’s OS.
The server’s TCP software catches them, looks at their sequence numbers, and perfectly reassembles the TLS briefcase.
It uses the Session Key to unlock the briefcase, pulls out the binary HTTP/2 frames, rebuilds the JSON request, and shoves it through the Socket on Port 8443.
📸 Packet Reassembly
8. The Go Server Wakes Up
My main.go program gets tapped on the shoulder by the OS.
It reads the JSON, runs my rpcHandler logic, and packages up the response.
9. The Return Trip and the Bouncer
The response is chopped into frames, encrypted, and fired back down the exact same TCP tube to my temporary client socket.
Postman displays the JSON on my screen.
The TCP tube stays open, just in case I want to send another request.
But after 30 seconds of silence, the Go server decides I’ve overstayed my welcome. It sends a FIN packet, and both computers quietly dismantle the tube and erase the connection from their memory.
📸 TCP Connection Close
🌊 The Most Beautiful Realization
The biggest mental unlock in networking is this:
Routers do NOT understand:
- HTTP
- TLS
- JSON
- REST
- RPC
- WebSockets
They only understand:
- IP addresses
- MAC addresses
- Packet forwarding
Everything else exists only as agreements between software layers.
That realization changes how you see the internet forever.
Conclusion What started as a frustrated Google search about a Postman error turned into a profound appreciation for the internet. Millions of routers are playing a global game of hot potato with billions of encrypted, chopped-up packets every second — and as developers, we get to control all of it with just a few lines of code.
메타데이터
- post_id
- ddf8dac9bd65
- slug
- from-click-to-response-the-full-life-of-an-https-request-ddf8dac9bd65
- url
- https://medium.com/@annamdevularavi2003/from-click-to-response-the-full-life-of-an-https-request-ddf8dac9bd65
- canonical_url
- https://medium.com/@annamdevularavi2003/from-click-to-response-the-full-life-of-an-https-request-ddf8dac9bd65
- author_url
- https://medium.com/@annamdevularavi2003
- status
- ok
- fetched_at
- 2026-06-24 04:09:36