In Go 1.27.3's standard HTTP transport, socks5 and socks5h do the same destination-name handling. A hostname target is sent as a hostname to the proxy. Switching those schemes does not toggle local versus remote DNS as it does in 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)
}

Replace the documentation address with your SOCKS5 endpoint; candidates can be browsed in the SOCKS5 proxy list. The example uses net/http's own transport; another Go library can implement different behavior.

There are still two names to distinguish. A numeric proxy address needs no proxy-host lookup; a named proxy must be found locally before a SOCKS request can be sent. A numeric destination has no target name to resolve and cannot demonstrate hostname handling. To inspect the actual SOCKS choice, check whether the destination field carries a name or address.

The standard transport supports http, https, socks5 and socks5h proxy schemes. A generic SOCKS label does not establish SOCKS5 support at an endpoint. This example sends HTTP over TCP and tests neither other SOCKS commands nor UDP relaying.

Related articles