Отделно прокси за HTTP клиент в Go
Клонирайте стандартния транспорт на Go, задайте ProxyURL за избрания IP и не променяйте поведението на другите клиенти.
Транспортът на HTTP клиента в Go избира проксито. Клонирайте стандартния транспорт преди промяна, за да запазят другите потребители на клиента по подразбиране съществуващите си маршрути.
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 директно?
Стандартният транспорт е споделен. Промяната му може да засегне код, който никога не е искал да използва вашето прокси, а промени по време на използването му от заявки създават излишни проблеми с едновременния достъп. Отделният транспорт прави маршрута част от настройките на този клиент.
http.ProxyURL връща селектор, който винаги избира подадения URL. Това се различава от стандартния селектор за средата, който отчита прокси променливите и правилата за заобикаляне. Ако искате да тествате конкретен запис от HTTP списъка, изричният селектор премахва този източник на неяснота.
Затворете отговора и използвайте клиента повторно
Примерът прочита цялото тяло на отговора и го затваря. Прочитането докрай помага на транспорта да използва връзката повторно, когато може. В програма с няколко заявки през едно прокси запазете клиента и транспорта, вместо да създавате нова двойка за всяка заявка.
Времевият лимит на клиента обхваща не само отварянето на сокета, но и жизнения цикъл на заявката, включително четенето на тялото на отговора. Грешките при четене трябва да се обработват и след връщане от Get. Статус като 403 не е транспортна грешка на Go, затова проверявайте StatusCode отделно от err.