โครงการนี้เสร็จสมบูรณ์ซึ่งเป็นส่วนหนึ่งของหลักสูตร 42 Core มันทำกับ Alouane04
เป้าหมายของโครงการคือการสร้างเว็บเซิร์ฟเวอร์ HTTP ที่เข้ากันได้กับ C ++ 98 ตั้งแต่เริ่มต้น เว็บเซิร์ฟเวอร์สามารถจัดการ HTTP GET, head, post, put และลบคำขอและสามารถให้บริการไฟล์คงที่จากไดเรกทอรีรูทที่ระบุหรือเนื้อหาแบบไดนามิกที่ระบุโดยใช้ CGI นอกจากนี้ยังสามารถจัดการการเชื่อมต่อไคลเอนต์หลายรายการพร้อมกันด้วยความช่วยเหลือของ SELECT ()
การใช้งาน
การแนะนำ
ส่วนหนึ่งของเว็บเซิร์ฟเวอร์
make
./webserv [Config File] # # leave empty to use the default configuration.HTTP (Hypertext Transfer Protocol) เป็นโปรโตคอลสำหรับการส่งและรับข้อมูลผ่านอินเทอร์เน็ต มันเป็นรากฐานของเวิลด์ไวด์เว็บและใช้โดยเว็บเบราว์เซอร์และเว็บเซิร์ฟเวอร์เพื่อสื่อสารซึ่งกันและกัน
เว็บเซิร์ฟเวอร์ HTTP เป็นแอปพลิเคชั่นซอฟต์แวร์ที่รับฟังและตอบสนองต่อคำขอ HTTP จากลูกค้า (เช่นเว็บเบราว์เซอร์) วัตถุประสงค์หลักของเว็บเซิร์ฟเวอร์คือการโฮสต์เนื้อหาเว็บและทำให้ผู้ใช้ผ่านอินเทอร์เน็ตสามารถใช้ได้
HTTP ประกอบด้วยคำขอและคำตอบ เมื่อไคลเอนต์ (เช่นเว็บเบราว์เซอร์) ต้องการดึงหน้าเว็บจากเซิร์ฟเวอร์จะส่งคำขอ HTTP ไปยังเซิร์ฟเวอร์ จากนั้นเซิร์ฟเวอร์จะประมวลผลคำขอและส่งการตอบกลับ HTTP กลับมา
รูปแบบข้อความ http
start-line CRLF
Headers CRLF
CRLF(end of headers)
[message-body]
CRLF are Carriage Return and Line Feed (rn), which is just a new line.
ข้อความ HTTP สามารถเป็นคำขอหรือตอบกลับได้
คำขอ http
คำขอ HTTP ประกอบด้วยบรรทัดคำขอส่วนหัวและเนื้อหาข้อความเสริม นี่คือตัวอย่างของคำขอ HTTP:
GET /index.html HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
สายคำขอประกอบด้วยสามส่วน: วิธีการเส้นทางและรุ่น HTTP วิธีการระบุการกระทำที่ลูกค้าต้องการดำเนินการเช่น GET (เพื่อดึงทรัพยากร) หรือโพสต์ (เพื่อส่งข้อมูลไปยังเซิร์ฟเวอร์) เส้นทางหรือ URI ระบุตำแหน่งของทรัพยากรบนเซิร์ฟเวอร์ เวอร์ชัน HTTP ระบุเวอร์ชันของโปรโตคอล HTTP ที่ใช้
ส่วนหัวมีข้อมูลเพิ่มเติมเกี่ยวกับคำขอเช่นชื่อโฮสต์ของเซิร์ฟเวอร์และประเภทของเบราว์เซอร์ที่ใช้
ในตัวอย่างข้างต้นไม่มีข้อความข้อความเพราะวิธีการรับมักจะไม่รวมร่างกายใด ๆ
การตอบสนอง http
การตอบสนอง HTTP ยังประกอบด้วยบรรทัดสถานะส่วนหัวและเนื้อหาข้อความเสริม นี่คือตัวอย่างของการตอบกลับ HTTP:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234
<Message Body>
บรรทัดสถานะประกอบด้วยสามส่วน: รุ่น HTTP รหัสสถานะและวลีเหตุผล รหัสสถานะระบุผลลัพธ์ของการร้องขอเช่น 200 OK (สำเร็จ) หรือ 404 ไม่พบ (ไม่พบทรัพยากร) วลีเหตุผลคือคำอธิบายสั้น ๆ ของรหัสสถานะ ต่อไปนี้เป็นบทสรุปโดยย่อว่ารหัสสถานะหมายถึงอะไร:
1xx ระบุข้อความข้อมูลเท่านั้น
2xx บ่งบอกถึงความสำเร็จบางอย่าง
3xx เปลี่ยนเส้นทางลูกค้าไปยัง URL อื่น
4xx ระบุข้อผิดพลาดในส่วนของลูกค้า
5xx ระบุข้อผิดพลาดในส่วนของเซิร์ฟเวอร์
ส่วนหัวมีข้อมูลเพิ่มเติมเกี่ยวกับการตอบสนองเช่นประเภทและขนาดของเนื้อหาที่ถูกส่งคืน เนื้อหาข้อความมีเนื้อหาจริงของการตอบกลับเช่นรหัส HTML สำหรับหน้าเว็บ
วิธี HTTP
| วิธี | คำอธิบาย | ร่างกายที่เป็นไปได้ |
|---|---|---|
GET | ดึงทรัพยากรเฉพาะหรือการรวบรวมทรัพยากรไม่ควรส่งผลกระทบต่อข้อมูล/ทรัพยากร | เลขที่ |
POST | ดำเนินการประมวลผลเฉพาะทรัพยากรในเนื้อหาคำขอ | ใช่ |
DELETE | ลบทรัพยากรเป้าหมายที่กำหนดโดย URI | ใช่ |
PUT | สร้างทรัพยากรใหม่ที่มีข้อมูลจากข้อความข้อความหากมีทรัพยากรอยู่แล้วให้อัปเดตด้วยข้อมูลในร่างกาย | ใช่ |
HEAD | เหมือนกับ Get แต่อย่าถ่ายโอนเนื้อหาการตอบกลับ | เลขที่ |
รับ
วิธี HTTP GET ใช้ในการอ่าน (หรือดึงข้อมูล) การเป็นตัวแทนของทรัพยากร ในกรณีที่ประสบความสำเร็จ (หรือไม่ใช่ข้อผิดพลาด) รับผลตอบแทนการเป็นตัวแทนของทรัพยากรในการตอบสนองและรหัสสถานะการตอบกลับ HTTP ที่ 200 (OK) ในกรณีข้อผิดพลาดส่วนใหญ่มักจะส่งคืน 404 (ไม่พบ) หรือ 400 (คำขอที่ไม่ดี)
โพสต์
วิธีการโพสต์ HTTP ส่วนใหญ่มักใช้เพื่อสร้างทรัพยากรใหม่ ในการสร้างที่ประสบความสำเร็จรหัสตอบกลับ HTTP (สร้าง) จะถูกส่งกลับ
ลบ
HTTP DELETE เป็นไปข้างหน้า มันลบทรัพยากรที่ระบุไว้ใน URI ในการลบที่ประสบความสำเร็จจะส่งคืนรหัสสถานะการตอบกลับ HTTP 204 (ไม่มีเนื้อหา)
อ่านเพิ่มเติมเกี่ยวกับวิธี HTTP RFC9110#9.1
เว็บเซิร์ฟเวอร์ HTTP พื้นฐานประกอบด้วยส่วนประกอบหลายอย่างที่ทำงานร่วมกันเพื่อรับและประมวลผลคำขอ HTTP จากลูกค้าและส่งคำตอบกลับ ด้านล่างเป็นส่วนหลักของเว็บเซิร์ฟเวอร์ของเรา
ส่วนเครือข่ายของเว็บเซิร์ฟเวอร์ที่จัดการการเชื่อมต่อ TCP และดำเนินงานเช่นการฟังคำขอที่เข้ามาและส่งการตอบกลับ มันมีหน้าที่รับผิดชอบงานเครือข่ายระดับต่ำของเว็บเซิร์ฟเวอร์เช่นการสร้างและการจัดการซ็อกเก็ตการจัดการสตรีมอินพุตและเอาต์พุตและการจัดการการไหลของข้อมูลระหว่างเซิร์ฟเวอร์และไคลเอนต์
ก่อนที่จะเขียนเว็บเซิร์ฟเวอร์ของคุณฉันขอแนะนำให้อ่านคู่มือที่ยอดเยี่ยมนี้เกี่ยวกับการสร้างไคลเอนต์/เซิร์ฟเวอร์ TCP อย่างง่ายใน C เนื่องจากจะช่วยให้คุณเข้าใจวิธีการทำงานของ TCP ใน C/C ++ นอกจากนี้คุณจะต้องเข้าใจหลาย I/O Multiplixing วิดีโอนี้จะช่วยให้คุณเข้าใจแนวคิดหลักของการเลือก ()
กระบวนการมัลติเพล็กซ์ I/O ในเว็บเซิร์ฟเวอร์ของเราสรุปไว้ในผังงานด้านล่าง (CGI ไม่รวมอยู่ในผังงาน แต่อาจเพิ่มในอนาคต)
การแยกวิเคราะห์ส่วนหนึ่งของเว็บเซิร์ฟเวอร์หมายถึงกระบวนการที่รับผิดชอบในการตีความและแยกข้อมูลจากคำขอ HTTP ในเว็บเซิร์ฟเวอร์นี้การแยกการร้องขอจะดำเนินการโดยคลาส HTTPREQUEST วัตถุ HTTPREQUEST ได้รับการร้องขอที่เข้ามาแยกวิเคราะห์และแยกข้อมูลที่เกี่ยวข้องเช่นวิธีการเส้นทางส่วนหัวและข้อความข้อความ (ถ้ามี) หากพบข้อผิดพลาดทางไวยากรณ์ใด ๆ ในคำขอระหว่างการแยกวิเคราะห์ค่าธงข้อผิดพลาดจะถูกตั้งค่าและหยุดการแยกวิเคราะห์ การร้องขอสามารถป้อนเข้ากับวัตถุผ่านวิธีการฟีด () อย่างเต็มที่หรือบางส่วนสิ่งนี้เป็นไปได้เนื่องจากตัวแยกวิเคราะห์จะสแกนไบต์คำขอครั้งละครั้งและอัปเดตสถานะการแยกวิเคราะห์เมื่อใดก็ตามที่จำเป็น วิธีการแยกวิเคราะห์แบบเดียวกันนั้นใช้โดย Nginx และ NodeJS คำขอตัวแยกวิเคราะห์
ด้านล่างเป็นภาพรวมของวิธีการทำงานของตัวแยกวิเคราะห์
ตัวสร้างการตอบกลับมีหน้าที่รับผิดชอบในการสร้างและจัดรูปแบบการตอบสนอง HTTP ที่ส่งกลับไปยังลูกค้าเพื่อตอบสนองต่อคำขอของพวกเขา ในเว็บเซิร์ฟเวอร์นี้คลาสการตอบกลับมีหน้าที่รับผิดชอบในการสร้างและจัดเก็บการตอบกลับ HTTP รวมถึงบรรทัดสถานะส่วนหัวและเนื้อหาข้อความ ตัวสร้างการตอบกลับอาจทำงานเช่นการตั้งค่ารหัสสถานะที่เหมาะสมและวลีเหตุผลตามผลลัพธ์ของการร้องขอการเพิ่มส่วนหัวในการตอบสนองเพื่อให้ข้อมูลเพิ่มเติมเกี่ยวกับเนื้อหาหรือเซิร์ฟเวอร์และการจัดรูปแบบเนื้อหาข้อความตามประเภทเนื้อหาและการเข้ารหัสการตอบสนอง ตัวอย่างเช่นหากเซิร์ฟเวอร์ได้รับการร้องขอสำหรับหน้าเว็บจากไคลเอนต์เซิร์ฟเวอร์จะแยกวิเคราะห์คำขอและส่งผ่านไปยังวัตถุตอบกลับซึ่งจะดึงเนื้อหาของหน้าเว็บและสร้างการตอบสนอง HTTP ด้วยเนื้อหา HTML ในเนื้อหาข้อความและส่วนหัวที่เหมาะสมเช่นเนื้อหาประเภทเนื้อหาและความยาวเนื้อหา
ไฟล์การกำหนดค่าเป็นไฟล์ข้อความที่มีการตั้งค่าและคำสั่งต่าง ๆ ที่กำหนดวิธีการใช้งานเว็บเซิร์ฟเวอร์ การตั้งค่าเหล่านี้อาจรวมถึงสิ่งต่าง ๆ เช่นหมายเลขพอร์ตที่เว็บเซิร์ฟเวอร์ควรฟังตำแหน่งของไดเรกทอรีรูทของเว็บเซิร์ฟเวอร์และการตั้งค่าอื่น ๆ อีกมากมาย
นี่คือตัวอย่าง FIE ที่แสดงรูปแบบไฟล์กำหนดค่าและคำสั่งที่รองรับ
server {
listen 8001 ; # listening port, mandatory parameter
host 127.0.0.1; # host or 127.0.0.1 by default
server_name test; # specify server_name, need to be added into /etc/hosts to work
error_page 404 /error/404.html; # default error page
client_max_body_size 1024 ; # max request body size in bytes
root docs/fusion_web/; # root folder of site directory, full or relative path, mandatory parameter
index index.html; # default page when requesting a directory, index.html by default
location /tours {
root docs/fusion_web; # root folder of the location, if not specified, taken from the server.
# EX: - URI /tours --> docs/fusion_web/tours
# - URI /tours/page.html --> docs/fusion_web/tours/page.html
autoindex on ; # turn on/off directory listing
allow_methods POST GET; # allowed methods in location, GET only by default
index index.html; # default page when requesting a directory, copies root index by default
return abc/index1.html; # redirection
alias docs/fusion_web; # replaces location part of URI.
# EX: - URI /tours --> docs/fusion_web
# - URI /tours/page.html --> docs/fusion_web/page.html
}
location cgi-bin {
root ./; # cgi-bin location, mandatory parameter
cgi_path /usr/bin/python3 /bin/bash; # location of interpreters installed on the current system, mandatory parameter
cgi_ext .py .sh; # extensions for executable files, mandatory parameter
}
}CGI เป็นมาตรฐานสำหรับการเรียกใช้โปรแกรมภายนอกจากเว็บเซิร์ฟเวอร์ เมื่อผู้ใช้ร้องขอเว็บเพจที่ควรจัดการโดยโปรแกรม CGI เว็บเซิร์ฟเวอร์จะดำเนินการโปรแกรมและส่งคืนผลลัพธ์ไปยังเว็บเบราว์เซอร์ของผู้ใช้
โปรแกรม CGI เป็นเพียงสคริปต์ที่สามารถเขียนได้ในภาษาการเขียนโปรแกรมใด ๆ เช่น Perl, Python หรือ Bash และโดยทั่วไปจะใช้ในการประมวลผลข้อมูลที่ส่งโดยผู้ใช้ผ่านเว็บเบราว์เซอร์หรือสร้างเนื้อหาแบบไดนามิกบนเว็บเพจ