Skip to content

Commit

Permalink
add check for host rewrite to DynamicMiddleware (js plugin)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamdjones committed Dec 20, 2024
1 parent d46c967 commit 79a9536
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 4 deletions.
33 changes: 29 additions & 4 deletions gateway/mw_js_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"time"

"github.com/TykTechnologies/tyk/apidef"
"github.com/TykTechnologies/tyk/ctx"

"github.com/robertkrimen/otto"
_ "github.com/robertkrimen/otto/underscore"
Expand Down Expand Up @@ -243,10 +244,7 @@ func (d *DynamicMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Reques
// make sure request's body can be re-read again
nopCloseRequestBody(r)

r.URL, err = url.Parse(newRequestData.Request.URL)
if err != nil {
return nil, http.StatusOK
}
d.SetUrlAndCheckHostRewrite(newRequestData.Request.URL, r)

ignoreCanonical := d.Gw.GetConfig().IgnoreCanonicalMIMEHeaderKey
// Delete and set headers
Expand Down Expand Up @@ -323,6 +321,33 @@ func mapStrsToIfaces(m map[string]string) map[string]interface{} {
return m2
}

func (d *DynamicMiddleware) SetUrlAndCheckHostRewrite(newTarget string, r *http.Request) error {

// During looping target can be API name
// Need make it compatible with URL parser
if strings.HasPrefix(newTarget, LoopScheme) {
newTarget = LoopHostRE.ReplaceAllStringFunc(newTarget, func(match string) string {
host := strings.TrimPrefix(match, LoopScheme+"://")
return LoopingUrl(host)
})
}

newAsURL, errParseNew := url.Parse(newTarget)
if errParseNew != nil {
return errParseNew
}

if shouldRewriteHost(r.URL, newAsURL) {
log.Debug("Detected a host rewrite in pattern!")
d.Spec.URLRewriteEnabled = true
setCtxValue(r, ctx.RetainHost, true)
}

r.URL = newAsURL

return nil
}

// --- Utility functions during startup to ensure a sane VM is present for each API Def ----

type JSVM struct {
Expand Down
88 changes: 88 additions & 0 deletions gateway/mw_js_plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1049,3 +1049,91 @@ func testJSVM_Auth(t *testing.T, hashKeys bool) {
},
}...)
}

func TestDynamicMiddleware_SetUrlAndCheckHostRewrite(t *testing.T) {
ts := StartTest(nil)
defer ts.Close()

type args struct {
oldPath string
newTarget string
}

tests := []struct {
name string
args args
errExpected bool
retainHostVal interface{}
}{
{
name: "no host rewrite",
args: args{
oldPath: "/hello",
newTarget: "/status",
},
errExpected: false,
retainHostVal: nil,
},
{
name: "invalid new path",
args: args{
oldPath: "/hello",
newTarget: "http:// example.com/status",
},
errExpected: true,
retainHostVal: nil,
},
{
name: "host rewrite",
args: args{
oldPath: "/hello",
newTarget: "http://example.com/status",
},
errExpected: false,
retainHostVal: true,
},
{
name: "scheme in oldPath - host rewrite",
args: args{
oldPath: "http://tyk-gateway/hello",
newTarget: "http://example.com/status",
},
errExpected: false,
retainHostVal: true,
},
{
name: "scheme in oldPath - no host rewrite",
args: args{
oldPath: "http://tyk-gateway/hello",
newTarget: "/status",
},
errExpected: false,
retainHostVal: nil,
},
{
name: "same host for new and old URL",
args: args{
oldPath: "http://tyk-gateway/hello",
newTarget: "http://tyk-gateway/status",
},
errExpected: false,
retainHostVal: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ts := StartTest(nil)
defer ts.Close()

m := &DynamicMiddleware{
BaseMiddleware: &BaseMiddleware{
Spec: &APISpec{APIDefinition: &apidef.APIDefinition{}},
Gw: ts.Gw,
}}
r := httptest.NewRequest("GET", tt.args.oldPath, nil)
err := m.SetUrlAndCheckHostRewrite(tt.args.newTarget, r)
assert.Equal(t, tt.errExpected, err != nil)
assert.Equal(t, tt.retainHostVal, r.Context().Value(ctx.RetainHost))
})
}
}

0 comments on commit 79a9536

Please sign in to comment.