Created
April 18, 2020 04:01
-
-
Save epelc/cc286ad0fd7878fb176a89f2af1177b6 to your computer and use it in GitHub Desktop.
Override http.Client host to ip address or separate host
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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