Repository: caddyserver/caddy
File: modules/caddyhttp/reverseproxy/httptransport.go (Go)

Code before:
			}
		}

		// if read/write timeouts are configured and this is a TCP connection,
		// enforce the timeouts by wrapping the connection with our own type
		if tcpConn, ok := conn.(*net.TCPConn); ok && (h.ReadTimeout > 0 || h.WriteTimeout > 0) {
			conn = &tcpRWTimeoutConn{
				TCPConn:      tcpConn,
				readTimeout:  time.Duration(h.ReadTimeout),
				writeTimeout: time.Duration(h.WriteTimeout),
				logger:       caddyCtx.Logger(),
			}
		}

		return conn, nil
	}

	// negotiate any HTTP/SOCKS proxy for the HTTP transport
	var proxy func(*http.Request) (*url.URL, error)
	if h.ForwardProxyURL != "" {
		pUrl, err := url.Parse(h.ForwardProxyURL)
		if err != nil {
			return nil, fmt.Errorf("failed to parse transport proxy url: %v", err)
		}
		caddyCtx.Logger().Info("setting transport proxy url", zap.String("url", h.ForwardProxyURL))
		proxy = func(request *http.Request) (*url.URL, error) {
			return pUrl, nil
		}
	} else {
		proxy = http.ProxyFromEnvironment
	}

	rt := &http.Transport{
		Proxy:                  proxy,
		DialContext:            dialContext,
		MaxConnsPerHost:        h.MaxConnsPerHost,
		ResponseHeaderTimeout:  time.Duration(h.ResponseHeaderTimeout),
		ExpectContinueTimeout:  time.Duration(h.ExpectContinueTimeout),
		MaxResponseHeaderBytes: h.MaxResponseHeaderSize,
		WriteBufferSize:        h.WriteBufferSize,
		ReadBufferSize:         h.ReadBufferSize,
	}

	if h.TLS != nil {
		rt.TLSHandshakeTimeout = time.Duration(h.TLS.HandshakeTimeout)
		var err error
		rt.TLSClientConfig, err = h.TLS.MakeTLSClientConfig(caddyCtx)
		if err != nil {
			return nil, fmt.Errorf("making TLS client config: %v", err)
		}
	}

Review comment (suggestion):
Should just use [`http.ProxyURL`](https://pkg.go.dev/net/http#ProxyURL).

Code after:
			}
		}

		// if read/write timeouts are configured and this is a TCP connection,
		// enforce the timeouts by wrapping the connection with our own type
		if tcpConn, ok := conn.(*net.TCPConn); ok && (h.ReadTimeout > 0 || h.WriteTimeout > 0) {
			conn = &tcpRWTimeoutConn{
				TCPConn:      tcpConn,
				readTimeout:  time.Duration(h.ReadTimeout),
				writeTimeout: time.Duration(h.WriteTimeout),
				logger:       caddyCtx.Logger(),
			}
		}

		return conn, nil
	}

	// negotiate any HTTP/SOCKS proxy for the HTTP transport
	var proxy func(*http.Request) (*url.URL, error)
	if h.ForwardProxyURL != "" {
		pUrl, err := url.Parse(h.ForwardProxyURL)
		if err != nil {
			return nil, fmt.Errorf("failed to parse transport proxy url: %v", err)
		}
		caddyCtx.Logger().Info("setting transport proxy url", zap.String("url", h.ForwardProxyURL))
		proxy = http.ProxyURL(pUrl)
	} else {
		proxy = http.ProxyFromEnvironment
	}

	rt := &http.Transport{
		Proxy:                  proxy,
		DialContext:            dialContext,
		MaxConnsPerHost:        h.MaxConnsPerHost,
		ResponseHeaderTimeout:  time.Duration(h.ResponseHeaderTimeout),
		ExpectContinueTimeout:  time.Duration(h.ExpectContinueTimeout),
		MaxResponseHeaderBytes: h.MaxResponseHeaderSize,
		WriteBufferSize:        h.WriteBufferSize,
		ReadBufferSize:         h.ReadBufferSize,
	}

	if h.TLS != nil {
		rt.TLSHandshakeTimeout = time.Duration(h.TLS.HandshakeTimeout)
		var err error
		rt.TLSClientConfig, err = h.TLS.MakeTLSClientConfig(caddyCtx)
		if err != nil {
			return nil, fmt.Errorf("making TLS client config: %v", err)
		}
	}

	if h.KeepAlive != nil {