Assegna un proxy dedicato a un client HTTP Go
Clona il trasporto predefinito di Go, imposta ProxyURL per l’IP scelto ed evita di modificare il comportamento degli altri client.
È il trasporto del client HTTP Go a scegliere il proxy. Clona il trasporto standard prima di modificarlo, così gli altri utenti del client predefinito mantengono le proprie rotte.
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)
}
}
L’indirizzo è un segnaposto di documentazione. Sostituiscilo con IP e porta di un proxy HTTP reale, per esempio un candidato della lista di proxy HTTP. L’esempio usa soltanto la libreria standard di Go; questa richiesta tramite proxy HTTP non richiede pacchetti SOCKS né variabili d’ambiente per l’intero processo.
Perché non modificare direttamente DefaultTransport?
Il trasporto predefinito è condiviso. Modificarlo può cambiare il comportamento di codice che non ha mai chiesto di usare il tuo proxy; farlo mentre le richieste lo usano introduce anche problemi di concorrenza evitabili. Un trasporto dedicato inserisce la rotta nella configurazione di questo client.
http.ProxyURL restituisce un selettore che sceglie sempre l’URL fornito. È diverso dal selettore d’ambiente predefinito, che considera le variabili proxy e le regole di esclusione. Se vuoi provare una voce precisa della lista HTTP, il selettore esplicito elimina questa fonte di ambiguità.
Chiudi la risposta e riutilizza il client
L’esempio legge interamente il corpo della risposta e lo chiude. Leggerlo fino in fondo aiuta il trasporto a riutilizzare una connessione quando possibile. Se il programma fa più richieste attraverso lo stesso proxy, conserva client e trasporto anziché creare una nuova coppia a ogni richiesta.
Il timeout del client non copre soltanto l’apertura del socket: limita anche il ciclo della richiesta, inclusa la lettura del corpo della risposta. Gli errori di lettura vanno ancora gestiti dopo il ritorno di Get. Uno stato come 403 non è un errore del trasporto Go, quindi controlla StatusCode separatamente da err.