ЁЯПл The SchoolтА║ЁЯХ╕я╕П NetworkingтА║ЁЯУи рдзрдбрд╛ 07 тАФ wire рд╡рд░рдЪреЗ HTTP: рд▓рдЦреЛрдЯреНрдпрд╛рддрд▓реА рдЪрд┐рдареНрдареА
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯУи рдзрдбрд╛ 07 тАФ wire рд╡рд░рдЪреЗ HTTP: рд▓рдЦреЛрдЯреНрдпрд╛рддрд▓реА рдЪрд┐рдареНрдареА

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 07 ┬╖ рдкреБрдвреЗ: lesson-08-tls


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбреЗ 01тАУ07. API рд╢рд╛рд│реЗрдЪреА request рдЪреА рдЪрд┐рдареНрдареА, TCP stream рд╡рд░рдЪреЗ bytes рдореНрд╣рдгреВрди, рдЖрдгрд┐ HTTP/1.1, HTTP/2 рдЖрдгрд┐ HTTP/3 рдиреЗ рд▓рдЦреЛрдЯреНрдпрд╛рдмрджреНрджрд▓ рдХрд╛рдп рдмрджрд▓рд▓реЗ.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

API рд╢рд╛рд│реЗрдиреЗ рдЪрд┐рдареНрдареА рд╢рд┐рдХрд╡рд▓реА: method, path, headers, body, рдЖрдгрд┐ рдХрд╛рд░рдХреБрдирд╛рдЪрд╛ рд╢рд┐рдХреНрдХрд╛. рд╣рд╛ рдзрдбрд╛ рд▓рдЦреЛрдЯрд╛ рдЙрдШрдбрддреЛ: рдЪрд┐рдареНрдареА рдореНрд╣рдгрдЬреЗ рдлрдХреНрдд рдУрд│реА рддреЛрдбрд▓реЗрд▓рд╛ рдордЬрдХреВрд░, TCP stream рдордзреНрдпреЗ рд▓рд┐рд╣рд┐рд▓реЗрд▓рд╛, рдЖрдгрд┐ рд╢рд┐рдХреНрдХрд╛ рддреНрдпрд╛рдЪ рдорд╛рд░реНрдЧрд╛рдиреЗ рдкрд░рдд рдпреЗрддреЛ. HTTP/1.1 рдкреБрдврдЪреНрдпрд╛ рдЪрд┐рдареНрдареАрд╕рд╛рдареА рд▓рдЦреЛрдЯрд╛ рдЙрдШрдбрд╛ рдареЗрд╡рддреЛ (keep-alive); HTTP/2 рдПрдХрд╛рдЪ рд▓рдЦреЛрдЯреНрдпрд╛рдд рдПрдХрд╛рдЪ рд╡реЗрд│реА рдЕрдиреЗрдХ рдЪрд┐рдареНрдареНрдпрд╛ рдкрд╛рдард╡реВ рджреЗрддреЛ; HTTP/3 рдиреЛрдВрджрдгреАрдХреГрдд рдЯрдкрд╛рд▓рд╛рдРрд╡рдЬреА рдПрдХрд╛ рд╣реБрд╢рд╛рд░ рд▓рд╛рдЙрдбрд╕реНрдкреАрдХрд░рд╡рд░ (QUIC) рдЬрд╛рддреЛ, рдореНрд╣рдгрдЬреЗ рдПрдХ рдкрд╛рди рд╣рд░рд╡рд▓реЗ рддрд░реА рдмрд╛рдХреАрдЪреА рдЕрдбрдХреВрди рд░рд╛рд╣рдд рдирд╛рд╣реАрдд.

ЁЯЧ║я╕П рдЖрдХреГрддреА

sequenceDiagram
  participant C as client
  participant S as server :80
  C->>S: GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n
  S->>C: HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 571\r\n\r\n<html>тАж

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

рдХрдЪреНрдЪреЗ HTTP рд╡рд╛рдЪрддрд╛ рдпреЗрдгреЗ рд╣рд╛рдЪ proxies, CORS, redirects, caching headers рдЖрдгрд┐ "curl рдиреЗ рдЪрд╛рд▓рддреЗ рдкрдг browser рдордзреНрдпреЗ рдирд╛рд╣реА" debug рдХрд░рдгреНрдпрд╛рдЪрд╛ рдорд╛рд░реНрдЧ рдЖрд╣реЗ. curl -v рдиреЗрдордХреНрдпрд╛ рдпрд╛рдЪ рдУрд│реА рджрд╛рдЦрд╡рддреЛ; рдЖрддрд╛ рддреБрдореНрд╣реА рддреНрдпрд╛ рд╡рд╛рдЪреВ рд╢рдХрддрд╛.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

http() рдЪрд╛рд░ рдУрд│реА рд╣рд╛рддрд╛рдиреЗ рд▓рд┐рд╣рд┐рддреЛ, server рдмрдВрдж рдХрд░реЗрдкрд░реНрдпрдВрдд рд╡рд╛рдЪрддреЛ, рдкрд╣рд┐рд▓реНрдпрд╛ рд░рд┐рдХрд╛рдореНрдпрд╛ рдУрд│реАрд╡рд░ рддреЛрдбрддреЛ, рдЖрдгрд┐ status line рд╕реЛрдмрдд рддреАрди headers рдЫрд╛рдкрддреЛ. рдмрд╛рд░рд╛ рдУрд│реАрдВрдд рд╣рд╛ рдПрдХ рдкреВрд░реНрдг HTTP client рдЖрд╣реЗ тАФ рдкреНрд░рддреНрдпреЗрдХ framework рдореНрд╣рдгрдЬреЗ рд╣реЗрдЪ, рдЕрдзрд┐рдХ рдХрд╛рд╣реА рдЕрдкрд╡рд╛рджрд╛рддреНрдордХ рдкреНрд░рдХрд░рдгреЗ.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

python3 net/demo.py http
printf 'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n' | nc example.com 80 | head -12   # by hand, no Python
curl -sv http://example.com -o /dev/null 2>&1 | grep -E '^(>|<)'       # the same lines, from the grown-up tool
curl -sI --http2 https://example.com | head -3                          # HTTP/2 when TLS is on

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

HTTP/1.1 200 OK, рдПрдХ Content-Type: text/html header, body: 571 bytes (рдХрд┐рдВрд╡рд╛ рд╕рд╛рдзрд╛рд░рдг рддрд┐рддрдХреЗ). nc рдЕрдЧрджреА рддреНрдпрд╛рдЪ рдУрд│реА рджрд╛рдЦрд╡рддреЛ. curl --http2 HTTP/2 200 рд╕рд╛рдВрдЧрддреЛ.

ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ

HTTP рдореНрд╣рдгрдЬреЗ stream рд╡рд░рдЪрд╛ рдордЬрдХреВрд░, рддреБрдореНрд╣реА library рд╢рд┐рд╡рд╛рдп рддреЗ рдмреЛрд▓реВ рд╢рдХрддрд╛, рдЖрдгрд┐ versions рдордзрд▓рд╛ рдлрд░рдХ рд▓рдЦреЛрдЯреНрдпрд╛рдд рдЖрд╣реЗ, рдЪрд┐рдареНрдареАрдд рдирд╛рд╣реА.

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: proxy рдХрдбреВрди рдЖрд▓реЗрд▓рд╛ 502, Content-Length рдирд╕рд▓реНрдпрд╛рдиреЗ рдЕрдбрдХрд▓реЗрд▓реА request, Cache-Control рдХрдбреЗ рджреБрд░реНрд▓рдХреНрд╖ рдХрд░рдгрд╛рд░рд╛ CDN тАФ рдУрд│реА рдорд╛рд╣реАрдд рдЭрд╛рд▓реНрдпрд╛ рдХреА рд╣реЗ рд╕рдЧрд│реЗ curl -v рдордзреНрдпреЗ рд╡рд╛рдЪрддрд╛ рдпреЗрддреЗ.

тПня╕П рдкреБрдвреЗ

рдзрдбрд╛ 08 тАФ TLS рдЖрдгрд┐ certificates: рд╕реАрд▓ рдХреЗрд▓реЗрд▓рд╛ рд▓рдЦреЛрдЯрд╛, рдЖрдгрд┐ padlock рдХрд╛рдп рд╡рдЪрди рджреЗрддреЛ рдЖрдгрд┐ рдХрд╛рдп рджреЗрдд рдирд╛рд╣реА.

ЁЯУи Lesson 07 тАФ HTTP on the wire: the slip in the envelope

ЁЯУН You are here: Lesson 07 of 12 ┬╖ Next: lesson-08-tls


ЁЯУж What's in this branch

Lessons 01тАУ07. The API school's request slip as bytes on a TCP stream, and what HTTP/1.1, HTTP/2 and HTTP/3 changed about the envelope.

ЁЯзТ Explain like I'm 5

The API school taught the slip: method, path, headers, body, and the clerk's stamp. This lesson opens the envelope: the slip is just text with line breaks, written into a TCP stream, and the stamp comes back the same way. HTTP/1.1 keeps the envelope open for the next slip (keep-alive); HTTP/2 lets many slips travel in one envelope at once; HTTP/3 switches from registered post to a cleverer loudspeaker (QUIC) so one lost page does not hold up the others.

ЁЯЧ║я╕П Diagram

sequenceDiagram
  participant C as client
  participant S as server :80
  C->>S: GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n
  S->>C: HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 571\r\n\r\n<html>тАж

тЭУ What

ЁЯдФ Why

Reading raw HTTP is how you debug proxies, CORS, redirects, caching headers and "it works with curl but not in the browser". curl -v shows exactly these lines; now you can read them.

ЁЯФз How (in this repo)

http() writes the four lines by hand, reads until the server closes, splits on the first blank line, and prints the status line plus three headers. That is a complete HTTP client in twelve lines тАФ every framework is this plus edge cases.

ЁЯзк Try it

python3 net/demo.py http
printf 'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n' | nc example.com 80 | head -12   # by hand, no Python
curl -sv http://example.com -o /dev/null 2>&1 | grep -E '^(>|<)'       # the same lines, from the grown-up tool
curl -sI --http2 https://example.com | head -3                          # HTTP/2 when TLS is on

тЬЕ Verify тАФ what you should see

HTTP/1.1 200 OK, a Content-Type: text/html header, body: 571 bytes (or thereabouts). nc shows identical lines. curl --http2 reports HTTP/2 200.

ЁЯПБ What you just proved

HTTP is text on a stream, you can speak it without a library, and the versions differ in the envelope, not the slip.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: a 502 from a proxy, a hung request with no Content-Length, a CDN ignoring Cache-Control тАФ all readable in curl -v once you know the lines.

тПня╕П Next

Lesson 08 тАФ TLS & certificates: the sealed envelope, and what the padlock does and does not promise.

тЖР PreviousdnsNext тЖТtls

This page is the lesson's README from the lesson-07-http-on-the-wire branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.