Transport của HTTP client trong Go chọn proxy. Hãy sao chép transport chuẩn trước khi thay đổi để những bên khác dùng client mặc định vẫn giữ đường đi hiện tại.

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)
    }
}

Địa chỉ là giá trị mẫu trong tài liệu. Thay bằng IP và cổng của proxy HTTP thật, chẳng hạn một ứng viên từ danh sách proxy HTTP. Ví dụ chỉ dùng thư viện chuẩn của Go; yêu cầu qua proxy HTTP này không cần gói SOCKS hay biến môi trường cho toàn bộ tiến trình.

Vì sao không sửa trực tiếp DefaultTransport?

Transport mặc định được dùng chung. Sửa nó có thể thay đổi hành vi của mã chưa từng yêu cầu dùng proxy của bạn; sửa khi các yêu cầu đang dùng nó còn gây ra vấn đề đồng thời có thể tránh được. Transport riêng đưa đường đi vào cấu hình của chính client này.

http.ProxyURL trả về bộ chọn luôn chọn URL được cung cấp. Điều này khác với bộ chọn môi trường mặc định, vốn xét biến proxy và quy tắc bỏ qua. Nếu bạn muốn thử một mục cụ thể trong danh sách HTTP, bộ chọn tường minh loại bỏ nguồn nhập nhằng đó.

Đóng phản hồi và dùng lại client

Ví dụ đọc hết thân phản hồi rồi đóng nó. Đọc đến cuối giúp transport tái sử dụng kết nối khi có thể. Trong chương trình gửi nhiều yêu cầu qua cùng proxy, giữ lại client và transport thay vì tạo cặp mới cho mỗi yêu cầu.

Thời gian chờ của client không chỉ giới hạn việc mở socket mà còn giới hạn vòng đời yêu cầu, gồm cả đọc thân phản hồi. Vẫn phải xử lý lỗi đọc sau khi Get trả về. Trạng thái như 403 không phải lỗi transport của Go, vì vậy hãy kiểm tra StatusCode riêng với err.

Bài viết liên quan