Skip to content

Commit

Permalink
[TT-1944/TT-12550/TT-12865] Backport critical fixes (#6513)
Browse files Browse the repository at this point in the history
### **User description**
<!-- Provide a general summary of your changes in the Title above -->

## Description
Backport critical fixes from PRs in order
#6480
#6437
#6475
#6506



## Related Issue
https://tyktech.atlassian.net/browse/TT-1944
https://tyktech.atlassian.net/browse/TT-12550
https://tyktech.atlassian.net/browse/TT-12865

## Motivation and Context

<!-- Why is this change required? What problem does it solve? -->

## How This Has Been Tested

<!-- Please describe in detail how you tested your changes -->
<!-- Include details of your testing environment, and the tests -->
<!-- you ran to see how your change affects other areas of the code,
etc. -->
<!-- This information is helpful for reviewers and QA. -->

## Screenshots (if appropriate)

## Types of changes

<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Refactoring or add test (improvements in base code or adds test
coverage to functionality)

## Checklist

<!-- Go over all the following points, and put an `x` in all the boxes
that apply -->
<!-- If there are no documentation updates required, mark the item as
checked. -->
<!-- Raise up any additional concerns not covered by the checklist. -->

- [ ] I ensured that the documentation is up to date
- [ ] I explained why this PR updates go.mod in detail with reasoning
why it's required
- [ ] I would like a code coverage CI quality gate exception and have
explained why


___

### **PR Type**
Enhancement, Bug fix, Tests


___

### **Description**
- Introduced new configuration options for path prefix and suffix
matching to enhance URL matching capabilities.
- Refactored URLSpec to improve regex generation and logging for URL
matching.
- Enhanced GranularAccessMiddleware with improved URL matching logic and
error handling.
- Added utility functions for handling path regex preparation and
matching, with caching for performance.
- Updated and added test cases to verify new URL matching logic and
configurations.
- Added regression tests for issue 12865 to ensure stability and
correctness of new features.


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>4
files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>config.go</strong><dd><code>Introduce path prefix and
suffix matching configuration</code>&nbsp; &nbsp; </dd></summary>
<hr>

config/config.go

<li>Added new configuration options for path prefix and suffix
matching.<br> <li> Enhanced documentation for new URL matching
behavior.<br>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/6513/files#diff-fe44f09c4d5977b5f5eaea29170b6a0748819c9d02271746a20d81a5f3efca17">+43/-0</a>&nbsp;
&nbsp; </td>

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>api_definition.go</strong><dd><code>Refactor and
enhance URLSpec for better URL matching</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

gateway/api_definition.go

<li>Refactored URLSpec to use private fields.<br> <li> Enhanced regex
generation for URL matching.<br> <li> Improved logging for URL matching
process.<br>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/6513/files#diff-0cf80174bbafb36f6d4f4308ebbd971b2833b76a936bad568220aa1a4ba0ee8b">+52/-36</a>&nbsp;
</td>

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>mw_granular_access.go</strong><dd><code>Enhance URL
matching and error handling in
GranularAccessMiddleware</code></dd></summary>
<hr>

gateway/mw_granular_access.go

<li>Enhanced URL matching in GranularAccessMiddleware.<br> <li> Improved
error handling and logging.<br>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/6513/files#diff-618f7d55751d572562a29506a13beba2da969436e974f8b51df7d9708c925436">+79/-12</a>&nbsp;
</td>

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>mux.go</strong><dd><code>Add utility functions for path
regex handling</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

internal/httputil/mux.go

<li>Introduced utility functions for path regex preparation and
matching.<br> <li> Implemented caching for path regex patterns.<br>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/6513/files#diff-3d9ee5f5e946d72e6f2ae662ff03ee5253bbdc15203d2e4f6e9f46c13011ebf8">+139/-0</a>&nbsp;
</td>

</tr>                    

</table></details></td></tr><tr><td><strong>Tests</strong></td><td><details><summary>4
files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>api_definition_test.go</strong><dd><code>Update and add
test cases for enhanced URL matching</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

gateway/api_definition_test.go

<li>Updated test cases to reflect changes in URL matching logic.<br>
<li> Added new test scenarios for prefix and suffix matching.<br>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/6513/files#diff-2394daab6fdc5f8dc234699c80c0548947ee3d68d2e33858258d73a8b5eb6f44">+15/-33</a>&nbsp;
</td>

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>mw_granular_access_test.go</strong><dd><code>Add tests
for enhanced URL matching in
GranularAccessMiddleware</code></dd></summary>
<hr>

gateway/mw_granular_access_test.go

<li>Added tests for new URL matching logic in
GranularAccessMiddleware.<br> <li> Verified behavior with different path
configurations.<br>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/6513/files#diff-8e0d7cfef26688edd7d08334d955039dab5deb3caf860d29eff6d09894eaba20">+50/-24</a>&nbsp;
</td>

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>mux_test.go</strong><dd><code>Add tests for path regex
utility functions</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

internal/httputil/mux_test.go

<li>Added tests for new path regex utility functions.<br> <li> Verified
regex preparation and matching logic.<br>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/6513/files#diff-8f7ce1891e221d7adb9e68f2e951f33edfbde2128187abb6e837ac01952d7888">+162/-0</a>&nbsp;
</td>

</tr>                    

<tr>
  <td>
    <details>
<summary><strong>issue_12865_test.go</strong><dd><code>Add regression
tests for issue 12865</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

tests/regression/issue_12865_test.go

<li>Added regression tests for issue 12865.<br> <li> Tested various path
matching configurations.<br>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/6513/files#diff-1a4f9c47cb4152844d641098b6e7ca8e5e8739eefdec7178f9437750d11db6ec">+171/-0</a>&nbsp;
</td>

</tr>                    
</table></details></td></tr><tr><td><strong>Configuration
changes</strong></td><td><details><summary>1 files</summary><table>
<tr>
  <td>
    <details>
<summary><strong>schema.json</strong><dd><code>Update schema for new
path matching options</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

cli/linter/schema.json

- Updated schema to include new path matching configuration options.



</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/6513/files#diff-103cec746d3e61d391c5a67c171963f66fea65d651d704d5540e60aa5d574f46">+6/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>                    
</table></details></td></tr></tr></tbody></table>

___

> 💡 **PR-Agent usage**:
>Comment `/help` on the PR to get a list of all available PR-Agent tools
and their descriptions

---------

Co-authored-by: Tit Petric <tit.petric@monotek.net>
Co-authored-by: Tit Petric <tit@tyk.io>
  • Loading branch information
3 people authored Sep 13, 2024
1 parent 7cbb40a commit 6e2634d
Show file tree
Hide file tree
Showing 20 changed files with 1,413 additions and 125 deletions.
6 changes: 3 additions & 3 deletions .taskfiles/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ tasks:
package:
sh: go mod edit -json | jq .Module.Path -r
packages:
sh: go list ./... | sed -e 's|{{.package}}|.|g'
sh: go list ./... | tail -n +2 | sed -e 's|{{.package}}|.|g'
cmds:
- defer: { task: services:down }
- rm -rf coverage && mkdir -p coverage
- for: { var: packages, as: package }
cmd: |-
gotestsum --no-color=false --hide-summary=skipped --raw-command \
go test -p 1 -json {{.testArgs}} {{.args}} -count=1 -v \
go test -p 1 -parallel 1 -json {{.testArgs}} {{.args}} -count=1 -v \
-coverprofile=coverage/{{.package | replace "." "gateway" | replace "/" "-"}}.cov {{.package}} | head -n -2
integration-combined:
Expand All @@ -66,7 +66,7 @@ tasks:
- defer: { task: services:down }
- defer: { task: report }
- rm -rf coverage && mkdir -p coverage
- go test -p 1 -json {{.testArgs}} {{.args}} -coverprofile=coverage/{{.product}}-all.cov -count=1 -v ./... > coverage/{{.product}}-all.json
- go test -p 1 -parallel 1 -json {{.testArgs}} {{.args}} -coverprofile=coverage/{{.product}}-all.cov -count=1 -v ./... > coverage/{{.product}}-all.json

plugin:race:
dir: '{{.dir}}'
Expand Down
6 changes: 6 additions & 0 deletions cli/linter/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,12 @@
"enable_strict_routes": {
"type": "boolean"
},
"enable_path_prefix_matching": {
"type": "boolean"
},
"enable_path_suffix_matching": {
"type": "boolean"
},
"flush_interval": {
"type": "integer"
},
Expand Down
43 changes: 43 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,49 @@ type HttpServerOptionsConfig struct {
// Regular expressions and parameterized routes will be left alone regardless of this setting.
EnableStrictRoutes bool `json:"enable_strict_routes"`

// EnablePathPrefixMatching changes the URL matching from wildcard mode to prefix mode.
// For example, `/json` matches `*/json*` by current default behaviour.
// If prefix matching is enabled, the match will be performed as a prefix match (`/json*`).
//
// The `/json` url would be matched as `^/json` against the following paths:
//
// - Full listen path and versioning URL (`/listen-path/v4/json`)
// - Stripped listen path URL (`/v4/json`)
// - Stripped version information (`/json`) - match.
//
// If versioning is disabled then the following URLs are considered:
//
// - Full listen path and endpoint (`/listen-path/json`)
// - Stripped listen path (`/json`) - match.
//
// For inputs that start with `/`, a prefix match is ensured by
// prepending the start of string `^` caret.
//
// For all other cases, the pattern remains unmodified.
//
// Combine this option with `enable_path_suffix_matching` to achieve
// exact url matching with `/json` being evaluated as `^/json$`.
EnablePathPrefixMatching bool `json:"enable_path_prefix_matching"`

// EnablePathSuffixMatching changes the URL matching to match as a suffix.
// For example: `/json` is matched as `/json$` against the following paths:
//
// - Full listen path and versioning URL (`/listen-path/v4/json`)
// - Stripped listen path URL (`/v4/json`)
// - Stripped version information (`/json`) - match.
//
// If versioning is disabled then the following URLs are considered:
//
// - Full listen path and endpoint (`/listen-path/json`)
// - Stripped listen path (`/json`) - match.
//
// If the input pattern already ends with a `$` (`/json$`)
// then the pattern remains unmodified.
//
// Combine this option with `enable_path_prefix_matching` to achieve
// exact url matching with `/json` being evaluated as `^/json$`.
EnablePathSuffixMatching bool `json:"enable_path_suffix_matching"`

// Disable TLS verification. Required if you are using self-signed certificates.
SSLInsecureSkipVerify bool `json:"ssl_insecure_skip_verify"`

Expand Down
88 changes: 52 additions & 36 deletions gateway/api_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/getkin/kin-openapi/routers"

"github.com/TykTechnologies/tyk/internal/graphengine"
"github.com/TykTechnologies/tyk/internal/httputil"

"github.com/getkin/kin-openapi/routers/gorillamux"

Expand All @@ -35,7 +36,6 @@ import (

sprig "github.com/Masterminds/sprig/v3"

"github.com/gorilla/mux"
"github.com/sirupsen/logrus"

circuit "github.com/TykTechnologies/circuitbreaker"
Expand Down Expand Up @@ -134,7 +134,8 @@ const (
// path is on any of the white, black or ignored lists. This is generated as part of the
// configuration init
type URLSpec struct {
Spec *regexp.Regexp
spec *regexp.Regexp

Status URLStatus
MethodActions map[string]apidef.EndpointMethodMeta
Whitelist apidef.EndPointMeta
Expand Down Expand Up @@ -818,15 +819,27 @@ func (a APIDefinitionLoader) getPathSpecs(apiVersionDef apidef.VersionInfo, conf
}

func (a APIDefinitionLoader) generateRegex(stringSpec string, newSpec *URLSpec, specType URLStatus, conf config.Config) {
apiLangIDsRegex := regexp.MustCompile(`{([^}]*)}`)
asRegexStr := apiLangIDsRegex.ReplaceAllString(stringSpec, `([^/]*)`)
var (
pattern string
err error
)
// Hook per-api settings here via newSpec *URLSpec
isPrefixMatch := conf.HttpServerOptions.EnablePathPrefixMatching
isSuffixMatch := conf.HttpServerOptions.EnablePathSuffixMatching
isIgnoreCase := newSpec.IgnoreCase || conf.IgnoreEndpointCase

pattern = httputil.PreparePathRegexp(stringSpec, isPrefixMatch, isSuffixMatch)

// Case insensitive match
if newSpec.IgnoreCase || conf.IgnoreEndpointCase {
asRegexStr = "(?i)" + asRegexStr
if isIgnoreCase {
pattern = "(?i)" + pattern
}
asRegex, _ := regexp.Compile(asRegexStr)

asRegex, err := regexp.Compile(pattern)
log.WithError(err).Debugf("URLSpec: %s => %s type=%d", stringSpec, pattern, specType)

newSpec.Status = specType
newSpec.Spec = asRegex
newSpec.spec = asRegex
}

func (a APIDefinitionLoader) compilePathSpec(paths []string, specType URLStatus, conf config.Config) []URLSpec {
Expand Down Expand Up @@ -1488,7 +1501,7 @@ func (a *APISpec) getURLStatus(stat URLStatus) RequestStatus {
// URLAllowedAndIgnored checks if a url is allowed and ignored.
func (a *APISpec) URLAllowedAndIgnored(r *http.Request, rxPaths []URLSpec, whiteListStatus bool) (RequestStatus, interface{}) {
for i := range rxPaths {
if !rxPaths[i].Spec.MatchString(r.URL.Path) {
if !rxPaths[i].matchesPath(r.URL.Path, a) {
continue
}

Expand All @@ -1499,7 +1512,7 @@ func (a *APISpec) URLAllowedAndIgnored(r *http.Request, rxPaths []URLSpec, white

// Check if ignored
for i := range rxPaths {
if !rxPaths[i].Spec.MatchString(r.URL.Path) {
if !rxPaths[i].matchesPath(r.URL.Path, a) {
continue
}

Expand Down Expand Up @@ -1629,7 +1642,7 @@ func (a *APISpec) getVersionFromRequest(r *http.Request) string {

return vName
case apidef.URLLocation:
uPath := a.StripListenPath(r, r.URL.Path)
uPath := a.StripListenPath(r.URL.Path)
uPath = strings.TrimPrefix(uPath, "/"+a.Slug)

// First non-empty part of the path is the version ID
Expand Down Expand Up @@ -1771,8 +1784,32 @@ func (a *APISpec) Version(r *http.Request) (*apidef.VersionInfo, RequestStatus)
return &version, StatusOk
}

func (a *APISpec) StripListenPath(r *http.Request, path string) string {
return stripListenPath(a.Proxy.ListenPath, path)
// StripListenPath will strip the listen path from the URL, keeping version in tact.
func (a *APISpec) StripListenPath(reqPath string) string {
return httputil.StripListenPath(a.Proxy.ListenPath, reqPath)
}

// StripVersionPath will strip the version from the URL. The input URL
// should already have listen path stripped.
func (a *APISpec) StripVersionPath(reqPath string) string {
// First part of the url is the version fragment
part := strings.Split(strings.Trim(reqPath, "/"), "/")[0]

matchesUrlVersioningPattern := true
if a.VersionDefinition.UrlVersioningPattern != "" {
re, err := regexp.Compile(a.VersionDefinition.UrlVersioningPattern)
if err != nil {
log.Error("Error compiling versioning pattern: ", err)
} else {
matchesUrlVersioningPattern = re.Match([]byte(part))
}
}

if (a.VersionDefinition.StripVersioningData || a.VersionDefinition.StripPath) && matchesUrlVersioningPattern {
return strings.Replace(reqPath, "/"+part+"/", "/", 1)
}

return reqPath
}

func (a *APISpec) SanitizeProxyPaths(r *http.Request) {
Expand All @@ -1782,9 +1819,9 @@ func (a *APISpec) SanitizeProxyPaths(r *http.Request) {

log.Debug("Stripping proxy listen path: ", a.Proxy.ListenPath)

r.URL.Path = a.StripListenPath(r, r.URL.Path)
r.URL.Path = a.StripListenPath(r.URL.Path)
if r.URL.RawPath != "" {
r.URL.RawPath = a.StripListenPath(r, r.URL.RawPath)
r.URL.RawPath = a.StripListenPath(r.URL.RawPath)
}

log.Debug("Upstream path is: ", r.URL.Path)
Expand Down Expand Up @@ -1834,27 +1871,6 @@ func (r *RoundRobin) WithLen(len int) int {
return int(cur) % len
}

func stripListenPath(listenPath, path string) (res string) {
defer func() {
if !strings.HasPrefix(res, "/") {
res = "/" + res
}
}()

if !strings.Contains(listenPath, "{") {
res = strings.TrimPrefix(path, listenPath)
return
}

tmp := new(mux.Route).PathPrefix(listenPath)
s, err := tmp.GetPathRegexp()
if err != nil {
return path
}
reg := regexp.MustCompile(s)
return reg.ReplaceAllString(path, "")
}

func (s *APISpec) hasVirtualEndpoint() bool {
for _, version := range s.VersionData.Versions {
for _, virtual := range version.ExtendedPaths.Virtual {
Expand Down
48 changes: 15 additions & 33 deletions gateway/api_definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func TestWhitelist(t *testing.T) {

ts.Run(t, []test.TestCase{
// Should mock path
{Path: "/reply/", Code: http.StatusOK, BodyMatch: "flump"},
{Path: "/reply/", Code: http.StatusForbidden},
{Path: "/reply/123", Code: http.StatusOK, BodyMatch: "flump"},
// Should get original upstream response
{Path: "/get", Code: http.StatusOK, BodyMatch: `"Url":"/get"`},
Expand Down Expand Up @@ -147,14 +147,14 @@ func TestWhitelist(t *testing.T) {

ts.Run(t, []test.TestCase{
{Path: "/foo", Code: http.StatusForbidden},
{Path: "/foo/", Code: http.StatusOK},
{Path: "/foo/", Code: http.StatusForbidden},
{Path: "/foo/1", Code: http.StatusOK},
{Path: "/foo/1/bar", Code: http.StatusForbidden},
{Path: "/foo/1/bar/", Code: http.StatusOK},
{Path: "/foo/1/bar/", Code: http.StatusForbidden},
{Path: "/foo/1/bar/1", Code: http.StatusOK},
{Path: "/", Code: http.StatusForbidden},
{Path: "/baz", Code: http.StatusForbidden},
{Path: "/baz/", Code: http.StatusOK},
{Path: "/baz/", Code: http.StatusForbidden},
{Path: "/baz/1", Code: http.StatusOK},
{Path: "/baz/1/", Code: http.StatusOK},
{Path: "/baz/1/bazz", Code: http.StatusOK},
Expand Down Expand Up @@ -412,13 +412,15 @@ func TestConflictingPaths(t *testing.T) {

ts.Run(t, []test.TestCase{
// Should ignore auth check
{Method: "POST", Path: "/customer-servicing/documents/metadata/purge", Code: http.StatusOK},
{Method: "GET", Path: "/customer-servicing/documents/metadata/{id}", Code: http.StatusOK},
{Method: "POST", Path: "/metadata/purge", Code: http.StatusOK},
{Method: "GET", Path: "/metadata/{id}", Code: http.StatusOK},
}...)
}

func TestIgnored(t *testing.T) {
ts := StartTest(nil)
ts := StartTest(func(c *config.Config) {
c.HttpServerOptions.EnablePathPrefixMatching = true
})
defer ts.Close()

t.Run("Extended Paths", func(t *testing.T) {
Expand All @@ -445,14 +447,13 @@ func TestIgnored(t *testing.T) {
{Path: "/ignored/literal", Code: http.StatusOK},
{Path: "/ignored/123/test", Code: http.StatusOK},
// Only GET is ignored
{Method: "POST", Path: "/ext/ignored/literal", Code: 401},
{Method: "POST", Path: "/ext/ignored/literal", Code: http.StatusUnauthorized},

{Path: "/", Code: 401},
{Path: "/", Code: http.StatusUnauthorized},
}...)
})

t.Run("Simple Paths", func(t *testing.T) {

ts.Gw.BuildAndLoadAPI(func(spec *APISpec) {
UpdateAPIVersion(spec, "v1", func(v *apidef.VersionInfo) {
v.Paths.Ignored = []string{"/ignored/literal", "/ignored/{id}/test"}
Expand All @@ -467,15 +468,14 @@ func TestIgnored(t *testing.T) {
// Should ignore auth check
{Path: "/ignored/literal", Code: http.StatusOK},
{Path: "/ignored/123/test", Code: http.StatusOK},
// All methods ignored
{Method: "POST", Path: "/ext/ignored/literal", Code: http.StatusOK},

{Path: "/", Code: 401},
{Method: "POST", Path: "/ext/ignored/literal", Code: http.StatusUnauthorized},

{Path: "/", Code: http.StatusUnauthorized},
}...)
})

t.Run("With URL rewrite", func(t *testing.T) {

ts.Gw.BuildAndLoadAPI(func(spec *APISpec) {
UpdateAPIVersion(spec, "v1", func(v *apidef.VersionInfo) {
v.ExtendedPaths.URLRewrite = []apidef.URLRewriteMeta{{
Expand Down Expand Up @@ -510,7 +510,6 @@ func TestIgnored(t *testing.T) {
})

t.Run("Case Sensitivity", func(t *testing.T) {

spec := BuildAPI(func(spec *APISpec) {
UpdateAPIVersion(spec, "v1", func(v *apidef.VersionInfo) {
v.ExtendedPaths.Ignored = []apidef.EndPointMeta{{Path: "/Foo", IgnoreCase: false}, {Path: "/bar", IgnoreCase: true}}
Expand Down Expand Up @@ -1032,7 +1031,7 @@ func (ts *Test) testPrepareDefaultVersion() (string, *APISpec) {
func TestGetVersionFromRequest(t *testing.T) {

versionInfo := apidef.VersionInfo{}
versionInfo.Paths.WhiteList = []string{"/foo"}
versionInfo.Paths.WhiteList = []string{"/foo", "/v3/foo"}
versionInfo.Paths.BlackList = []string{"/bar"}

t.Run("Header location", func(t *testing.T) {
Expand Down Expand Up @@ -1339,23 +1338,6 @@ func TestAPIExpiration(t *testing.T) {
}
}

func TestStripListenPath(t *testing.T) {
assert.Equal(t, "/get", stripListenPath("/listen", "/listen/get"))
assert.Equal(t, "/get", stripListenPath("/listen/", "/listen/get"))
assert.Equal(t, "/get", stripListenPath("listen", "listen/get"))
assert.Equal(t, "/get", stripListenPath("listen/", "listen/get"))
assert.Equal(t, "/", stripListenPath("/listen/", "/listen/"))
assert.Equal(t, "/", stripListenPath("/listen", "/listen"))
assert.Equal(t, "/", stripListenPath("listen/", ""))

assert.Equal(t, "/get", stripListenPath("/{_:.*}/post/", "/listen/post/get"))
assert.Equal(t, "/get", stripListenPath("/{_:.*}/", "/listen/get"))
assert.Equal(t, "/get", stripListenPath("/pre/{_:.*}/", "/pre/listen/get"))
assert.Equal(t, "/", stripListenPath("/{_:.*}", "/listen"))
assert.Equal(t, "/get", stripListenPath("/{myPattern:foo|bar}", "/foo/get"))
assert.Equal(t, "/anything/get", stripListenPath("/{myPattern:foo|bar}", "/anything/get"))
}

func TestAPISpec_SanitizeProxyPaths(t *testing.T) {
a := APISpec{APIDefinition: &apidef.APIDefinition{}}
a.Proxy.ListenPath = "/listen/"
Expand Down
2 changes: 1 addition & 1 deletion gateway/handler_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (e *ErrorHandler) HandleError(w http.ResponseWriter, r *http.Request, errMs
}

if e.Spec.Proxy.StripListenPath {
r.URL.Path = e.Spec.StripListenPath(r, r.URL.Path)
r.URL.Path = e.Spec.StripListenPath(r.URL.Path)
}

oauthClientID := ""
Expand Down
Loading

0 comments on commit 6e2634d

Please sign in to comment.