Разрешение имён SOCKS5 в HTTP-клиенте Go
Почему socks5 и socks5h не выбирают разные режимы DNS в стандартном HTTP-транспорте Go.
В стандартном HTTP-транспорте Go 1.27.3 схемы socks5 и socks5h одинаково обрабатывают имя цели. Цель с именем хоста передаётся прокси как имя хоста. Переключение схем не меняет локальный DNS на удалённый и обратно, как в curl.
package main
import (
"fmt"
"log"
"net/http"
"net/url"
"time"
)
func main() {
proxyURL, err := url.Parse("socks5://203.0.113.10:1080")
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)
}
Замените адрес для документации своим SOCKS5-узлом; кандидатов можно посмотреть в списке SOCKS5-прокси. Пример использует собственный транспорт net/http; другая библиотека Go может работать иначе.
Два имени всё же нужно различать. Числовой адрес прокси не требует поиска его хоста; прокси с именем нужно найти локально до отправки запроса SOCKS. Числовая цель не имеет имени для разрешения и не демонстрирует обработку имён хостов. Чтобы проверить реальный выбор SOCKS, посмотрите, несёт ли поле назначения имя или адрес.
Стандартный транспорт поддерживает схемы прокси http, https, socks5 и socks5h. Общая пометка SOCKS не доказывает поддержку SOCKS5 узлом. Этот пример передаёт HTTP по TCP и не проверяет ни другие команды SOCKS, ни ретрансляцию UDP.