تشريح رسالة HTTP: سطر البدء والترويسات والجسم

تاريخ النشر: وقت القراءة:
للقراءة
عدد الكلمات:
كلمة

يرسل المتصفح طلب HTTP في صورة بايتات متتالية، وعلى الخادم أن يستخرج منها ما يريده العميل بدقة: أي مورد يطلب، وما البيانات الوصفية التي تحدد معالم طلبه، وأين تبدأ البيانات المرسلة إن وجدت. ولا يستقيم هذا الفهم إلا لأن رسالة HTTP/1.1 تصاغ بقالب حرفي ثابت، يعرف الطرفان فيه موضع كل جزء وما يعين علامة نهايته.

وتفاصيل هذه الصيغة ليست قيودا شكلية عابرة؛ فمسافة واحدة تفصل بين اسم الترويسة والنقطتين الرأسيتين تجعل الخادم يرفض الطلب كله، وسطر فارغ يسقط من نهاية الترويسات يترك الخادم معلقا ينتظر بقية رسالة لم تكتمل في نظره.

تشريح رسالة HTTP: سطر البدء والترويسات والجسم

البايتات تصل متصلة بلا فواصل

يعمل بروتوكول HTTP فوق قناة نقل توصل البايتات كاملة وبترتيبها، لكنها تسلمها مجردة من أي تقسيم دلالي. فالطرف المستقبل يتلقى البايتات متتابعة كأنها شريط واحد طويل، ولا يجد فيها أي علامة تضعها القناة لتقول: هنا انتهى السطر الأول، وهنا بدأت البيانات.

لذلك كان لزاما أن تحمل الرسالة حدود أجزائها في بنيتها الداخلية. والبرنامج الذي يتولى قراءة الرسالة الواصلة وتفكيك أجزائها يسمى المحلل (parser). ولما كان المحلل لا يرى أمامه سوى شريط البايتات، فهو يحتاج إلى قواعد دقيقة يتفق عليها الطرفان مسبقا ليعرف أين ينتهي كل جزء. وتحدد مواصفة HTTP/1.1 هذه القواعد بدقة، ليفصل المحلل أقسام الرسالة بيقين لا تخمين فيه.

ثلاثة أجزاء بترتيب ثابت

خذ طلبا يرسله المتصفح ليقرأ صفحة مقال في مدونة:

CODE
GET /articles/http-message?lang=ar HTTP/1.1
Host: blog.example.com
User-Agent: Mozilla/5.0
Accept: text/html

في هذا الطلب سطر أول يفتتح بكلمة GET، تليه ثلاثة أسطر يتألف كل منها من اسم ونقطتين رأسيتين وقيمة. وبعد السطر الأخير يأتي سطر فارغ تماما لا يظهر في هذا العرض، لكنه جزء أصيل من بنية الرسالة لا يكتمل الطلب بدونه.

ويرد الخادم باستجابة تقوم على الترتيب الهيكلي نفسه:

CODE
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 21

<h1>HTTP message</h1>

يسمى السطر الأول في كل رسالة سطر البدء (start line)، ووظيفته تلخيص الرسالة: ففي الطلب يحدد ماذا يريد العميل وأي مورد يقصد، وفي الاستجابة يبين نتيجة معالجة الطلب. وتلي سطر البدء سطور الترويسات (headers)، حيث يمثل كل سطر ترويسة مستقلة تحمل معلومة وصفية واحدة عن الرسالة. ثم يأتي سطر فارغ يعلن اكتمال الترويسات ونهايتها. وما بعد هذا السطر الفارغ هو الجسم (body)، أي المحتوى الفعلي أو البيانات التي تنقلها الرسالة: مستند HTML قصير في استجابة هذا المثال، في حين خلا الطلب السابق من أي جسم.

ولكل طريقة ورمز حالة وترويسة وردت في المثالين دلالة تفصيلية ستفرد لها الدروس اللاحقة حقها في الدورة، ولا يتوقف استيعاب البنية الهيكلية هنا على تلك المعاني؛ إذ يكفي الآن إدراك موضع كل جزء، وصيغة سطوره، وما يحدد نقطة نهايته.

نهاية السطر: الحرفان CR وLF

الأسطر المستقلة التي رأيناها في العرضين السابقين وسيلة لتيسير قراءة الرسالة على الشاشة، أما على أسلاك الشبكة فلا توجد أسطر مرئية، بل سيل متتابع من البايتات. والذي يعين نهاية كل سطر للمستقبل حرفان غير مرئيين يتعاقبان مباشرة: حرف الرجوع إلى أول السطر (carriage return, CR)، يليه حرف السطر الجديد (line feed, LF). وتطلق المواصفة القياسية على هذين الحرفين مجتمعين اسم CRLF، ويكتبان في معظم لغات البرمجة بالصيغة \r\n.

وهذا هو طلب قراءة المقال نفسه معروضا في سطر واحد متصل، تماما كما تتدفق بايتاته عبر الشبكة، مبينا فيه كل زوج من الحرفين بصيغته البرمجية \r\n:

CODE
GET /articles/http-message?lang=ar HTTP/1.1\r\nHost: blog.example.com\r\nUser-Agent: Mozilla/5.0\r\nAccept: text/html\r\n\r\n

ينتهي كل سطر من سطور الطلب بالزوج \r\n. وعند ختام الترويسات يتجاور زوجان متعاقبان: الزوج الأول ينهي سطر ترويسة Accept، والثاني يمثل السطر الفارغ ذاته، أي سطر لا يحتوي على أي محتوى قبل علامة ختامه. ومن هنا، فإن تتابع الرمزين \r\n\r\n هو العلامة الحاسمة التي يستدل بها المحلل على اكتمال قسم الترويسات.

وتعتمد مواصفة البروتوكول الزوج CRLF نهاية قياسية إلزامية لسطر البدء وكل سطر من سطور الترويسات. ومع أن المواصفة تسمح للطرف المستقبل بالتسامح وقبول حرف LF بمفرده نهاية للسطر، إلا أنها لا تلزمه بهذا القبول. ولهذا قد ينجح طلب كتب يدويا بنهاية \n مع خادم متساهل، في حين يرفضه خادم آخر يلتزم نص المعيار؛ أما الطلب المنضبط الذي يلتزم بصيغة \r\n فلا يرهن نجاحه بتسامح المستقبل.

سطر الطلب: الطريقة والهدف والنسخة

سطر البدء في رسالة الطلب يسمى سطر الطلب (request line)، وهو مبني من ثلاث قطع تفصل بين كل قطعة وتاليتها مسافة واحدة، ويختم بـCRLF:

CODE
GET /articles/http-message?lang=ar HTTP/1.1
  • الطريقة (method): الكلمة GET في هذا المثال، وهي الفعل الذي يحدد طبيعة العملية المطلوبة على المورد. ولكل طريقة دلالات وخصائص تفرد لها الدورة درسا مستقلا.
  • هدف الطلب (request target): الجزء /articles/http-message?lang=ar، وهو المسار والاستعلام مدمجين كما استخلصهما المتصفح من الرابط. فالرابط لا يدرج بكامله في هذا السطر؛ إذ ينتقل اسم المضيف مستقلا داخل ترويسة Host، ويعرف المخطط تلقائيا من نوع القناة التي حملت الاتصال، في حين يستبعد ما بعد علامة # محليا ولا يرسل قط.
  • النسخة (HTTP version): الصيغة HTTP/1.1، وتخبر المستقبل بقواعد أي نسخة صيغت بها الرسالة ليعاملها بموجبها.

ويستطيع المحلل تفكيك هذا السطر بأمان عند المسافتين الفاصلتين دون أدنى لبس في تعيين حدود هدف الطلب؛ فالهدف لا يحتوي على أي مسافة حرفية، لأن أي مسافة يتطلبها المسار أو الاستعلام تخضع للترميز الإلزامي قبل الإرسال، كأن تكتب %20 وفق قواعد الترميز بالنسبة المئوية.

وتتسم الطريقة ورقم النسخة بحساسية تامة لحالة الأحرف؛ فالصيغة get ليست الطريقة القياسية GET، وhttp/1.1 ليست النسخة المعتمدة HTTP/1.1.

سطر الحالة: النسخة والرمز وعبارة السبب

يقابل سطر الطلب في الاستجابة سطر بدء خاص يسمى سطر الحالة (status line)، ويتألف هو الآخر من ثلاث قطع تفصل بينها مسافات، لكن بترتيب مختلف:

CODE
HTTP/1.1 200 OK
  • النسخة: HTTP/1.1، وتتصدر أول السطر هذه المرة لتبين نسخة البروتوكول المتبعة في صياغة الجواب.
  • رمز الحالة: الرقم 200، ثلاثة أرقام يقرؤها برنامج العميل آليا ليعرف نتيجة طلبه.
  • عبارة السبب (reason phrase): النص OK، وهو وصف بشري موجز يوضح معنى الرمز لمن يقرأ الرسالة من البشر.

وتنفرد عبارة السبب بين عناصر سطر البدء بأنها لا تحمل أي وزن وظيفي في منطق البرمجيات؛ فالمواصفة تجعلها اختيارية، وتوصي العميل بتجاهل محتواها لأنها ليست وسيلة موثوقة لنقل المعلومات. وقد يرسل خادم 200 OK ويرسل خادم آخر 200 Success، والنتيجة عند العميل واحدة لأن الرمز واحد. وإذا غابت العبارة، بقي على الخادم أن يرسل المسافة التي تلي الرمز، فيصير السطر HTTP/1.1 200 مختوما بمسافة في آخره.

برنامج العميل يقرأ رمز الحالة لا عبارة السبب. فالاستجابة HTTP/1.1 404 Page Gone هي HTTP/1.1 404 Not Found نفسها في نظره، فلا يصح أن يبني المطور منطق برنامجه على نص العبارة.

الترويسات: سطر لكل حقل

بعد سطر البدء مباشرة تبدأ الترويسات. وكل ترويسة سطر مستقل تسميه المواصفة حقل ترويسة (header field). ويتكون هذا السطر من اسم الحقل (field name)، ثم نقطتين، ثم قيمة الحقل (field value)، وينتهي بـCRLF:

CODE
Content-Type: text/html

الاسم في هذا السطر Content-Type، والقيمة text/html. ولكتابة سطر الترويسة وقراءته ثلاث قواعد:

  • اسم الحقل لا يتأثر بحالة الأحرف. Content-Type وcontent-type وCONTENT-TYPE اسم واحد، بخلاف الطريقة والنسخة في سطر البدء. ولذلك قد تحمل استجابة حقيقية واحدة أسماء تبدأ بحروف كبيرة مثل Content-Type، وأخرى مكتوبة كلها بحروف صغيرة مثل last-modified، دون أن يختلف معناها.
  • المسافات حول القيمة ليست منها. Content-Type:text/html وContent-Type: text/html يحملان القيمة نفسها، لأن المحلل يحذف المسافات في أول القيمة وآخرها. والمعتاد مسافة واحدة بعد النقطتين.
  • لا مسافة بين الاسم والنقطتين. السطر Content-Type : text/html مخالف للمواصفة، وعلى الخادم أن يرفض الطلب الذي يحمله برمز 400. وسبب هذا التشدد أن البرامج اختلفت في الماضي في تفسير هذه المسافة، ففتح هذا الاختلاف ثغرات أمنية.

السطر الفارغ الذي ينهي الترويسات

لا يحدد HTTP عددا ثابتا للترويسات؛ فقد تحمل الرسالة ثلاث ترويسات أو ثلاثين. لذلك لا يعرف المحلل نهايتها من عدد السطور، بل من علامة: سطر فارغ، أي زوج CRLF يأتي مباشرة بعد الزوج الذي أنهى السطر السابق. فيقرأ المحلل سطرا بعد سطر، ويعد كل سطر حقل ترويسة، حتى يصل إلى السطر الفارغ فيعرف أن قسم الترويسات انتهى.

والسطر الفارغ واجب في كل رسالة، حتى في طلب لا جسم له. فلو أرسل العميل سطر الطلب وترويساته ولم يرسل السطر الفارغ، لظل الخادم ينتظر، لأن البايتات التي وصلته لا تقول إن الترويسات اكتملت، وقد يكون سطر ترويسة آخر في الطريق. ويستمر هذا الانتظار حتى تنقضي مهلة يحددها الخادم فيقطع الطلب، وهي ستون ثانية في الإعداد الافتراضي لخادم nginx.

ويظهر وجوب السطر الفارغ في أصغر طلب صحيح في HTTP/1.1، وهو ثلاثة أسطر: سطر الطلب، وترويسة Host، ثم السطر الفارغ، مع أن الطلب لا جسم له:

CODE
GET / HTTP/1.1\r\nHost: example.com\r\n\r\n

وأما ترويسة Host فلا يكتمل الطلب في HTTP/1.1 من دونها. فالمواصفة تلزم العميل بإرسالها في كل طلب، وتلزم الخادم بأن يرفض الطلب الذي يخلو منها برمز الحالة 400، وهو الرمز الذي يرد به الخادم على طلب يراه خطأ من جهة العميل.

فكرة جوهرية

للرسالة علامتان تحددان بنيتها: CRLF تنهي كل سطر، والسطر الفارغ ينهي الترويسات. ما قبل السطر الفارغ سطور تقرأ واحدا بعد واحد، وما بعده جسم.

الجسم: ما بعد السطر الفارغ

لم يحمل طلب قراءة المقال جسما، لأن العميل لم يرسل فيه بيانات، بل طلب موردا فحسب. أما حين يرسل العميل بيانات، كتعليق يكتبه القارئ تحت المقال، فتنتقل هذه البيانات في جسم الطلب:

CODE
POST /articles/http-message/comments HTTP/1.1
Host: blog.example.com
Content-Type: application/json
Content-Length: 31

{"comment":"Clear explanation"}

يبدأ الجسم بأول بايت بعد السطر الفارغ، وهو { في هذا المثال. والجسم اختياري: طلب القراءة بـGET يأتي بلا جسم عادة، وطلب مثل POST يرسل بيانات فيحمله، والاستجابة تحمله في أغلب الحالات لأنها تنقل المورد المطلوب.

ولا تسري على الجسم قواعد السطور التي تحكم الترويسات. فهو بايتات تنقل كما هي: قد يكون نصا فيه أسطر فارغة كثيرة، كمستند HTML طويل، وقد يكون صورة لا علاقة لبايتاتها بالنص أصلا، فقد تتجاور فيها البايتات \r\n\r\n في أي موضع. ولا يلزم كذلك أن تنتهي آخر بايتات الجسم بالزوج \r\n.

لذلك لا يستطيع المحلل أن يعرف نهاية الجسم بالطريقة التي عرف بها نهاية الترويسات. فلو بحث عن سطر فارغ آخر، لقطع الجسم عند أول سطر فارغ في مستند HTML، أو عند أول موضع في صورة تتجاور فيه هذه البايتات. وإنما تعلن الترويسات كيف يعرف طول الجسم: في هذا المثال تقول Content-Length: 31 إن الجسم 31 بايتا، وهو طول {"comment":"Clear explanation"} بالضبط. وحين لا تعلن ترويسات الطلب عن جسم، ينتهي الطلب عند السطر الفارغ نفسه. أما طرق إعلان الطول، وما يحدث في الاستجابات التي لا تعلنه، فلها درس مستقل.

السطر الفارغ يحدد أين يبدأ الجسم، لا أين ينتهي. ونهاية الجسم تعرف بطريقة تعلنها الترويسات، لا بالبحث عن سطر فارغ آخر.

كيف يقرأ الخادم طلبا وصله

حين تصل بايتات طلب التعليق إلى الخادم، يمر بها المحلل بهذا الترتيب:

  1. يقرأ حتى أول CRLF، فيحصل على سطر الطلب، ويقطعه عند المسافتين إلى الطريقة POST، والهدف /articles/http-message/comments، والنسخة HTTP/1.1.
  2. يقرأ السطور التالية واحدا بعد واحد، ويقسم كل سطر عند أول نقطتين إلى اسم وقيمة: Host ثم Content-Type ثم Content-Length. ويقسم عند أول نقطتين تحديدا لأن القيمة نفسها قد تحتوي نقطتين، كما في Host: localhost:3000.
  3. يصل إلى السطر الفارغ، فيعرف أن الترويسات انتهت، وأن ما بعده جسم.
  4. يرى أن Content-Length تعلن جسما طوله 31 بايتا، فيقرأ 31 بايتا بالضبط، ثم يعد الطلب مكتملا.

ولا يبحث المحلل داخل الجسم عن نقطتين أو عن أسطر. فالبايتات التي تلي السطر الفارغ، بالطول الذي أعلنته الترويسات، كلها من الجسم، ولو بدا جزء منها كأنه سطر ترويسة. وبعد أن تنفصل الأجزاء، يسلمها المحلل إلى تطبيق الخادم: الطريقة والهدف ليعرف ما يفعله، والترويسات لتصف الطلب، والجسم ليحمل نص التعليق نفسه. ويقرأ المتصفح الاستجابة بخطوات مماثلة، مع فرق في الخطوة الأولى: السطر الذي يقطعه هناك سطر حالة.

الأجزاء نفسها في HTTP/2 وHTTP/3

الشكل النصي الذي سبق هو شكل HTTP/1.1 وحده. أما HTTP/2 وHTTP/3 فلا ينقلان الرسالة سطورا من النص، بل يضعانها في إطارات ثنائية (binary frames)، أي وحدات من البايتات لا تكتب نصا يقرأ بالعين، ولها تفصيل مستقل في الدورة. ومع ذلك تبقى أجزاء الرسالة كما هي: في كل طلب طريقة وهدف، وفي كل استجابة رمز حالة، وفي الرسالتين ترويسات وجسم اختياري. الذي يتغير هو طريقة حمل هذه الأجزاء.

فلا سطر بدء في النسختين. وتنتقل قطعه إلى حقول خاصة تسمى حقول الترويسة الزائفة (pseudo-header fields)، يبدأ اسم كل منها بنقطتين، وتأتي قبل الترويسات العادية. وهذا طلب قراءة المقال نفسه معروضا بحقوله كما يحملها HTTP/2:

CODE
:method: GET
:scheme: https
:authority: blog.example.com
:path: /articles/http-message?lang=ar
user-agent: Mozilla/5.0
accept: text/html

يقابل :method الطريقة، و:path هدف الطلب، و:authority المضيف الذي كانت تحمله ترويسة Host، و:scheme المخطط الذي لم يكن سطر الطلب في HTTP/1.1 يذكره. أما الاستجابة فلها حقل زائف واحد هو :status، ويحمل رمز الحالة وحده؛ فلا مكان في النسختين لعبارة السبب ولا لرقم النسخة. وتشترط النسختان كذلك أن تكتب أسماء الحقول كلها بحروف صغيرة.

وعرض هذه الحقول في سطور تيسير للقراءة فقط؛ أما على الشبكة فتنتقل مضغوطة داخل إطار ثنائي. ولهذا تعرض بعض الأدوات رسائل HTTP/2 في صورة قريبة من شكل HTTP/1.1: فأداة curl تكتب أول سطر في الاستجابة HTTP/2 200 بلا عبارة سبب، وتعرض أسماء الترويسات بعده بحروف صغيرة. وهذا سطر تصنعه الأداة لتسهيل القراءة، لا سطر مر على الشبكة.

رسالة تحمل حدودها معها

يقوم الجزء النصي من رسالة HTTP/1.1 على اتفاق حول بايتات قليلة: مسافة تفصل قطع سطر البدء، ونقطتان تفصلان اسم الحقل عن قيمته، وCRLF تنهي السطر، وسطر فارغ ينهي الترويسات. وبفضل هذه البساطة يقرأ المطور الرسالة بعينه، ويستطيع أن يكتب طلبا صحيحا في ثلاثة أسطر.

والاتفاق نفسه يفرض الدقة. فالمحلل لا يرى غير البايتات، وإذا اختلف برنامجان على موضع علامة واحدة، قرأ كل منهما من البايتات نفسها رسالة مختلفة. لذلك تمنع المواصفة المسافة قبل النقطتين منعا صارما، وتلزم الخادم برفض الطلب الذي يحملها: الخلاف في مثل هذه التفاصيل خلاف على حدود الرسالة نفسها، لا على طريقة كتابتها.

اختبر فهمك

ثمانية أسئلة قصيرة تغطي أفكار الدرس. اختر إجابة ثم اضغط «تحقق» لترى إن كانت صحيحة ولماذا. وفي آخر الاختبار تظهر نتيجتك، ومع كل سؤال أخطأت فيه زر يعيدك إلى القسم الذي يشرحه.

كتب مطور طلبا يدويا وأنهى كل سطر فيه بالحرف \n وحده. ماذا تقول المواصفة عن هذا الطلب؟
يقبله كل خادم، لأن \n هي نهاية السطر المعتمدة في HTTP/1.1
نهاية السطر المعتمدة \r\n، ويجوز للخادم أن يقبل \n لكنه غير ملزم
يحول الخادم كل \n إلى \r\n قبل قراءة الطلب، فلا فرق بينهما
يرفضه كل خادم، لأن المواصفة تمنع قبول \n وحده
تجعل المواصفة CRLF نهاية سطر البدء وسطور الترويسات، وتسمح للمستقبل بقبول LF وحده دون أن تلزمه. لذلك قد يقبل خادم هذا الطلب ويرفضه آخر، ولا يصح وصفه بأنه مقبول دائما أو مرفوض دائما.
نهاية السطر: الحرفان CR وLF
ما هدف الطلب في سطر الطلب POST /search?q=http&page=2 HTTP/1.1؟
POST /search، لأن الهدف يبدأ بالطريقة
/search وحده، لأن الاستعلام يرسل في ترويسة مستقلة
HTTP/1.1، لأنه آخر قطعة في السطر
/search?q=http&page=2، أي المسار والاستعلام معا
هدف الطلب هو القطعة الثانية بين المسافتين، ويضم المسار والاستعلام معا كما أخذهما المتصفح من الرابط. أما POST فهو الطريقة، وHTTP/1.1 هو النسخة، ولا يفصل الاستعلام في ترويسة خاصة.
سطر الطلب: الطريقة والهدف والنسخة
وصلت إلى برنامج عميل استجابة سطر حالتها HTTP/1.1 200 Not Found. كيف يفهم البرنامج نتيجة طلبه؟
نجاح، لأنه يقرأ الرمز 200 ويتجاهل عبارة السبب
فشل، لأن عبارة السبب تقول Not Found
رسالة مشوهة، لأن العبارة لا تطابق الرمز
نتيجة مجهولة، فيعيد إرسال الطلب ليصله رمز آخر
يبني البرنامج حكمه على رمز الحالة، والمواصفة توصي بتجاهل محتوى عبارة السبب لأنها ليست وسيلة موثوقة لنقل المعلومات. فالرمز 200 هنا هو ما يحدد النتيجة، مهما قالت العبارة بعده.
سطر الحالة: النسخة والرمز وعبارة السبب
أي سطر من هذه الأسطر يجب على الخادم أن يرفض الطلب الذي يحمله؟
accept: text/html
Accept:text/html
Accept : text/html
ACCEPT: text/html
تمنع المواصفة أي مسافة بين اسم الحقل والنقطتين، وتلزم الخادم برفض الطلب برمز 400. أما حالة أحرف الاسم فلا تغير شيئا، والمسافات حول القيمة يحذفها المحلل، فالأسطر الثلاثة الأخرى صحيحة.
الترويسات: سطر لكل حقل
أرسل عميل البايتات GET / HTTP/1.1\r\nHost: example.com\r\n ثم توقف دون أن يغلق الاتصال. ماذا يحدث عند الخادم؟
يرد فورا، لأن طلب GET لا جسم له
ينتظر، لأن السطر الفارغ الذي ينهي الترويسات لم يصل
يعد سطر Host جسما للطلب، لأنه آخر سطر وصل
يرد برمز 400، لأن الطلب يخلو من ترويسة Host
غياب الجسم لا يغني عن السطر الفارغ، فهو العلامة الوحيدة على أن الترويسات اكتملت. والبايتات التي وصلت تنتهي بنهاية سطر Host، فيبقى الخادم ينتظر سطر ترويسة آخر أو السطر الفارغ، ولا سبب للرمز 400 لأن ترويسة Host موجودة.
السطر الفارغ الذي ينهي الترويسات
لماذا لا يحدد المحلل نهاية الجسم بالبحث عن سطر فارغ بعده، كما فعل مع الترويسات؟
لأن المواصفة تمنع وضع أسطر فارغة داخل جسم الرسالة
لأن الجسم يرسل دائما في رسالة منفصلة بعد الترويسات
لأن الجسم لا يتكون في HTTP/1.1 إلا من سطر واحد
لأن الجسم بايتات حرة قد تتجاور فيها \r\n\r\n في أي موضع
لا تحكم الجسم قواعد السطور، فقد يكون مستند HTML فيه أسطر فارغة أو صورة تصادف بايتاتها هذا التسلسل. لذلك تعلن الترويسات كيف يعرف طول الجسم، بدلا من البحث عن علامة داخله.
الجسم: ما بعد السطر الفارغ
وصلت إلى المتصفح البايتات HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\nsaved:1. كيف يعامل المحلل النص saved:1؟
جزء من الجسم، لأنه جاء بعد السطر الفارغ
حقل ترويسة اسمه saved وقيمته 1، لأن فيه نقطتين
ترويسة ناقصة، لأنها لم تنته بالزوج \r\n
خطأ في الرسالة، لأن الجسم لا يجوز أن يحتوي نقطتين
بعد السطر الفارغ لا يقسم المحلل شيئا عند النقطتين، فكل ما يليه بايتات من الجسم. وتعلن Content-Length: 7 أن الجسم سبعة بايتات، وهي بالضبط saved:1، ولا يلزم الجسم أن ينتهي بالزوج \r\n.
كيف يقرأ الخادم طلبا وصله
في استجابة ينقلها HTTP/2، أين يوجد رمز الحالة؟
في سطر حالة نصي مثل HTTP/2 200 OK في أول الرسالة
في ترويسة عادية اسمها Status بين بقية الترويسات
في الحقل الزائف :status، ولا تحمل الرسالة عبارة سبب
لا يرسل، ويستنتجه العميل من وجود الجسم أو غيابه
لا سطر بدء في HTTP/2، ورمز الحالة ينتقل في الحقل الزائف :status الذي يسبق الترويسات العادية، ولا مكان فيه لعبارة السبب. أما السطر HTTP/2 200 الذي تعرضه أداة مثل curl فتصنعه الأداة للقراءة، ولم يمر على الشبكة.
الأجزاء نفسها في HTTP/2 وHTTP/3
التصنيفات

قد تُعجبك هذه المشاركات

4419914284293787151

العلامات المرجعية

قائمة العلامات المرجعية فارغة ... قم بإضافة مقالاتك الآن

    البحث