
وكيل HTTP قابل للاختراق لاختبار المرونة ومحاكاة ظروف الشبكة
لا تتم صيانته بنشاط، قد لا يعمل مع أحدث إصدارات node.js. إذا كنت مهتماً بصيانة toxy، يرجى فتح issue.
وكيل HTTP قابل للتخصيص لمحاكاة سيناريوهات فشل الخادم، اختبار مرونة الأنظمة وظروف شبكة غير متوقعة، مبني لـ node.js.
تم تصميمه بشكل أساسي لاختبار مقاومة الفشل، حيث يصبح toxy مفيدًا بشكل خاص لتغطية قدرات تحمل الأخطاء والمرونة للنظام، خاصة في الشبكات المتسامحة مع الانقطاع والهندسة الموجهة نحو الخدمة، حيث يمكن لـ toxy العمل كوكيل وسيط (MitM) بين الخدمات لحقن الفشل.
يسمح لك toxy بتوصيل poisons، والتي يتم تصفيتها اختياريًا بواسطة rules، والتي يمكنها بشكل أساسي اعتراض وتعديل تدفق HTTP حسب حاجتك، مع تنفيذ إجراءات ضارة متعددة في منتصف تلك العملية، مثل تحديد النطاق الترددي، تأخير حزم الشبكة، حقن زمن انتقال شبكة (jitter)، أو الرد برمز خطأ أو حالة مخصص.
يعمل بشكل أساسي على الطبقة السابعة (L7)، على الرغم من أنه يمكنه محاكاة ظروف الشبكة للطبقة الثالثة (L3).
يمكن استخدام toxy بسلاسة برمجيًا أو عبر HTTP API.
تم بناؤه فوق rocky، وهو وكيل HTTP كامل الميزات موجه للوسائط (middleware)، وهو أيضًا قابل للتوصيل في connect/express كوسيط (middleware) قياسي.
يتطلب node.js +4.
توجد بعض الحلول المشابهة لـ toxy في السوق، لكن معظمها لا يوفر تحكمًا برمجيًا مناسبًا وعادةً لا يكون سهلاً في التخصيص أو التكوين أو أنها مغلقة مباشرة أمام قابلية التوسع.
علاوة على ذلك، تعمل غالبية هذه الحلول فقط على مستوى TCP L3 بدلاً من توفير تجريدات عالية المستوى لتغطية المتطلبات الشائعة في المجال المحدد وطبيعة بروتوكول HTTP L7، كما يحاول toxy توفيره.
يجلب toxy حلاً قويًا وقابلًا للتخصيص والتوسع مع تجريد مريح، ولكن دون فقدان قدرات الواجهة ذات المستوى المنخفض المناسبة للتعامل مع بدائيات بروتوكول HTTP بسهولة.
تم تصميم toxy بناءً على مبادئ التركيب والبساطة وقابلية التوسع. من خلال طبقة الوسائط الهرمية الخاصة بالمجال المدمجة، يمكنك بسهولة توسيع ميزات toxy لتناسب احتياجاتك الخاصة.
يقدم toxy توجيهين: poisons و rules.
Poisons هي المنطق المحدد الذي يصيب معاملة HTTP واردة أو صادرة (مثل: حقن زمن انتقال (latency)، الرد بخطأ). يمكن تسميم معاملة HTTP واحدة بواسطة poison واحد أو أكثر، ويمكن تكوين هذه poisons أيضًا لإصابة حركة المرور على المستوى العام أو مستوى المسار.
Rules هي نوع من مرشحات التحقق من المطابقة التي تفحص طلب/استجابة HTTP لتحديد، وفقًا لقواعد معينة، ما إذا كان يجب تسميم معاملة HTTP أم لا (على سبيل المثال: إذا تطابقت الرؤوس (headers)، معاملات الاستعلام (query params)، الطريقة (method)، النص (body)...). يمكن إعادة استخدام rules وتطبيقها على كل من تدفقات حركة المرور الواردة والصادرة، بما في ذلك نطاقات مختلفة: المستوى العام، مستوى المسار، أو مستوى poison.
↓ ( Incoming request ) ↓ ↓ ||| ↓ ↓ +-------------+ ↓ ↓ | Toxy Router | ↓ -> Match the incoming request ↓ +-------------+ ↓ ↓ ||| ↓ ↓ +--------------------+ ↓ ↓ | Incoming phase | ↓ -> The proxy receives the request from the client ↓ |~~~~~~~~~~~~~~~~~~~~| ↓ ↓ | ---------------- | ↓ ↓ | | Exec Rules | | ↓ -> Apply configured rules for the incoming request ↓ | ---------------- | ↓ ↓ | ||| | ↓ ↓ | ---------------- | ↓ ↓ | | Exec Poisons | | ↓ -> If all rules passed, then poison the HTTP flow ↓ | ---------------- | ↓ ↓ +~~~~~~~~~~~~~~~~~~~~+ ↓ ↓ / \ ↓ ↓ \ / ↓ ↓ +--------------------+ ↓ ↓ | HTTP dispatcher | ↓ -> Forward the HTTP traffic to the target server, either poisoned or not ↓ +--------------------+ ↓ ↓ / \ ↓ ↓ \ / ↓ ↓ +--------------------+ ↓ ↓ | Outgoing phase | ↓ -> Receives response from target server ↓ |~~~~~~~~~~~~~~~~~~~~| ↓ ↓ | ---------------- | ↓ ↓ | | Exec Rules | | ↓ -> Apply configured rules for the outgoing request ↓ | ---------------- | ↓ ↓ | ||| | ↓ ↓ | ---------------- | ↓ ↓ | | Exec Poisons | | ↓ -> If all rules passed, then poison the HTTP flow before send it to the client ↓ | ---------------- | ↓ ↓ +~~~~~~~~~~~~~~~~~~~~+ ↓ ↓ ||| ↓ ↓ ( Send to the client ) ↓ -> Finally, send the request to the client, either poisoned or not
## الاستخدام
### التثبيت```
npm install toxy
انظر إلى دليل أمثلة لمزيد من حالات الاستخدام.```js var toxy = require('toxy') var poisons = toxy.poisons var rules = toxy.rules
// Create a new toxy proxy var proxy = toxy()
// Default server to forward incoming traffic proxy .forward('http://httpbin.org')
// Register global poisons and rules proxy .poison(poisons.latency({ jitter: 500 })) .rule(rules.probability(25))
// Register multiple routes proxy .get('/download/') .forward('http://files.myserver.net') .poison(poisons.bandwidth({ bps: 1024 })) .withRule(rules.headers({'Authorization': /^Bearer (.)$/i }))
// Infect outgoing traffic only (after the server replied properly) proxy .get('/image/*') .outgoingPoison(poisons.bandwidth({ bps: 512 })) .withRule(rules.method('GET')) .withRule(rules.timeThreshold({ duration: 1000, threshold: 1000 * 10 })) .withRule(rules.responseStatus({ range: [ 200, 400 ] }))
proxy .all('/api/*') .poison(poisons.rateLimit({ limit: 10, threshold: 1000 })) .withRule(rules.method(['POST', 'PUT', 'DELETE'])) // And use a different more permissive poison for GET requests .poison(poisons.rateLimit({ limit: 50, threshold: 1000 })) .withRule(rules.method('GET'))
// Handle the rest of the traffic proxy .all('/*') .poison(poisons.slowClose({ delay: 1000 })) .poison(poisons.slowRead({ bps: 128 })) .withRule(rules.probability(50))
proxy.listen(3000) console.log('Server listening on port:', 3000) console.log('Test it:', 'http://localhost:3000/image/jpeg')
## المعيار
انظر [toxy/benchmark](https://github.com/h2non/toxy/tree/master/benchmark) للتفاصيل.
## السموم
تستضيف السموم منطقًا محددًا يعترض ويُغيّر ويُلفّ ويُعدّل و/أو يلغي معاملة HTTP في الخادم الوكيل.
يمكن تطبيق السموم على تدفقات المرور الواردة أو الصادرة، أو حتى كليهما (انظر [مراحل التسميم](#poisoning-phases)).
يمكن تكوين السموم وإعادة استخدامها لسيناريوهات HTTP مختلفة.
يتم تنفيذها بترتيب FIFO وبشكل غير متزامن.
### نطاقات التسميم
لدى `toxy` تصميم هرمي يعتمد على نطاقين مختلفين: `global` و `route`.
نطاق **Global** يشير إلى جميع حركة المرور HTTP الواردة التي يستقبلها الخادم الوكيل، بغض النظر عن طريقة HTTP أو المسار.
نطاق **Route** يشير إلى أي حركة مرور واردة تطابق فعل HTTP محدد ومسار URI.
يمكن توصيل السموم بكلا النطاقين، مما يعني أنه يمكنك العمل بدقة أكبر وتقييد نطاق التسميم،
على سبيل المثال، قد ترغب في تطبيق تسميم حد النطاق الترددي فقط على مسارات معينة، مثل `/download` أو `/images`.
انظر [routes.js](https://github.com/h2non/toxy/blob/master/examples/routes.js) للحصول على مثال مميز.
### مراحل التسميم
يمكن توصيل السموم بتدفقات حركة المرور الواردة أو الصادرة، أو حتى كليهما.
يتم تطبيق التسميم **الوارد** عندما يتم استلام حركة المرور بواسطة الوكيل ولكن لم يتم إعادة توجيهها إلى الخادم الهدف بعد.
يشير التسميم **الصادر** إلى حركة المرور التي تم إعادة توجيهها إلى الخادم الهدف وعندما يتلقى الوكيل الرد منه، ولكن لم يتم إرسال هذا الرد إلى العميل بعد.
هذا يعني بشكل أساسي أنه يمكنك توصيل سمومك لإصابة حركة مرور HTTP قبل أو بعد إعادة توجيه الطلب إلى خادم HTTP الهدف أو إرساله إلى العميل.
يسمح لك هذا بتطبيق تسميم أفضل وأكثر دقة بناءً على الطلب أو استجابة الخادم.
على سبيل المثال، نظرًا لطبيعة بعض السموم، مثل `inject error`، قد ترغب في تمكينه وفقًا لاستجابة الخادم الهدف (مثل: وجود رأس معين أو عدم وجوده).
انظر [poison-phases.js](https://github.com/h2non/toxy/blob/master/examples/poison-phases.js) للحصول على مثال مميز.
### السموم المضمنة
#### زمن الوصول
<table>
<tr>
<td><b>الاسم</b></td><td>latency</td>
</tr>
<tr>
<td><b>مرحلة التسميم</b></td><td>incoming / outgoing</td>
</tr>
<tr>
<td><b>يصل إلى الخادم</b></td><td>true</td>
</tr>
</table>
يصيب تدفق HTTP بحقن تذبذب زمن الوصول في الاستجابة
**الوسائط**:
- **options** `object`
- **jitter** `number` - قيمة التذبذب بالميلي ثانية
- **max** `number` - القيمة القصوى للتذبذب العشوائي
- **min** `number` - القيمة الدنيا للتذبذب العشوائي```js
toxy.poison(toxy.poisons.latency({ jitter: 1000 }))
// Or alternatively using a random value
toxy.poison(toxy.poisons.latency({ max: 1000, min: 100 }))
| الاسم | inject |
| مرحلة التسميم | incoming / outgoing |
| يصل إلى الخادم | false (فقط كتسميم وارد) |
يقوم بحقن استجابة مخصصة، مع اعتراض الطلب قبل إرساله إلى الخادم الهدف. مفيد لحقن الأخطاء الناشئة في الخادم.
الوسائط:
object
number - رمز حالة HTTP للاستجابة. الافتراضي 500object - رؤوس اختيارية للإرسالmixed - بيانات الجسم الاختيارية للإرسال. يمكن أن تكون buffer أو stringstring - ترميز الجسم. الافتراضي `utf8````js
toxy.poison(toxy.poisons.inject({
code: 503,
body: '{"error": "toxy injected error"}',
headers: {'Content-Type': 'application/json'}
}))#### النطاق الترددي (Bandwidth)
<table>
<tr>
<td><b>الاسم</b></td><td>bandwidth</td>
</tr>
<tr>
<td><b>مرحلة التسميم</b></td><td>وارد / صادر</td>
</tr>
<tr>
<td><b>يصل إلى الخادم</b></td><td>true</td>
</tr>
</table>
يحدد كمية البايتات المرسلة عبر الشبكة في حركة HTTP الصادرة خلال إطار زمني معين.
هذا السم هو في الأساس اسم مستعار لـ [throttle](#throttle).
**الوسائط**:
- **options** `object`
- **bytes** `number` - حجم جزء البايتات المراد إرساله. القيمة الافتراضية `1024`
- **threshold** `number` - إطار زمني للحزم بالمللي ثانية. القيمة الافتراضية `1000````js
toxy.poison(toxy.poisons.bandwidth({ bytes: 512 }))
| الاسم | rateLimit |
| مرحلة التسميم | وارد / صادر |
| يصل إلى الخادم | صحيح |
يحد من عدد الطلبات التي يستقبلها الوكيل في إطار زمني محدد. مصمم لاختبار حدود واجهات برمجة التطبيقات. يعرض رؤوس X-RateLimit-* النمطية.
لاحظ أن هذا تطبيق بسيط جدًا لحد المعدل، حيث يتم تخزين الحدود في الذاكرة، وبالتالي فهي مؤقتة تمامًا. هناك مجموعة من تطبيقات تحديد المعدل المميزة والمتسقة في npm يمكنك توصيلها كسم. قد تكون مهتمًا أيضًا بـ خوارزمية دلو الرموز.
الوسائط:
object
number - إجمالي عدد الطلبات. القيمة الافتراضية 10number - الإطار الزمني المحدد بالميلي ثانية. القيمة الافتراضية 1000string - رسالة خطأ اختيارية عند الوصول إلى الحد.number - رمز حالة HTTP عند الوصول إلى الحد. القيمة الافتراضية 429.```js
toxy.poison(toxy.poisons.rateLimit({ limit: 5, threshold: 10 * 1000 }))#### قراءة بطيئة
<table>
<tr>
<td><b>الاسم</b></td><td>slowRead</td>
</tr>
<tr>
<td><b>مرحلة التسميم</b></td><td>incoming</td>
</tr>
<tr>
<td><b>يصل إلى الخادم</b></td><td>true</td>
</tr>
</table>
يقرأ حزم بيانات الحمولة الواردة ببطء. صالح فقط لطلبات غير GET.
**الوسائط**:
- **options** `object`
- **chunk** `number` - حجم حزمة البيانات بالبايت. القيمة الافتراضية: `1024`
- **threshold** `number` - الحد الزمني للإطار بالمللي ثانية. القيمة الافتراضية: `1000````js
toxy.poison(toxy.poisons.slowRead({ chunk: 2048, threshold: 1000 }))
الاسم: slowOpen
| الاسم | slowOpen |
| مرحلة التسميم | incoming |
| يصل إلى الخادم | true |
يؤخر حالة استعداد اتصال HTTP.
الوسائط:
object
number - تأخير الاتصال بالميلي ثانية. القيمة الافتراضية `1000````js
toxy.poison(toxy.poisons.slowOpen({ delay: 2000 }))#### إغلاق بطيء
<table>
<tr>
<td><b>الاسم</b></td><td>slowClose</td>
</tr>
<tr>
<td><b>مرحلة التسميم</b></td><td>واردة / صادرة</td>
</tr>
<tr>
<td><b>يصل إلى الخادم</b></td><td>true</td>
</tr>
</table>
يؤخر إشارة إغلاق اتصال HTTP (نهاية الملف).
**الوسائط**:
- **options** `object`
- **delay** `number` - وقت التأخير بالميلي ثانية. القيمة الافتراضية `1000````js
toxy.poison(toxy.poisons.slowClose({ delay: 2000 }))
| الاسم | throttle |
| مرحلة التسميم | وارد / صادر |
| يصل إلى الخادم | true |
يحد من كمية الحزم المرسلة عبر الشبكة في إطار زمني محدد للعتبة.
الوسائط:
object
number - حجم قطعة الحزمة بالبايت. الافتراضي 1024object - الإطار الزمني لتأخير قطعة البيانات بالميلي ثانية. الافتراضي `100````js
toxy.poison(toxy.poisons.throttle({ chunk: 2048, threshold: 1000 }))#### إحباط الاتصال
<table>
<tr>
<td><b>الاسم</b></td><td>abort</td>
</tr>
<tr>
<td><b>مرحلة التسميم</b></td><td>وارد / صادر</td>
</tr>
<tr>
<td><b>يصل إلى الخادم</b></td><td>false (فقط كسم وارد)</td>
</tr>
</table>
يقطع اتصال TCP. من منظور منخفض المستوى، سيؤدي ذلك إلى إتلاف المقبس (socket) على الخادم، ويعمل فقط على مستوى TCP دون إرسال أي بيانات محددة على مستوى تطبيق HTTP.
**الوسائط**:
- **options** `object`
- **delay** `number` - يقطع اتصال TCP بعد انتظار المدة المحددة بالمللي ثانية. القيمة الافتراضية `0`
- **next** `boolean` - إذا كانت `true`، سيتم إحباط الاتصال إذا استغرق الخادم الهدف وقتًا أطول من المعامل `delay` للرد. القيمة الافتراضية `false`
- **error** `Error` - خطأ داخلي مخصص في Node.js لاستخدامه عند إتلاف المقبس. القيمة الافتراضية `null````js
// Basic connection abort
toxy.poison(toxy.poisons.abort())
// Abort after a delay
toxy.poison(toxy.poisons.abort(1000))
// In this case, the socket will be closed if
// the target server takes more than
// 2 seconds to respond
toxy.poison(toxy.poisons.abort({ delay: 2000, next: true }))
| Name | timeout |
| Poisoning Phase | incoming / outgoing |
| Reaches the server | true |
يحدد مهلة زمنية للاستجابة. مفيد عند التوجيه إلى خوادم قد تكون بطيئة.
الوسائط:
number - الحد الأقصى للمهلة بالمللي ثانية```js
toxy.poison(toxy.poisons.timeout(5000))### كيفية كتابة السموم
يتم تنفيذ السموم كدالة وسيطة قياسية بنفس الواجهة التي تستخدمها وسائط connect/express.
بعض السموم ليست بسيطة التنفيذ، لذا يجب أن تكون على دراية بوحدة [http](https://nodejs.org/api/http.html) الخاصة بـ node.js وواجهة برمجة التطبيقات الخاصة بها.
إليك مثال بسيط على سم تأخير الخادم:```js
var toxy = require('toxy')
function customLatencyPoison (delay) {
// We name the function since toxy uses it as identifier to get/disable/remove it in the future
return function customLatency (req, res, next) {
var timeout = setTimeout(process, delay)
req.once('close', onClose)
function onClose () {
clearTimeout(timeout)
next('client connection closed')
}
function process () {
req.removeListener('close', onClose)
next()
}
}
}
var proxy = toxy()
// Register and enable the poison
proxy
.get('/foo')
.poison(customLatencyPoison(2000))
يمكنك اختيارياً توسيع السموم المضمنة بإضافة سمومك الخاصة:```js toxy.addPoison(customLatency)
// Then you can use it as a built-in poison proxy .get('/foo') .poison(toxy.poisons.customLatency)
للحصول على مثال واقعي مميز، ألق نظرة على تنفيذ [السموم المدمجة](https://github.com/h2non/toxy/tree/master/lib/poisons).
## القواعد
القواعد هي مرشحات تحقق بسيطة تفحص حركة HTTP الواردة أو الصادرة لتحديد، بناءً على قواعد معينة (مثل: تطابق الطريقة، الرؤوس، معاملات الاستعلام، النص...)، ما إذا كان يجب تسميم معاملة HTTP الحالية أم لا، بناءً على قيمة دقة القاعدة.
القواعد مفيدة لتكوين وفصل وإعادة استخدام المنطق بين سيناريوهات التسميم المختلفة.
يمكن تطبيق القواعد على النطاق العام، أو المسار، أو حتى نطاق السم، وينطبق أيضًا على كل من [مراحل التسميم](#poisoning-phases).
يتم تنفيذ القواعد بترتيب FIFO. منطق تقييمها يعادل `Array#every()` في JavaScript: يجب أن تمر جميع القواعد للمتابعة بالتسميم.
### القواعد المدمجة
#### الاحتمالية
<table>
<tr>
<td><b>الاسم</b></td><td>probability</td>
</tr>
<tr>
<td><b>مرحلة التسميم</b></td><td>incoming / outgoing</td>
</tr>
</table>
تفعيل القاعدة بواسطة احتمالية عشوائية. مفيد للتسميم العشوائي.
**الوسائط**:
- **percentage** `number` - نسبة التصفية. الافتراضي `50````js
var rule = toxy.rules.probability(85)
toxy.rule(rule)
| الاسم | timeThreshold |
| مرحلة التسميم | وارد / صادر |
قاعدة بسيطة لتفعيل التسميمات بناءً على حد زمني ومدة محددة. على سبيل المثال، يمكنك تفعيل تسميم معين خلال مدة زمنية محددة (مثل: ثانية واحدة) ضمن حد زمني (مثل: دقيقة واحدة).
الوسائط:
object
number - الفترة الزمنية للتفعيل بالميلي ثانية. القيمة الافتراضية 1000number - الحد الزمني بالميلي ثانية للانتظار قبل إعادة تفعيل التسميم. القيمة الافتراضية `10000````js
// Enable the poisoning only 100 milliseconds per each 10 seconds
proxy.rule(toxy.rules.timeThreshold(100))
// Enable poisoning during 1 second every minute
proxy.rule(toxy.rules.timeThreshold({ duration: 1000, period: 1000 * 60 }))#### الطريقة
<table>
<tr>
<td><b>الاسم</b></td><td>method</td>
</tr>
<tr>
<td><b>مرحلة التسميم</b></td><td>واردة / صادرة</td>
</tr>
</table>
يقوم بالتصفية حسب طريقة HTTP.
**الوسائط**:
- **method** `string|array` - طريقة أو طرق للتصفية.```js
var method = toxy.rules.method(['GET', 'POST'])
toxy.rule(method)
يقوم بالتصفية حسب رأس نوع المحتوى. يجب أن يكون موجودًا
الوسائط:
string|regexp - قيمة الرأس للمطابقة.```js
var rule = toxy.rules.contentType('application/json')
toxy.rule(rule)#### الرؤوس (Headers)
<table>
<tr>
<td><b>الاسم</b></td><td>headers</td>
</tr>
<tr>
<td><b>مرحلة التسميم</b></td><td>وارد / صادر</td>
</tr>
</table>
تصفية حسب رؤوس الطلبات.
**الوسائط**:
- **headers** `object` - الرؤوس المطلوب مطابقتها بواسطة زوج المفتاح-القيمة. يمكن أن تكون `value` سلسلة نصية، تعبيرًا نمطيًا، `boolean` أو `function(headerValue, headerName) => boolean````js
var matchHeaders = {
'content-type': /^application/\json/i,
'server': true, // meaning it should be present,
'accept': function (value, key) {
return value.indexOf('text') !== -1
}
}
var rule = toxy.rules.headers(matchHeaders)
toxy.rule(rule)
| الاسم | responseHeaders |
| مرحلة التسميم | outgoing |
التصفية حسب رؤوس الاستجابة من الخادم الهدف. نفس قاعدة headers، ولكن بتقييم الطلب الصادر.
الوسائط:
object - رؤوس للمطابقة حسب زوج المفتاح والقيمة. يمكن أن تكون value سلسلة نصية، أو تعبيرًا منتظمًا، أو قيمة منطقية، أو دالة function(headerValue, headerName) => boolean.```js
var matchHeaders = {
'content-type': /^application/\json/i,
'server': true, // meaning it should be present,
'accept': function (value, key) {
return value.indexOf('text') !== -1
}
}var rule = toxy.rules.responseHeaders(matchHeaders) toxy.rule(rule)
#### Body
<table>
<tr>
<td><b>الاسم</b></td><td>body</td>
</tr>
<tr>
<td><b>مرحلة التسميم</b></td><td>وارد / صادر</td>
</tr>
</table>
طابق حمولة الجسم الواردة باستخدام `string` أو `regexp` أو دالة تصفية مخصصة `function`.
هذه القاعدة بسيطة نسبياً، لذا إذا كنت بحاجة إلى مطابقة معقدة للجسم (مثلاً: التحقق من صحته وفق مخطط JSON)، فعليك كتابة قاعدتك الخاصة.
**الوسائط**:
- **match** `string|regexp|function` - محتوى الجسم المطلوب مطابقته
- **limit** `string` - اختياري. حد الجسم بحجم بشري. مثال: `5mb`
- **encoding** `string` - تشفير الجسم. الافتراضي `utf8`
- **length** `number` - طول الجسم. الافتراضي مأخوذ من ترويسة `Content-Length````js
var rule = toxy.rules.body('"hello":"world"')
toxy.rule(rule)
// Or using a filter function returning a boolean
var rule = toxy.rules.body(function contains(body) {
return body.indexOf('hello') !== -1
})
toxy.rule(rule)
| الاسم | responseBody |
| مرحلة التسميم | outgoing |
مطابقة حمولة الجسم الصادرة بواسطة string أو regexp أو دالة تصفية مخصصة function.
الوسائط:
string|regexp|function - محتوى الجسم للمطابقةstring - ترميز الجسم. الافتراضي utf8number - طول الجسم. يتم أخذ الافتراضي من رأس `Content-Length````js
var rule = toxy.rules.responseBody('"hello":"world"')
toxy.rule(rule)// Or using a filter function returning a boolean var rule = toxy.rules.responseBody(function contains(body) { return body.indexOf('hello') !== -1 }) toxy.rule(rule)
#### حالة الاستجابة
<table>
<tr>
<td><b>الاسم</b></td><td>responseStatus</td>
</tr>
<tr>
<td><b>مرحلة التسميم</b></td><td>صادر</td>
</tr>
</table>
يقيم حالة الاستجابة من الخادم الهدف.
ينطبق فقط على التسميمات الصادرة.
**الوسائط**:
- **range** `array` - زوج من نطاق رموز الحالة للمطابقة. القيمة الافتراضية `[200, 300]`.
- **lower** `number` - مقارنة الحالة كعملية `أقل من`. القيمة الافتراضية `null`.
- **higher** `number` - مقارنة الحالة كعملية `أكبر من`. القيمة الافتراضية `null`.
- **value** `number` - رمز الحالة للمطابقة باستخدام مقارنة صارمة للمساواة. القيمة الافتراضية `null`.
- **include** `array` - قائمة غير مرتبة من رموز الحالة للمطابقة. مفيد لتحديد حالة مخصصة. القيمة الافتراضية `null````js
// Strict evaluation of the status code
toxy.rule(toxy.rules.responseBody(200))
// Using a range of valid status
toxy.rule(toxy.rules.responseBody([200, 204]))
// Using relational comparison
toxy.rule(toxy.rules.responseBody({ higher: 199, lower: 400 }))
// Custom unordered status code to match
toxy.rule(toxy.rules.responseBody({ include: [200, 204, 400, 404] }))
قائمة بقواعد الطرف الثالث المتاحة التي يقدمها المجتمع. مرحب بطلبات السحب (PR).
القواعد هي دوال وسيطة (middleware) بسيطة تُحل بشكل غير متزامن بقيمة boolean لتحديد ما إذا كان يجب تجاهل معاملة HTTP معينة عند التسميم.
يجب أن تتحل القاعدة بقيمة boolean عن طريق استدعاء الدالة next(err, shouldIgnore) في الوسيط (middleware)، مع تمرير قيمة true إذا كانت القاعدة لا تتطابق ولا يجب تطبيق التسميم، وبالتالي المتابعة مع مكدس الوسيط التالي.
إليك مثال لقاعدة بسيطة تطابق طريقة HTTP لتحديد ما إذا:```js var toxy = require('toxy')
function customMethodRule(matchMethod) { /**
var proxy = toxy()
// Register and enable the rule proxy .get('/foo') .rule(customMethodRule('GET')) .poison(/* ... */)
يمكنك اختياريًا توسيع القواعد المضمنة بالقواعد الخاصة بك:```js
toxy.addRule(customMethodRule)
// Then you can use it as a built-in poison
proxy
.get('/foo')
.rules(toxy.rules.customMethodRule)
للحصول على أمثلة واقعية مميزة، ألق نظرة على تنفيذ القواعد المدمجة
تم بناء واجهة برمجة التطبيقات toxy بالكامل فوق واجهة rocky API. بعبارة أخرى، يمكنك استخدام أي من الطرق والميزات وطبقة الوسيطة المقدمة أصلاً بواسطة rocky.
أنشئ وكيل toxy جديد.
للاطلاع على الخيارات المدعومة، يرجى مراجعة وثائق rocky```js
var toxy = require('toxy')
toxy({ forward: 'http://server.net', timeout: 30000 })
toxy .get('/foo') .poison(toxy.poisons.latency(1000)) .withRule(toxy.rules.contentType('json')) .forward('http://foo.server')
toxy .post('/bar') .poison(toxy.poisons.bandwidth({ bps: 1024 })) .withRule(toxy.rules.probability(50)) .forward('http://bar.server')
toxy .post('/boo') .outgoingPoison(toxy.poisons.bandwidth({ bps: 1024 })) .withRule(toxy.rules.method('GET')) .forward('http://boo.server')
toxy.all('/*')
toxy.listen(3000)
#### toxy#get(path, [ middleware... ])
الإرجاع: `ToxyRoute`
تسجيل مسار جديد لطريقة `GET`.
#### toxy#post(path, [ middleware... ])
الإرجاع: `ToxyRoute`
تسجيل مسار جديد لطريقة `POST`.
#### toxy#put(path, [ middleware... ])
الإرجاع: `ToxyRoute`
تسجيل مسار جديد لطريقة `PUT`.
#### toxy#patch(path, [ middleware... ])
الإرجاع: `ToxyRoute`
تسجيل مسار جديد لطريقة `PATCH`.
#### toxy#delete(path, [ middleware... ])
الإرجاع: `ToxyRoute`
تسجيل مسار جديد لطريقة `DELETE`.
#### toxy#head(path, [ middleware... ])
الإرجاع: `ToxyRoute`
تسجيل مسار جديد لطريقة `HEAD`.
#### toxy#all(path, [ middleware... ])
الإرجاع: `ToxyRoute`
تسجيل مسار جديد لأي طريقة.
#### toxy#poisons `=>` Object
يعرض خريطة تحتوي على السموم المدمجة. اسم مستعار للنموذج الأولي `toxy.poisons`.
#### toxy#rules `=>` Object
يعرض خريطة تحتوي على القواعد المدمجة. اسم مستعار للنموذج الأولي `toxy.rules`.
#### toxy#forward(url)
تحديد عنوان URL لإعادة توجيه حركة المرور الواردة التي يستقبلها الوكيل.
#### toxy#balance(urls)
إعادة التوجيه إلى خوادم متعددة مع الموازنة بينها.
لمزيد من المعلومات، راجع [rocky docs](https://github.com/h2non/rocky#programmatic-api).
#### toxy#replay(url)
تحديد خادم إعادة تشغيل جديد.
يمكنك استدعاء هذه الطريقة عدة مرات لتحديد خوادم إعادة تشغيل متعددة.
لمزيد من المعلومات، راجع [rocky docs](https://github.com/h2non/rocky#programmatic-api).
#### toxy#use(middleware)
توصيل وسيط مخصص.
لمزيد من المعلومات، راجع [rocky docs](https://github.com/h2non/rocky#middleware-layer).
#### toxy#useResponse(middleware)
توصيل وسيط لحركة المرور الصادرة (الاستجابة).
لمزيد من المعلومات، راجع [rocky docs](https://github.com/h2non/rocky#middleware-layer).
#### toxy#useReplay(middleware)
توصيل وسيط لحركة إعادة التشغيل.
لمزيد من المعلومات، راجع [rocky docs](https://github.com/h2non/rocky#middleware-layer).
#### toxy#requestBody(middleware)
اعتراض نص الطلب الوارد. مفيد لتعديله أثناء التنقل.
لمزيد من المعلومات، راجع [rocky docs](https://github.com/h2non/rocky#programmatic-api).
#### toxy#responseBody(middleware)
اعتراض نص الاستجابة الصادرة. مفيد لتعديله أثناء التنقل.
لمزيد من المعلومات، راجع [rocky docs](https://github.com/h2non/rocky#programmatic-api).
#### toxy#middleware()
إرجاع وسيط قياسي لاستخدامه مع connect/express.
#### toxy#host(host)
الكتابة فوق رأس `Host` بقيمة مخصصة. مشابه لخيار `forwardHost`.
#### toxy#redirect(url)
إعادة توجيه حركة المرور إلى عنوان URL المحدد.
#### toxy#findRoute(routeIdOrPath, [ method ])
البحث عن مسار بواسطة المعرف أو المسار والطريقة.
#### toxy#listen(port)
بدء تشغيل خادم HTTP المدمج، والاستماع على منفذ TCP معين.
#### toxy#close([ callback ])
إغلاق خادم HTTP.
#### toxy#poison(poison)
الاسم المستعار: `usePoison`, `useIncomingPoison`
تسجيل سم جديد لإصابة حركة المرور [الواردة](#poisoning-phases).
#### toxy#outgoingPoison(poison)
الاسم المستعار: `useOutgoingPoison`, `responsePoison`
تسجيل سم جديد لإصابة حركة المرور [الصادرة](#poisoning-phases).
#### toxy#rule(rule)
الاسم المستعار: `useRule`
تسجيل قاعدة جديدة.
#### toxy#withRule(rule)
الأسماء المستعارة: `ifRule`, `whenRule`, `poisonRule`, `poisonFilter`
تطبيق قاعدة جديدة لأحدث سم تم تسجيله.
#### toxy#enable(poison)
تفعيل سم بواسطة معرف الاسم.
#### toxy#disable(poison)
تعطيل سم بواسطة معرف الاسم.
#### toxy#remove(poison)
الإرجاع: `boolean`
إزالة سم لحركة المرور الواردة بواسطة معرف الاسم أو مرجع الكائن.
#### toxy#removeOutgoing(poison)
الإرجاع: `boolean`
إزالة سم لحركة المرور الصادرة بواسطة معرف الاسم أو مرجع الكائن.
#### toxy#isEnabled(poison)
الإرجاع: `boolean`
التحقق مما إذا كان السم مفعّلاً بواسطة معرف الاسم.
#### toxy#disableAll()
الاسم المستعار: `disablePoisons`
تعطيل جميع السموم المسجلة.
#### toxy#getPoison(name)
الإرجاع: `Directive|null`
البحث واسترجاع سم مسجل في المكدس بواسطة معرف الاسم.
#### toxy#getIncomingPoison(name)
الإرجاع: `Directive|null`
البحث واسترجاع سم `واردة` مسجل في المكدس بواسطة معرف الاسم.
#### toxy#getOutgoingPoison(name)
الإرجاع: `Directive|null`
البحث واسترجاع سم `صادرة` مسجل في المكدس بواسطة معرف الاسم.
#### toxy#getPoisons()
الإرجاع: `array<Directive>`
إرجاع مصفوفة من السموم المسجلة.
#### toxy#getIncomingPoisons()
الإرجاع: `array<Directive>`
إرجاع مصفوفة من السموم `الواردة` المسجلة.
#### toxy#getOutgoingPoisons()
الإرجاع: `array<Directive>`
إرجاع مصفوفة من السموم `الصادرة` المسجلة.
#### toxy#flush()
الاسم المستعار: `flushPoisons`
إزالة جميع السموم المسجلة لكل من تدفقات حركة المرور الواردة والصادرة.
#### toxy#enableRule(rule)
تفعيل قاعدة بواسطة معرف الاسم.
#### toxy#disableRule(rule)
تعطيل قاعدة بواسطة معرف الاسم.
#### toxy#removeRule(rule)
الإرجاع: `boolean`
إزالة قاعدة بواسطة معرف الاسم.
#### toxy#disableRules()
تعطيل جميع القواعد المسجلة.
#### toxy#isRuleEnabled(rule)
الإرجاع: `boolean`
التحقق مما إذا كانت القاعدة المحددة مفعّلة بواسطة معرف الاسم.
#### toxy#getRule(rule)
الإرجاع: `Directive|null`
البحث واسترجاع قاعدة مسجلة في المكدس بواسطة معرف الاسم.
#### toxy#getRules()
الإرجاع: `array<Directive>`
إرجاع مصفوفة تحتوي على القواعد المسجلة ملفوفة كـ `Directive`.
#### toxy#flushRules()
إزالة جميع القواعد.
### toxy.addPoison(name, fn)
توسيع السموم المدمجة.
### toxy.addRule(name, fn)
توسيع القواعد المدمجة.
### toxy.poisons `=>` Object
يعرض خريطة تحتوي على السموم المدمجة.
### toxy.rules `=>` Object
يعرض خريطة تحتوي على القواعد المدمجة.
### toxy.VERSION `=>` String
الإصدار الدلالي الحالي لـ toxy.
### ToxyRoute
`ToxyRoute` يعرض نفس واجهة الواجهة العامة لـ `Toxy`، ولكنه يضيف بعض [الطرق الإضافية](https://github.com/h2non/rocky#routepath) على مستوى المسار.
الإجراءات الإضافية التي تقوم بها مقابل واجهة برمجة تطبيقات `ToxyRoute` ستكون قابلة للتطبيق فقط على مستوى المسار (متدرج). بعبارة أخرى: أنت تعرف الواجهة بالفعل.
ربما يوضح هذا المثال الشكوك المحتملة:```js
var toxy = require('toxy')
var proxy = toxy()
// Now using the global API
proxy
.forward('http://server.net')
.poison(toxy.poisons.bandwidth({ bps: 1024 }))
.rule(toxy.rules.method('GET'))
// Now create a route
var route = proxy
.get('/foo')
.toPath('/bar') // Route-level API method
.host('server.net') // Route-level API method
.forward('http://new.server.net')
// Now using the ToxyRoute interface
route
.poison(toxy.poisons.bandwidth({ bps: 512 }))
.rule(toxy.rules.contentType('json'))
غلاف مناسب يُستخدم داخليًا للسموم والقواعد.
عادةً لا تحتاج إلى معرفة هذه الواجهة، ولكن لأغراض الاختراق أو الإجراءات منخفضة المستوى قد تكون مفيدة.
الإرجاع: boolean
الإرجاع: boolean
الإرجاع: boolean
الاسم المستعار: filter
الإرجاع: function(req, res, next)
تتبع واجهة toxy HTTP اتفاقيات JSON API، بما في ذلك الربط التشعبي القائم على الموارد.
لحالة استخدام مميزة، راجع مثال خادم الإدارة.```js const toxy = require('toxy')
// Create the toxy admin server var admin = toxy.admin({ cors: true }) admin.listen(9000)
// Create the toxy proxy var proxy = toxy() proxy.listen(3000)
// Add the toxy instance to be managed by the admin server admin.manage(proxy)
// Then configure the proxy proxy .forward('http://my.target.net')
proxy .get('/slow') .poison(toxy.poisons.bandwidth({ bps: 1024 }))
// Handle the rest of the traffic proxy .all('/*') .poison(toxy.poisons.bandwidth({ bps: 1024 * 5 }))
console.log('toxy proxy listening on port:', 3000) console.log('toxy admin server listening on port:', 9000)
لمزيد من التفاصيل حول واجهة برمجة التطبيقات الإدارية البرمجية، انظر [أدناه](#programmatic-api-1).
### التفويض
يمكن حماية واجهة برمجة التطبيقات HTTP من العملاء غير المصرح لهم.
يجب على العملاء المصرح لهم تعريف رمز مفتاح API عبر رؤوس HTTP `API-Key` أو `Authorization`.
لتمكين ذلك، يجب عليك ببساطة تمرير الخيارات التالية إلى خادم الإدارة `toxy`:```js
const toxy = require('toxy')
const opts = { apiKey: 's3cr3t' }
var admin = toxy.admin(opts)
admin.listen(9000)
console.log('protected toxy admin server listening on port:', 9000)
التسلسل الهرمي:
toxy المُدارة
يقبل: application/json
مثال على الحمولة:```js { "name": "method", "options": "GET" }
#### DELETE /servers/:id/rules
#### GET /servers/:id/rules/:id
#### DELETE /servers/:id/rules/:id
### السموم
#### GET /servers/:id/poison
#### POST /servers/:id/poisons
يقبل: `application/json`
مثال على الحمولة:```js
{
"name": "latency",
"phase": "outgoing",
"options": { "jitter": 1000 }
}
يقبل: application/json
مثال على الحمولة:```js { "name": "method", "options": "GET" }
#### DELETE /servers/:id/poisons/:id/rules
#### GET /servers/:id/poisons/:id/rules/:id
#### DELETE /servers/:id/poisons/:id/rules/:id
### المسارات
#### GET /servers/:id/routes
#### POST /servers/:id/routes
يقبل: `application/json`
مثال على الحمولة:```js
{
"path": "/foo", // Required
"method": "GET", // use ALL for all the methods
"forward": "http://my.server", // Optional custom forward server URL
}
يقبل: application/json
مثال للحمولة النافعة:```js { "name": "method", "options": "GET" }
#### DELETE /servers/:id/routes/:id/rules
#### GET /servers/:id/routes/:id/rules/:id
#### DELETE /servers/:id/routes/:id/rules/:id
### تسميم المسار (Route poisons)
#### GET /servers/:id/routes/:id/poisons
#### POST /servers/:id/routes/:id/poisons
يقبل: `application/json`
مثال على الحمولة:```js
{
"name": "latency",
"phase": "outgoing",
"options": { "jitter": 1000 }
}
يقبل: application/json
مثال على البيانات:```js { "name": "method", "options": "GET" }
#### DELETE /servers/:id/routes/:id/poisons/:id/rules
#### GET /servers/:id/routes/:id/poisons/:id/rules/:id
#### DELETE /servers/:id/routes/:id/poisons/:id/rules/:id
### واجهة برمجية
يقدم خادم إدارة HTTP المدمج أيضًا واجهة بسيطة مفتوحة للتوسع وأغراض الاختراق.
على سبيل المثال، يمكنك إضافة برمجيات وسيطة إضافية إلى خادم الإدارة، أو تسجيل مسارات جديدة.
#### toxy.admin([ opts ])
يرجع: `Admin`
**الخيارات المدعومة**:
- **apiKey** `string` - مفتاح API اختياري لحماية الخادم
- **port** `number` - اختياري. منفذ TCP للاستماع
- **cors** `boolean` - تمكين CORS للوصول عبر متصفح الويب
- **middleware** `array<function>` - إضافة برمجيات وسيطة إضافية
- **ssl** `object` - خيارات [TLS](https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener) لخادم HTTPS الخاص بـ Node.js
##### Admin#listen([ port, host ])
بدء الاستماع على الشبكة.
##### Admin#manage(toxy)
إدارة مثيل خادم `toxy`.
##### Admin#find(toxy)
البحث عن مثيل toxy. يقبل معرف خادم toxy أو مثيل toxy.
##### Admin#remove(toxy)
إيقاف إدارة مثيل toxy.
##### Admin#use(...middleware)
تسجيل برمجية وسيطة.
##### Admin#param(...middleware)
تسجيل برمجية وسيطة للمعاملات.
##### Admin#get(path, [ ...middleware ])
تسجيل مسار GET.
##### Admin#post(path, [ ...middleware ])
تسجيل مسار POST.
##### Admin#put(path, [ ...middleware ])
تسجيل مسار PUT.
##### Admin#delete(path, [ ...middleware ])
تسجيل مسار DELETE.
##### Admin#patch(path, [ ...middleware ])
تسجيل مسار PATCH.
##### Admin#all(path, [ ...middleware ])
تسجيل مسار يقبل أي طريقة HTTP.
##### Admin#middleware(req, res, next)
برمجية وسيطة للاستخدام مع connect/express.
##### Admin#close(cb)
إيقاف الخادم.
## الترخيص
MIT - Tomas Aparicio
[](https://sourcegraph.com/github.com/h2non/toxy)