
مكتبة وكيل HTTP/HTTPS قابلة للتخصيص للغة Go، تدعم إعادة التوجيه العادية، ونفق CONNECT، واعتراض MITM لاتصالات TLS، والتعديل البرمجي للطلبات والاستجابات.
GoProxy هي مكتبة لإنشاء خادم وكيل HTTP/HTTPS مخصص باستخدام
Go (المعروفة أيضًا باسم Golang)، مع توفر عدة إعدادات قابلة للتهيئة.
الهدف من هذا المشروع هو تقديم خادم وكيل محسّن، قابل للاستخدام مع
كمية معقولة من حركة المرور، لكنه في الوقت نفسه قابل للتخصيص وللبرمجة.
الوكيل نفسه هو ببساطة معالج net/http، لذا يمكنك إضافة عدة
وسطاء (middlewares) فوقه (مثل استعادة panic، والتسجيل logging، والضغط compression، وما إلى ذلك). ويمكن
دمجه بسهولة مع أي مكتبة شبكات HTTP أخرى.
لاستخدام goproxy، يجب على المستخدم ضبط متصفحه (أو أي عميل آخر)
لاستخدام goproxy كوكيل HTTP.
إليك كيفية القيام بذلك في Chrome
وفي Firefox.
إذا قررت البدء بمثال base، فإن عنوان URL الذي يجب استخدامه
كوكيل هو localhost:8080، وهو الافتراضي في مثالنا.
كما يجب عليك الوثوق
بشهادة CA الخاصة بالوكيل، لتجنب أي مشكلة في الشهادات لدى العملاء.
مضيفين محددين، بمقارنة مساواة واحدة أو بتقييم تعبير نمطي (regex)الطلبات والاستجابات قبل إرسالها إلى المتصفحhttp.Transport مخصص لتنفيذ الطلبات إلى الخادم الهدفذاكرة تخزين مؤقت لشهادات MITM، لإعادة استخدامها لاحقًا لطلبات أخرى إلى نفس المضيف، مما يوفر طاقة المعالجة (CPU). غير مفعّلة افتراضيًا، لكن يجب استخدامها في الإنتاج!معالج مخصص، عندما يكون الهدف مسارًا نسبيًا (مثل /ping)Loggerتعطيل تطبيع (canonicalization) ترويسات طلبات HTTP، بتعيين PreventCanonicalization إلى trueهل تستخدم شركتك GoProxy؟ ساعدنا في إبقاء المشروع مُصانًا وبصحة جيدة! دعم GoProxy يتيح لنا تخصيص المزيد من الوقت لإصلاح الأخطاء البرمجية وإضافة ميزات جديدة. في المقابل، إذا اخترت خطة داعم ذهبي (Gold Supporter) أو خطة مؤسسات (Enterprise)، فسنعرض شعار شركتك هنا بكل فخر.
إذا كنت بحاجة إلى دمج GoProxy في مشروعك، أو كنت بحاجة إلى بعض الميزات المخصصة للاحتفاظ بها في نسختك المعدلة (fork)، يمكنك التواصل مع Erik (المشرف الحالي) عبر البريد الإلكتروني، ويمكنكما مناقشة كيف يمكنه مساعدتك كمستشار مستقل مدفوع الأجر.
إذا واجهت أي مشكلة، أو كان لديك اقتراح، أو وجدت خطأ برمجيًا، فلا تتردد في التواصل
عبر فتح issue على GitHub.
هذا مشروع مفتوح المصدر يُدار بواسطة متطوعين، ويسعدنا
مناقشة أي شيء يمكن أن يحسّنه.
تأكد من شرح كل شيء، بما في ذلك السبب وراء المشكلة
وما تريد تغييره، لتسهيل فهم المشكلة.
يمكنك أيضًا فتح Pull Request مباشرة، إذا كان تغييرًا برمجيًا صغيرًا، لكن
يجب أن تشرح كل شيء في الوصف.
إذا فتحت طلب سحب باسم refactoring مع تغيير 5,000 سطر،
فلن ندمجه... :D
كود هذا المشروع مُصدَر تحت رخصة BSD 3-Clause،
مما يجعله مفيدًا للاستخدامات التجارية أيضًا.
إذًا، لقد قمت بإدخال ودمج GoProxy في أحد مشاريعك الشخصية أو في مشروع داخل الشركة التي تعمل بها.
يسعدنا الاطلاع على حلول إبداعية جديدة صُنعت بهذه المكتبة،
فلا تتردد في التواصل مع المشرف المذكور أعلاه عبر البريد الإلكتروني، لشرح
لماذا وجدت هذا المشروع مفيدًا لاحتياجاتك.
إذا كنت قد وقّعت اتفاقية عدم إفصاح (NDA) مع الشركة،
يمكنك أن تقترح عليهم كتابة تدوينة على موقعهم الرسمي حول
هذا الموضوع، بحيث تكون هذه المعلومات علنية باختيارهم، ويمكنك
مشاركة رابط التدوينة معنا :)
الغرض من دراسات الحالة هو مشاركة المجتمع لماذا جميع
المساهمين في هذا المشروع يحسّنون العالم بمساعدتهم وما
الذي يبنيه الناس باستخدامه.
تستخدم قاعدة الكود فحصًا آليًا (lint) على كود طلب السحب (Pull Request) الخاص بك. قبل فتحه، يجب التحقق من أن تغييراتك تحترمه، بتشغيل أداة الفحص على جهازك المحلي، حتى لا تكون هناك أي مفاجآت.
لتثبيت أداة الفحص:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
سيؤدي هذا إلى إنشاء ملف تنفيذي في مجلد $GOPATH/bin الخاص بك
($GOPATH هو متغير بيئة، عادةً
تكون قيمته مكافئة لـ ~/go، تحقق من قيمته على جهازك إذا
لم تكن متأكدًا منه).
تأكد من تضمين مجلد bin في مسار الصدفة (shell) الخاصة بك، لتتمكن من
استخدام أمر golangci-lint run مباشرة.
للحصول على لمحة عن goproxy، إليك وكيل HTTP/HTTPS أساسي
يقوم فقط بتمرير البيانات إلى الوجهة:
package main
import (
"log"
"net/http"
"github.com/elazarl/goproxy"
)
func main() {
proxy := goproxy.NewProxyHttpServer()
proxy.Verbose = true
log.Fatal(http.ListenAndServe(":8080", proxy))
}
يضيف هذا السطر ترويسة X-GoProxy: yxorPoG-X إلى جميع الطلبات المرسلة عبر الوكيل،
قبل إرسالها إلى الوجهة:
proxy.OnRequest().DoFunc(
func(r *http.Request,ctx *goproxy.ProxyCtx)(*http.Request,*http.Response) {
r.Header.Set("X-GoProxy","yxorPoG-X")
return r,nil
})
عندما يكون مدخل OnRequest() فارغًا، ستقوم الدالة المحددة في DoFunc
بمعالجة جميع الطلبات الواردة إلى الوكيل. في هذه الحالة، ستضيف
ترويسة إلى الطلب وتعيده إلى المتصل.
سيرسل الوكيل الطلب المعدل إلى الوجهة.
يمكنك أيضًا استخدام Do بدلاً من DoFunc، إذا قمت بتنفيذ الواجهة
المحددة في النوع الخاص بك.
⚠️ لاحظ أننا أعدنا قيمة nil كاستجابة. إذا لم تكن الاستجابة المعادة nil، فسيتجاهل goproxy الطلب ويرسل الاستجابة المحددة إلى العميل.
رفض الاتصالات بـ www.reddit.com بين الساعة 8 و17 بالتوقيت المحلي للخادم:
proxy.OnRequest(goproxy.DstHostIs("www.reddit.com")).DoFunc(
func(req *http.Request,ctx *goproxy.ProxyCtx)(*http.Request,*http.Response) {
if h,_,_ := time.Now().Clock(); h >= 8 && h <= 17 {
resp := goproxy.NewResponse(req, goproxy.ContentTypeText, http.StatusForbidden, "Don't waste your time!")
return req, resp
}
return req, nil
})
يعيد DstHostIs ReqCondition، وهي دالة تستقبل *http.Request
وتعيد قيمة منطقية تتحقق مما إذا كان الطلب يفي بالشرط (وسيتم معالجته).
سيعيد DstHostIs("www.reddit.com") ReqCondition تعيد true
عندما يكون الطلب موجهًا إلى "www.reddit.com".
فحص مساواة المضيف غير حساس لحالة الأحرف، ليعكس سلوك
خوادم DNS، لذا حتى إذا كتب المستخدم "www.rEdDit.com"، فستستوفي
المقارنة الشرط.
عندما تكون الساعة بين 8:00 صباحًا و5:59 مساءً، نعيد مباشرة
استجابة في DoFunc()، فلن يستقبل الوجهة البعيدة
الطلب وسيتلقى العميل استجابة "لا تضيّع وقتك!".
import "github.com/elazarl/goproxy"
توجد بعض أمثلة استخدام الوكيل في مجلد examples، والتي
تغطي الحالات الأكثر شيوعًا. ألقِ نظرة عليها وحظًا سعيدًا!