Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds request IP address template placeholders #1713

Merged
merged 1 commit into from
Feb 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/reference/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ Template placeholder is replaced by the value that is looked up in the following
* request url query (if starts with `request.query.` prefix, e.g `${request.query.q}` is replaced by `q` query parameter value)
* request headers (if starts with `request.header.` prefix, e.g `${request.header.Content-Type}` is replaced by `Content-Type` request header value)
* request cookies (if starts with `request.cookie.` prefix, e.g `${request.cookie.PHPSESSID}` is replaced by `PHPSESSID` request cookie value)
* request IP address
- `${request.source}` - first IP address from `X-Forwarded-For` header or request remote IP address if header is absent, similar to [Source](predicates.md#source) predicate
- `${request.sourceFromLast}` - last IP address from `X-Forwarded-For` header or request remote IP address if header is absent, similar to [SourceFromLast](predicates.md#sourcefromlast) predicate
- `${request.clientIP}` - request remote IP address similar to [ClientIP](predicates.md#clientip) predicate
* response headers (if starts with `response.header.` prefix, e.g `${response.header.Location}` is replaced by `Location` response header value)
* filter context path parameters (e.g. `${id}` is replaced by `id` path parameter value)

Expand Down
14 changes: 13 additions & 1 deletion eskip/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
package eskip

import (
"net"
"net/http"
"regexp"
"strings"

snet "github.com/zalando/skipper/net"
)

var placeholderRegexp = regexp.MustCompile(`\$\{([^{}]+)\}`)
Expand Down Expand Up @@ -71,8 +74,17 @@ func (t *Template) ApplyContext(ctx TemplateContext) (string, bool) {
}
return ""
}
if key == "request.path" {
switch key {
case "request.path":
return ctx.Request().URL.Path
case "request.source":
return snet.RemoteHost(ctx.Request()).String()
case "request.sourceFromLast":
return snet.RemoteHostFromLast(ctx.Request()).String()
case "request.clientIP":
if host, _, err := net.SplitHostPort(ctx.Request().RemoteAddr); err == nil {
return host
}
}
if ctx.Response() != nil {
if h := strings.TrimPrefix(key, "response.header."); h != key {
Expand Down
59 changes: 59 additions & 0 deletions eskip/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,65 @@ func TestTemplateApplyContext(t *testing.T) {
},
"Hello one two three four five",
true,
}, {
"request source and X-Forwarded-For present",
"${request.source}",
&filtertest.Context{
FRequest: &http.Request{
RemoteAddr: "192.168.0.1:9876",
Header: http.Header{
"X-Forwarded-For": []string{"203.0.113.195, 70.41.3.18, 150.172.238.178"},
},
},
},
"203.0.113.195",
true,
}, {
"request source and X-Forwarded-For absent",
"${request.source}",
&filtertest.Context{
FRequest: &http.Request{
RemoteAddr: "192.168.0.1:9876",
},
},
"192.168.0.1",
true,
}, {
"request sourceFromLast and X-Forwarded-For present",
"${request.sourceFromLast}",
&filtertest.Context{
FRequest: &http.Request{
RemoteAddr: "192.168.0.1:9876",
Header: http.Header{
"X-Forwarded-For": []string{"203.0.113.195, 70.41.3.18, 150.172.238.178"},
},
},
},
"150.172.238.178",
true,
}, {
"request sourceFromLast and X-Forwarded-For absent",
"${request.sourceFromLast}",
&filtertest.Context{
FRequest: &http.Request{
RemoteAddr: "192.168.0.1:9876",
},
},
"192.168.0.1",
true,
}, {
"request clientIP (ignores X-Forwarded-For)",
"${request.clientIP}",
&filtertest.Context{
FRequest: &http.Request{
RemoteAddr: "192.168.0.1:9876",
Header: http.Header{
"X-Forwarded-For": []string{"203.0.113.195, 70.41.3.18, 150.172.238.178"},
},
},
},
"192.168.0.1",
true,
},
} {
t.Run(ti.name, func(t *testing.T) {
Expand Down