Skip to content

Commit

Permalink
Feat: Pass encoded characters in path unchanged
Browse files Browse the repository at this point in the history
We enable passing substrings that represent encoded reserved symbols, like
`%2f` for `/`, in the path of a request.

NB: This does not enable using encoded characters in rewrite rules (e.g. in the
urlprefix directive).

Cf. fabiolb#347 and fabiolb#486
  • Loading branch information
Valentin Krasontovitsch authored and valentin-krasontovitsch committed Feb 2, 2020
1 parent 1c9dc1d commit 3ed8dc3
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
17 changes: 17 additions & 0 deletions route/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,37 @@ func (t *Target) BuildRedirectURL(requestURL *url.URL) {
Scheme: t.URL.Scheme,
Host: t.URL.Host,
Path: t.URL.Path,
RawPath: t.URL.Path,
RawQuery: t.URL.RawQuery,
}
// treat case of $path not separated with a / from host
if strings.HasSuffix(t.RedirectURL.Host, "$path") {
t.RedirectURL.Host = t.RedirectURL.Host[:len(t.RedirectURL.Host)-len("$path")]
t.RedirectURL.Path = "$path"
}
// remove / before $path in redirect url
if strings.Contains(t.RedirectURL.Path, "/$path") {
t.RedirectURL.Path = strings.Replace(t.RedirectURL.Path, "/$path", "$path", 1)
t.RedirectURL.RawPath = strings.Replace(t.RedirectURL.RawPath, "/$path", "$path", 1)
}
// insert passed request path, remove strip path, set quer
if strings.Contains(t.RedirectURL.Path, "$path") {
// replace in not raw path
t.RedirectURL.Path = strings.Replace(t.RedirectURL.Path, "$path", requestURL.Path, 1)
// replace in raw path - determine replacement first
var replaceRawPath string
if requestURL.RawPath == "" {
replaceRawPath = requestURL.Path
} else {
replaceRawPath = requestURL.RawPath
}
t.RedirectURL.RawPath = strings.Replace(t.RedirectURL.RawPath, "$path", replaceRawPath, 1)
// remove stip path
if t.StripPath != "" && strings.HasPrefix(t.RedirectURL.Path, t.StripPath) {
t.RedirectURL.Path = t.RedirectURL.Path[len(t.StripPath):]
t.RedirectURL.RawPath = t.RedirectURL.RawPath[len(t.StripPath):]
}
// set query
if t.RedirectURL.RawQuery == "" && requestURL.RawQuery != "" {
t.RedirectURL.RawQuery = requestURL.RawQuery
}
Expand Down
10 changes: 10 additions & 0 deletions route/target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ func TestTarget_BuildRedirectURL(t *testing.T) {
{req: "/abc/?aaa=1", want: "https://foo.com/bbb/abc/?aaa=1"},
},
},
{ // simple redirect to corresponding path with encoded char in path
route: "route add svc / http://bar.com/$path",
tests: []routeTest{
{req: "/%20", want: "http://bar.com/%20"},
{req: "/a%2fbc", want: "http://bar.com/a%2fbc"},
{req: "/a/b%22/c", want: "http://bar.com/a/b%22/c"},
{req: "/%2f/?aaa=1", want: "http://bar.com/%2f/?aaa=1"},
{req: "/%20/a%2f/", want: "http://bar.com/%20/a%2f/"},
},
},
{ // strip prefix
route: "route add svc /stripme http://bar.com/$path opts \"strip=/stripme\"",
tests: []routeTest{
Expand Down

0 comments on commit 3ed8dc3

Please sign in to comment.