Skip to content

Commit 79a9536

Browse files
committed
add check for host rewrite to DynamicMiddleware (js plugin)
1 parent d46c967 commit 79a9536

File tree

2 files changed

+117
-4
lines changed

2 files changed

+117
-4
lines changed

gateway/mw_js_plugin.go

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"time"
1717

1818
"github.com/TykTechnologies/tyk/apidef"
19+
"github.com/TykTechnologies/tyk/ctx"
1920

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

246-
r.URL, err = url.Parse(newRequestData.Request.URL)
247-
if err != nil {
248-
return nil, http.StatusOK
249-
}
247+
d.SetUrlAndCheckHostRewrite(newRequestData.Request.URL, r)
250248

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

324+
func (d *DynamicMiddleware) SetUrlAndCheckHostRewrite(newTarget string, r *http.Request) error {
325+
326+
// During looping target can be API name
327+
// Need make it compatible with URL parser
328+
if strings.HasPrefix(newTarget, LoopScheme) {
329+
newTarget = LoopHostRE.ReplaceAllStringFunc(newTarget, func(match string) string {
330+
host := strings.TrimPrefix(match, LoopScheme+"://")
331+
return LoopingUrl(host)
332+
})
333+
}
334+
335+
newAsURL, errParseNew := url.Parse(newTarget)
336+
if errParseNew != nil {
337+
return errParseNew
338+
}
339+
340+
if shouldRewriteHost(r.URL, newAsURL) {
341+
log.Debug("Detected a host rewrite in pattern!")
342+
d.Spec.URLRewriteEnabled = true
343+
setCtxValue(r, ctx.RetainHost, true)
344+
}
345+
346+
r.URL = newAsURL
347+
348+
return nil
349+
}
350+
326351
// --- Utility functions during startup to ensure a sane VM is present for each API Def ----
327352

328353
type JSVM struct {

gateway/mw_js_plugin_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,3 +1049,91 @@ func testJSVM_Auth(t *testing.T, hashKeys bool) {
10491049
},
10501050
}...)
10511051
}
1052+
1053+
func TestDynamicMiddleware_SetUrlAndCheckHostRewrite(t *testing.T) {
1054+
ts := StartTest(nil)
1055+
defer ts.Close()
1056+
1057+
type args struct {
1058+
oldPath string
1059+
newTarget string
1060+
}
1061+
1062+
tests := []struct {
1063+
name string
1064+
args args
1065+
errExpected bool
1066+
retainHostVal interface{}
1067+
}{
1068+
{
1069+
name: "no host rewrite",
1070+
args: args{
1071+
oldPath: "/hello",
1072+
newTarget: "/status",
1073+
},
1074+
errExpected: false,
1075+
retainHostVal: nil,
1076+
},
1077+
{
1078+
name: "invalid new path",
1079+
args: args{
1080+
oldPath: "/hello",
1081+
newTarget: "http:// example.com/status",
1082+
},
1083+
errExpected: true,
1084+
retainHostVal: nil,
1085+
},
1086+
{
1087+
name: "host rewrite",
1088+
args: args{
1089+
oldPath: "/hello",
1090+
newTarget: "http://example.com/status",
1091+
},
1092+
errExpected: false,
1093+
retainHostVal: true,
1094+
},
1095+
{
1096+
name: "scheme in oldPath - host rewrite",
1097+
args: args{
1098+
oldPath: "http://tyk-gateway/hello",
1099+
newTarget: "http://example.com/status",
1100+
},
1101+
errExpected: false,
1102+
retainHostVal: true,
1103+
},
1104+
{
1105+
name: "scheme in oldPath - no host rewrite",
1106+
args: args{
1107+
oldPath: "http://tyk-gateway/hello",
1108+
newTarget: "/status",
1109+
},
1110+
errExpected: false,
1111+
retainHostVal: nil,
1112+
},
1113+
{
1114+
name: "same host for new and old URL",
1115+
args: args{
1116+
oldPath: "http://tyk-gateway/hello",
1117+
newTarget: "http://tyk-gateway/status",
1118+
},
1119+
errExpected: false,
1120+
retainHostVal: nil,
1121+
},
1122+
}
1123+
for _, tt := range tests {
1124+
t.Run(tt.name, func(t *testing.T) {
1125+
ts := StartTest(nil)
1126+
defer ts.Close()
1127+
1128+
m := &DynamicMiddleware{
1129+
BaseMiddleware: &BaseMiddleware{
1130+
Spec: &APISpec{APIDefinition: &apidef.APIDefinition{}},
1131+
Gw: ts.Gw,
1132+
}}
1133+
r := httptest.NewRequest("GET", tt.args.oldPath, nil)
1134+
err := m.SetUrlAndCheckHostRewrite(tt.args.newTarget, r)
1135+
assert.Equal(t, tt.errExpected, err != nil)
1136+
assert.Equal(t, tt.retainHostVal, r.Context().Value(ctx.RetainHost))
1137+
})
1138+
}
1139+
}

0 commit comments

Comments
 (0)