traefik/pkg/proxy/httputil/builder.go
2024-10-17 09:12:04 +02:00

54 lines
1.8 KiB
Go

package httputil
import (
"crypto/tls"
"fmt"
"net/http"
"net/url"
"time"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/metrics"
)
// TransportManager manages transport used for backend communications.
type TransportManager interface {
Get(name string) (*dynamic.ServersTransport, error)
GetRoundTripper(name string) (http.RoundTripper, error)
GetTLSConfig(name string) (*tls.Config, error)
}
// ProxyBuilder handles the http.RoundTripper for httputil reverse proxies.
type ProxyBuilder struct {
bufferPool *bufferPool
transportManager TransportManager
semConvMetricsRegistry *metrics.SemConvMetricsRegistry
}
// NewProxyBuilder creates a new ProxyBuilder.
func NewProxyBuilder(transportManager TransportManager, semConvMetricsRegistry *metrics.SemConvMetricsRegistry) *ProxyBuilder {
return &ProxyBuilder{
bufferPool: newBufferPool(),
transportManager: transportManager,
semConvMetricsRegistry: semConvMetricsRegistry,
}
}
// Update does nothing.
func (r *ProxyBuilder) Update(_ map[string]*dynamic.ServersTransport) {}
// Build builds a new httputil.ReverseProxy with the given configuration.
func (r *ProxyBuilder) Build(cfgName string, targetURL *url.URL, shouldObserve, passHostHeader, preservePath bool, flushInterval time.Duration) (http.Handler, error) {
roundTripper, err := r.transportManager.GetRoundTripper(cfgName)
if err != nil {
return nil, fmt.Errorf("getting RoundTripper: %w", err)
}
if shouldObserve {
// Wrapping the roundTripper with the Tracing roundTripper,
// to handle the reverseProxy client span creation.
roundTripper = newObservabilityRoundTripper(r.semConvMetricsRegistry, roundTripper)
}
return buildSingleHostProxy(targetURL, passHostHeader, preservePath, flushInterval, roundTripper, r.bufferPool), nil
}