WebArchitecture

What happens when you hit Enter

🌐 HTTP Fundamentals

When you type a URL and hit Enter, this is what happens. Click any step to learn more.

What does an HTTP message actually look like?

HTTP is just text. Your browser sends:

GET /page HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 ...
Accept: text/html

The server responds:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234

<html>
  <body>Hello, world!</body>
</html>
HTTP Methods (GET, POST, PUT, DELETE)
  • GET — Retrieve data (the default when you visit a URL)
  • POST — Submit data (forms, API calls)
  • PUT — Replace a resource
  • DELETE — Remove a resource
  • HEAD — Like GET, but only return headers
Status Codes (200, 404, 502...)
  • 2xx — Success (200 OK, 201 Created)
  • 3xx — Redirect (301 Moved, 302 Found)
  • 4xx — Client error (400 Bad Request, 404 Not Found)
  • 5xx — Server error (500 Internal, 502 Bad Gateway)
502 Bad Gateway = the reverse proxy couldn't reach your app. Usually means Flask isn't running.
Try It: Send a real HTTP request
Request
Click "Inspect" to see the HTTP request
Response
Response will appear here
Quiz: Test your understanding

1. What does "HTTP is stateless" mean?

2. You see a 502 error. What's most likely wrong?

🔌 TCP & Sockets

HTTP rides on top of TCP (Transmission Control Protocol). While HTTP defines the message format, TCP handles the actual delivery — ensuring bytes arrive in order, retransmitting lost packets, and managing connections.

A socket is the programming interface to TCP. When your Flask app listens on port 5000, it's creating a socket that waits for incoming TCP connections.

What is a port? A port is just a 16-bit number (0-65535) that identifies which application should receive incoming data. It's not a physical thing — it's like an apartment number in a building (the IP address).

When you run flask run --port 5000, here's what happens:

# Your app does (simplified):
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('0.0.0.0', 5000))  # Claim port 5000
sock.listen()                  # Start accepting connections

while True:
    client, addr = sock.accept()  # Wait for a connection
    data = client.recv(1024)       # Read the HTTP request
    client.send(b'HTTP/1.1 200 OK\r\n\r\nHello')
    client.close()

The bind() call claims the port. If another process already has it, you get the dreaded error:

OSError: [Errno 98] Address already in use

This usually means:

  • Another instance of your app is running
  • The previous instance crashed but the OS hasn't released the port yet
  • Some other service is using that port
Common Ports
80 HTTP (unencrypted)
443 HTTPS (encrypted)
22 SSH
5432 PostgreSQL
5000-9999 Common range for development servers

Connection Lifecycle

TCP connections go through a handshake before data can flow:

Client                    Server
   |                         |
   |-------- SYN ----------->|  "I want to connect"
   |<------ SYN-ACK ---------|  "OK, I acknowledge"
   |-------- ACK ----------->|  "Great, let's go"
   |                         |
   |====== DATA FLOWS =======|
   |                         |
   |-------- FIN ----------->|  "I'm done"
   |<------ FIN-ACK ---------|  "OK, me too"
Keep-alive connections: HTTP/1.1 introduced persistent connections. Instead of closing after each request, the connection stays open for multiple requests. This avoids the overhead of repeated handshakes.
Quick Check

1. What is a port?

2. "Address already in use" usually means:

🚧 Coming Soon

This section is still being written. Check back soon!