پردازندههای CONNECT در Node.js باید بافر head را حفظ کنند
سوکت CONNECT و بافر head را در مرز HTTP به تونل مدیریت کنید و بایتهایی را که پیشتر فراتر از سرآیندها خوانده شدهاند حفظ کنید.
یک سرور HTTP در Node درخواست پروکسی معمولی را از طریق callback درخواست پردازش میکند. CONNECT مسیر دیگری را میرود: سرور رویداد connect را همراه با درخواست، سوکت کلاینت و یک بافر head منتشر میکند.
آن رویداد، نقطه تحویل میان تجزیه HTTP و یک تونل است. هیچ شیء ServerResponse معمولی برای ادامه استفاده در ترافیک تونلشده وجود ندارد.
| آرگومان | چه چیزی حمل میکند |
|---|---|
req | درخواست CONNECT، شامل اختیار مقصد و سرآیندهای آن |
clientSocket | اتصال بازگشتی به کلاینت |
head | دادههای تونل که Node پیشتر فراتر از سرآیندهای HTTP خوانده است، احتمالاً خالی |
پیش از بازفرستادن بایتها تصمیم HTTP را کامل کنید
میزبان و پورت درخواستی را اعتبارسنجی کنید، سیاست دسترسی و احراز هویت پروکسی را اعمال کنید و اتصال بالادست را برقرار کنید. CONNECT اختیاری مانند service.example:443 را شناسایی میکند؛ آن قالب را با در نظر گرفتن اختیارهای IPv6 تجزیه کنید، نه اینکه کورکورانه روی هر دونقطه تقسیم کنید.
وقتی تونل پذیرفته شد، پاسخ موفق HTTP را همراه با سطر خالی پایانی آن بفرستید. سپس هر بایت head را پیش از ادامه با بایتهای بعدی سوکت کلاینت به بالادست بفرستید. افزودن یک شنونده داده جدید نمیتواند بافری را که پیشتر جداگانه به پردازنده تحویل شده بازیابی کند.
مثال رسمی تونلسازی Node آن تحویل را با serverSocket.write(head) پیش از اتصال دو جهت جریان انجام میدهد. مثال کوچکش گذار را نشان میدهد؛ پروکسی مستقر نیز به تلاشهای اتصال محدود، کنترلهای دسترسی و مدیریت چرخه عمر نیاز دارد.
پس از موفقیت، بایتها به پروتکل سرویس تعلق دارند
پاسخ موفق CONNECT اتصال را به یک جریان بایت تبدیل میکند. اگر مقصد یک سایت HTTPS باشد، تبادل TLS آن درون همان جریان انجام میشود. صرفاً تونل کردن آن نیازی به صدور گواهی جایگزین وبسایت توسط پروکسی ندارد.
پیش از پذیرش CONNECT، یک خطای HTTP میتواند توضیح دهد چرا رد شده است. پس از پذیرش، نوشتن یک HTTP 500 در جریان، بایتها را به پروتکل تونل تزریق میکند. در عوض، در خرابیهای بعدی اتصالهای مناسب را پایان دهید یا نابود کنید.
هر دو جهت را با مدیریت جریان با آگاهی از فشار برگشتی به هم وصل کنید و تصمیم بگیرید رویدادهای end، error و close چگونه همتای مقابل را پایان میدهند. بافر head اولیه را بخشی از همان مدل مالکیت نگه دارید؛ این داده برنامه است، نه سرآیندهای HTTP اضافی برای دور ریختن.