يختار transport الخاص بعميل HTTP في Go البروكسي. انسخ transport القياسي قبل تعديله حتى يحتفظ مستخدمو العميل الافتراضي الآخرون بمساراتهم الحالية.

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "net/url"
    "time"
)

func main() {
    proxyURL, err := url.Parse("http://203.0.113.10:8080")
    if err != nil {
        log.Fatal(err)
    }

    transport := http.DefaultTransport.(*http.Transport).Clone()
    transport.Proxy = http.ProxyURL(proxyURL)
    defer transport.CloseIdleConnections()

    client := &http.Client{
        Transport: transport,
        Timeout:   15 * time.Second,
    }

    response, err := client.Get("https://example.com/")
    if err != nil {
        log.Fatal(err)
    }
    defer response.Body.Close()

    fmt.Println(response.StatusCode)
    if _, err := io.Copy(io.Discard, response.Body); err != nil {
        log.Fatal(err)
    }
}

العنوان عنصر نائب للتوثيق. استبدله بعنوان IP ومنفذ لبروكسي HTTP حقيقي، مثل مرشح من قائمة بروكسيات HTTP. يستخدم المثال مكتبة Go القياسية فقط؛ ولا يحتاج طلب HTTP هذا عبر البروكسي إلى حزمة SOCKS أو متغير بيئة على مستوى العملية كلها.

لماذا لا نعدّل DefaultTransport مباشرة؟

transport الافتراضي مشترك. قد يؤثر تعديله في شيفرة لم تطلب استخدام البروكسي أصلًا، كما أن تغييره أثناء استخدام الطلبات له يخلق مشكلات تزامن يمكن تجنبها. يجعل transport المخصص المسار جزءًا من إعداد هذا العميل.

يعيد http.ProxyURL محدّدًا يختار دائمًا عنوان URL المقدّم. يختلف ذلك عن محدّد البيئة الافتراضي الذي يراعي متغيرات البروكسي وقواعد التجاوز. إذا أردت اختبار إدخال بعينه من قائمة HTTP، فإن المحدّد الصريح يزيل هذا المصدر للالتباس.

أغلق الاستجابة وأعد استخدام العميل

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

لا تقتصر مهلة العميل على فتح المقبس؛ بل تحدّ أيضًا دورة حياة الطلب، بما في ذلك قراءة جسم الاستجابة. ما زال عليك معالجة أخطاء القراءة بعد عودة Get. حالة مثل 403 ليست خطأ transport في Go، لذا افحص StatusCode بصورة منفصلة عن err.

مقالات ذات صلة