Do not evaluate templated URL in redirectRegex middleware
This commit is contained in:
parent
1c505903ff
commit
e9cccf6504
2 changed files with 6 additions and 38 deletions
|
@ -1,9 +1,6 @@
|
||||||
package redirect
|
package redirect
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"html/template"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -47,24 +44,17 @@ func (r *redirect) GetTracingInformation() (string, ext.SpanKindEnum) {
|
||||||
func (r *redirect) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
func (r *redirect) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
oldURL := rawURL(req)
|
oldURL := rawURL(req)
|
||||||
|
|
||||||
// If the Regexp doesn't match, skip to the next handler
|
// If the Regexp doesn't match, skip to the next handler.
|
||||||
if !r.regex.MatchString(oldURL) {
|
if !r.regex.MatchString(oldURL) {
|
||||||
r.next.ServeHTTP(rw, req)
|
r.next.ServeHTTP(rw, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply a rewrite regexp to the URL
|
// Apply a rewrite regexp to the URL.
|
||||||
newURL := r.regex.ReplaceAllString(oldURL, r.replacement)
|
newURL := r.regex.ReplaceAllString(oldURL, r.replacement)
|
||||||
|
|
||||||
// replace any variables that may be in there
|
// Parse the rewritten URL and replace request URL with it.
|
||||||
rewrittenURL := &bytes.Buffer{}
|
parsedURL, err := url.Parse(newURL)
|
||||||
if err := applyString(newURL, rewrittenURL, req); err != nil {
|
|
||||||
r.errHandler.ServeHTTP(rw, req, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the rewritten URL and replace request URL with it
|
|
||||||
parsedURL, err := url.Parse(rewrittenURL.String())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.errHandler.ServeHTTP(rw, req, err)
|
r.errHandler.ServeHTTP(rw, req, err)
|
||||||
return
|
return
|
||||||
|
@ -78,7 +68,7 @@ func (r *redirect) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
req.URL = parsedURL
|
req.URL = parsedURL
|
||||||
|
|
||||||
// make sure the request URI corresponds the rewritten URL
|
// Make sure the request URI corresponds the rewritten URL.
|
||||||
req.RequestURI = req.URL.RequestURI()
|
req.RequestURI = req.URL.RequestURI()
|
||||||
r.next.ServeHTTP(rw, req)
|
r.next.ServeHTTP(rw, req)
|
||||||
}
|
}
|
||||||
|
@ -138,14 +128,3 @@ func rawURL(req *http.Request) string {
|
||||||
|
|
||||||
return strings.Join([]string{scheme, "://", host, port, uri}, "")
|
return strings.Join([]string{scheme, "://", host, port, uri}, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyString(in string, out io.Writer, req *http.Request) error {
|
|
||||||
t, err := template.New("t").Parse(in)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
data := struct{ Request *http.Request }{Request: req}
|
|
||||||
|
|
||||||
return t.Execute(out, data)
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||||
"github.com/traefik/traefik/v2/pkg/testhelpers"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRedirectRegexHandler(t *testing.T) {
|
func TestRedirectRegexHandler(t *testing.T) {
|
||||||
|
@ -35,16 +34,6 @@ func TestRedirectRegexHandler(t *testing.T) {
|
||||||
expectedURL: "https://foobar.com:443",
|
expectedURL: "https://foobar.com:443",
|
||||||
expectedStatus: http.StatusFound,
|
expectedStatus: http.StatusFound,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "use request header",
|
|
||||||
config: dynamic.RedirectRegex{
|
|
||||||
Regex: `^(?:http?:\/\/)(foo)(\.com)(:\d+)(.*)$`,
|
|
||||||
Replacement: `https://${1}{{ .Request.Header.Get "X-Foo" }}$2:443$4`,
|
|
||||||
},
|
|
||||||
url: "http://foo.com:80",
|
|
||||||
expectedURL: "https://foobar.com:443",
|
|
||||||
expectedStatus: http.StatusFound,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
desc: "URL doesn't match regex",
|
desc: "URL doesn't match regex",
|
||||||
config: dynamic.RedirectRegex{
|
config: dynamic.RedirectRegex{
|
||||||
|
@ -186,7 +175,7 @@ func TestRedirectRegexHandler(t *testing.T) {
|
||||||
method = test.method
|
method = test.method
|
||||||
}
|
}
|
||||||
|
|
||||||
req := testhelpers.MustNewRequest(method, test.url, nil)
|
req := httptest.NewRequest(method, test.url, nil)
|
||||||
if test.secured {
|
if test.secured {
|
||||||
req.TLS = &tls.ConnectionState{}
|
req.TLS = &tls.ConnectionState{}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue