type ProxyRequest … // SetURL routes the outbound request to the scheme, host, and base path // provided in target. If the target's path is "/base" and the incoming // request was for "/dir", the target request will be for "/base/dir". // // SetURL rewrites the outbound Host header to match the target's host. // To preserve the inbound request's Host header (the default behavior // of [NewSingleHostReverseProxy]): // // rewriteFunc := func(r *httputil.ProxyRequest) { // r.SetURL(url) // r.Out.Host = r.In.Host // } func (r *ProxyRequest) SetURL(target *url.URL) { … } // SetXForwarded sets the X-Forwarded-For, X-Forwarded-Host, and // X-Forwarded-Proto headers of the outbound request. // // - The X-Forwarded-For header is set to the client IP address. // - The X-Forwarded-Host header is set to the host name requested // by the client. // - The X-Forwarded-Proto header is set to "http" or "https", depending // on whether the inbound request was made on a TLS-enabled connection. // // If the outbound request contains an existing X-Forwarded-For header, // SetXForwarded appends the client IP address to it. To append to the // inbound request's X-Forwarded-For header (the default behavior of // [ReverseProxy] when using a Director function), copy the header // from the inbound request before calling SetXForwarded: // // rewriteFunc := func(r *httputil.ProxyRequest) { // r.Out.Header["X-Forwarded-For"] = r.In.Header["X-Forwarded-For"] // r.SetXForwarded() // } func (r *ProxyRequest) SetXForwarded() { … } type ReverseProxy … type BufferPool … func singleJoiningSlash(a, b string) string { … } func joinURLPath(a, b *url.URL) (path, rawpath string) { … } // NewSingleHostReverseProxy returns a new [ReverseProxy] that routes // URLs to the scheme, host, and base path provided in target. If the // target's path is "/base" and the incoming request was for "/dir", // the target request will be for /base/dir. // // NewSingleHostReverseProxy does not rewrite the Host header. // // To customize the ReverseProxy behavior beyond what // NewSingleHostReverseProxy provides, use ReverseProxy directly // with a Rewrite function. The ProxyRequest SetURL method // may be used to route the outbound request. (Note that SetURL, // unlike NewSingleHostReverseProxy, rewrites the Host header // of the outbound request by default.) // // proxy := &ReverseProxy{ // Rewrite: func(r *ProxyRequest) { // r.SetURL(target) // r.Out.Host = r.In.Host // if desired // }, // } func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy { … } func rewriteRequestURL(req *http.Request, target *url.URL) { … } func copyHeader(dst, src http.Header) { … } var hopHeaders … func (p *ReverseProxy) defaultErrorHandler(rw http.ResponseWriter, req *http.Request, err error) { … } func (p *ReverseProxy) getErrorHandler() func(http.ResponseWriter, *http.Request, error) { … } // modifyResponse conditionally runs the optional ModifyResponse hook // and reports whether the request should proceed. func (p *ReverseProxy) modifyResponse(rw http.ResponseWriter, res *http.Response, req *http.Request) bool { … } func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { … } var inOurTests … // shouldPanicOnCopyError reports whether the reverse proxy should // panic with http.ErrAbortHandler. This is the right thing to do by // default, but Go 1.10 and earlier did not, so existing unit tests // weren't expecting panics. Only panic in our own tests, or when // running under the HTTP server. func shouldPanicOnCopyError(req *http.Request) bool { … } // removeHopByHopHeaders removes hop-by-hop headers. func removeHopByHopHeaders(h http.Header) { … } // flushInterval returns the p.FlushInterval value, conditionally // overriding its value for a specific request/response. func (p *ReverseProxy) flushInterval(res *http.Response) time.Duration { … } func (p *ReverseProxy) copyResponse(dst http.ResponseWriter, src io.Reader, flushInterval time.Duration) error { … } // copyBuffer returns any write errors or non-EOF read errors, and the amount // of bytes written. func (p *ReverseProxy) copyBuffer(dst io.Writer, src io.Reader, buf []byte) (int64, error) { … } func (p *ReverseProxy) logf(format string, args ...any) { … } type maxLatencyWriter … func (m *maxLatencyWriter) Write(p []byte) (n int, err error) { … } func (m *maxLatencyWriter) delayedFlush() { … } func (m *maxLatencyWriter) stop() { … } func upgradeType(h http.Header) string { … } func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, res *http.Response) { … } type switchProtocolCopier … func (c switchProtocolCopier) copyFromBackend(errc chan<- error) { … } func (c switchProtocolCopier) copyToBackend(errc chan<- error) { … } func cleanQueryParams(s string) string { … } func ishex(c byte) bool { … }