Go
Route Go's net/http client through NyxonProxies: http.ProxyURL with credentials, rotation, sticky sessions, SOCKS5, environment variables and errors.
Go's standard library handles authenticated proxies on its own. Put the credentials in the proxy URL, hand it to the transport, and net/http sends them to the gateway for every connection.
Basic request
package main
import (
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
proxyURL, err := url.Parse("http://USERNAME:[email protected]:8080")
if err != nil {
panic(err)
}
client := &http.Client{
Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
Timeout: 30 * time.Second,
}
resp, err := client.Get("https://api.ipify.org")
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, string(body))
}The proxy URL starts with http:// even for HTTPS sites. The transport opens a tunnel through the gateway and runs TLS to the site inside it. Create the client once and reuse it.
A new IP on every request
The transport keeps connections open and reuses them, so requests to the same site share one IP. Turn keep-alives off and every request opens a new connection, which gets a new IP on a rotating username:
package main
import (
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
proxyURL, _ := url.Parse("http://USERNAME:[email protected]:8080")
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyURL),
DisableKeepAlives: true,
},
Timeout: 30 * time.Second,
}
for i := 0; i < 3; i++ {
resp, err := client.Get("https://api.ipify.org")
if err != nil {
panic(err)
}
body, _ := io.ReadAll(resp.Body)
resp.Body.Close()
fmt.Println(string(body))
}
}Country and sticky session
Targeting and sessions go in the username. Build the URL with url.UserPassword, which also takes care of special characters in the password:
package main
import (
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func stickyClient(country string, minutes int) *http.Client {
b := make([]byte, 4)
rand.Read(b)
user := fmt.Sprintf("USERNAME-country-%s-session-%s-time-%d", country, hex.EncodeToString(b), minutes)
proxyURL := &url.URL{
Scheme: "http",
User: url.UserPassword(user, "PASSWORD"),
Host: "geo.gw.nyxon.sh:8080",
}
return &http.Client{
Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
Timeout: 30 * time.Second,
}
}
func main() {
client := stickyClient("de", 10)
for i := 0; i < 2; i++ {
resp, err := client.Get("https://api.ipify.org")
if err != nil {
panic(err)
}
body, _ := io.ReadAll(resp.Body)
resp.Body.Close()
fmt.Println(string(body))
}
}Both requests print the same German IP for up to 10 minutes. See Rotating and sticky sessions.
SOCKS5
net/http supports SOCKS5 proxies too. Change the scheme and the port:
proxyURL, _ := url.Parse("socks5://USERNAME:[email protected]:1080")
client := &http.Client{
Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
Timeout: 30 * time.Second,
}Go sends the hostname to the gateway, so DNS is resolved on the proxy side.
Environment variables
Go's default client, http.DefaultClient, reads HTTPS_PROXY, HTTP_PROXY and NO_PROXY. A transport you create yourself uses them when you set Proxy: http.ProxyFromEnvironment. Go never sends localhost or loopback addresses through a proxy. See Environment variables.
Errors
| Error | Cause |
|---|---|
Proxy Authentication Required | Wrong username or password, on an HTTPS site. |
A response with status 407 | The same mistake on a plain http:// site. Check resp.StatusCode. |
proxyconnect tcp: followed by a dial error | Wrong host or port, or a firewall. |
parse ...: invalid port ... after host from url.Parse | Special characters in the password. Build the URL with url.UserPassword. |
More in Error codes and Troubleshooting.
Last updated
Still stuck?
People answer the live chat around the clock. Send the proxy line you used (without the password) and the error you see.