diff --git a/main.go b/main.go index 5d571c2..fabe050 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,7 @@ import ( "net/url" "io/ioutil" "log" + "strings" ) var serverAddress, serverCert, serverKey, clientCAFile, targetURL string @@ -23,6 +24,43 @@ func init() { } +// stolen from NewSingleHostReverseProxy +func singleJoiningSlash(a, b string) string { + aslash := strings.HasSuffix(a, "/") + bslash := strings.HasPrefix(b, "/") + switch { + case aslash && bslash: + return a + b[1:] + case !aslash && !bslash: + return a + "/" + b + } + return a + b +} + +// stolen from NewSingleHostReverseProxy +func NewCertainlyReverseProxy(target *url.URL) *httputil.ReverseProxy { + targetQuery := target.RawQuery + director := func(req *http.Request) { + req.URL.Scheme = target.Scheme + req.URL.Host = target.Host + req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path) + if targetQuery == "" || req.URL.RawQuery == "" { + req.URL.RawQuery = targetQuery + req.URL.RawQuery + } else { + req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery + } + if _, ok := req.Header["User-Agent"]; !ok { + // explicitly disable User-Agent so it's not set to default value + req.Header.Set("User-Agent", "") + } + + // this is probably unsafe ;) + clientDN := req.TLS.PeerCertificates[len(req.TLS.PeerCertificates)-1].Subject.String() + req.Header.Set("Certainly-Client-DN", clientDN) + } + return &httputil.ReverseProxy{Director: director} +} + func main() { clientCAData, err := ioutil.ReadFile(clientCAFile) if err != nil { @@ -49,11 +87,9 @@ func main() { }, } - proxy := httputil.NewSingleHostReverseProxy(targetURL) - proxyServer := http.Server{ Addr: serverAddress, - Handler: proxy, + Handler: NewCertainlyReverseProxy(targetURL), TLSConfig: serverTLSConfig, TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0), }