سؤال

نحن نبني إطار عمل شامل للتكامل في C # لتطبيقنا الموجود على رأس HTTP باستخدام IIS7 لاستضافة تطبيقاتنا.

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

أنا أبحث عن مكتبة المقبس المستندة إلى .NET FX أو استبدال Http WebRequest المخصص الذي يسمح للمطورين خصيصا بمحاكاة مثل هذه الشروط لإضافتها إلى جناح اختبار التكامل لدينا. هل يعرف أحد بأي مكتبات من هذا القبيل؟ حل قابلة للناس سوف يعمل كذلك.

هل كانت مفيدة؟

المحلول

قم بتعيين خاصية Contentlength قبل استدعاء GetRequestStream (أو begingetrequeststream) ثم اكتب عددا أقل بذاتها إلى هذا الدفق. سوف رمي ContentLength إذا حاولت ضبطه بعد أن حصلت على دفق الطلب. إذا لم تقم بتعيين contentlength، فسيقوم httpWebRequest بتعليم الرؤوس حتى يتم إغلاق الدفق حتى يتمكن من ضبط الطول contentlenger بشكل مناسب (بالتناوب، يمكنك استخدام SendChunked ولكن هذا لن يعمل من أجلك هنا). إذا كنت ترغب في الحد الأقصى للتحكم في هذا، فقم بإنشاء طلب مشحون أو سنتين ثم افتح مأخذ توصيل إلى منفذ 80 على الخادم واكتب الطلب إلى تيار TCP ثم قراءة الاستجابة وتحقق من الاتصال لمعرفة ما إذا كان مغلقا وبعد

ومع ذلك: لا أعتقد أن هذا الاختبار هو فكرة جيدة. إليك المشكلة:

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

الجواب هو أن الخادم سيفترض أن هذه البايتات كانت جزءا من الطلب السابق وعلاجها على هذا النحو، ثم ابدأ في قراءة طلب "جديد" 10 بايت بعد بدايةها، والتي من شأنها أن تؤدي إلى رؤوس مشوهة. لن يعجب الخادم بذلك، لذلك سترسل خطأ 4XX ثم سيغلق الاتصال. السبب في إغلاق الاتصال هو أنه ليس لديه الآن طريقة لمعرفة البيانات التي يتم إرسالها إليها ولا طريقة لاستردادها. أيضا، لن يكون إغلاق الاتصال رشيقا، وسوف يكون مفاجئا و HttpWebRequest في الطرف الآخر الذي يقدم طلبا آخر (أو ثالث أو رابع إذا كانوا في قائمة الانتظار) سوف يرمي WebException أن تم إغلاق الاتصال الأساسي وأتركك تخمين لماذا.

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

أخيرا، لا يختبر الاختبار الخاص ب endofstreamexception من دفق الشبكة باستخدام TCP أي معنى بالنسبة لي على الإطلاق. لا يمثل TCP "إنهاء" دفق، إنه فقط يحتفظ بإرسال البيانات كما هو مكتوب إلى المقبس. لا يوجد "EOF" لأي طريقة لاكتشافها إذا تم نقل جميع البيانات إلا إذا كنت تعرف مقدار البيانات التي تتوقعها. لا تتمتع TCP حقا ب "إنهاء" إلى دفقها ما لم يتم إغلاق الاتصال، وفي هذه الحالة، ستحصل على WebException أو SocketException اعتمادا على المكان الذي تعمل فيه في المكدس. يتم التعامل مع أي أخطاء نقل في البروتوكول في Winsock. إذا لم يتم إرسال المزيد من البيانات، فسوف ترسل أحد الطرفين للاتصال في نهاية المطاف للحارس إلى الآخر للتأكد من أن الاتصال لا يزال مفتوحا بالفعل ولم يسقط مضيف واحد فقط. إذا خرجت أوقات الحارس، فسيتم إغلاق الاتصال وقد تحصل على WebException في المرة القادمة التي تحاول فيها قراءتها. نظرا لأن كل هذا يعمل، أنا فقط لا أرى كيف ستحصل على أي قيمة من هذا الاختبار. أنت أفضل بكثير من إرسال الطلبات المشوهة وضمان معالجة الأخطاء وفقا لذلك ويتم إرسال رسالة 4XX المناسبة إلى العميل ويتم إغلاق الاتصال بشكل صحيح.

نصائح أخرى

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

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

لا يمكنك فقط ضبط HttpWebRequest.ContentLength الممتلكات على العملاء إلى قيمة أصغر أو أكبر من الحجم الفعلي للبيانات؟

إذا كنت ترغب في محاكاة أي أشياء مثل هذا، فأين تنتهك بروتوكول HTTP، فسيتعين عليك كتابة التعليمات البرمجية الخاصة بك للقيام بذلك. HttpWebRequest لا يسمح لك بأي أشياء مثل هذا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top