transport ของ HTTP client ใน 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

บทความที่เกี่ยวข้อง