سؤال

أنا أستخدم com.sun.net.httpserver.httpserver في مشروعي. ومع ذلك ، يبدو أن الخادم يتسرب اتصالات عندما يحصل على بيانات غير صالحة من اتصال HTTP. الخطأ هذا واحد:

http://bugs.sun.com/view_bug.do؛jsessionid=dfe841c3152d878571573bafceb8؟bug_id=6946825

الآن ، يقال إن هذا يتم إصلاحه في الإصدار "7 (B94)" - ومع ذلك ، ما زلنا نستخدم Java 1.6 ومن غير المرجح أن نريد تبديل إصدارات Java في هذه المرحلة.

لذلك ، أنا أبحث عن طرق لإصلاح هذا الموقف. ليس لدي الكثير من الوقت ، لذلك أفضل حلولًا سريعة تعمل في الوقت الحالي ، على استعداد الكثير من الأشياء في وقت لاحق.

لدي بعض الأفكار حول كيفية القيام بذلك:

  • تحديث إلى جافا الأحدث - هذا شيء لا أريد القيام به.
  • ابحث عن جرة تحتوي فقط على إصدار أكثر حداثة من com.sun.net.httpserver وتأكد من تحميل الجرة قبل الجرار النظام.
  • ابحث عن بديل إسقاط لـ com.sun.net.httpserver - أنا منفتح على المؤشرات هنا.
  • تعديل رمز للعمل مع خادم HTTP مضمن آخر ، ونأمل أن لا يختلف عن الخادم الحالي. يمكنني إعادة كتابة رمز إعداد الخادم ، إلى حد ما ، ولكن يجب أن تبقى معظم الواجهات كما هي.
  • فك تشفير الفئة com.sun.net.httpserver.serverimpl ، إصلاح الأماكن المخالفة ، وإعادة ترجمة تلك الفئة الفردية إلى جرة خاصة بها

لكنني منفتح على اقتراحات جيدة!

شكرا لكم مقدما.


يتم تنفيذ الإصلاح الآن ويعمل. سوف ألصق هنا البتات ذات الصلة إذا احتاج أي شخص آخر هذه:

final Field httpserverimpl_server = Class.forName("sun.net.httpserver.HttpServerImpl").getDeclaredField("server");
final Field httpsserverimpl_server = Class.forName("sun.net.httpserver.HttpsServerImpl").getDeclaredField("server");
final Field serverimpl_allconnections = Class.forName("sun.net.httpserver.ServerImpl").getDeclaredField("allConnections");
final Field httpconnection_closed = Class.forName("sun.net.httpserver.HttpConnection").getDeclaredField("closed");

httpserverimpl_server.setAccessible(true);
httpsserverimpl_server.setAccessible(true);
serverimpl_allconnections.setAccessible(true);
httpconnection_closed.setAccessible(true);

Object serverimpl = httpserverimpl_server.get(server);
Set allconnections = (Set)serverimpl_allconnections.get(serverimpl);
LinkedList<Object> toRemove = new LinkedList<Object>();
for (Object conn : allconnections) {
    if (httpconnection_closed.getBoolean(conn)) {
        toRemove.add(conn);
    }
}
for (Object conn : toRemove) {
    allconnections.remove(conn);
}
هل كانت مفيدة؟

المحلول

أستطيع أن أفهم ترددك في الترقية إلى بناء ما قبل الإصدار من Java 7.

هذه إقتراحاتي:

  • احصل على عقد دعم Java من Oracle واجعلهم يوفرون لك تصحيحًا لـ Java 6 الذي يعمل على إصلاح الخلل.

  • قم بتنزيل مصادر Java 6 للإصدار الذي تستخدمه حاليًا ، و Packport إصلاح الأخطاء من مصادر Java 7 والبناء. ربما تحتاج فقط إلى بناء ملفات جرة معينة.

  • انظر إلى الكود ومعرفة ما إذا كان يمكنك تطوير حل بديل. على سبيل المثال ، قد تكون قادرًا على استخدام التأمل لتجنب "قائمة مثيلات HTTPCONNECTION" التي يتحدث عنها تقرير الأخطاء ، وإزالة الإدخالات بشكل دوري التي تبدو وكأنها ميتة. (سأتعامل مع هذا كملاذ أخير.)


(محدث: 2012-05-15)

والآن بعد أن تم إصدار Java 7 بشكل جيد وحقيقي (نحن الآن في 1.7u4):

  • الترقية إلى Java 7 ، و

  • تخلص من الاختراقات العاكسة السيئة التي استخدمتها كحل مؤقت.

نصائح أخرى

هل يمكن أن تضع وكيلًا عكسيًا أمام خادم HTTP ، للتأكد من السماح فقط بالطلبات الجيدة المعروفة؟ الورنيش أو الحبار أو أباتشي؟

أو ضرب شيء ما في رصيف بحيث يكون بمثابة وكيل عكسي؟

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

هل يمكنك الوصول إلى 7 (B94)؟ ثم يمكنك مقارنة المصادر ومعرفة ما إذا كان يمكنك إصلاحها عن طريق تجاوز أو توفير ملحقات مختلفة.

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