Δώστε σε έναν HTTP client του Go τον δικό του proxy
Κλωνοποιήστε τον προεπιλεγμένο transport του Go, ορίστε ProxyURL για την επιλεγμένη IP και μην αλλάξετε τη συμπεριφορά άλλων πελατών.
Ο transport ενός HTTP client του Go επιλέγει τον proxy. Κλωνοποιήστε τον τυπικό transport πριν τον αλλάξετε, ώστε οι άλλοι χρήστες του προεπιλεγμένου client να κρατήσουν την υπάρχουσα δρομολόγησή τους.
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 proxy, όπως έναν υποψήφιο από τη λίστα HTTP proxy. Το παράδειγμα χρησιμοποιεί μόνο την τυπική βιβλιοθήκη του Go· για αυτό το αίτημα μέσω HTTP proxy δεν απαιτείται πακέτο SOCKS ή μεταβλητή περιβάλλοντος για όλη τη διεργασία.
Γιατί να μην αλλάξετε απευθείας τον DefaultTransport;
Ο προεπιλεγμένος transport είναι κοινόχρηστος. Η αλλαγή του μπορεί να επηρεάσει κώδικα που δεν ζήτησε ποτέ τον proxy σας, ενώ αλλαγές όταν τον χρησιμοποιούν αιτήματα δημιουργούν αποφεύξιμα προβλήματα ταυτόχρονης εκτέλεσης. Ένας αποκλειστικός transport κάνει τη διαδρομή μέρος της ρύθμισης αυτού του client.
Το http.ProxyURL επιστρέφει έναν επιλογέα που επιλέγει πάντα το δοσμένο URL. Διαφέρει από τον προεπιλεγμένο επιλογέα περιβάλλοντος, που λαμβάνει υπόψη μεταβλητές proxy και κανόνες παράκαμψης. Αν θέλετε να δοκιμάσετε μια συγκεκριμένη εγγραφή της λίστας HTTP, ο ρητός επιλογέας αφαιρεί αυτή την πηγή αμφισημίας.
Κλείστε την απόκριση και επαναχρησιμοποιήστε τον client
Το παράδειγμα διαβάζει ολόκληρο το σώμα απόκρισης και το κλείνει. Η ανάγνωση ως το τέλος βοηθά τον transport να επαναχρησιμοποιήσει τη σύνδεση όταν μπορεί. Σε πρόγραμμα με πολλά αιτήματα μέσω του ίδιου proxy, κρατήστε client και transport αντί να δημιουργείτε νέο ζεύγος για κάθε αίτημα.
Το χρονικό όριο του client δεν καλύπτει μόνο το άνοιγμα του socket· περιορίζει και τον κύκλο του αιτήματος, μαζί με την ανάγνωση του σώματος απόκρισης. Τα σφάλματα ανάγνωσης χρειάζονται χειρισμό και μετά την επιστροφή του Get. Μια κατάσταση όπως η 403 δεν είναι σφάλμα transport του Go, οπότε εξετάστε το StatusCode χωριστά από το err.