تم الانتهاء من هذا المشروع كجزء من منهج أساسي 42. تم ذلك مع alouane04
الهدف من المشروع هو إنشاء خادم الويب HTTP متوافق مع C ++ 98 من نقطة الصفر. يمكن لخادم الويب التعامل مع الطلبات HTTP ، والرأس ، والنشر ، والطرح ، وحذف الطلبات ، ويمكن أن يقدم ملفات ثابتة من دليل جذر محدد أو محتوى ديناميكي باستخدام CGI. كما أنه قادر على التعامل مع اتصالات العميل المتعددة بشكل متزامن بمساعدة Select ().
الاستخدام
مقدمة
أجزاء من خادم الويب
make
./webserv [Config File] # # leave empty to use the default configuration.HTTP (بروتوكول نقل النص التشعبي) هو بروتوكول لإرسال واستلام المعلومات عبر الإنترنت. إنه أساس شبكة الويب العالمية ويستخدمها متصفحات الويب وخوادم الويب للتواصل مع بعضها البعض.
خادم الويب 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 ، ولكن لا تنقل محتوى الاستجابة | لا |
يحصل
يتم استخدام طريقة GET HTTP لقراءة (أو استرداد) تمثيل مورد. في حالة النجاح (أو غير المؤسسة) ، احصل على إرجاع تمثيل المورد في هيئة الاستجابة ورمز حالة استجابة HTTP 200 (OK). في حالة الخطأ ، غالبًا ما يعيد 404 (غير موجود) أو 400 (طلب سيء).
بريد
غالبًا ما يتم استخدام طريقة نشر HTTP لإنشاء موارد جديدة. على الإنشاء الناجح ، يتم إرجاع رمز استجابة HTTP 201 (تم إنشاؤه).
يمسح
HTTP DELETE هو Stright إلى الأمام. يحذف مورد محدد في URI. عند الحذف الناجح ، يعيد رمز حالة استجابة HTTP 204 (بدون محتوى).
اقرأ المزيد حول طرق HTTP RFC9110#9.1
يتكون خادم الويب الأساسي HTTP من عدة مكونات تعمل معًا لتلقي ومعالجة طلبات HTTP من العملاء وإرسال ردود. فيما يلي الأجزاء الرئيسية من خادم الويب الخاص بنا.
جزء الشبكات من خادم الويب الذي يتولى اتصالات TCP ويؤدي مهام مثل الاستماع للطلبات الواردة وإرسال الاستجابات. إنه مسؤول عن مهام الشبكات ذات المستوى المنخفض لخادم الويب ، مثل إنشاء وإدارة مآخذ ، معالجة تدفقات الإدخال والإخراج ، وإدارة تدفق البيانات بين الخادم والعملاء.
قبل كتابة خادم الويب الخاص بك ، أوصي بقراءة هذا الدليل الرائع على إنشاء عميل/خادم بسيط TCP في C لأنه سيساعدك على فهم جيد لكيفية عمل TCP في C/C ++. ستحتاج أيضًا إلى فهم I/O Multiplixing ، سيساعدك هذا الفيديو على فهم الفكرة الرئيسية لـ Select ().
يتم تلخيص عملية الإرسال I/O في خادم الويب الخاص بنا في المخطط الانسيابي أدناه. (لا يتم تضمين CGI في المخطط الانسيابي ولكن يمكن إضافته في المستقبل)
يشير جزء تحليل خادم الويب إلى العملية المسؤولة عن تفسير المعلومات واستخراجها من طلبات HTTP. في خادم الويب هذا ، يتم تنفيذ تحليل الطلبات بواسطة فئة HTTPrequest. يتلقى كائن httprequest طلبًا وارد ، ويخوضه ، ويستخرج المعلومات ذات الصلة مثل الطريقة والمسار والرؤوس وجسم الرسائل (إذا كانت موجودة). إذا تم العثور على أي خطأ في بناء الجملة في الطلب أثناء التحليل ، يتم تعيين أعلام الخطأ وتوقف التحليل. يمكن تغذية الطلب إلى الكائن من خلال طريقة FEED () إما بالكامل أو جزئيًا ، وهذا ممكن لأن المحلل يقوم بمسح بايت الطلب في وقت واحد وتحديث حالة التحليلية كلما لزم الأمر. يتم استخدام نفس طريقة التحليل بواسطة 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 ، وعادة ما يتم استخدامها لمعالجة البيانات المقدمة من قبل المستخدم من خلال متصفح الويب ، أو لإنشاء محتوى ديناميكي على صفحة ويب.