Установите в поле proxy.Transport реализацию, которая выводит запрос перед делегированием в транспорт по умолчанию:
package main
import (
"fmt"
"log"
"net/http"
"net/http/httputil"
"net/url"
)
type DebugTransport struct{}
func (DebugTransport) RoundTrip(r *http.Request) (*http.Response, error) {
b, err := httputil.DumpRequestOut(r, false)
if err != nil {
return nil, err
}
fmt.Println(string(b))
return http.DefaultTransport.RoundTrip(r)
}
func main() {
target, _ := url.Parse("https://example.com:443")
log.Printf("forwarding to -> %s\n", target)
proxy := httputil.NewSingleHostReverseProxy(target)
proxy.Transport = DebugTransport{}
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
req.Host = req.URL.Host
proxy.ServeHTTP(w, req)
})
log.Fatal(http.ListenAndServe(":8989", nil))
}
Вывод из этой программы выглядит примерно так:
2018/10/26 13:06:35 forwarding to -> https://example.com:443
GET / HTTP/1.1
Host: example.com:443
User-Agent: HTTPie/0.9.4
Accept: */*
Accept-Encoding: gzip, deflate
X-Forwarded-For: 127.0.0.1
Или, после удаления назначения req.Host:
2018/10/26 13:06:54 forwarding to -> https://example.com:443
GET / HTTP/1.1
Host: localhost:8989
User-Agent: HTTPie/0.9.4
Accept: */*
Accept-Encoding: gzip, deflate
X-Forwarded-For: 127.0.0.1
Поскольку заголовок хоста очень часто используется веб-серверами для направления запроса на правильный виртуальный хост или внутренний сервер, имеет смысл, что неожиданный хостзаголовок ("localhost: 8989" в приведенном выше примере) заставляет сервер ответить 404.
Установка заголовка узла с помощью httputil.ReverseProxy обычно выполняется с помощью функции Director
:
target, err := url.Parse("https://example.com:443")
if err != nil {
log.Fatal(err)
}
log.Printf("forwarding to -> %s\n", target)
proxy := httputil.NewSingleHostReverseProxy(target)
d := proxy.Director
proxy.Director = func(r *http.Request) {
d(r) // call default director
r.Host = target.Host // set Host header as expected by target
}
log.Fatal(http.ListenAndServe(":8989", proxy))