2018-11-14 12:18:03 +03:00
package stripprefixregex
import (
"context"
"net/http"
2019-09-03 21:32:03 +03:00
"regexp"
2018-11-14 12:18:03 +03:00
"strings"
"github.com/opentracing/opentracing-go/ext"
2020-09-16 16:46:04 +03:00
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/log"
"github.com/traefik/traefik/v2/pkg/middlewares"
"github.com/traefik/traefik/v2/pkg/middlewares/stripprefix"
"github.com/traefik/traefik/v2/pkg/tracing"
2018-11-14 12:18:03 +03:00
)
const (
typeName = "StripPrefixRegex"
)
// StripPrefixRegex is a middleware used to strip prefix from an URL request.
type stripPrefixRegex struct {
2019-09-03 21:32:03 +03:00
next http . Handler
expressions [ ] * regexp . Regexp
name string
2018-11-14 12:18:03 +03:00
}
// New builds a new StripPrefixRegex middleware.
2019-07-10 10:26:04 +03:00
func New ( ctx context . Context , next http . Handler , config dynamic . StripPrefixRegex , name string ) ( http . Handler , error ) {
2019-09-13 20:28:04 +03:00
log . FromContext ( middlewares . GetLoggerCtx ( ctx , name , typeName ) ) . Debug ( "Creating middleware" )
2018-11-14 12:18:03 +03:00
stripPrefix := stripPrefixRegex {
2019-09-03 21:32:03 +03:00
next : next ,
name : name ,
2018-11-14 12:18:03 +03:00
}
2019-09-03 21:32:03 +03:00
for _ , exp := range config . Regex {
reg , err := regexp . Compile ( strings . TrimSpace ( exp ) )
if err != nil {
return nil , err
}
stripPrefix . expressions = append ( stripPrefix . expressions , reg )
2018-11-14 12:18:03 +03:00
}
return & stripPrefix , nil
}
func ( s * stripPrefixRegex ) GetTracingInformation ( ) ( string , ext . SpanKindEnum ) {
return s . name , tracing . SpanKindNoneEnum
}
func ( s * stripPrefixRegex ) ServeHTTP ( rw http . ResponseWriter , req * http . Request ) {
2019-09-03 21:32:03 +03:00
for _ , exp := range s . expressions {
parts := exp . FindStringSubmatch ( req . URL . Path )
if len ( parts ) > 0 && len ( parts [ 0 ] ) > 0 {
prefix := parts [ 0 ]
if ! strings . HasPrefix ( req . URL . Path , prefix ) {
continue
}
2018-11-14 12:18:03 +03:00
2019-09-03 21:32:03 +03:00
req . Header . Add ( stripprefix . ForwardedPrefixHeader , prefix )
2018-11-14 12:18:03 +03:00
2019-11-14 12:32:05 +03:00
req . URL . Path = ensureLeadingSlash ( strings . Replace ( req . URL . Path , prefix , "" , 1 ) )
2019-09-03 21:32:03 +03:00
if req . URL . RawPath != "" {
2019-11-14 12:32:05 +03:00
req . URL . RawPath = ensureLeadingSlash ( req . URL . RawPath [ len ( prefix ) : ] )
2019-09-03 21:32:03 +03:00
}
2018-11-14 12:18:03 +03:00
2019-11-14 12:32:05 +03:00
req . RequestURI = req . URL . RequestURI ( )
2019-09-03 21:32:03 +03:00
s . next . ServeHTTP ( rw , req )
return
}
2018-11-14 12:18:03 +03:00
}
2019-09-03 21:32:03 +03:00
s . next . ServeHTTP ( rw , req )
2018-11-14 12:18:03 +03:00
}
func ensureLeadingSlash ( str string ) string {
2019-11-14 12:32:05 +03:00
if str == "" {
return str
}
if str [ 0 ] == '/' {
return str
}
return "/" + str
2018-11-14 12:18:03 +03:00
}