Я пытаюсь написать обратный прокси в golang, который повторно использует прокси, но я получаю нулевой указатель по причине, которую я не вижу.
type Configuration struct {
Proxies map[string]Proxy `mapstructure:"proxies"`
Port int `mapstructure:"port"`
}
type Proxy struct {
Upstream string `mapstructure:"upstream"`
SkipVerify bool `mapstructure:"tls-skip-verify"`
HostProxy *httputil.ReverseProxy
}
Это Структуры, которые я загружаю. Затем я перебираю карту, чтобы создать объект ReverseProxy в структуре прокси и запустить сервис.
for host, proxy := range config.Proxies {
log.Printf("Loading proxies for: %s", host)
log.Printf("Upstream: %s", proxy.Upstream)
log.Printf("SkipVerify: %t", proxy.SkipVerify)
remoteURL, err := url.Parse(proxy.Upstream)
if err != nil {
log.Fatalf("Unable to parse target: %v", err)
}
log.Infof("Remote : %v", remoteURL)
proxy.HostProxy = httputil.NewSingleHostReverseProxy(remoteURL)
proxy.HostProxy.Transport = &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 15 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: &tls.Config{InsecureSkipVerify: proxy.SkipVerify},
}
log.Print(proxy.HostProxy.Transport)
}
log.Info("Starting Up on Port", config.Port)
http.Handle("/", &config)
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(config.Port), &config))
Когда он вызывается, я обрабатываю его так:
func (config *Configuration) ServeHTTP(w http.ResponseWriter, r *http.Request) {
host := r.Host
r.Host = r.URL.Host
log.Info(config)
if proxy, ok := config.Proxies[host]; ok {
log.Infof("Processing request for %s", host)
log.Printf("Upstream: %s", proxy.Upstream)
log.Printf("SkipVerify: %t", proxy.SkipVerify)
log.Print(proxy.HostProxy.Transport)
proxy.HostProxy.ServeHTTP(w, r)
} else {
w.Write([]byte("403: Host forbidden " + host))
}
}
Но это генерирует исключения, что объект proxy.HostProxy имеет значение nil. Все остальные данные сохраняются и регистрируются правильно. Такие как proxy.Upstream и proxy.SkipVerify.