HTTP Protocol

เนื่องจาก Ruby on Rails เป็น Web Application กระบวนการสื่อสารระหว่างผู้ใช้กับแอพลิเคชัน จึงเป็นการสื่อสารด้วย HTTP Protocol ซึ่งจัดเป็นวิธีที่สะดวกและง่ายที่สุดในการสื่อสารผ่าน Internet

การสื่อสารด้วย HTTP Protocol มีขั้นตอนคร่าวๆ ดังนี้

เครื่องลูกข่าย Client

เครื่องแม่ข่าย Server

สร้าง HTTP Request String เปิด TCP Server Socket รอรับ Request
เปิด TCP Socket เปิด TCP Socket รับการสื่อสารจากเครื่องลูก
ส่ง HTTP Request รับ HTTP Request
รอการประมวลผล หากรอนานเกินไปจะเกิด Timeout ตีความ ประมวลผล
สร้าง HTTP Response
รับ HTTP Response ส่ง HTTP Response กลับไปยังเครื่องลูก
แสดงผลจาก HTTP Response ปิด TCP Socket ปิด TCP Socket
จบการทำงาน รอรับ Request อื่นๆ ต่อไป

จะเห็นได้ว่าการทำงานของ HTTP นี้เป็นระบบ Request – Response โดยไม่มีการคำนึงถึง State หรือ Session ในการทำงาน ดังนั้นการพัฒนา Application บน HTTP Protocol นี้ต้องมีการบันทึก State หรือ Session การทำงานด้วยกลไกของ Application เอง

TCP คืออะไร UPD คืออะไร ทั้งสองอย่างมีความเหมือนและความแตกต่างกันอย่างไร? เป็นคำถามสำคัญที่ควรทราบ แต่เป็นคำถามที่อยู่นอกเหนือขอบเขตการบรรยายครั้งนี้ จึงขอฝากเป็นการบ้านให้ผู้ฟังศึกษาเพิ่มเติม

HTTP Request

HTTP Request ประกอบด้วยสองส่วนหลักคือ Header กับ Body ทุกครั้งที่มีการสื่อสาร HTTP Request จะต้องมี Header แต่ในหลายๆ กรณีอาจไม่มี Body ก็ได้

ใน Request Header จะประกอบด้วย

  • Method (GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH)
  • Request-URI (/index.html, ฯลฯ)
  • HTTP version (HTTP/1.1)
  • Header field อื่นๆ เช่น Accept, Accept-Charset, ฯลฯ

ตัวอย่างเช่น

GET / HTTP/1.1
Host: www.google.com

หรือ

GET / HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Cache-Control: max-age=0
Connection: keep-alive
Cookie: lu=ggU_YAFFI7P4YLcl--A_ppfw; datr=Tb7pUSSYzjhj3BYRUcanobwv; sub=524288; p=107; presence=EM376106286EuserFA2615107A2EstateFDutF0Et2F_5b_5dEuct2F1376105683BElm2FnullEtrFnullEtwF2153187741EatF1376106286653Esb2F0CEchFDp_5f615107F148CC; c_user=615107; csm=2; fr=0ZyfQqMV7sceE64Kz.AWX0mAH1xINpMzgCl_u5wnSrrTY.BRUAD8.J9.FH_.AWVS61C4; s=Aa5cNzPCyaxoEAAW.BRUAD8; xs=2%3AlhltfhyxFSQrLg%3A2%3A1364197627
DNT: 1
Host: www.facebook.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36

ใน HTTP POST, PUT, PATCH request จะต้องมี Request body เป็น key-value pair เพื่อส่งข้อมูลที่ผู้ใช้ต้องการนำไปเก็บไว้บนเซิร์ฟเวอร์

ตัวอย่าง Request Body

utf8=%E2%9C%93&authenticity_token=BWYKfdlGLaI7zzhs98lWjmpbavlZGOz%2Fo5Z1%2FMqbGac%3D&name=Student+A&callback_email=a%40example.com&phone_number=0987654321&details=Inquiry+on+Swiftlet+and+its+job+openings.&recaptcha_challenge_field=03AHJ_VuvCgYF6bKe0BrVevxMDWuzpq-a_XR8YC3Q6FHJuvUfphD6-soWOWeCt1nIt5m4wlRpzDVA80MYhGgJ2o4QoDXOz9ynhZkau-71olUWqviyF98xYRZxkirWsEc6emyNRkbYuf38OYEAQWCLNQkaVs-sDnf6RBOWIKRw7uGy22-VbiJxIJ0c&recaptcha_response_field=sent+roxcipt

เมื่อแกะออกมาแล้วจะได้เป็น

utf8:✓
authenticity_token:BWYKfdlGLaI7zzhs98lWjmpbavlZGOz/o5Z1/MqbGac=
name:Student A
callback_email:a@example.com
phone_number:0987654321
details:Inquiry on Swiftlet and its job openings.
recaptcha_challenge_field:03AHJ_VuvCgYF6bKe0BrVevxMDWuzpq-a_XR8YC3Q6FHJuvUfphD6-soWOWeCt1nIt5m4wlRpzDVA80MYhGgJ2o4QoDXOz9ynhZkau-71olUWqviyF98xYRZxkirWsEc6emyNRkbYuf38OYEAQWCLNQkaVs-sDnf6RBOWIKRw7uGy22-VbiJxIJ0c
recaptcha_response_field:sent roxcipt

HTTP Response

ผลลัพธ์จากการประมวลผล HTTP Request จากเซิร์ฟเวอร์จะถูกส่งกลับมาโดยมีส่วนประกอบ สองส่วนคือ Header และ Body โดยในบางกรณีก็จะไม่มี Body เช่นเดียวกันกับ Request

ใน Response Header จะประกอบด้วย

  • HTTP Version (HTTP/1.1)
  • Status Code (200, 404, 503, ฯลฯ)
  • Reason (OK, File not found, Service Unavailable ฯลฯ)
  • Response-Header อื่นๆ

ตัวอย่างเช่น

HTTP/1.1 200 OK
Date: Sat, 10 Aug 2013 03:53:49 GMT
Status: 200 OK
Content-Type: text/html; charset=utf-8
X-UA-Compatible: IE=Edge,chrome=1
ETag: "7215ee9c7d9dc229d2921a40e899ec5f"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: c5cc8b00f456025741b46a55cde342d3
X-Runtime: 6.579408
X-Rack-Cache: invalidate, pass
Set-Cookie: _www_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJWU2MDNlZWI1MTVhOGM3ZGY1ZDQ4Zjk3MmRmMTFhMDZhBjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMUJXWUtmZGxHTGFJN3p6aHM5OGxXam1wYmF2bFpHT3ovbzVaMS9NcWJHYWM9BjsARg%3D%3D--ab08970757c8a9c9b74f1480ecc0a85fcab86878; path=/; HttpOnly
Via: 1.1 www.swiftlet.co.th
Vary: Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked

Response Body โดยปกติก็คือ String content เช่น HTML, XML, JSON, ฯลฯ ที่เวบแอพลิเคชัน ต้องการแสดงใน web browser ของเครื่องลูกข่ายนั่นเอง

ข้อสังเกตที่น่าสนใจคือ เมื่อ Request เป็นประเภทเรียกดูข้อมูลเช่น GET เมื่อได้รับ Response ก็มักจะมี Body มาด้วย แต่เมื่อ Request เป็นประเภทส่งข้อมูลเช่น POST, PUT, DELETE เมื่อได้รับ Response กลับมา มักจะมีแต่ Header หรืออาจมี Body เพื่อแสดง Error ที่เกิดขึ้น