פרוקסי ייעודי ללקוח HTTP ב-Go
שכפלו את ה-transport המוגדר כברירת מחדל ב-Go, הגדירו ProxyURL עבור ה-IP הנבחר ואל תשנו את התנהגות הלקוחות האחרים.
ה-transport של לקוח HTTP ב-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.