package urlrewrite import ( "context" "net/http" "path" "strings" "github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/traefik/traefik/v3/pkg/middlewares" "go.opentelemetry.io/otel/trace" ) const ( typeName = "URLRewrite" ) type urlRewrite struct { name string next http.Handler hostname *string path *string pathPrefix *string } // NewURLRewrite creates a URL rewrite middleware. func NewURLRewrite(ctx context.Context, next http.Handler, conf dynamic.URLRewrite, name string) http.Handler { logger := middlewares.GetLogger(ctx, name, typeName) logger.Debug().Msg("Creating middleware") return urlRewrite{ name: name, next: next, hostname: conf.Hostname, path: conf.Path, pathPrefix: conf.PathPrefix, } } func (u urlRewrite) GetTracingInformation() (string, string, trace.SpanKind) { return u.name, typeName, trace.SpanKindInternal } func (u urlRewrite) ServeHTTP(rw http.ResponseWriter, req *http.Request) { newPath := req.URL.Path if u.path != nil && u.pathPrefix == nil { newPath = *u.path } if u.path != nil && u.pathPrefix != nil { newPath = path.Join(*u.path, strings.TrimPrefix(req.URL.Path, *u.pathPrefix)) // add the trailing slash if needed, as path.Join removes trailing slashes. if strings.HasSuffix(req.URL.Path, "/") && !strings.HasSuffix(newPath, "/") { newPath += "/" } } req.URL.Path = newPath req.URL.RawPath = req.URL.EscapedPath() req.RequestURI = req.URL.RequestURI() if u.hostname != nil { req.Host = *u.hostname } u.next.ServeHTTP(rw, req) }