Skip to content

Commit

Permalink
OPENAPI: added better logging to path rewriting. Specifically, if an …
Browse files Browse the repository at this point in the history
…identifier is provided in a path config, it now ends up in the log message.
  • Loading branch information
jacobm-splunk authored and daveshanley committed Jun 26, 2024
1 parent 0579e55 commit 1ec155c
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 67 deletions.
130 changes: 76 additions & 54 deletions config/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ const (
RewriteIdHeader = "RewriteId"
)

type PathRewrite struct {
RewrittenPath string
PathConfiguration *shared.WiretapPathConfig
}

func FindPaths(path string, configuration *shared.WiretapConfiguration) []*shared.WiretapPathConfig {
var foundConfigurations []*shared.WiretapPathConfig
for x := configuration.CompiledPaths.First(); x != nil; x = x.Next() {
Expand Down Expand Up @@ -72,7 +77,7 @@ func PathValidationAllowListed(path string, configuration *shared.WiretapConfigu
return false
}

func rewriteTaget(path string, pathConfig *shared.WiretapPathConfig, configuration *shared.WiretapConfiguration) string {
func rewriteTaget(path string, pathConfig *shared.WiretapPathConfig, configuration *shared.WiretapConfiguration) *PathRewrite {
scheme := "http://"
if pathConfig.Secure {
scheme = "https://"
Expand All @@ -83,7 +88,10 @@ func rewriteTaget(path string, pathConfig *shared.WiretapPathConfig, configurati
if path[0] != '/' && pathConfig.Target[len(pathConfig.Target)-1] != '/' {
path = fmt.Sprintf("/%s", path)
}
return fmt.Sprintf("%s%s%s", scheme, target, path)
return &PathRewrite{
RewrittenPath: fmt.Sprintf("%s%s%s", scheme, target, path),
PathConfiguration: pathConfig,
}
}

func FindPathWithRewriteId(paths []*shared.WiretapPathConfig, req *http.Request) *shared.WiretapPathConfig {
Expand All @@ -108,76 +116,90 @@ func FindPathWithRewriteId(paths []*shared.WiretapPathConfig, req *http.Request)
return nil
}

func RewritePath(path string, req *http.Request, configuration *shared.WiretapConfiguration) string {
func RewritePath(path string, req *http.Request, configuration *shared.WiretapConfiguration) *PathRewrite {
paths := FindPaths(path, configuration)
var replaced = path
if len(paths) > 0 {

var pathConfig *shared.WiretapPathConfig
// If there are no configurations that match the request path, we should crash out early
if len(paths) == 0 {
return &PathRewrite{
RewrittenPath: path,
PathConfiguration: nil,
}
}

// Check if request headers have rewrite id; if so, we should try to find a matching rewrite config
pathConfig = FindPathWithRewriteId(paths, req)
var pathConfig *shared.WiretapPathConfig

// if rewriteId not specified in request or not found, extract first path
if pathConfig == nil {
pathConfig = paths[0]
}
// Check if request headers have rewrite id; if so, we should try to find a matching rewrite config
pathConfig = FindPathWithRewriteId(paths, req)

// if rewriteId not specified in request or not found, extract first path
if pathConfig == nil {
pathConfig = paths[0]
}

replaced = ""

for _, globalIgnoreRewrite := range configuration.CompiledIgnorePathRewrite {
// If the current path matches the ignore rewrite, we should skip rewriting,
// and instead check if we even want to rewrite the target
if globalIgnoreRewrite.CompiledIgnoreRewrite.Match(path) {
if globalIgnoreRewrite.RewriteTarget {
return rewriteTaget(path, pathConfig, configuration)
} else {
pterm.Info.Printf("[wiretap] Not re-writing path '%s' due to global ignore rewrite configuration\n", path)
return path
for _, globalIgnoreRewrite := range configuration.CompiledIgnorePathRewrite {
// If the current path matches the ignore rewrite, we should skip rewriting,
// and instead check if we even want to rewrite the target
if globalIgnoreRewrite.CompiledIgnoreRewrite.Match(path) {
if globalIgnoreRewrite.RewriteTarget {
return rewriteTaget(path, pathConfig, configuration)
} else {
pterm.Info.Printf("[wiretap] Not re-writing path '%s' due to global ignore rewrite configuration\n", path)
return &PathRewrite{
RewrittenPath: path,
PathConfiguration: pathConfig,
}
}
}
}

for key := range pathConfig.CompiledPath.CompiledPathRewrite {
if pathConfig.CompiledPath.CompiledPathRewrite[key].MatchString(path) {

// Check if this path matches a local ignore rewrite. If so, then check if we need to rewrite the target
for _, ignoreRewrite := range pathConfig.CompiledIgnoreRewrite {
if ignoreRewrite.CompiledIgnoreRewrite.Match(path) {
if ignoreRewrite.RewriteTarget {
return rewriteTaget(path, pathConfig, configuration)
} else {
pterm.Info.Printf("[wiretap] Not re-writing path '%s' due to local ignore rewrite configuration\n", path)
return path
var replaced = ""

for key := range pathConfig.CompiledPath.CompiledPathRewrite {
if pathConfig.CompiledPath.CompiledPathRewrite[key].MatchString(path) {

// Check if this path matches a local ignore rewrite. If so, then check if we need to rewrite the target
for _, ignoreRewrite := range pathConfig.CompiledIgnoreRewrite {
if ignoreRewrite.CompiledIgnoreRewrite.Match(path) {
if ignoreRewrite.RewriteTarget {
return rewriteTaget(path, pathConfig, configuration)
} else {
pterm.Info.Printf("[wiretap] Not re-writing path '%s' due to local ignore rewrite configuration\n", path)
return &PathRewrite{
RewrittenPath: path,
PathConfiguration: pathConfig,
}
}
}
}

replace := pathConfig.PathRewrite[key]
rex := pathConfig.CompiledPath.CompiledPathRewrite[key]
replacedPath := rex.ReplaceAllString(path, replace)

scheme := "http://"
if pathConfig.Secure {
scheme = "https://"
}
if replacedPath[0] != '/' && pathConfig.Target[len(pathConfig.Target)-1] != '/' {
replacedPath = fmt.Sprintf("/%s", replacedPath)
}
target := strings.ReplaceAll(strings.ReplaceAll(configuration.ReplaceWithVariables(pathConfig.Target),
"http://", ""), "https://", "")
replace := pathConfig.PathRewrite[key]
rex := pathConfig.CompiledPath.CompiledPathRewrite[key]
replacedPath := rex.ReplaceAllString(path, replace)

replaced = fmt.Sprintf("%s%s%s", scheme, target, replacedPath)
break
scheme := "http://"
if pathConfig.Secure {
scheme = "https://"
}
}
if replacedPath[0] != '/' && pathConfig.Target[len(pathConfig.Target)-1] != '/' {
replacedPath = fmt.Sprintf("/%s", replacedPath)
}
target := strings.ReplaceAll(strings.ReplaceAll(configuration.ReplaceWithVariables(pathConfig.Target),
"http://", ""), "https://", "")

// no rewriting, just replace target.
if replaced == "" {
replaced = rewriteTaget(path, pathConfig, configuration)
replaced = fmt.Sprintf("%s%s%s", scheme, target, replacedPath)
break
}
}

// If we already replaced the path, then we should just return that
if replaced != "" {
return &PathRewrite{
RewrittenPath: replaced,
PathConfiguration: pathConfig,
}
}

return replaced
// Otherwise, there's no rewriting, and we just try to replace the target.
return rewriteTaget(path, pathConfig, configuration)
}
16 changes: 8 additions & 8 deletions config/paths_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ paths:
wcConfig.CompilePaths()

path := RewritePath("/pb33f/test/123/slap/a/chap", nil, &wcConfig)
assert.Equal(t, "http://localhost:9093/123/slap/a/chap", path)
assert.Equal(t, "http://localhost:9093/123/slap/a/chap", path.RewrittenPath)

}

Expand All @@ -105,7 +105,7 @@ paths:
wcConfig.CompilePaths()

path := RewritePath("/pb33f/cakes/test/123/smelly/jelly", nil, &wcConfig)
assert.Equal(t, "https://localhost:9093/flat/jam/123/smelly/jelly", path)
assert.Equal(t, "https://localhost:9093/flat/jam/123/smelly/jelly", path.RewrittenPath)

}

Expand All @@ -125,7 +125,7 @@ paths:
wcConfig.CompilePaths()

path := RewritePath("/pb33f/cakes/test/lemons/321/smelly/jelly", nil, &wcConfig)
assert.Equal(t, "https://localhost:9093/slippy/cakes/whip/321/lemons/smelly/jelly", path)
assert.Equal(t, "https://localhost:9093/slippy/cakes/whip/321/lemons/smelly/jelly", path.RewrittenPath)

}

Expand All @@ -148,7 +148,7 @@ paths:
c.CompilePaths()

path := RewritePath("/en-US/burgerd/__raw/noKetchupPlease/nobody/", nil, &c)
assert.Equal(t, "http://localhost:80/noKetchupPlease/-/", path)
assert.Equal(t, "http://localhost:80/noKetchupPlease/-/", path.RewrittenPath)

}

Expand All @@ -171,7 +171,7 @@ paths:
c.CompilePaths()

path := RewritePath("/en-US/burgerd/__raw/noKetchupPlease/nobody/yummy/yum?onions=true", nil, &c)
assert.Equal(t, "http://localhost:80/noKetchupPlease/-/yummy/yum?onions=true", path)
assert.Equal(t, "http://localhost:80/noKetchupPlease/-/yummy/yum?onions=true", path.RewrittenPath)

}

Expand Down Expand Up @@ -210,7 +210,7 @@ paths:
}

path := RewritePath("/pb33f/test/id", req, &c)
assert.Equal(t, "https://localhost:9093/pb33f/correct/id", path)
assert.Equal(t, "https://localhost:9093/pb33f/correct/id", path.RewrittenPath)

actualConfig := FindPathWithRewriteId(pathConfigs, req)
expectedConfig := pathConfigs[1] // second config is the valid one
Expand Down Expand Up @@ -244,7 +244,7 @@ paths:
}

path := RewritePath("/pb33f/test/id", req, &c)
assert.Equal(t, "https://localhost:9093/pb33f/correct/id", path)
assert.Equal(t, "https://localhost:9093/pb33f/correct/id", path.RewrittenPath)

}

Expand Down Expand Up @@ -277,7 +277,7 @@ paths:
}

path := RewritePath("/pb33f/test/id", req, &c)
assert.Equal(t, "https://localhost:9093/pb33f/correct/id", path)
assert.Equal(t, "https://localhost:9093/pb33f/correct/id", path.RewrittenPath)

}

Expand Down
11 changes: 8 additions & 3 deletions daemon/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,17 @@ func (ws *WiretapService) callAPI(req *http.Request) (*http.Response, error) {

// lookup path and determine if we need to redirect it.
replaced := config.RewritePath(req.URL.Path, req, wiretapConfig)
if replaced != req.URL.Path {
newUrl, _ := url.Parse(replaced)
if replaced.RewrittenPath != req.URL.Path {
newUrl, _ := url.Parse(replaced.RewrittenPath)
if req.URL.RawQuery != "" {
newUrl.RawQuery = req.URL.RawQuery
}
pterm.Info.Printf("[wiretap] Re-writing path '%s' to '%s'\n", req.URL.String(), newUrl.String())
if replaced.PathConfiguration != nil && replaced.PathConfiguration.RewriteId != "" {
rewriteId := replaced.PathConfiguration.RewriteId
pterm.Info.Printf("[wiretap] Re-writing path '%s' to '%s' with identifier '%s'\n", req.URL.String(), newUrl.String(), rewriteId)
} else {
pterm.Info.Printf("[wiretap] Re-writing path '%s' to '%s'\n", req.URL.String(), newUrl.String())
}
req.URL = newUrl
}

Expand Down
4 changes: 2 additions & 2 deletions daemon/build_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@ func BuildHttpTransaction(build HttpTransactionConfig) *HttpTransaction {

replaced := config.RewritePath(build.NewRequest.URL.Path, newReq, cf)
var newUrl = build.NewRequest.URL
if replaced != "" {
if replaced.RewrittenPath != "" {
var e error
newUrl, e = url.Parse(replaced)
newUrl, e = url.Parse(replaced.RewrittenPath)
if e != nil {
newUrl = build.NewRequest.URL
pterm.Error.Printf("major configuration problem: cannot parse URL: `%s`: %s", replaced, e.Error())
Expand Down

0 comments on commit 1ec155c

Please sign in to comment.