APPLICATION LAYER · HTTP/1.1 MESSAGE
อ่านข้อความที่ Browser และ Server พูดกัน
ครั้งหนึ่ง telnet ทำให้เราเห็น HTTP ได้ตรงไปตรงมา แต่เว็บสาธารณะส่วนใหญ่ใช้ TLS แล้ว ห้องทดลองนี้จึงเปิดข้อความ plaintext ณ จุดก่อนเข้ารหัสและหลังถอดรหัส ให้ตรวจได้ทุกช่องว่าง CRLF และบรรทัดว่างอย่างปลอดภัย
MESSAGE COMPOSER
ประกอบ Request แล้วเดินดูการแลกเปลี่ยน
พร้อมสร้างข้อความ
FROM SOCKET TO MESSAGE
สิ่งที่ telnet เคยเผยให้เห็น และ HTTPS ซ่อนไว้
TCP connection
HTTP/1.1 เดินทางบน byte stream การเชื่อมต่อมี address และ port แต่ TCP ไม่เข้าใจ request line หรือ header
TLS tunnel
เมื่อเป็น HTTPS, TLS เข้ารหัส byte ของ HTTP ทำให้ telnet เจรจา TLS สมัยใหม่ไม่ได้ แต่ Browser ยังเห็น plaintext ก่อนเข้ารหัส
HTTP semantics
Method และ target บอกเจตนา, header ส่ง metadata, บรรทัดว่างปิดส่วน header และ body ที่อาจมีหรือไม่มีก็ได้ใช้ส่ง representation
MESSAGE ANATOMY
ไวยากรณ์ที่ชี้ให้เห็นได้จริง
GET /path HTTP/1.1Request line
Method เว้นหนึ่งช่อง ตามด้วย request target เว้นหนึ่งช่อง แล้วจบด้วย protocol version และ CRLF
Host: warin.meHeader field
ชื่อ field, colon, ช่องว่างที่เลือกมีได้ และค่า โดยชื่อ HTTP field ไม่แยกตัวพิมพ์ใหญ่เล็ก
␍␊บรรทัดว่าง
CRLF ชุดที่สองปิดส่วน header การลืมบรรทัดนี้คือเหตุผลคลาสสิกที่ทำให้ request ผ่าน telnet ดูเหมือนค้าง
{"student":"A"}Message body
Content-Length นับจำนวน byte ของ body ไม่ใช่จำนวนอักขระ JavaScript เพราะ UTF-8 หนึ่งอักขระอาจใช้หลาย byte
DO NOT OVERGENERALIZE
นี่คือ HTTP/1.1 ไม่ใช่รูปแบบบนสายของ HTTP ทุกยุค
| Protocol | รูปแบบบนสาย | พฤติกรรมการเชื่อมต่อ | วิธีตรวจ |
|---|---|---|---|
| HTTP/1.1 | start-line และ field เป็นข้อความ คั่นด้วย CRLF | คงการเชื่อมต่อโดยปริยาย; ไม่ค่อยใช้ pipelining | curl -v, DevTools, Wireshark + TLS keys |
| HTTP/2 | binary frame และ header block ที่บีบอัด | หลาย stream อยู่บน connection เดียว | DevTools, nghttp, Wireshark |
| HTTP/3 | HTTP semantics บน QUIC frame | หลาย stream บน QUIC ที่เข้ารหัสและใช้ UDP | DevTools, qlog, Wireshark |
CLASSROOM INVESTIGATION
โจทย์ที่เปลี่ยน syntax ให้เป็นหลักฐาน
- เปลี่ยน GET เป็น POST แล้วหาว่า field ใดต้องเปลี่ยนเมื่อมี body
- ใส่ภาษาไทยใน body แล้วเทียบจำนวนอักขระกับจำนวน byte ใน Content-Length
- เปรียบเทียบ 200, 301, 304 และ 404 ว่า response ใดมี representation body
- ใช้ Connection: close แล้วอธิบายว่าใครเป็นผู้ปิด connection หลัง response
- อธิบายว่าเหตุใดแบบจำลองเห็น plaintext ได้ แม้ URL สาธารณะใช้ HTTPS
- จับ request เดียวกันใน Browser DevTools แล้วหา header ที่ Browser เติมให้อัตโนมัติ