Skip to content

Instantly share code, notes, and snippets.

@epelc
Created April 18, 2020 04:01
Show Gist options
  • Save epelc/cc286ad0fd7878fb176a89f2af1177b6 to your computer and use it in GitHub Desktop.
Save epelc/cc286ad0fd7878fb176a89f2af1177b6 to your computer and use it in GitHub Desktop.
Override http.Client host to ip address or separate host
// Override http.Client host to ip address or separate host
// Basically a programic equivalent of `/etc/hosts` in go for http clients
package main
import (
"context"
"fmt"
"io/ioutil"
"net"
"net/http"
"time"
)
// hostOverrides is a map of hosts or ips to replace override with the value given.
// The value of each key can be an ip address or separate hostname to lookup.
var hostOverrides = map[string]string{
"google.com": "192.168.0.1",
}
func main() {
myClient := &http.Client{
Transport: NewOverrideHostTransport(hostOverrides),
}
resp, err := myClient.Get("https://google.com")
if err != nil {
panic("error making req: " + err.Error())
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic("error reading resp: " + err.Error())
}
fmt.Println("Response")
fmt.Println(string(data))
}
// NewOverrideHostTransport creates a new transport which overrides hostnames.
func NewOverrideHostTransport(overrides map[string]string) http.RoundTripper {
// Start with default transport since it has many default proxy and timeout options you want.
myTransport := http.DefaultTransport.(*http.Transport).Clone()
myDialer := &net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}
myTransport.DialContext = func(ctx context.Context, network, address string) (net.Conn, error) {
fmt.Println("Resolving address:", network, address)
// address contains `host:port` ie `google.com:443`
host, port, err := net.SplitHostPort(address)
if err != nil {
return nil, err
}
// Lookup to see if we have a host override
newHost, ok := overrides[host]
if !ok {
fmt.Println("No override found for host, using original", host)
return myDialer.DialContext(ctx, network, address)
}
overrideAddress := net.JoinHostPort(newHost, port)
fmt.Println("Overriding address:", address, overrideAddress)
return myDialer.DialContext(ctx, network, overrideAddress)
}
return myTransport
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment