وب‌سوكت

(تم التحويل من WebSocket)
وب‌سوكت
Websocket connection.png
رسم بياني يصف الاتصال باستخدام وب‌سوكت
المعيار الدوليRFC 6455
طورهIETF
الصناعةعلم الحاسوب
نوع الموصلTCP

وب‌سوكت إنگليزية: WebSocket هو پروتوكول اتصالات للحاسب يوفر قنوات اتصال ثنائية الاتجاه عبر اتصال TCP واحد. كما تم توحيد پروتوكول وب‌سوكت بواسطة IETF كـ RFC 6455 في عام 2011. تُعرف مواصفات واجهة برمجة التطبيقات الحالية التي تسمح لتطبيقات الوب باستخدام هذا الپروتوكول باسم وب‌سوكت.[1]وهو مستوى فعال تحتفظ به WHATWG وخليفة لـ واجهة برمجة تطبيقات وب‌سوكت من W3C.[2]

يختلف وب‌سوكت عن HTTP. يقع كلا الپروتوكولين في layer 7 في نموذج أو‌إس‌أي ويعتمدان على TCP في الطبقة 4. على الرغم من اختلافهما، إلا أن RFC 6455 ينص على أن وب‌سوكت "مصمم للعمل عبر منافذ HTTP 443 و80 بالإضافة إلى دعم وكلاء ووسائط HTTP"، مما يجعله متوافقاً مع HTTP. لتحقيق التوافق، يستخدم وب‌سوكت مصافحة قمة ترقية HTTP[3]للتغيير من پروتوكول HTTP إلى پروتوكول وب‌سوكت.

يتيح پروتوكول وب‌سوكت التفاعل بين متصفح وب (أو تطبيق عميل آخر) وخادم وب مع حمل أقل من البدائل أحادية الاتجاه مثل استقصاء HTTP، تسهيل نقل البيانات في الزمن الفعلي من وإلى الخادم. أصبح هذا ممكناً من خلال توفير طريقة موحدة للخادم لإرسال المحتوى إلى العميل دون أن يطلبه العميل أولاً، والسماح بتمرير الرسائل ذهاباً وإياباً مع إبقاء الاتصال مفتوحاً. بهذه الطريقة، يمكن إجراء محادثة مستمرة ثنائية الاتجاه بين العميل والخادم. كما تتم الاتصالات عادةً عبر منفذ TCP رقم 443 (أو 80 في حالة الاتصالات غير الآمنة)، وهو أمر مفيد للبيئات التي تحظر اتصالات الإنترنت غير المتصلة بالإنترنت باستخدام جدار الحماية. وقد تم تحقيق اتصالات مماثلة بين المتصفح والخادم بطرق غير قياسية باستخدام تقنيات مؤقتة مثل كومت أو أدوبي فلاش.[4]

تدعم معظم المتصفحات الپروتوكول، بما في ذلك گوگل كروم وموزيلا فايرفوكس ومايكروسوفت إيدج وإنترنت إكسپلورر و سفاري و أوپرا.[5]

بخلاف HTTP، يوفر وب‌سوكت اتصالاً مزدوج الاتجاه.[6][7] بالإضافة إلى ذلك، يتيح وب‌سوكت تدفقات الرسائل أعلى TCP. يتعامل TCP وحده مع تدفقات البايت مع عدم وجود مفهوم ملازم للرسالة. قبل وب‌سوكت، كان من الممكن الوصول إلى اتصال مزدوج الاتجاه عبر المنفذ 80 باستخدام قنوات كومت؛ ومع ذلك، فإن تنفيذ كومت غير بديهي، وبسبب مصافحة TCP وقمة HTTP، فإنه غير فعال للرسائل الصغيرة. يهدف بروتوكول وب‌سوكت إلى حل هذه المشكلات دون المساس بافتراضات أمان الوب.

تحدد مواصفات پروتوكول ws (وب‌سوكت) و wss (وب‌سوكت الآمن) كنظامين جديدين لمعرف الموارد الموحد (URI)[8]التي يتم استخدامها للاتصالات غير المشفرة والمشفرة على التوالي. بصرف النظر عن اسم المخطط و الجزء (على سبيل المثال، # غير مدعوم)، يتم تعريف باقي مكونات URI لاستخدام بناء جملة URI العام.[9]

باستخدام أدوات مطور المستعرض، يمكن للمطورين فحص مصافحة وب‌سوكت وكذلك إطارات وب‌سوكت.[10]

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

تاريخ

اُشير إلى وب‌سوكت لأول مرة باسم تي‌سي‌پي‌كونكشن في مواصفات HTML5، كعنصر نائب لواجهة برمجة تطبيقات مأخذ توصيل تستند إلى پروتوكول تي‌سي‌پي.[11]في يونيو 2008، قاد مايكل كارتر سلسلة من المناقشات أسفرت عن الإصدار الأول من الپروتوكول المعروف باسم وب‌سوكت.[12]

ابتكر الاسم "وب‌سوكت" إيان هكسون ومايكل كارتر بعد ذلك بوقت قصير من خلال التعاون في غرفة دردشة #whatwg IRC ،[13]وتم تأليفه لاحقاً لإدراجها في مواصفات HTML5 بواسطة إيان هكسون. في ديسمبر 2009، كان گوگل كروم 4 هو أول متصفح يقدم الدعم الكامل للمعيار، مع تمكين وب‌سوكت افتراضياً.[14] وقد نُقل تطوير بروتوكول وب‌سوكت لاحقاً من مجموعة W3C وWHATWG إلى IETF في فبراير 2010، وتم تأليفه لمراجعين تحت إشراف إيان هكسون.[15]

بعد شحن الپروتوكول وتمكينه افتراضياً في متصفحات متعددة، تم الانتهاء من RFC 6455 تحت إشراف إيان فت في ديسمبر 2011.

قدم RFC 7692 امتداد ضغط إلى وب‌سوكت باستخدام خوارزمية DEFLATE على أساس كل رسالة.


تنفيذ المتصفح

تم تنفيذ إصدار آمن من پروتوكول وب‌سوكت في فايرفوكس 6،[16]سفاري 6، گوگل كروم 14،[17] أوپرا 12.10 وإنترنت إكسپلورر 10.[18]ويسرد تقرير مفصل عن مجموعة اختبار الپروتوكول[19]توافق هذه المتصفحات مع جوانب پروتوكول محددة.

تم تنفيذ إصدار أقدم وأقل أماناً من الپروتوكول في أوپرا 11 و سفاري 5، بالإضافة إلى إصدار الجوال من سفاري في آي أو إس 4.2.[20]كما يقوم متصفح بلاك‌بري في OS7 بتنفيذ وب‌سوكت.[21] بسبب نقاط الضعف، تم تعطيله في فايرفوكس 4 و5،[22] وأوپرا 11.[23]

حالة التنفيذ
الپروتوكول، الإصدار تاريخ المسودة إنترنت إكسپلورر فايرفوكس[24] (الحاسب الشخصي) فايرفوكس (أندرويد) كروم (الحاسب الشخصي، الجوال) سفاري (ماك، آي أو إس) أوپرا (الحاسب الشخصي، الجوال) مستعرض الأندرويد
hixie-75 4 فبراير، 2010 4 5.0.0
hixie-76
hybi-00
6 مايو، 2010
23 مايو، 2010
4.0 (تم تعطيله) 6 5.0.1 11.00 (تم تعطيله)
hybi-07, v7 22 أبريل، 2011 6[25][أ]
hybi-10, v8 11 يوليو، 2011 7[27][أ] 7 14[28]
RFC 6455, v13 ديسمبر، 2011 10[29] 11 11 16[30] 6 12.10[31] 4.4

مثال على عميل جاڤاسكريپت

// Creates new WebSocket object with a wss URI as the parameter
const socket = new WebSocket('wss://game.example.com/ws/updates');

// Fired when a connection with a WebSocket is opened
socket.onopen = function () {
  setInterval(function() {
    if (socket.bufferedAmount == 0)
      socket.send(getUpdateData());
  }, 50);
};

// Fired when data is received through a WebSocket
socket.onmessage = function(event) {
  handleUpdateData(event.data);
};

// Fired when a connection with a WebSocket is closed
socket.onclose = function(event) {
  onSocketClose(event);
};

// Fired when a connection with a WebSocket has been closed because of an error
socket.onerror = function(event) {
  onSocketError(event);
};

تنفيذ خادم الوب

يدعم إنجن‌إكس وب‌سوكت منذ 2013، مطبق في الإصدار 1.3.13[32]بما في ذلك العمل كـ پروكسي معكوس و موازن التحميل لتطبيقات وب‌سوكت.[33]

دعم مخدم HTTP أپاتشي وب‌سوكت منذ يوليو 2013، وتم تنفيذه في الإصدار 2.4.5[34][35]

أضافت خوادم معلومات الإنترنت دعماً لـ وب‌سوكت في الإصدار 8 الذي تم إصداره مع خادم ويندوز 2012.[36]

دعمت لايت‌پاد وب‌سوكت منذ عام 2017، تم تنفيذه في الإصدار 1.4.46.[37] يمكن أن يعمل لايت‌پاد mod_proxy كوكيل معكوس وموازن تحميل لتطبيقات وب‌سوكت. يمكن لـ lighttpd mod_wstunnel إنشاء أنفاق وب‌سوكت لنقل البيانات العشوائية، بما في ذلك بتنسيق جسون، إلى تطبيق الواجهة الخلفية.

يدعم Tempesta FW وب‌سوكت لاتصالات HTTP/1.1 وHTTPS منذ عام 2022.[38]تم اعتبار وب‌سوكت عبر HTTP/2 بواسطة RFC 8441 من قبل المطورين على أنها ليست منتشرة على نطاق واسع بما يكفي ولم يتم تنفيذها.

مصافحة الپروتوكول

لتأسيس اتصال وب‌سوكت، يرسل العميل طلب مصافحة وب‌سوكت، حيث يقوم الخادم بإرجاع استجابة مصافحة وب‌سوكت، كما هو موضح في المثال أدناه.[39]

طلب العميل (تماماً كما هو الحال في HTTP، ينتهي كل سطر بـ \r\n ويجب أن يكون هناك سطر فارغ إضافي في النهاية):

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

استجابة الخادم:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

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

بالإضافة إلى ترويسة Upgrade، يرسل العميل ترويسة Sec-WebSocket-Key يحتوي على base64 - وحدات بايت عشوائية مشفرة، ويرد الخادم بالتجزئة للمفتاح في ترويسة Sec-WebSocket-Accept. ويهدف هذا إلى منع پروكسي التخزين المؤقت من إعادة إرسال مداولة وب‌سوكت سابقة،[40] ولا توفر أي مصادقة أو خصوصية أو أمانة. تقوم دالة التجزئة بإلحاق السلسلة الثابتة 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 بالقيمة من ترويسة Sec-WebSocket-Key (والذي لم يتم فك تشفيره من base64)، يطبق وظيفة التجزئة SHA-1 ويرمز النتيجة باستخدام base64.[41]

يتطلب RFC6455 أن يكون المفتاح هو مناسبة يتكون من قيمة 16 بايت تم اختيارها عشوائياً والتي تم ترميزها باستخدام base64،[42]أي 24 بايت في base64 (على أن تكون آخر وحدتي بايت ==). على الرغم من أن بعض خوادم HTTP المريحة تسمح بوجود مفاتيح أقصر، فإن العديد من خوادم HTTP الحديثة ترفض الطلب مع ظهور الخطأ "عنوان Sec-WebSocket-Key غير صالح".

بمجرد إنشاء الاتصال، يمكن للعميل والخادم إرسال بيانات وب‌سوكت أو إطارات نصية ذهاباً وإياباً في وضع الازدواج الكامل. البيانات مؤطرة بأدنى حد، بترويسة صغيرة متبوعة بالحمولة.[43] توصف عمليات إرسال وب‌سوكت على أنها "رسائل"، حيث يمكن تقسيم رسالة واحدة اختيارياً عبر إطارات بيانات متعددة. يمكن أن يسمح هذا بإرسال الرسائل حيث تكون البيانات الأولية متاحة ولكن الطول الكامل للرسالة غير معروف (يرسل إطار بيانات واحداً تلو الآخر حتى يتم الوصول إلى النهاية والالتزام بـ FIN بت). مع امتدادات الپروتوكول، يمكن أيضاً استخدام هذا لتعدد إرسال تدفقات متعددة في وقت واحد (على سبيل المثال لتجنب احتكار استخدام سوكت لحمولة واحدة كبيرة).[44]

اعتبارات أمنية

على عكس طلبات HTTP العادية عبر النطاقات، لا يتم تقييد طلبات وب‌سوكت بواسطة سياسة المصدر نفسه. لذلك، يجب أن تتحقق خوادم وب‌سوكت من صحة عنوان "الأصل" مقابل الأصول المتوقعة أثناء إنشاء الاتصال، لتجنب هجمات اختراق وب‌سوكت عبر المواقع (على غرار تزوير طلب عبر المواقع)، والذي قد يكون ممكناً عند مصادقة الاتصال مع ملفات تعريف الارتباط أو مصادقة HTTP. من الأفضل استخدام الرموز المميزة أو آليات الحماية المماثلة لمصادقة اتصال وب‌سوكت عند نقل بيانات حساسة (خاصة) عبر وب‌سوكت.[45]شوهد مثال حي للثغرات الأمنية في عام 2020 في شكل Cable Haunt.

اجتياز الپروكسي

تحاول تطبيقات پروكسي پروتوكول وب‌سوكت اكتشاف ما إذا كان وكيل المستخدم قد تم تكوينه لاستخدام وكيل عند الاتصال بالمضيف والمنفذ الوجهة، وإذا كان كذلك، يستخدم أسلوب HTTP CONNECT إنشاء نفق مستمر.

في حين أن پروتوكول وب‌سوكت نفسه غير مدرك للخوادم الوكيلة والجدران الأمنية، فإنه يتميز بمصافحة متوافقة مع HTTP، مما يسمح لخوادم HTTP بمشاركة منافذ HTTP وHTTPS الافتراضية (80 و443 على التوالي) مع منفذ أو خادم وب‌سوكت. يعرّف پروتوكول وب‌سوكت البادئة ws:// و wss:// للإشارة إلى وب‌سوكت واتصال وب‌سوكت الآمن على التوالي. يستخدم كلا النظامين آلية ترقية HTTP للترقية إلى پروتوكول وب‌سوكت. بعض الخوادم الوكيلة شفافة وتعمل بشكل جيد مع وب‌سوكت؛ سيمنع الآخرون وب‌سوكت من العمل بشكل صحيح، مما يتسبب في فشل الاتصال. في بعض الحالات، قد يلزم تكوين خادم وكيل إضافي، وقد يلزم ترقية خوادم پروكسي معينة لدعم وب‌سوكت.

إذا كانت حركة مرور وب‌سوكت غير المشفرة تتدفق عبر خادم وكيل (پروكسي) صريح أو شفاف بدون دعم وب‌سوكت، فمن المحتمل أن يفشل الاتصال.[46]

إذا تم استخدام اتصال وب‌سوكت مشفر، فإن استخدام أمن طبقة النقل (TLS) في اتصال وب‌سوكت آمن يضمن إصدار أمر HTTP CONNECT عندما يتم تكوين المتصفح لاستخدام خادم وكيل صريح. يؤدي هذا إلى إنشاء نفق، والذي يوفر اتصال TCP منخفض المستوى من طرف إلى طرف من خلال وكيل HTTP، بين عميل وب‌سوكت آمن وخادم وب‌سوكت. في حالة الخوادم الوكيلة الصريحة، لا يكون المتصفح على علم بالخادم الوكيل، لذلك لا يتم إرسال HTTP CONNECT. ومع ذلك، نظراً لأن حركة المرور السلكية مشفرة، فقد تسمح خوادم الوكيل الوسيطة الشفافة ببساطة بحركة المرور المشفرة، لذلك هناك فرصة أفضل بكثير لنجاح اتصال وب‌سوكت إذا تم استخدام وب‌سوكت آمن. لا يعد استخدام التشفير خالياً من تكلفة الموارد، ولكنه غالباً ما يوفر أعلى معدل نجاح، حيث إنه سينتقل عبر نفق آمن.

كسرت مسودة منتصف عام 2010 (الإصدار hixie-76) التوافق مع الپروكسي المعكوس والبوابات من خلال تضمين ثمانية بايت من البيانات الرئيسية بعد الترويسات، ولكن لم يتم الإعلان عن تلك البيانات في طول المحتوى ترويسة Content-Length: 8.[47] لم يتم إعادة توجيه هذه البيانات من قبل جميع الوسطاء، مما قد يؤدي إلى فشل الپروتوكول. المسودات الأحدث (على سبيل المثال، hybi-09[48])كما توضع البيانات الرئيسية في ترويسةSec-WebSocket-Key، لحل هذه المشكلة.

انظر أيضاً

ملاحظات

  1. ^ أ ب Gecko-based browsers versions 6–10 implement the WebSocket object as "MozWebSocket",[26] requiring extra code to integrate with existing WebSocket-enabled code.

المراجع

  1. ^ "WebSockets Standard". websockets.spec.whatwg.org. Retrieved 2022-05-16.
  2. ^ "The WebSocket API". www.w3.org (in الإنجليزية). Retrieved 2022-05-16.
  3. ^ قالب:Cite IETF
  4. ^ "Adobe Flash Platform – Sockets". help.adobe.com. Retrieved 2021-07-28. TCP connections require a "client" and a "server". Flash Player can create client sockets.{{cite web}}: CS1 maint: url-status (link)
  5. ^ "WebSockets – Lista Web API" (in الإنجليزية الأمريكية). Mozilla Developer Network. Retrieved 2021-07-28.
  6. ^ "Glossary: WebSockets". Mozilla Developer Network. 2015.
  7. ^ "HTML5 WebSocket – A Quantum Leap in Scalability for the Web". www.websocket.org.
  8. ^ Graham Klyne, ed. (2011-11-14). "IANA Uniform Resource Identifer (URI) Schemes". Internet Assigned Numbers Authority. Retrieved 2011-12-10.
  9. ^ قالب:Cite IETF
  10. ^ Wang, Vanessa; Salim, Frank; Moskovits, Peter (February 2013). "APPENDIX A: WebSocket Frame Inspection with Google Chrome Developer Tools". The Definitive Guide to HTML5 WebSocket. Apress. ISBN 978-1-4302-4740-1. Retrieved 7 April 2013.
  11. ^ "HTML 5". www.w3.org. Retrieved 2016-04-17.
  12. ^ "[whatwg] TCPConnection feedback from Michael Carter on 2008-06-18 (whatwg.org from June 2008)". lists.w3.org. Retrieved 2016-04-17.
  13. ^ "IRC logs: freenode / #whatwg / 20080618". krijnhoetmer.nl. Retrieved 2016-04-18.
  14. ^ "Web Sockets Now Available In Google Chrome". Chromium Blog (in الإنجليزية الأمريكية). Retrieved 2016-04-17.
  15. ^ <ian@hixie.ch>, Ian Hickson (6 May 2010). "The WebSocket protocol". tools.ietf.org. Retrieved 2016-04-17.
  16. ^ Dirkjan Ochtman (May 27, 2011). "WebSocket enabled in Firefox 6". Mozilla.org. Retrieved 2011-06-30.
  17. ^ "Chromium Web Platform Status". Retrieved 2011-08-03.
  18. ^ "WebSockets (Windows)". Microsoft. 2012-09-28. Retrieved 2012-11-07.
  19. ^ "WebSockets Protocol Test Report". Tavendo.de. 2011-10-27. Retrieved 2011-12-10.
  20. ^ Katie Marsal (November 23, 2010). "Apple adds accelerometer, WebSockets support to Safari in iOS 4.2". AppleInsider.com. Retrieved 2011-05-09.
  21. ^ "Web Sockets API". BlackBerry. Archived from the original on June 10, 2011. Retrieved 8 July 2011.
  22. ^ Chris Heilmann (December 8, 2010). "WebSocket disabled in Firefox 4". Hacks.Mozilla.org. Retrieved 2011-05-09.
  23. ^ Aleksander Aas (December 10, 2010). "Regarding WebSocket". My Opera Blog. Archived from the original on 2010-12-15. Retrieved 2011-05-09.
  24. ^ "WebSockets (support in Firefox)". developer.mozilla.org. Mozilla Foundation. 2011-09-30. Retrieved 2011-12-10.
  25. ^ "Bug 640003 - WebSockets - upgrade to ietf-06". Mozilla Foundation. 2011-03-08. Retrieved 2011-12-10.
  26. ^ "WebSockets - MDN". developer.mozilla.org. Mozilla Foundation. 2011-09-30. Retrieved 2011-12-10.
  27. ^ "Bug 640003 - WebSockets - upgrade to ietf-07(comment 91)". Mozilla Foundation. 2011-07-22.
  28. ^ "Chromium bug 64470". code.google.com. 2010-11-25. Retrieved 2011-12-10.
  29. ^ "WebSockets in Windows Consumer Preview". IE Engineering Team. Microsoft. 2012-03-19. Retrieved 2012-07-23.
  30. ^ "WebKit Changeset 97247: WebSocket: Update WebSocket protocol to hybi-17". trac.webkit.org. Retrieved 2011-12-10.
  31. ^ "A hot Opera 12.50 summer-time snapshot". Opera Developer News. 2012-08-03. Archived from the original on 2012-08-05. Retrieved 2012-08-03.
  32. ^ "Archived copy". nginx.org. Archived from the original on 17 July 2012. Retrieved 3 February 2022.{{cite web}}: CS1 maint: archived copy as title (link)
  33. ^ "Using NGINX as a WebSocket Proxy". NGINX. May 17, 2014.
  34. ^ "Overview of new features in Apache HTTP Server 2.4". Apache.
  35. ^ "Changelog Apache 2.4". Apache Lounge.
  36. ^ "IIS 8.0 WebSocket Protocol Support". Microsoft Docs. 28 November 2012. Retrieved 2020-02-18.
  37. ^ https://redmine.lighttpd.net/projects/lighttpd/wiki/Release-1_4_46
  38. ^ "Tempesta FW Handling clients WebSockets". Tempesta FW wiki. Retrieved 6 June 2022.
  39. ^ قالب:Cite IETF
  40. ^ "Main Goal of WebSocket protocol". IETF. Retrieved 25 July 2015. The computation [...] is meant to prevent a caching intermediary from providing a WS-client with a cached WS-server reply without actual interaction with the WS-server.
  41. ^ قالب:Cite IETF
  42. ^ قالب:Cite IETF
  43. ^ قالب:Cite IETF
  44. ^ قالب:Cite IETF
  45. ^ Christian Schneider (August 31, 2013). "Cross-Site WebSocket Hijacking (CSWSH)". Web Application Security Blog.
  46. ^ Peter Lubbers (March 16, 2010). "How HTML5 Web Sockets Interact With Proxy Servers". Infoq.com. C4Media Inc. Retrieved 2011-12-10.
  47. ^ Willy Tarreau (2010-07-06). "WebSocket -76 is incompatible with HTTP reverse proxies". ietf.org (email). Internet Engineering Task Force. Retrieved 2011-12-10.
  48. ^ قالب:Cite IETF


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

وصلات خارجية